termio ioctl returns incorrect value for suspend character

Bug #1428651 reported by Steven Pemberton
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
glibc (Ubuntu)
New
Undecided
Unassigned

Bug Description

When calling ioctl to request some special key bindings, it seems to return a random value for the Suspend binding (see attached C file).

On my system, if I do a stty -a I get this:

$ stty -a
speed 38400 baud; rows 24; columns 80; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = M-^?; eol2 = M-^?;
swtch = M-^?; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W;
lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 hupcl -cstopb cread -clocal -crtscts
-ignbrk brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
-iuclc ixany imaxbel iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke

If I run the enclosed C program, which does an ioctl for TCGETA:

       if (ioctl(0, TCGETA, (char*) &sgbuf) == 0) {

and then retrieves the key bindings for interrupt, erase, and suspend (^C, ^?, and ^Z in the above output). It returns Interrupt and Erase correctly, but it returns the wrong value for Suspend; each time I run the program it returns a different value, though it consistently returns the same (wrong) value within the program:

                                 if ((int) sgbuf.c_cc[VSUSP] != 0377) {
   printf("Suspend=%i\n", (int)sgbuf.c_cc[VSUSP]);
  }

The program calls the ioctl three times to see if it always returns the same value within the program. It does.

An example output:
Erase= 127, Interrupt=3, Suspend=31
Erase= 127, Interrupt=3, Suspend=31
Erase= 127, Interrupt=3, Suspend=31

but the next time I run it:

Erase= 127, Interrupt=3, Suspend=171
Erase= 127, Interrupt=3, Suspend=171
Erase= 127, Interrupt=3, Suspend=171

ProblemType: Bug
DistroRelease: Ubuntu 14.04
Package: gcc 4:4.8.2-1ubuntu6
ProcVersionSignature: Ubuntu 3.13.0-46.77-generic 3.13.11-ckt15
Uname: Linux 3.13.0-46-generic x86_64
ApportVersion: 2.14.1-0ubuntu3.7
Architecture: amd64
CurrentDesktop: Unity
Date: Thu Mar 5 14:41:28 2015
SourcePackage: gcc-defaults
UpgradeStatus: No upgrade log present (probably fresh install)

Revision history for this message
Steven Pemberton (steven-pemberton) wrote :
Revision history for this message
Steven Pemberton (steven-pemberton) wrote :

termios.h says there are 17 characters (0..16) in the c_cc buffer. If I print them all out (here I've run it three times), it seems like 4 characters change their value between calls: 8 (VSTART) 9 (VSTOP) 10 (VSUSP) 16 (VEOL2)

   0:3 1:28 2:127 3:21 4:4 5:0 6:1 7:255 8: 18 9:122 10:99 11:255 12:127 13:0 14:0 15:0 16:134
   0:3 1:28 2:127 3:21 4:4 5:0 6:1 7:255 8:215 9:152 10:145 11:255 12:127 13:0 14:0 15:0 16:129
   0:3 1:28 2:127 3:21 4:4 5:0 6:1 7:255 8: 10 9:97 10:251 11:255 12:127 13:0 14:0 15:0 16:239

I'll upload this program as termio2.c.

Finally the equivalent function from termios, namely tcgetattr, seems to give the right results, consistently over calls:

   0:3 1:28 2:127 3:21 4:4 5:0 6:1 7:255 8:17 9:19 10:26 11:255 12:18 13:15 14:23 15:22 16:255

I'll upload this as termio3.c

Revision history for this message
Steven Pemberton (steven-pemberton) wrote :
Revision history for this message
Steven Pemberton (steven-pemberton) wrote :

Since I ran into this bug again today, and since it hasn't been touched in the 5 years since I reported it, I thought I would just add the code to program around it, for those people who come here with the same problem (if there are such people).

replace
   #include <termio.h>
   struct termio sgbuf;
   ioctl(f, TCGETA, (char*)&sgbuf)

with
   #include <termios.h>
   struct termios sgbuf;
   tcgetattr(f, &sgbuf)

Matthias Klose (doko)
affects: gcc-defaults (Ubuntu) → glibc (Ubuntu)
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.