Source-Changes archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

CVS commit: src/bin/sh



Module Name:    src
Committed By:   kre
Date:           Sun Nov 10 01:22:24 UTC 2024

Modified Files:
        src/bin/sh: eval.c redir.c redir.h sh.1 show.c

Log Message:
exec builtin command redirection fixes

Several changes, all related to the exec special built in command,
or to close on exec, one way or another.   (Except a few white space
and comment additions, KNF, etc)

1. The bug found by Edgar Fuß reported in:
      http://mail-index.netbsd.org/tech-userlevel/2024/11/05/msg014588.html
   has been fixed, now "exec N>whatever" will set close-on-exec for fd N
   (as do ksh versions, and allowed by POSIX, though other shells do not)
   which has happened now for many years.   But "exec cmd N>whatever"
   (which looks like the same command when redirections are processed)
   which was setting close-on-exec on N, now no longer does, so fd N
   can be passed to cmd as an open fd.

   For anyone who cares, the big block of change just after "case CMDBUILTIN:"
   in evalcommand() in eval.c is the fix for this (one line replaced by
   about 90 ... though most of that is comments or #if 0'd example code
   for later).   It is a bit ugly, and will get worse if our exec command
   ever gets any options, as others have, but it does work.

2. when the exec builtin utility is used to alter the shell's redirections
   it is now "all or nothing".   Previously the redirections were executed
   left to right.  If one failed, no more were attempted, but the earlier
   ones remained.   This makes no practical difference to a non-interactive
   shell, as a redirection error causes that shell to exit, but it makes
   a difference to interactive shells.   Now if a redirection fails, any
   earlier ones which had been performed are undone.   Note however that
   side-effects of redirections (like creating, or truncating, files in
   the filesystem, cannot be reversed - just the shell's file descriptors
   returned to how they were before the error).

   Similarly usage errors on exec now exist .. our exec takes no options
   (but does handle "--" as POSIX says it must - has done for ages).
   Until now, that was the only magic piece of exec, running
        exec -a name somecommand
   (which several other shells support) would attempt to exec the "-a"
   command, and most likely fail, causing immediate exit from the shell.
   Now that is a usage error - a non-interactive shell still exits, as
   exec is a special builtin, and any error from a special builtin causes
   a non-interactive shell to exit.   But now, an interactive shell will
   no longer exit (and any redirections that were on the command will be
   undone, the same as for a redirection error).

3. When a "close on exec" file descriptor is temporarily saved, so the
   same fd can be redirected for another command (only built-in commands
   and functions matter, redirects for file system commands happen after
   a fork() and at that stage if anything goes wrong, the child simply
   exits - but for non-forking commands, doing something like printf >file
   required the previous stdout to be saved elsewhere, "file" opened to
   be the new stdout, then when printf is finished, the old stdout moved
   back.   Anyway, if the fd being moved had close on exec set, then
   when it was moved back, the close on exec was lost.  That is now fixed.

4. The fdflags command no longer allows setting close on exec on stdin,
   stdout, or stderr - POSIX requires that those 3 fd's always be open
   (to something) when any normal command is invoked.  With close-on-exec
   set on one of these, that is impossible, so simply refuse it (when
   "exec N>file" sets close on exec, it only does it for N>2).

Minor changes (should be invisible)

a. The shell now keeps track of the highest fd number it sees doing
   normal operations (there are a few internal pipe() calls that aren't
   monitored and a couple of others, but in general the shell will now
   know the highest fd it ever saw allocated to it).  This is mostly
   for debugging.

b. calls to fcntl() passing an int as the "arg" are now all properly
   cast to the void * that the fcntl kernel is expecting to receive.
   I suspect that makes no actual difference to anything, but ...


To generate a diff of this commit:
cvs rdiff -u -r1.194 -r1.195 src/bin/sh/eval.c
cvs rdiff -u -r1.72 -r1.73 src/bin/sh/redir.c
cvs rdiff -u -r1.26 -r1.27 src/bin/sh/redir.h
cvs rdiff -u -r1.267 -r1.268 src/bin/sh/sh.1
cvs rdiff -u -r1.56 -r1.57 src/bin/sh/show.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.




Home | Main Index | Thread Index | Old Index