From 4bbbf25b1235f2105f0648c5a444b3f74ca449f3 Mon Sep 17 00:00:00 2001 From: Antoine Rousseau <_antoine_@metalu.net> Date: Wed, 9 Oct 2024 12:48:15 +0200 Subject: [PATCH 1/2] on Linux and Mac, allow to lock the device with flock(), if it's already locked elsewhere then close it --- comport.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/comport.c b/comport.c index 426f301..5d83c45 100644 --- a/comport.c +++ b/comport.c @@ -43,6 +43,7 @@ JZ 20210321 allow the user to specify a device pattern as creation argument #include #include /* for ioctl DTR */ #include /* for TERMIO ioctl calls */ +#include /* for flock() */ #include #include #define HANDLE int @@ -74,6 +75,8 @@ typedef struct comport int comhandle; /* holds the comport handle */ struct termios oldcom_termio; /* save the old com config */ struct termios com_termio; /* for the new com config */ + t_bool x_lock; /* the file descriptor has to be locked when opened */ + t_bool x_locked; /* the file descriptor has been locked */ #endif /* device specifications */ @@ -933,6 +936,30 @@ static int set_break(t_comport *x, int on) return ((status < 0)? status: (on != 0)); } +static t_bool lock_fd(t_comport *x, int fd, int lock) +{ + int operation = (lock ? LOCK_EX : LOCK_UN) | LOCK_NB; + int ret; + + if((lock == x->x_locked) || (fd == INVALID_HANDLE_VALUE)) return 1; + ret = flock(fd, operation); + if(ret == 0) { + x->x_locked = lock; + } + return (ret == 0); +} + +static void check_lock(t_comport *x) +{ + if(x->x_lock) { + if(!lock_fd(x, x->comhandle, 1)) { + comport_verbose("[comport] file descriptor of %s is already locked, closing!\n", + x->serial_device->s_name); + comport_close(x); + } + } +} + static int open_serial(unsigned int com_num, t_comport *x) { int fd; @@ -1073,6 +1100,7 @@ static int close_serial(t_comport *x) if(fd != INVALID_HANDLE_VALUE) { + lock_fd(x, fd, 0); tcsetattr(fd, TCSANOW, tios); close(fd); comport_verbose("[comport] closed port %i (%s)", x->comport, x->serial_device->s_name); @@ -1480,6 +1508,9 @@ static void *comport_new(t_symbol *s, int argc, t_atom *argv) x->x_verbose = 0; x->x_inprocess = 0; +#ifndef _WIN32 + x->x_lock = x->x_locked = 0; +#endif return x; } @@ -1654,6 +1685,13 @@ static void comport_close(t_comport *x) if (x->x_status_outlet != NULL) outlet_float(x->x_status_outlet, (float)x->comport); } +static void comport_lock(t_comport *x, t_floatarg f) +{ +#ifndef _WIN32 + x->x_lock = (f != 0); +#endif +} + static void comport_open(t_comport *x, t_floatarg f) { if(x->comhandle != INVALID_HANDLE_VALUE) @@ -1662,6 +1700,9 @@ static void comport_open(t_comport *x, t_floatarg f) x->comhandle = open_serial(f,x); clock_delay(x->x_clock, x->x_deltime); +#ifndef _WIN32 + check_lock(x); +#endif } /* @@ -1677,6 +1718,9 @@ static void comport_devicename(t_comport *x, t_symbol *s) x->comhandle = open_serial(USE_DEVICENAME,x); clock_delay(x->x_clock, x->x_deltime); +#ifndef _WIN32 + check_lock(x); +#endif } static void comport_print(t_comport *x, t_symbol *s, int argc, t_atom *argv) @@ -1986,6 +2030,7 @@ void comport_setup(void) class_addmethod(comport_class, (t_method)comport_parity, gensym("parity"), A_FLOAT, 0); class_addmethod(comport_class, (t_method)comport_xonxoff, gensym("xonxoff"), A_FLOAT, 0); class_addmethod(comport_class, (t_method)comport_hupcl, gensym("hupcl"), A_FLOAT, 0); + class_addmethod(comport_class, (t_method)comport_lock, gensym("lock"), A_FLOAT, 0); class_addmethod(comport_class, (t_method)comport_close, gensym("close"), 0); class_addmethod(comport_class, (t_method)comport_open, gensym("open"), A_FLOAT, 0); class_addmethod(comport_class, (t_method)comport_devicename, gensym("devicename"), A_SYMBOL, 0); From 6469552ae2cfa43ee95826de047f8eb2ee456cc7 Mon Sep 17 00:00:00 2001 From: Antoine Rousseau <_antoine_@metalu.net> Date: Wed, 9 Oct 2024 12:48:59 +0200 Subject: [PATCH 2/2] update help patch: document [lock( and localize $0-comctl --- comport-help.pd | 241 ++++++++++++++++++++++++------------------------ 1 file changed, 123 insertions(+), 118 deletions(-) diff --git a/comport-help.pd b/comport-help.pd index d6a6b4d..a0bb5c1 100644 --- a/comport-help.pd +++ b/comport-help.pd @@ -1,4 +1,4 @@ -#N canvas 456 56 1151 653 10; +#N canvas 399 53 1151 653 10; #X obj 15 49 cnv 18 220 400 empty empty Query\ info 20 12 1 16 #e0e0e0 #404040 0; #X obj 246 49 cnv 18 320 400 empty empty Open\ /\ close\ /\ control 20 12 1 16 #e0e0e0 #404040 0; #X obj 577 49 cnv 18 250 400 empty empty Configure 20 12 1 16 #e0e0e0 #404040 0; @@ -9,7 +9,6 @@ #X msg 584 218 parity 0; #X text 642 217 parity 1=even \, -1=odd \, 0=off; #X text 633 105 databits 5 \, 6 \, 7 \, 8; -#X obj 584 428 s comctl; #X text 654 255 use handshake xon/off 1=on 0=off, f 22; #X text 647 299 cts/rts hardwarehandshake 1=on 0=off, f 25; #X obj 854 95 hsl 128 15 0 255 0 0 empty empty empty -2 -6 0 8 #fcfcfc #000000 #000000 0 1; @@ -31,7 +30,6 @@ #X msg 258 273 baud 9600; #X msg 239 254 baud 4800; #X msg 220 235 baud 2400; -#X obj 427 459 s comctl; #X msg 201 216 baud 1800; #X msg 182 197 baud 1200; #X msg 163 178 baud 600; @@ -58,7 +56,6 @@ #X text 478 159 (1-115200); #X obj 415 199 t b f; #X text 386 142 On Windows some other baud rates might work:; -#X obj 968 420 s comctl; #X msg 946 380 baud 4e+06; #X msg 927 361 baud 3.5e+06; #X msg 908 342 baud 3e+06; @@ -74,46 +71,48 @@ #X msg 718 152 baud 230400; #X text 714 134 Other baud rates might be avaiable \, depending on the OS:; #X text 8 8 Standard baud rates for linux:; -#X connect 0 0 8 0; -#X connect 1 0 8 0; -#X connect 2 0 8 0; -#X connect 3 0 8 0; -#X connect 4 0 8 0; -#X connect 5 0 8 0; -#X connect 6 0 8 0; -#X connect 7 0 8 0; -#X connect 9 0 8 0; -#X connect 10 0 8 0; -#X connect 11 0 8 0; -#X connect 12 0 8 0; -#X connect 13 0 8 0; -#X connect 14 0 8 0; -#X connect 15 0 8 0; -#X connect 16 0 8 0; -#X connect 17 0 8 0; -#X connect 18 0 8 0; -#X connect 19 0 8 0; -#X connect 23 0 8 0; +#X obj 427 459 s \$0-comctl; +#X obj 968 420 s \$0-comctl; +#X connect 0 0 49 0; +#X connect 1 0 49 0; +#X connect 2 0 49 0; +#X connect 3 0 49 0; +#X connect 4 0 49 0; +#X connect 5 0 49 0; +#X connect 6 0 49 0; +#X connect 7 0 49 0; +#X connect 8 0 49 0; +#X connect 9 0 49 0; +#X connect 10 0 49 0; +#X connect 11 0 49 0; +#X connect 12 0 49 0; +#X connect 13 0 49 0; +#X connect 14 0 49 0; +#X connect 15 0 49 0; +#X connect 16 0 49 0; +#X connect 17 0 49 0; +#X connect 18 0 49 0; +#X connect 22 0 49 0; +#X connect 26 0 28 0; #X connect 27 0 29 0; #X connect 28 0 30 0; -#X connect 29 0 31 0; -#X connect 30 1 33 0; -#X connect 31 0 23 0; -#X connect 33 0 27 0; -#X connect 33 1 29 1; -#X connect 36 0 35 0; -#X connect 37 0 35 0; -#X connect 38 0 35 0; -#X connect 39 0 35 0; -#X connect 40 0 35 0; -#X connect 41 0 35 0; -#X connect 42 0 35 0; -#X connect 43 0 35 0; -#X connect 44 0 35 0; -#X connect 45 0 35 0; -#X connect 46 0 35 0; -#X connect 47 0 35 0; -#X connect 48 0 35 0; +#X connect 29 1 32 0; +#X connect 30 0 22 0; +#X connect 32 0 26 0; +#X connect 32 1 28 1; +#X connect 34 0 50 0; +#X connect 35 0 50 0; +#X connect 36 0 50 0; +#X connect 37 0 50 0; +#X connect 38 0 50 0; +#X connect 39 0 50 0; +#X connect 40 0 50 0; +#X connect 41 0 50 0; +#X connect 42 0 50 0; +#X connect 43 0 50 0; +#X connect 44 0 50 0; +#X connect 45 0 50 0; +#X connect 46 0 50 0; #X restore 584 81 pd bauds; #X msg 584 262 xonxoff \$1; #X obj 595 241 tgl 15 0 empty empty empty 0 -6 0 8 #e8e828 #f430f0 #000000 0 1; @@ -134,10 +133,8 @@ #X text 849 78 You can send bytes directly (0-255):; #X text 38 620 2006-2010 Martin Peach; #X text 15 606 (C) 1998-2015 IEM Winfried Ritsch GPL (see LICENSE.txt); -#X obj 851 226 s comctl; #X msg 852 278 print hello_world; #X text 850 257 send some text:; -#X obj 852 309 s comctl; #N canvas 200 243 450 300 send_from_keyboard 0; #X obj 48 122 key; #X obj 48 146 sel 0; @@ -154,7 +151,6 @@ #X restore 944 161 pd send_from_keyboard; #X msg 984 396 break \$1; #X obj 984 277 tgl 15 0 empty empty empty 0 -6 0 8 #e8e828 #f430f0 #000000 0 1; -#X obj 984 421 s comctl; #X obj 1003 325 t b b; #X obj 1003 304 bng 15 250 50 0 empty empty empty 17 7 0 10 #fcfcfc #000000 #000000; #X obj 1030 348 del 50; @@ -162,14 +158,12 @@ #X msg 1030 371 0; #X text 1000 287 send a 50ms break; #X text 982 258 set break condition:; -#X obj 23 380 s comctl; #X text 54 305 print usage info; #X msg 23 350 verbose \$1; #X obj 37 329 tgl 15 0 empty empty empty 0 -6 0 8 #e8e828 #f430f0 #000000 0 1; #X text 57 271 send status list to right outlet, f 23; #X text 64 116 list available ports to right outlet, f 25; #X text 54 328 verbose to console; -#X obj 254 360 s comctl; #X msg 254 211 pollintervall 1; #X msg 254 168 close; #X msg 254 82 open 1; @@ -199,7 +193,6 @@ #X text 299 167 close Serial port; #X obj 22 507 cnv 18 142 25 empty empty empty 20 12 1 16 #feffc6 #404040 0; #X obj 25 511 comport 1 9600, f 22; -#X obj 25 486 r comctl; #X obj 25 565 print incoming bytes; #X obj 25 541 spigot; #X obj 70 541 tgl 15 0 empty empty empty 0 -6 0 8 #e8e828 #f430f0 #000000 0 1; @@ -231,73 +224,85 @@ #X text 97 154 only print USB devices; #X msg 23 184 ports usb; #X text 87 178 list only USB ports to right outlet, f 24; -#X connect 5 0 10 0; -#X connect 6 0 10 0; -#X connect 7 0 10 0; -#X connect 13 0 83 0; -#X connect 14 0 10 0; -#X connect 15 0 14 0; -#X connect 16 0 17 0; -#X connect 17 0 10 0; -#X connect 18 0 58 0; -#X connect 19 0 58 0; -#X connect 20 0 58 0; -#X connect 21 0 43 0; -#X connect 24 0 10 0; -#X connect 25 0 24 0; -#X connect 26 0 10 0; -#X connect 27 0 26 0; -#X connect 29 0 43 0; -#X connect 30 0 58 0; -#X connect 31 0 43 0; -#X connect 34 0 38 0; -#X connect 35 0 38 0; -#X connect 36 0 38 0; -#X connect 38 0 10 0; -#X connect 44 0 46 0; -#X connect 47 0 43 0; -#X connect 48 0 50 0; -#X connect 49 0 48 0; -#X connect 51 0 54 0; -#X connect 51 1 53 0; -#X connect 52 0 51 0; -#X connect 53 0 55 0; -#X connect 54 0 48 0; -#X connect 55 0 48 0; -#X connect 60 0 58 0; -#X connect 61 0 60 0; -#X connect 66 0 65 0; -#X connect 67 0 65 0; -#X connect 68 0 65 0; -#X connect 69 0 65 0; -#X connect 71 0 65 0; -#X connect 72 0 65 0; -#X connect 73 0 65 0; -#X connect 75 0 76 0; -#X connect 76 0 65 0; -#X connect 83 0 21 0; -#X connect 87 0 90 0; -#X connect 87 1 105 0; -#X connect 88 0 87 0; -#X connect 90 0 89 0; -#X connect 91 0 90 1; -#X connect 94 0 92 0; -#X connect 94 1 93 0; -#X connect 94 2 99 0; -#X connect 99 0 95 0; -#X connect 99 1 96 0; -#X connect 99 2 97 0; -#X connect 99 3 110 0; -#X connect 105 0 100 0; -#X connect 105 1 101 0; -#X connect 105 2 102 0; -#X connect 105 3 103 0; -#X connect 105 4 104 0; -#X connect 105 5 94 0; -#X connect 110 0 107 0; -#X connect 110 1 108 0; -#X connect 110 2 113 0; -#X connect 113 0 111 0; -#X connect 113 1 112 0; -#X connect 116 0 58 0; -#X connect 118 0 58 0; +#X msg 254 382 lock 1; +#X obj 584 428 s \$0-comctl; +#X obj 254 425 s \$0-comctl; +#X obj 25 486 r \$0-comctl; +#X obj 23 380 s \$0-comctl; +#X obj 852 309 s \$0-comctl; +#X obj 851 226 s \$0-comctl; +#X obj 984 421 s \$0-comctl; +#X obj 269 362 tgl 15 0 empty empty empty 0 -6 0 8 #e8e828 #fc0400 #000000 0 1; +#X text 301 360 lock the device so other [comport]s cannot open it. Will take effect on next opening. Note: on Windows \, lock is always enabled., f 43; +#X connect 5 0 114 0; +#X connect 6 0 114 0; +#X connect 7 0 114 0; +#X connect 12 0 77 0; +#X connect 13 0 114 0; +#X connect 14 0 13 0; +#X connect 15 0 16 0; +#X connect 16 0 114 0; +#X connect 17 0 117 0; +#X connect 18 0 117 0; +#X connect 19 0 117 0; +#X connect 20 0 119 0; +#X connect 23 0 114 0; +#X connect 24 0 23 0; +#X connect 25 0 114 0; +#X connect 26 0 25 0; +#X connect 28 0 119 0; +#X connect 29 0 117 0; +#X connect 30 0 119 0; +#X connect 33 0 37 0; +#X connect 34 0 37 0; +#X connect 35 0 37 0; +#X connect 37 0 114 0; +#X connect 42 0 118 0; +#X connect 44 0 119 0; +#X connect 45 0 120 0; +#X connect 46 0 45 0; +#X connect 47 0 50 0; +#X connect 47 1 49 0; +#X connect 48 0 47 0; +#X connect 49 0 51 0; +#X connect 50 0 45 0; +#X connect 51 0 45 0; +#X connect 55 0 117 0; +#X connect 56 0 55 0; +#X connect 60 0 115 0; +#X connect 61 0 115 0; +#X connect 62 0 115 0; +#X connect 63 0 115 0; +#X connect 65 0 115 0; +#X connect 66 0 115 0; +#X connect 67 0 115 0; +#X connect 69 0 70 0; +#X connect 70 0 115 0; +#X connect 77 0 20 0; +#X connect 81 0 83 0; +#X connect 81 1 98 0; +#X connect 83 0 82 0; +#X connect 84 0 83 1; +#X connect 87 0 85 0; +#X connect 87 1 86 0; +#X connect 87 2 92 0; +#X connect 92 0 88 0; +#X connect 92 1 89 0; +#X connect 92 2 90 0; +#X connect 92 3 103 0; +#X connect 98 0 93 0; +#X connect 98 1 94 0; +#X connect 98 2 95 0; +#X connect 98 3 96 0; +#X connect 98 4 97 0; +#X connect 98 5 87 0; +#X connect 103 0 100 0; +#X connect 103 1 101 0; +#X connect 103 2 106 0; +#X connect 106 0 104 0; +#X connect 106 1 105 0; +#X connect 109 0 117 0; +#X connect 111 0 117 0; +#X connect 113 0 115 0; +#X connect 116 0 81 0; +#X connect 121 0 113 0;