108 Commits

Author SHA1 Message Date
jilles
6d26f3b024 sh: If a SIGINT or SIGQUIT interrupts "wait", return status 128+sig. 2013-02-23 22:50:57 +00:00
delphij
c27302a50c Catch TRACE parameters up with r238888. This change is only needed when
debugging is enabled.
2013-02-07 19:00:54 +00:00
jilles
db77635860 sh: Show negated commands (!) in jobs output. 2013-01-31 21:50:44 +00:00
jilles
da771ef7de sh: Prefer strsignal() to accessing sys_siglist directly.
Accessing sys_siglist directly requires rtld to copy it from libc to the sh
executable's BSS. Also, strsignal() will put in the signal number for
unknown signals (FreeBSD-specific) so we need not do that ourselves.

Unfortunately, there is no function for sys_signame.
2012-12-25 14:17:09 +00:00
jilles
99ca87dd2d sh: Prefer internal nextopt() to libc getopt().
This reduces code duplication and code size.

/usr/bin/printf is not affected.

Side effect: different error messages when certain builtins are passed
invalid options.
2012-09-15 21:56:30 +00:00
jilles
0df7adbcbe sh: Fix EINTR race condition in "wait" and "set -T" using sigsuspend().
When waiting for child processes using "wait" or if "set -T" is in effect, a
signal interrupts the wait. Make sure there is no window where the signal
handler may be invoked (setting a flag) just before going to sleep.

There is a similar race condition in the shell language, but scripts can
avoid it by exiting from the trap handler or enforcing synchronization using
a fifo.

If SIGCHLD is not trapped, a signal handler must be installed for it. Only
install this handler for the duration of the wait to avoid triggering
unexpected [EINTR] errors elsewhere.

Note that for some reason only SIGINT and SIGQUIT interrupt a "wait"
command. This remains the case.
2012-07-29 18:04:38 +00:00
jilles
68e92f2ba9 sh: Do not ask for stopped/continued processes if we do not need them
rather than retrying wait3 if they happen.
2012-07-28 15:13:48 +00:00
jilles
acf68e5eb4 sh: Inline waitproc() into its only caller. 2012-07-28 14:56:50 +00:00
jilles
d73fbcf117 sh: Track continued jobs (even if not continued by bg or fg).
This uses wait3's WCONTINUED flag.

There is no message for this. The change is visible in "jobs" or if the job
stops again.
2012-07-28 14:32:55 +00:00
jilles
4d945ad412 sh: Remove unused variable in_dowait. 2012-07-15 10:49:16 +00:00
jilles
17b84cf238 sh: Fix build with -DDEBUG=2.
Reported by:	Kristof Provost
MFC after:	1 week
2012-04-02 17:16:24 +00:00
jilles
c9a60ad55a sh: Use vfork in a few common cases.
This uses vfork() for simple commands and command substitutions containing a
single simple command, invoking an external program under certain conditions
(no redirections or variable assignments, non-interactive shell, no job
control). These restrictions limit the amount of code executed in a vforked
child.

There is a large speedup (for example 35%) in microbenchmarks. The
difference in buildkernel is smaller (for example 0.5%) but still
statistically significant. See
http://lists.freebsd.org/pipermail/freebsd-hackers/2012-January/037581.html
for some numbers.

The use of vfork() can be disabled by setting a variable named
SH_DISABLE_VFORK.
2012-02-04 23:12:14 +00:00
charnier
11c560ec5e Add prototypes, ANSIfy functions definitions to reduce WARNS=6 output. 2012-01-25 08:42:19 +00:00
jilles
16addb8673 sh: Fix duplicate prototypes for builtins.
Have mkbuiltins write the prototypes for the *cmd functions to builtins.h
instead of builtins.c and include builtins.h in more .c files instead of
duplicating prototypes for *cmd functions in other headers.
2011-06-13 21:03:27 +00:00
jilles
91789615b4 sh: Save/restore changed variables in optimized command substitution.
In optimized command substitution, save and restore any variables changed by
expansions (${var=value} and $((var=assigned))), instead of trying to
determine if an expansion may cause such changes.

If $! is referenced in optimized command substitution, do not cause jobs to
be remembered longer.

This fixes $(jobs $!) again, simplifies the man page and shortens the code.
2011-06-12 23:06:04 +00:00
jilles
e193bb76ce sh: Reduce more needless differences between error messages. 2011-06-04 15:05:52 +00:00
jilles
95ad413d4a sh: Remove special code for shell scripts without magic number.
These are called "shell procedures" in the source.

If execve() failed with [ENOEXEC], the shell would reinitialize itself
and execute the program as a script. This requires a fair amount of code
which is not frequently used (most scripts have a #! magic number).
Therefore just execute a new instance of sh (_PATH_BSHELL) to run the
script.
2011-02-04 22:47:55 +00:00
jilles
8605caacbf sh: Send messages about signals to stderr.
This is required by POSIX and seems to make more sense.

See also r217557.
2011-01-30 22:57:52 +00:00
jilles
460d7b088e sh: Fix signal messages being sent to the wrong file sometimes.
When a foreground job exits on a signal, a message is printed to stdout
about this. The buffer was not flushed after this which could result in the
message being written to the wrong file if the next command was a builtin
and had stdout redirected.

Example:
  sh -c 'kill -9 $$'; : > foo; echo FOO:; cat foo

Reported by:	gcooper
MFC after:	1 week
2011-01-18 21:18:31 +00:00
jilles
ae2aabc349 sh: Add kill builtin.
This allows specifying a %job (which is equivalent to the corresponding
process group).

Additionally, it improves reliability of kill from sh in high-load
situations and ensures "kill" finds the correct utility regardless of PATH,
as required by POSIX (unless the undocumented %builtin mechanism is used).

Side effect: fatal errors (any error other than kill(2) failure) now return
exit status 2 instead of 1. (This is consistent with other sh builtins, but
not in NetBSD.)

Code size increases about 1K on i386.

Obtained from:	NetBSD
2010-12-21 22:47:34 +00:00
jilles
9624ca1479 sh: Various simplifications to jobs.c:
* Prefer kill(-X) to killpg(X).
* Remove some dead code.
* No additional SIGINT is needed if int_pending() is already true.

No functional change is intended.
2010-12-12 22:59:34 +00:00
jilles
83a1280f2b sh: Improve internal-representation-to-text code to avoid binary output.
The code to translate the internal representation to text did not know about
various additions to the internal representation since the original ash and
therefore wrote binary stuff to the terminal.

The code is used in the jobs command and similar output.

Note that the output is far from complete and mostly serves for recognition
purposes.
2010-12-06 23:49:27 +00:00
jilles
0c87a741dc sh: POSIX says there should not be a space between Done and (exitstatus).
(On the other hand, (core dumped) does need a space and so does [1] +.)
2010-12-05 22:56:46 +00:00
jilles
91e61ea9fc sh: Improve jobs output of pipelines.
If describing the status of a pipeline, write all elements of the pipeline
and show the status of the last process (which would also end up in $?).
Only write one report per job, not one for every process that exits.

To keep some earlier behaviour, if any process started by the shell in a
foreground job terminates because of a signal, write a message about the
signal (at most one message per job, however).

Also, do not write messages about signals in the wait builtin in
non-interactive shells. Only true foreground jobs now write such messages
(for example, "Terminated").
2010-12-05 22:37:01 +00:00
jilles
506e81b852 sh: Avoid marking a job as done before it is fully created.
In r208489, I added code to reap zombies when forking new processes, to
limit the amount of zombies. However, this can lead to marking a job as done
or stopped if it consists of multiple processes and the first process ends
very quickly. Fix this by only checking for zombies before forking the first
process of a job and not marking any jobs without processes as done or
stopped.
2010-12-05 21:53:29 +00:00
jilles
81a44f4bf1 sh: jobs -p: Do not ask the kernel for the pgid.
The getpgid() call will fail if the first process in the job has already
terminated, resulting in output of "-1".

The pgid of a job is always the pid of the first process in the job and
other code already relies on this.
2010-12-05 16:09:03 +00:00
jilles
f8700ae02e sh: Use <stddef.h> rather than <sys/stddef.h>.
<sys/stddef.h> is only for the kernel and conflicts with <stddef.h>.
2010-10-16 12:40:00 +00:00
obrien
08b8d916b5 In the spirit of r90111, depend on c89 and remove the "STATIC" macro
and its usage.
2010-10-13 22:18:03 +00:00
jhb
ec1e5e05cc Make DEBUG traces 64-bit clean:
- Use %t to print ptrdiff_t values.
- Cast a ptrdiff_t value explicitly to int for a field width specifier.

While here, sort includes.

Submitted by:	Garrett Cooper
2010-10-13 13:22:11 +00:00
obrien
f31ad1c86b Consistently use "STATIC" for all functions in order to be able to set
breakpoints with in a debugger.  And use naked "static" for variables.

Noticed by:	bde
2010-10-13 04:01:01 +00:00
jilles
8fcbe1caf8 sh: Forget about terminated background processes sooner.
Unless $! has been referenced for a particular job or $! still contains that
job's pid, forget about it after it has terminated. If $! has been
referenced, remember the job until the wait builtin has reported its
completion (either with the pid as parameter or without parameters).

In interactive mode, jobs are forgotten after termination has been reported,
which happens before primary prompts and through the jobs builtin. Even
then, though, remember a job if $! has been referenced.

This is similar to what is suggested by POSIX and should fix most memory
leaks (which also tend to cause sh to use more CPU time) with long running
scripts that start background jobs.

Caveats:
* Repeatedly referencing $! without ever doing 'wait', like
    while :; do foo & echo started foo: $!; sleep 60; done
  will still use a lot of memory and CPU time in the long run.
* The jobs and jobid builtins do not cause a job to be remembered for longer
  like expanding $! does.

PR:		bin/55346
2010-06-29 22:37:45 +00:00
jilles
caf58c06dc sh: Pass through SIGINT from a child if interactive and job control
is enabled.

This already worked if without job control.

In either case, this depends on it that a process that terminates due to
SIGINT exits on it (so not with status 1, or worse, 0).

Example:
  sleep 5; echo continued
This does not print "continued" any more if sleep is aborted via ctrl+c.

MFC after:	1 month
2010-06-06 22:27:32 +00:00
jilles
95d1dcb0f4 sh: Reap any zombies before forking for a background command.
This prevents accumulating huge amounts of zombies if a script executes
many background commands but no external commands or subshells.

Note that zombies will not be reaped during long calculations (within
the shell process) or read builtins, but those actions do not create
more zombies.

The terminated background commands will also still be remembered by the
shell.

PR:		bin/55346
2010-05-24 10:35:57 +00:00
jilles
5e8a2136e7 sh: Various warning fixes (from WARNS=6 NO_WERROR=1):
- const
- initializations to silence -Wuninitialized (it was safe anyway)
- remove nested extern declarations
- rename "index" locals to "idx"
2009-12-27 18:04:05 +00:00
jilles
545cc5fec7 sh: Do not run callers' exception handlers in subshells.
Reset the exception handler in the child to main's.

This avoids inappropriate double cleanups or shell duplication when the
exception is caught, such as 'fc' and future 'command eval' and 'command .'.
2009-12-25 20:21:35 +00:00
jilles
f225be7d75 sh: Some changes to stderr flushing:
* increase buffer size from 100 to 256 bytes
* remove implied flush from out2str(), in particular this avoids unnecessary
  flushing in the middle of a -x tracing line
* rename dprintf() to out2fmt_flush(), make it flush out2 and use this
  function in various places where flushing is desired after an error
  message
2009-11-21 14:28:32 +00:00
stefanf
7819e9ab69 Add the POSIX option -p to the jobs builtin command. It prints the PID of the
process leader for each job.  Now the last specified option for the output
format (-l, -p or -s) wins, previously -s trumped -l.

PR:		99926
Submitted by:	Ed Schouten and novel (patches modified by me)
2006-10-07 16:51:16 +00:00
schweikh
627562241f Remove some white space at EOL. 2006-02-04 14:37:50 +00:00
maxim
b2df6a6cc0 o Now when SIG_IGN signal action for SIGCHLD reap zombies
automatically it is possible wait4(2) returns -1 and sets
errno = ECHILD if there were forked children.  A user can
set such signal handler e.g. via ``trap "" 20'', see a PR
for the test case.  Deal with this case and mark a job as
JOBDONE.

PR:		bin/90334
Submitted by:	bde
MFC after:	4 weeks
2005-12-14 17:26:29 +00:00
stefanf
db33f77468 Print pointers with %p rather than casting them to long. 2005-09-05 17:57:19 +00:00
maxim
d6497bbdb5 o Terminate an endless loop sh -T goes into in dowait() around waitproc().
XXX from Tor: "The shell can also go into a similar loop if the child was
killed by signal 127, since the shell would believe the child to have
only stopped (WIFSTOPPED() macro returns nonzero value).  Disallowing
signals 127 and 128 will fix that problem."  See kern/19402 for details.

PR:				bin/66242
Submitted by:			tegge
Analysis and testcase by:	demon
MFC after:			3 weeks
2004-12-02 13:12:43 +00:00
markm
4383f14801 Remove clause 3 from the UCB licenses.
OK'ed by:	imp, core
2004-04-06 20:06:54 +00:00
cracauer
6a8fae4553 Commit fix sent by Tor Egge <Tor.Egge@cvsup.no.freebsd.org>
Only use return value from system call if system call succeeded.

Tested with `make world` and some of my own scripts.

This should be MFCed soon.  While /bin/sh is hard to test the fix is
obviously correct and can be assumed not to break something else
(famous last words...).
2004-02-05 22:34:05 +00:00
njl
8d164f018e Use sys_nsig instead of NSIG for the length of the signal arrays. This
is important if we add new signals later.  From DragonflyBSD:
jobs.c:1.4, trap.c:1.3.

Obtained from:	DragonflyBSD
2004-01-28 19:01:10 +00:00
dds
34719e1dbb Changes following CScout analysis:
- Removed dead declarations
- Made objects that should have been declared as static, static.

The changes use STATIC instead of static, following the existing
convention in the rest of the code.

Approved by:	schweikh (mentor)
MFC after:	2 weeks
2003-07-05 15:18:44 +00:00
tjr
836d4a749e Flush the output buffers before forking a child process to avoid
the child process writing data that the parent should have written.

PR:		50051
MFC after:	2 weeks
2003-03-17 11:28:56 +00:00
tjr
29dbde6d3c Ensure that the TTY file descriptor is greater than or equal to 10 so that
it doesn't interfere with the user's redirections.

PR:		47136
MFC after:	1 week
2003-01-27 07:41:12 +00:00
tjr
81914313b7 Make this compile with DEBUG defined now that WARNS=0 has been removed
from the Makefile:
- Print pointers with %p instead of %x.
- Include missing headers to get prototypes.

Noticed by:	benno
2003-01-21 10:06:04 +00:00
tjr
0423e8e003 When job control is disabled, never show the job id when reporting the
status of a background process that has terminated because of a signal.
2002-12-14 01:08:04 +00:00
mux
b07890219d Use the %t format modifier to print differences between
pointers.  This fixes two format warnings on 64 bits
archs which are fatal now that WFORMAT=0 has been removed.

It doesn't fully fix the sh(1) build on 64 bits platforms
though, there is still some quad_t issues that need to be
fixed.

Tested on:	i386, sparc64
2002-10-01 08:40:07 +00:00