I know that a sleep() call can return EINTR.  It means an event like a
signal delivery caused the sleep() system call to be interrupted.

Not sure what it means if a read call returns this result, because
EINTR (with sleep()) means that the system call did partially execute.
So in the case of read(), it could be that part of the data requested
was read.  If that is true, it seems like the OS should return the
number of bytes read instead of EINTR.  If the read() did not execute
and the file descriptor is non-blocking, read() could return zero or
EAGAIN.

Maybe this is a case where the f.d. is configured to block and read()
has not yet read any data when the signal occurs.  In that case,
returning zero bytes usually means EOF (which is wrong), and returning
EAGAIN is probably only legal on non-blocking descriptors.  So it
is returning EINTR.  I think the thing to do is retry the read,
although if you are having this problem in this specific case, it
probably exists in other circumstances as well (not just exec).

Jim


>
> On Mon, Apr 09, 2001 at 02:52:41PM -0500, Robert Hentosh wrote:
> > I have been playing with aolserver on OpenBSD 2.8.  aolserver 3.3.1
> > now compiles cleanly on OpenBSD. And searching through the mailling
> > lists the only other problem seems to be an issue with tcl exec command.
> >
> > I have tried an exec from a tcl script and from an ADP and have
> > confirmed the problem.
> >
> > an ADP with the following in it:
> >
> >         <% ps_puts [exec /bin/ls] %>
> >
> > fails with the following in the log:
> >
> > Error: error reading output from command: interrupted system call
> >         while executing
> > "exec /bin/ls"
> >
> > This works on my redhat7.0 box.  I also tried OpenBSD-snapshot
> > (from Apr 08) with the same results. nsd76 has the same issue also.
> >
> > The log message seems to be generated from a failed call to
> > Tcl_ReadChars() within the procedure Tcl_ExecObjCmd() contained i
> > n tcl8.3.2/generic/tclIOCmd.c.
> >
> > This is the first time I have dug into aolserver's code.  So any
> > pointers/solutions/hunches would be most appreciated.
>
> I have traced this a little more.  Using GDB and stepping through
> Tcl_ReadChars after Tcl_ExecObjCmd is called allows it to complete without
> resulting in the error.
>
> Using ktrace on the nsd8x process and it seems that the read() from the
> pipe to the fork'd process is receiving SIGCHLD:
>
>   6481 nsd8x    CALL  fstat(0x10,0x1a5aec)
>   6481 nsd8x    RET   fstat 0
>   6481 nsd8x    CALL  close(0x10)
>   6481 nsd8x    RET   close 0
>   6481 nsd8x    CALL  read(0xe,0x1ca020,0x1000)
>   6481 nsd8x    GIO   fd 14 read 65 bytes
>        "bin
>         include
>         lib
>         log
>         modules
>         nsd8x.core
>         sample-config.tcl
>         servers
>        "
>   6481 nsd8x    RET   read 65/0x41
>   6481 nsd8x    CALL  read(0xe,0x1ca020,0x1000)
>   6481 nsd8x    PSIG  SIGCHLD caught handler=0x4018b9b8 mask=0x0 code=0x0
>   6481 nsd8x    RET   read -1 errno 4 Interrupted system call
>   6481 nsd8x    CALL  fcntl(0,0x4,0x4)
>   6481 nsd8x    RET   fcntl -1 errno 19 Operation not supported by device
>   6481 nsd8x    CALL  fcntl(0x1,0x4,0x6)
>   6481 nsd8x    RET   fcntl 0
>
> So it looks like to me that the read() at line 953 in tclUnixPipe.c is
> getting the SIGCHLD on the second read() after it has obtained the
> program output.  I am not sure what the proper solution should be.
>
> Suggestions?
>

Reply via email to