[PATCH] ash: clear NONBLOCK flag from stdin when in foreground
Rich Felker
dalias at aerifal.cx
Thu Aug 18 00:10:23 UTC 2011
On Thu, Aug 18, 2011 at 01:11:37AM +0200, Denys Vlasenko wrote:
> > you simply
> > call poll first (or select, but select requires the fd # to be < 1024)
> > to check that it won't block, then call read. select and poll are
> > specified to only mark the fd readable if a read would not block.
>
> An example from a different area of Unix API:
>
> EINTR is supposed to be returned only if non-DFL,
> non-IGN signal was reseived and handler was executed.
> Right? Right... but...
> real world chimes in: EINTR also may be returned if someone
> happened to attach to your program with "strace -p PID"
> while you are in a syscall. Syscall may return EINTR even though
> *no signal whatsoever* was delivered.
This is only true for non-restartable syscalls like sleep. open, read,
write, etc. can never return EINTR unless interrupted by a
non-restarting signal handler.
> My question stands:
>
> "How can I do nonblocking read from fd 0 without
> affecting other processes which might share it?"
Something like this (untested and missing some error handling):
static void *reader(void *x)
{
char buf[BUFSIZ];
int *fds = x, rd = fds[0], wr = fds[1];
free(x);
for (;;) {
ssize_t i, k, l = read(rd, buf, sizeof buf);
for (i=0; i<l; i+=k) {
k = write(wr, buf+i, l-i);
if (k<0) break;
}
if (l<=0 || k<0) break;
}
close(wr);
return 0;
}
int newfd, *p=malloc(sizeof *p * 2)
pipe(p);
newfd = p[0];
p[0] = oldfd;
pthread_create(&td, 0, reader, p);
Now poll and read from newfd...
> > If other processes might attempt a read at the same time your process
> > does, then you have serious data races which are probably not solvable
> > anyway.
>
> Well, the data units might be single bytes.
Indeed this is one of the few valid uses...
Rich
More information about the busybox
mailing list