fd write: accomodate non-partial writes to a non-full descriptor
If a write to a non-blocking descriptor fails, then try again with fewer bytes, since nothing in the spec write() seems to promise writing partial amounts. In particular, writing to a FIFO no Mac OS X might fail even if there are a few bytes of space; as it happens, the select() function seems to compensate and claim that such a FIFO is full, but kqeueue() doesn't.
This commit is contained in:
parent
5dad9a1ef1
commit
b2509614e2
|
@ -8122,13 +8122,23 @@ static intptr_t flush_fd(Scheme_Output_Port *op,
|
|||
}
|
||||
#else
|
||||
int flags;
|
||||
intptr_t amt;
|
||||
|
||||
flags = fcntl(fop->fd, F_GETFL, 0);
|
||||
fcntl(fop->fd, F_SETFL, flags | MZ_NONBLOCKING);
|
||||
|
||||
amt = buflen - offset;
|
||||
|
||||
do {
|
||||
len = write(fop->fd, bufstr + offset, buflen - offset);
|
||||
} while ((len == -1) && (errno == EINTR));
|
||||
do {
|
||||
len = write(fop->fd, bufstr + offset, amt);
|
||||
} while ((len == -1) && (errno == EINTR));
|
||||
|
||||
/* If there was no room to write `amt` bytes, then it's
|
||||
possible that writing fewer bytes will succeed. That seems
|
||||
to be the case with FIFOs on Mac OS X, for example. */
|
||||
amt = amt >> 1;
|
||||
} while ((len == -1) && (errno == EAGAIN) && (amt > 0));
|
||||
|
||||
errsaved = errno;
|
||||
fcntl(fop->fd, F_SETFL, flags);
|
||||
|
|
Loading…
Reference in New Issue
Block a user