diff options
author | rsc <devnull@localhost> | 2007-03-25 17:16:40 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2007-03-25 17:16:40 +0000 |
commit | edc77f0b2b9298831a6007acffd635a87f55a4d7 (patch) | |
tree | 7b3cf076fb7b0269dc6e3dfc7d22994643d87e4d /src/cmd/rc | |
parent | 3802adb1183fe2350add92dec6496b886c0ae70f (diff) | |
download | plan9port-edc77f0b2b9298831a6007acffd635a87f55a4d7.tar.gz plan9port-edc77f0b2b9298831a6007acffd635a87f55a4d7.tar.bz2 plan9port-edc77f0b2b9298831a6007acffd635a87f55a4d7.zip |
cope with programs that leave fd in non-blocking mode (Tim Wiess)
Diffstat (limited to 'src/cmd/rc')
-rw-r--r-- | src/cmd/rc/plan9ish.c | 3 | ||||
-rw-r--r-- | src/cmd/rc/unixcrap.c | 25 |
2 files changed, 27 insertions, 1 deletions
diff --git a/src/cmd/rc/plan9ish.c b/src/cmd/rc/plan9ish.c index 2e5514e1..4e1ab7c0 100644 --- a/src/cmd/rc/plan9ish.c +++ b/src/cmd/rc/plan9ish.c @@ -31,6 +31,7 @@ Rcmain(void) } char Fdprefix[]="/dev/fd/"; +long readnb(int, char *, long); void execfinit(void); void execbind(void); void execmount(void); @@ -488,7 +489,7 @@ long Read(int fd, char *buf, long cnt) { int i; - i = read(fd, buf, cnt); + i = readnb(fd, buf, cnt); if(ntrap) dotrap(); return i; } diff --git a/src/cmd/rc/unixcrap.c b/src/cmd/rc/unixcrap.c index 98660483..d71cbc38 100644 --- a/src/cmd/rc/unixcrap.c +++ b/src/cmd/rc/unixcrap.c @@ -2,6 +2,8 @@ #include <sys/time.h> #include <sys/stat.h> #include <sys/resource.h> +#include <errno.h> +#include <fcntl.h> #include <libc.h> #include "rc.h" #include "exec.h" @@ -209,3 +211,26 @@ out: poplist(); flush(err); } + +/* + * Cope with non-blocking read. + */ +long +readnb(int fd, char *buf, long cnt) +{ + int n, didreset; + int flgs; + + didreset = 0; + while((n = read(fd, buf, cnt)) == -1) + if(!didreset && errno == EAGAIN){ + if((flgs = fcntl(fd, F_GETFL, 0)) == -1) + return -1; + flgs &= ~O_NONBLOCK; + if(fcntl(fd, F_SETFL, flgs) == -1) + return -1; + didreset = 1; + } + + return n; +} |