I have a command line application that sets O_NONBLOCK on stdin. This also sets stdout to O_NONBLOCK as they point to the same file description.
The problem is when stdout's buffer gets full, fwrite doesn't return the number of bytes written; it is returning 0, though some bytes are, in fact, written. It is also setting errno to 35, "Resource temporarily unavailable". Even more strange is the entire buffer ends up being displayed on the console (all 18 lines).
According to the man page, fwrite should return the actual number of bytes written, not 0.
How can I fwrite to stdout with O_NONBLOCK and have fwrite return the number of characters actually written when the buffer is full?
The problem is when stdout's buffer gets full, fwrite doesn't return the number of bytes written; it is returning 0, though some bytes are, in fact, written. It is also setting errno to 35, "Resource temporarily unavailable". Even more strange is the entire buffer ends up being displayed on the console (all 18 lines).
According to the man page, fwrite should return the actual number of bytes written, not 0.
How can I fwrite to stdout with O_NONBLOCK and have fwrite return the number of characters actually written when the buffer is full?
Code Block #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <fcntl.h> #include <sys/errno.h> #include <string.h> int main(void); int main() { int flags; int serrno; int l,c; char *string="012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\r\n"; char *hello="Hello, world.\r\n"; flags = fcntl(fileno(stdin), F_GETFL, 0); printf("stdin fd=%d flags=%04x\n", fileno(stdin), flags); flags = fcntl(fileno(stdout), F_GETFL, 0); printf("stdout fd=%d flags=%04x\n", fileno(stdout), flags); flags = fcntl(fileno(stderr), F_GETFL, 0); printf("stderr fd=%d flags=%04x\n", fileno(stderr), flags); printf("stdout O_NONBLOCK\n"); fcntl(fileno(stdin), F_SETFL, flags | O_NONBLOCK); /* non-block mode */ flags = fcntl(fileno(stdin), F_GETFL, 0); printf("stdin fd=%d flags=%04x\n", fileno(stdin), flags); flags = fcntl(fileno(stdout), F_GETFL, 0); printf("stdout fd=%d flags=%04x\n", fileno(stdout), flags); flags = fcntl(fileno(stderr), F_GETFL, 0); printf("stderr fd=%d flags=%04x\n", fileno(stderr), flags); errno = 0; do { l = fwrite(string, 1, strlen(string), stdout); c++; } while (l == strlen(string)); serrno = errno; sleep(0); printf("c=%d l=%d, errno=%d, err_msg=\"%s\"\r\n", c, l, serrno, strerror(serrno)); fcntl(fileno(stdin), F_SETFL, flags); /* non-block mode */ }
Code Block % ./stdout stdin fd=0 flags=0002 stdout fd=1 flags=0002 stderr fd=2 flags=0002 stdout O_NONBLOCK stdin fd=0 flags=0006 stdout fd=1 flags=0006 stderr fd=2 flags=0006 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 c=18 l=0, errno=35, err_msg="Resource temporarily unavailable"