Hi Serge, ltns,

In Debian bug #726735, you wrote:
> Dash redirects stdin from /dev/null when a command is started
> asynchronously, as specified by POSIX. However, POSIX also specifies
> that this can be overridden by explicitely redirecting. This fails
> when redirecting stdin from stdin.

> The relevant text from POSIX (
> http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_09_03_02
> ):
> ] The standard input for an asynchronous list, before any explicit
> ] redirections are performed, shall be considered to be assigned to a file
> ] that has the same properties as /dev/null. If it is an interactive
> ] shell, this need not happen. In all cases, explicit redirection of
> ] standard input shall override this activity.

> To test: create the following script:
>     #!/bin/dash
>     sleep 100 <&0 &

> Run this, and then look at the open file descriptors of the sleep
> process:
>     ls -l /proc/`pgrep sleep`/fd
> The output is as follows:
>     lr-x------ 1 svdb svdb 64 Oct 18 15:58 0 -> /dev/null
>     lrwx------ 1 svdb svdb 64 Oct 18 15:58 1 -> /dev/pts/2
>     lrwx------ 1 svdb svdb 64 Oct 18 15:58 2 -> /dev/pts/2
> fd 0 is assigned to /dev/null instead of /dev/pts/2

In the example script, the redirection happens in the child process.
Therefore, the shell cannot, in the general case, know about this
redirection when it forks the child process. For some reason, bash still
overrides the implicit </dev/null if the outer command has a redirection
of stdin, and therefore your example works with bash.

The following version works in various shells:
  { sleep 100 & } </dev/stdin
(A <&0 is treated as a no-op by Almquist derivatives such as FreeBSD and
NetBSD /bin/sh, even for the purpose of suppressing the </dev/null
implicit in background commands; I consider this a bug and have fixed it
in FreeBSD 11-current.)

The code to suppress the implicit </dev/null in ash is very old. It is
in the first version of bin/sh/redir.c in the FreeBSD repository, and
the NetBSD commit that added it is from May 2, 1993 by 'sef', message
'Jim "wil...@moria.cygnus.com" Wilson's patches to make C News (and
other things) work.'. It looks like this code was deliberately removed
from dash years ago. No version in the dash git repository has it.

In particular, the modified example works in both ksh93 and the original
Bourne shell (Heirloom). Together with the fact that this override is
explicitly mentioned in POSIX (that the redirection in
  sleep 100 </dev/tty &
overrides the implicit /dev/null is obvious and would not warrant
explicit notice), I think the removal from dash was wrong.

Note that mksh does not implement this feature either, so relying on it
in scripts seems unwise at this time. Instead, duplicate stdin in the
parent and put it back in the child:
  { foo <&3 3<&- & } 3<&0

-- 
Jilles Tjoelker


-- 
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org

Reply via email to