Bug 20251
| Summary: | termio's ~ICANON causes read to return NUL for EOT sometimes | ||
|---|---|---|---|
| Product: | [Retired] Red Hat Linux | Reporter: | Todd Allen <todd.allen> |
| Component: | kernel | Assignee: | Arjan van de Ven <arjanv> |
| Status: | CLOSED CURRENTRELEASE | QA Contact: | Brian Brock <bbrock> |
| Severity: | medium | Docs Contact: | |
| Priority: | medium | ||
| Version: | 8.0 | CC: | bugsy |
| Target Milestone: | --- | ||
| Target Release: | --- | ||
| Hardware: | i686 | ||
| OS: | Linux | ||
| Whiteboard: | |||
| Fixed In Version: | Doc Type: | Bug Fix | |
| Doc Text: | Story Points: | --- | |
| Clone Of: | Environment: | ||
| Last Closed: | 2004-09-30 15:38:51 UTC | Type: | --- |
| Regression: | --- | Mount Type: | --- |
| Documentation: | --- | CRM: | |
| Verified Versions: | Category: | --- | |
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
| Cloudforms Team: | --- | Target Upstream Version: | |
| Embargoed: | |||
Confirmed in 8.0 but seems to be kernel not libc Thanks for the bug report. However, Red Hat no longer maintains this version of the product. Please upgrade to the latest version and open a new bug if the problem persists. The Fedora Legacy project (http://fedoralegacy.org/) maintains some older releases, and if you believe this bug is interesting to them, please report the problem in the bug tracker at: http://bugzilla.fedora.us/ |
If I turn off ICANON via tcsetattr(), and then do several reads(), EOT characters sometimes are turned into NUL's and sometimes remain EOT's. Build the following program, and run it. It expects input, will print "EOF" for every EOT character, and will print the hex code for any other character, including NUL as "00". Then type control-D over and over again real fast. You'll see "00" sometimes and "EOF" sometimes. I notice that, in n_tty.c, EOF_CHAR(tty) is mutated into __DISABLED_CHAR, and I suspect it's something to do with that. I'm guessing there's supposed to be a place where that's undone and it's not working right with ICANON turned off. That's all I've been able to deduce. Here's the source: #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <errno.h> #include <stdio.h> #include <termios.h> static int fd = 0; static int waiting = 0; static int sleepily = 0; main() { for (;;) { int eof_ch = '\004'; /* EOT, a.k.a. ^D */ char c; int got; struct termios termios_rec; struct termios otermios_rec; tcgetattr(fd, &termios_rec); memcpy(&otermios_rec, &termios_rec, sizeof(struct termios)); eof_ch = termios_rec.c_cc[VEOF]; termios_rec.c_lflag &= ~ICANON; termios_rec.c_cc[VMIN] = waiting; termios_rec.c_cc[VTIME] = 0; tcsetattr(fd, TCSANOW, &termios_rec); do { got = read(fd, &c, 1); if (got == -1 && errno != EAGAIN && errno != EINTR) { printf("read() go boom; errno = %d\n", errno); exit(1); } } while (waiting && got <= 0); tcsetattr(fd, TCSANOW, &otermios_rec); if (got <= 0) { if (sleepily) { printf("!avail\n"); } } else if (c == eof_ch) { printf("EOF\n"); } else { printf("%02x\n", c); } if (sleepily) { sleep(1); } } }