tcsetattr/ioctl problem causes stty tests to fail

Jim Meyering (meyering@ascend.com)
16 Feb 1999 08:25:26 -0600


Hi,

I'm wondering if I've found a problem with the way the kernel
handles the ioctl calls resulting from my call to tcsetattr.

I've included a simple program that demonstrates the problem
below and comments and a trace from Ulrich Drepper.

Either the kernel or stty.c (and my understanding of POSIX tcsetattr
semantics) will have to change.

FYI, here's how to demonstrate the problem that prompted this little
investigation:

$ stty parenb
stty: standard input: unable to perform all requested operations
[Exit 1]
$

Any suggestions?

===============================================================
From: Jim Meyering <meyering@ascend.com>
Subject: Re: sh-utils results
To: drepper@cygnus.com (Ulrich Drepper)
Date: 07 Feb 1999 23:31:50 -0600

Ulrich Drepper <drepper@cygnus.com> writes:
...
| Beside this, I gets this during `make check':
|
| Make[3]: Entering directory `/home/drepper/gnu/sh-utils-1.16f-ud/tests/stty'
| PASS: row-col-1
| ../../src/stty: standard input: unable to perform all requested operations
|
| The test is marked as passed but I'm still curious whether this is ok.

Thanks for bringing that up.
There is indeed a problem. First with the test script -- its
failure should have propagated out to make. I've fixed that.

Then, there's a problem with tcsetattr that causes both the latest stty
and distributed one from sh-utils-1.16 to fail on parenb and -cread.

Here's a simple program demonstrating the parenb failure.

/* Demonstrate the failure of `stty parenb' on linux 2.2.0-pre4 with
stock RH5.2 libraries. The same problem (but different bit) arises
with `stty -cread'. */
#include <termios.h>
#include <unistd.h>
#include <stdio.h>

int
main ()
{
static struct termios mode;
static struct termios new_mode;
int x;
x = tcgetattr (0, &mode);
if (x) exit (1);
new_mode = mode;
new_mode.c_cflag |= PARENB;
x = tcsetattr (0, TCSADRAIN, &new_mode);
if (x) exit (2);
x = tcgetattr (0, &mode);
if (x) exit (3);
if (memcmp (&mode, &new_mode, sizeof (mode)) != 0)
{
int i;
for (i = 0; i < sizeof (new_mode); i++)
{
int a = *(((unsigned char *) &new_mode) + i);
int b = *(((unsigned char *) &mode) + i);
if (a != b)
printf ("%d: 0x%02x: 0x%02x\n", i, a, b);
}
exit (4);
}
exit (0);
}

Here's what I get:

$ gcc -O -Wall stty-test.c && ./a.out
9: 0x01: 0x00
[Exit 4]

Do you feel like looking into it?

===============================================================
From: Ulrich Drepper <drepper@cygnus.com>
Subject: Re: sh-utils results
To: Jim Meyering <meyering@ascend.com>
Date: 07 Feb 1999 21:36:49 -0800
Reply-To: drepper@cygnus.com (Ulrich Drepper)

Jim Meyering <meyering@ascend.com> writes:

> Then, there's a problem with tcsetattr that causes both the latest stty
> and distributed one from sh-utils-1.16 to fail on parenb and -cread.

This has nothing to do with the library. Here's the strace output:

ioctl(0, TCGETS, {c_iflags=0x500, c_oflags=0x5, c_cflags=0xbd, c_lflags=0x8a3b, c_line=0, c_cc="\x03\x1c\x7f\x15\x04\x00\x01\x00\x11\x13\x1a\x00\x12\x0f\x17\x16\x00\x00\x00\xb8\xf7\xff\xbf\xb2\x87\x04\x08\x00\x00\x00\x00\x20"}) = 0
ioctl(0, TCSETSW, {c_iflags=0x500, c_oflags=0x5, c_cflags=0x1bd, c_lflags=0x8a3b, c_line=0, c_cc="\x03\x1c\x7f\x15\x04\x00\x01\x00\x11\x13\x1a\x00\x12\x0f\x17\x16\x00\x00\x00\xb8\xf7\xff\xbf\xe7\x87\x04\x08\x00\x00\x00\x00\x01"}) = 0
ioctl(0, TCGETS, {c_iflags=0x500, c_oflags=0x5, c_cflags=0xbd, c_lflags=0x8a3b, c_line=0, c_cc="\x03\x1c\x7f\x15\x04\x00\x01\x00\x11\x13\x1a\x00\x12\x0f\x17\x16\x00\x00\x00\xb8\xf7\xff\xbf\x01\x88\x04\x08\x00\x00\x00\x00\x20"}) = 0

The c_cflags element is interesting:

Initially: 0xbd
set to: 0x1bd
read again: 0xbd

I don't know enough about the terminal handling but either the kernel
or your expectations are wrong. Maybe you should post to the Linux
kernel list.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/