Subject: kern/34129: Nonblocking write to pty returns 0, not EAGAIN
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: Andreas Gustafsson <gson@gson.org>
List: netbsd-bugs
Date: 08/02/2006 18:30:00
>Number: 34129
>Category: kern
>Synopsis: Nonblocking write to pty can return 0
>Confidential: no
>Severity: serious
>Priority: high
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Wed Aug 02 18:30:00 +0000 2006
>Originator: Andreas Gustafsson
>Release: NetBSD 3.99.21
>Organization:
>Environment:
System: NetBSD guava.gson.org 3.99.21 NetBSD 3.99.21 (GENERIC) #1: Wed Jul 5 19:33:35 EEST 2006 gson@guru.araneus.fi:/usr/build/1002/obj/sys/arch/i386/compile/GENERIC i386
Architecture: i386
Machine: i386
>Description:
If a process is run under a pty in nonblocking mode, write() will
return 0 when the pty's buffer fills up. This is incorrect; it should
return -1 and set errno to EAGAIN.
>How-To-Repeat:
I noticed the bug while attempting to remotely install NetBSD in a
headless virtual machine using qemu -nographic, boot-com1.fs, and an
ISO image. Parts of the sysinst output would be lost, corrupting
the layout of some of the sysinst screens.
Since this is not trivial to repeat, here is a simpler test case:
Log in to a remote machine using ssh over a low-bandwidth connection
(1 Mbps or slower should suffice if the machine is fast enough).
Then compile and run the following test program:
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char **argv) {
static char text[10];
int i;
fcntl(1, F_SETFL, O_NONBLOCK);
for (i = 0; i < 100000; i++) {
int r;
sprintf(text, "%08d", i);
text[8] = '\n';
text[9] = '\0';
r = write(1, text, 9);
if (r <= 0) {
sleep(2);
printf("write returned %d\n", r);
exit(1);
}
}
}
Notice how the program prints some number of lines of output and then
"write returned 0". On other operating systems, it will correctly
print "write returned -1".
>Fix:
Not provided.