]> datadissipation.net git - ust.git/commitdiff
added support for locking the device
authorgit <redacted>
Thu, 19 Feb 2026 17:01:34 +0000 (12:01 -0500)
committergit <redacted>
Thu, 19 Feb 2026 17:01:34 +0000 (12:01 -0500)
config.def.h
ust.c

index 68e1a157a3241bab20509e462d270c654f79d3d8..1e68dd1167d32395a42f306a021aed1ec65920ff 100644 (file)
@@ -7,8 +7,10 @@ const size_t scratchwsz = 256;
 const size_t scratchrsz = 256;
 
 /* `nanosleep()` values inside the read and write loops */
-const long swritedelay = 0;
-const long nswritedelay = 1000000;
+const long swritedelay = 0; /* seconds */
+const long nswritedelay = 1000000; /* nanoseconds */
+
+/* other names follow the same logic as above */
 
 const long sreaddelay = 0;
 const long nsreaddelay = 1000000;
@@ -17,6 +19,9 @@ const long nsreaddelay = 1000000;
 const long spulsedelay = 0;
 const long nspulsedelay = 1000000;
 
+/* lock the opened device */
+const int exclusive = 1; /*(0|1)*/
+
 /* escape character for interactive use */
 const char escapechar = '~';
 
@@ -45,6 +50,7 @@ int verbose = 0; /*(0|1)*/
  * NetBSD:
  * dty* - opening does not block, does not wait for DCD
  * tty* - 'dial-in' device, blocks opening until a connection is established
+ * ttyU* - USB variant
  */
 char line[16] = "/dev/cuau0";
 
@@ -77,25 +83,24 @@ int canonical = 0; /*(0|1)*/
 /*
  * CR and LF (NL) translation options
  */
-
-typedef struct{
-       int crinlf;
-       int crtolf;
-       int lfincr;
-       int lftocr;
-       int nocr;
-       int nolf;
-} CRLFOpt;
-
-CRLFOpt tropts = {0};
-CRLFOpt itropts = {0};
+CRLFOpt tropts = { 0 };
+CRLFOpt itropts = { 0 };
 
 /*
  * backspace: setting to one makes `^H` the backspace character, `^?` otherwise
  */
 int backspace = 0; /*(0|1)*/
 
-int minchars = 1;
+/*
+ * the minimum of characters input before sending them to the line
+ */
+int minchars = 1; /*(>=1)*/
+
+/*
+ * delay between single characters being sent if the buffer has
+ * more than 1 (redirected stdin, writing a file)
+ * in nanoseconds
+ */
 long chardelay = 0;
 
 /*
diff --git a/ust.c b/ust.c
index 9e507c8a7645be21d09f206f7beda76c03de5eee..4517e0c37770ba97095e6f2eb4fb5072005402d2 100644 (file)
--- a/ust.c
+++ b/ust.c
@@ -1,6 +1,7 @@
+#include <sys/ioctl.h>
+
 #include <errno.h>
 #include <fcntl.h>
-#include <getopt.h>
 #include <limits.h>
 #include <signal.h>
 #include <stdarg.h>
@@ -8,8 +9,9 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+
+#include <getopt.h>
 #include <pthread.h>
-#include <sys/ioctl.h>
 
 #ifdef __linux__
  #include <asm/termbits.h>
@@ -18,8 +20,6 @@
  #include <termios.h>
 #endif
 
-#include "config.h"
-
 #define CR '\r'
 #define LF '\n'
 #define BS '\b'
@@ -42,6 +42,18 @@ typedef struct {
        ssize_t sizesm;
 } Sizes;
 
+typedef struct{
+       int crinlf;
+       int crtolf;
+       int lfincr;
+       int lftocr;
+       int nocr;
+       int nolf;
+} CRLFOpt;
+
+/* including here to access CRLFOpt */
+#include "config.h"
+
 static int gettermattr(int dv, void *strct);
 static int settermattr(int dv, const void *strct);
 static void settermspd(unsigned int lispeed, unsigned int lospeed, const void *strct);
@@ -63,9 +75,9 @@ static void sighandl(int signo);
 static void die(int code, const char *msg, ...);
 
 #ifdef __linux__
- static struct termios2 cntrl, origterm = {0}, newterm = {0};
+ static struct termios2 cntrl, origterm = { 0 }, newterm = { 0 };
 #else
- static struct termios cntrl, origterm = {0}, newterm = {0};
+ static struct termios cntrl, origterm = { 0 }, newterm = { 0 };
 #endif
 
 static Args bsargs = {DEL, DEL, 0};
@@ -126,9 +138,12 @@ settermspd(unsigned int lispeed, unsigned int lospeed, const void *strct)
 int
 openport()
 {
+       int flags;
+       struct flock fl = { 0 };
+
        if (verbose) fprintf(stderr, "opening \"%s\"\n", line);
 
-       fd = open(line, O_RDWR | O_NOCTTY | O_NDELAY);
+       fd = open(line, (O_RDWR | O_NOCTTY | O_NDELAY));
        if (fd == -1) {
                perror("error opening device");
                exit(1);
@@ -139,18 +154,32 @@ openport()
        if (!isatty(fd))
                die(2, "device \"%s\" is not a TTY\n", line);
 
-       int flags;
        flags = fcntl(fd, F_GETFL, 0);
        /* opened to check with non-blocking mode, now set to blocking */
        flags &= ~(O_NONBLOCK | O_NDELAY); 
-       if (fcntl(fd, F_SETFL, flags) == -1)
-               die(1, "failed to set the device to blocking mode\n");
+
+       if (fcntl(fd, F_SETFL, flags) == -1) {
+               perror("fcntl");
+               die(1, "exiting now\n");
+       }
                
        if (gettermattr(fd, &cntrl) == -1)
                 die(1, "failed to get device attributes\n");
-       
+
+       fl.l_type = F_WRLCK;
+       fl.l_whence = SEEK_SET;
+       fl.l_start = 0;
+       fl.l_len = 0;
+
+       if (exclusive) {
+               if (fcntl(fd, F_SETLK, &fl) == -1) {
+                       perror("fcntl");
+                       die(1, "failed to lock the device, exiting now\n");
+               }
+       }
+
        if (verbose) fprintf(stderr, "setting baudrate [RX:%u | TX:%u]\n", ispeed, ospeed);
-       
+
        settermspd(ispeed, ospeed, &cntrl);
        if (settermattr(fd, &cntrl) == -1)
                 die(2,"failed to set baudrate [RX:%u | TX:%u]\n",  ispeed, ospeed);
@@ -165,10 +194,10 @@ openport()
                cntrl.c_cflag |= PARENB;
        if (parity == 2)
                cntrl.c_cflag |= PARENB | PARODD;
-       
+
        if (settermattr(fd, &cntrl) == -1)
                die(2, "failed to set parity [even: %d, odd: %d]\n", parity & 1, (parity & 2) >> 1);
-       
+
        if (verbose) {
                /* it's so ugly and beautiful at the same time */
                int t = (((hard & 1) << 1) & (hard & 2)) >> 1;
@@ -236,6 +265,9 @@ openport()
        if (settermattr(fd, &cntrl) == -1)
                 die(1, "failed to set stop bits [%d]\n", stopb+1);
 
+       cntrl.c_cc[VMIN] = 1;
+       cntrl.c_cc[VTIME] = 0;
+
        #ifdef __linux__
         ioctl(fd, TCFLSH, TCIOFLUSH);
        #else
@@ -251,7 +283,7 @@ strtoui(const char *str, const char *msg, unsigned int min)
        char *endptr;
 
        t = strtol(str, &endptr, 10);
-       if (errno != 0 || *endptr != '\0' || t < min) {
+       if (errno != 0 || *endptr != '\0' || t < min || t > uintmax) {
                fprintf(stderr, msg, str);
                return uintmax;
        }
@@ -344,6 +376,7 @@ writeport(void *unused)
 {
        Sizes msizes;
        struct timespec ts;
+
        ts.tv_sec = swritedelay;
        ts.tv_nsec = nswritedelay;
        wts.tv_sec = 0;
@@ -526,9 +559,14 @@ interchck()
 
                newterm.c_iflag |= INLCR;
                newterm.c_cc[VMIN] = minchars;
-               newterm.c_cc[VINTR] = _POSIX_VDISABLE;
-               newterm.c_cc[VSUSP] = _POSIX_VDISABLE;
-               newterm.c_cc[VQUIT] = _POSIX_VDISABLE;
+               newterm.c_cc[VTIME] = 0;
+               newterm.c_cc[VINTR] = newterm.c_cc[VSUSP]\
+                       = newterm.c_cc[VQUIT] = newterm.c_cc[VLNEXT]\
+                       = newterm.c_cc[VDISCARD] = _POSIX_VDISABLE;
+                               
+               #ifdef VDSUSP
+                newterm.c_cc[VDSUSP] = _POSIX_VDISABLE;
+               #endif
 
                if (backspace)
                        bsargs.input = BS;
@@ -536,7 +574,7 @@ interchck()
                        bsargs.input = DEL;
 
                bsargs.find = origterm.c_cc[VERASE];
-
+               
                if (settermattr(STDOUT_FILENO, &newterm) < 0)
                        die(1, "failed to set terminal attributes\n");
        }
@@ -559,13 +597,13 @@ void
 getcmd(int escape)
 {
        Sizes msizes;
-       msizes.sizesm = scratchwsz;
-       msizes.sizebm = wbuffsz;
-
        char cmdchar;
        char ttr[64];
        unsigned int tspd;
 
+       msizes.sizesm = scratchwsz;
+       msizes.sizebm = wbuffsz;
+
        if (isatty(STDIN_FILENO) && isatty(STDOUT_FILENO))
                interactive = 1;
 
@@ -910,6 +948,7 @@ main(int argc, char **argv)
        signal(SIGINT, sighandl);
        signal(SIGQUIT, sighandl);
        signal(SIGTERM, sighandl);
+       signal(SIGCHLD, SIG_DFL);
 
        fd = openport();