summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPádraig Brady <P@draigBrady.com>2015-02-12 03:11:36 +0000
committerPádraig Brady <P@draigBrady.com>2015-02-17 03:03:23 +0000
commit321bd11352d1f378128d65746852e073f86319d3 (patch)
tree57cfd9397cf9806c2d122c116167b6cd44384416
parent3d4daddc7041724fc92b33d9495afa395cc5d995 (diff)
downloadcoreutils-321bd11352d1f378128d65746852e073f86319d3.tar.xz
stty: fix setting of 'extproc' on BSD
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.
-rw-r--r--src/stty.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/src/stty.c b/src/stty.c
index cc5a9e5b1..c0057f2d7 100644
--- a/src/stty.c
+++ b/src/stty.c
@@ -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);