subshell output swallowed (patch)
Pavel Tsekov
ptsekov at gmx.net
Tue Jan 24 14:37:38 UTC 2006
On Tue, 24 Jan 2006, Egmont Koblinger wrote:
> On Tue, Jan 24, 2006 at 02:24:40PM +0200, Pavel Tsekov wrote:
>
> > > > > write(1, "\33[0mcopy_reg.py\33[0m \33[0mi"..., 100) = 53
> > > >
> > > > This strace is not convincing - i don't see calls failing with -1.
> > >
> > > No, no syscall is failing. You ask the kernel to write 100 bytes, and since
> > > a signal interrupts it, it says "everything went find but I only wrote 53
> > > bytes". Then it's your job not to forget to write the remaining 47 bytes.
> >
> > If a system call is interrupted it returns -1 and sets errno to EINTR.
>
> If a system call is interrupted it either returns -1 and sets errno to EINTR
> (if it has not yet written anything) or returns success (the number of bytes
> written so far in case of write()) and most likely sets errno to 0 (if it
> has already written several bytes). I don't exactly know under what
> circumstances can this second case occur, but it definitely occurs to me as
> shown by the quoted strace output.
The second case has nothing to the with the routine being interrupted by
the delivery of the signal. Your first post implied that it was SIGCHLD
interrupting a write() call which is reponsible for the broken ouput of
`ls'.
> The second case can also occur when there's no signal arriving at all. It's
> perfectly okay that a write() call writes fewer bytes than it is supposed to
> do since there's no more room in the pipe's buffer or network socket etc...
> Probably in our case that the short write is not even directly caused by the
> signal. I don't know if such a thing can happen with normal files, but sure
> it can with byte-oriented streams.
I am aware of this but see above...
> > Yes, that's what SA_RESTART is supposed to do.
>
> For both cases? It seems to me that probably it only applies to the -1 EINTR
> case. A short write() still has to be manually continued. Most likely since
> it really might be unrelated to any signals.
Yes, SA_RESTART applies to the EINTR case. And, yes, write() may actually
write less bytes when in non-blocking body and this should be handled.
What worries me is that you don't understand well what is the cause of the
problem that you see. The code in the subshell is fragile and should be
touched with extra care.
More information about the mc-devel
mailing list