]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
stty: fix setting of 'extproc' on BSD
authorPádraig Brady <P@draigBrady.com>
Thu, 12 Feb 2015 03:11:36 +0000 (03:11 +0000)
committerPádraig Brady <P@draigBrady.com>
Tue, 17 Feb 2015 03:03:23 +0000 (03:03 +0000)
This setting is unusual on BSD as it's read normally in the local
flags returned by tcgetattr(), but can only be set with an ioctl.
Setting with tcsetattr() is ignored.

* src/stty.c (NO_SETATTR): A new flag to indicate the setting
is read and displayed like a normal termios flag, but is set
in some other manner.
(main): Skip tcsetattr() for this setting when this flag is set.
Also fixup the exiting 'extproc' processing to handle the
'-extproc' case correctly.
(sane_mode): Skip setting '-extproc' for 'sane' to avoid the error.
This isn't ideal but matches the operation of the BSD native stty.

src/stty.c

index cc5a9e5b18c37650e96c54905ac99a23a5ef2f1b..c0057f2d7ef5e30b9f12d1262e93e7be9af3061b 100644 (file)
@@ -191,6 +191,7 @@ enum mode_type
 #define SANE_UNSET 2           /* Unset in 'sane' mode. */
 #define REV 4                  /* Can be turned off by prepending '-'. */
 #define OMIT 8                 /* Don't display value. */
+#define NO_SETATTR 16          /* tcsetattr not used to set mode bits.  */
 
 /* Each mode.  */
 struct mode_info
@@ -342,7 +343,9 @@ static struct mode_info const mode_info[] =
   {"echoke", local, SANE_SET | REV, ECHOKE, 0},
   {"crtkill", local, REV | OMIT, ECHOKE, 0},
 #endif
-#ifdef EXTPROC
+#if defined TIOCEXT
+  {"extproc", local, SANE_UNSET | REV | NO_SETATTR, EXTPROC, 0},
+#elif defined EXTPROC
   {"extproc", local, SANE_UNSET | REV, EXTPROC, 0},
 #endif
 
@@ -1192,6 +1195,7 @@ main (int argc, char **argv)
     {
       char const *arg = argv[k];
       bool match_found = false;
+      bool not_set_attr = false;
       bool reversed = false;
       int i;
 
@@ -1207,8 +1211,13 @@ main (int argc, char **argv)
         {
           if (STREQ (arg, mode_info[i].name))
             {
-              match_found = set_mode (&mode_info[i], reversed, &mode);
-              require_set_attr = true;
+              if ((mode_info[i].flags & NO_SETATTR) == 0)
+                {
+                  match_found = set_mode (&mode_info[i], reversed, &mode);
+                  require_set_attr = true;
+                }
+              else
+                match_found = not_set_attr = true;
               break;
             }
         }
@@ -1236,7 +1245,7 @@ main (int argc, char **argv)
                 }
             }
         }
-      if (!match_found)
+      if (!match_found || not_set_attr)
         {
           if (STREQ (arg, "ispeed"))
             {
@@ -1263,10 +1272,11 @@ main (int argc, char **argv)
               require_set_attr = true;
             }
 #ifdef TIOCEXT
-          else if (STREQ (arg, "extproc") || STREQ (arg, "-extproc"))
+          /* This is the BSD interface to "extproc".
+            Even though it's an lflag, an ioctl is used to set it.  */
+          else if (STREQ (arg, "extproc"))
             {
-              /* This is the BSD interface to "extproc".  */
-              int val = *arg != '-';
+              int val = ! reversed;
 
               if (ioctl (STDIN_FILENO, TIOCEXT, &val) != 0)
                 {
@@ -2192,6 +2202,9 @@ sane_mode (struct termios *mode)
 
   for (i = 0; mode_info[i].name != NULL; ++i)
     {
+      if (mode_info[i].flags & NO_SETATTR)
+        continue;
+
       if (mode_info[i].flags & SANE_SET)
         {
           bitsp = mode_type_flag (mode_info[i].type, mode);