Commit 192e36a
committed
Fix undefined behaviour in write() call
write()ing zero bytes to not a regular file (e.g. stdout) is undefined behaviour
and can generate a SIGHUP under certain circumstances, e.g. on AIX when running
with unbuffered stdout within sudo, screen, tmux:
$ sudo python3 -u -c 'print(""); print("foo")'
Hangup
Python's print() implementation in this case calls write() twice:
# truss python3 -u -c 'print("")'
[...]
kwrite(1, 0x08001000A001B910, 0) = 0
kwrite(1, "\n", 1) = 1
However, the first write() is undefined behaviour.
ssize_t write(int fildes, const void *buf, size_t nbyte);
The write() function shall attempt to write nbyte bytes from the buffer
pointed to by buf to the file associated with the open file descriptor,
fildes.
Before any action described below is taken, and if nbyte is zero and the
file is a regular file, the write() function may detect and return errors as
described below. In the absence of errors, or if error detection is not
performed, the write() function shall return zero and have no other results.
If nbyte is zero and the file is not a regular file, the results are
unspecified.
https://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html1 parent 2faceee commit 192e36a
1 file changed
+11
-3
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1923 | 1923 | | |
1924 | 1924 | | |
1925 | 1925 | | |
1926 | | - | |
| 1926 | + | |
1927 | 1927 | | |
1928 | 1928 | | |
1929 | 1929 | | |
| |||
1970 | 1970 | | |
1971 | 1971 | | |
1972 | 1972 | | |
1973 | | - | |
| 1973 | + | |
| 1974 | + | |
| 1975 | + | |
| 1976 | + | |
| 1977 | + | |
1974 | 1978 | | |
1975 | 1979 | | |
1976 | 1980 | | |
| |||
1996 | 2000 | | |
1997 | 2001 | | |
1998 | 2002 | | |
1999 | | - | |
| 2003 | + | |
| 2004 | + | |
| 2005 | + | |
| 2006 | + | |
| 2007 | + | |
2000 | 2008 | | |
2001 | 2009 | | |
2002 | 2010 | | |
| |||
0 commit comments