rc

[fork] interactive rc shell
Log | Files | Refs | README | LICENSE

commit 5b624196125034b95d504be682127a5964e08da5
parent 5966ab2ca2632c5bed9815def1add4859beececa
Author: Toby Goodwin <toby@paccrat.org>
Date:   Thu,  1 Mar 2018 21:37:18 +0000

Merge branch 'master' into ifnot

Diffstat:
MAUTHORS | 20++++++++++----------
Macinclude.m4 | 36------------------------------------
Dconfig.h-dist | 204-------------------------------------------------------------------------------
Mconfigure.ac | 2--
Mfn.c | 11+++--------
Mglom.c | 2+-
Mrc.h | 1-
Msignal.c | 10++++------
Mstatus.c | 6++++--
Dtestcld.c | 19-------------------
Mtrip.rc | 10++++++++++
11 files changed, 32 insertions(+), 289 deletions(-)

diff --git a/AUTHORS b/AUTHORS @@ -28,13 +28,13 @@ FTP or HTTP directory as the shell). Please read this paper bearing in mind that it describes a program that was written at AT&T and that the version of rc presented here differs in some respects. -Toby would like to thank these people for their contributions since he took -over maintenance of rc. Aharon Robbins, Arvid Requate, Bengt Kleberg, -Brynjulv Hauksson, Byron Rakitzis, Callum Gibson, Casper Ti. Vector, Chris -Siebenmann, Christian Neukirchen, Dale Scheetz, Dan Moniz, David Luyer, -David Swasey, Decklin Foster, Donn Cave, Erik Quanstrom, Gary Carvell, -Gerry Tomlinson, Gert-Jan Vons, Ian Lance Taylor, Jakub Wilk, Jeremy -Fitzhardinge, Marc Moorcroft, Mark H Wilkinson, Mark K Gardner, Raymond -Venneker, Rich $alz, Rob Savoye, Scott Schwartz, Stefan Dalibor, Steve -Simon, Thomas Nordin, Tom Culliton, Tom Tromey, Vincent Broman, Wolfgang -Zekoll. +Toby would like to thank these people for their contributions since he +took over maintenance of rc. Aharon Robbins, Arvid Requate, Bengt +Kleberg, Bert Münnich, Brynjulv Hauksson, Byron Rakitzis, Callum Gibson, +Casper Ti. Vector, Chris Siebenmann, Dale Scheetz, Dan Moniz, David +Luyer, David Swasey, Decklin Foster, Donn Cave, Erik Quanstrom, Gary +Carvell, Gerry Tomlinson, Gert-Jan Vons, Ian Lance Taylor, Jakub Wilk, +Jeremy Fitzhardinge, Leah Neukirchen, Marc Moorcroft, Mark H Wilkinson, +Mark K Gardner, Raymond Venneker, Rich $alz, Rob Savoye, Scott Schwartz, +Stefan Dalibor, Steve Simon, Thomas Nordin, Tom Culliton, Tom Tromey, +Vincent Broman, Wolfgang Zekoll. diff --git a/acinclude.m4 b/acinclude.m4 @@ -128,42 +128,6 @@ AC_DEFUN([RC_TYPE_SIG_ATOMIC_T], [ ]) -dnl Do we have SysV SIGCLD semantics? In other words, if we set the -dnl action for SIGCLD to SIG_IGN does wait() always say ECHILD? Linux, -dnl of course, is bizarre here. It basically implements the SysV -dnl semantics, but if the parent calls wait() before the child calls -dnl exit(), wait() returns with the PID of the child as normal. (Real -dnl SysV waits for all children to exit, then returns with ECHILD.) -dnl Anyway, this is why the `sleep(1)' is there. -AC_DEFUN([RC_SYS_V_SIGCLD], [ - AC_CACHE_CHECK(for SysV SIGCLD semantics, rc_cv_sysv_sigcld, - AC_TRY_RUN([ -#include <errno.h> -#include <signal.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <unistd.h> -int main(void) { - int i; - signal(SIGCLD, SIG_IGN); - switch (fork()) { - case -1: - return 1; - case 0: - return 0; - default: - sleep(1); - if (wait(&i) == -1 && errno == ECHILD) return 0; - else return 1; - } -} - ], rc_cv_sysv_sigcld=yes, rc_cv_sysv_sigcld=no, rc_cv_sysv_sigcld=yes)) - case "$rc_cv_sysv_sigcld" in - yes) AC_DEFINE(HAVE_SYSV_SIGCLD, 1, [Has SysV SIGCLD]) ;; - esac -]) - - dnl Do we have /dev/fd or /proc/self/fd? AC_DEFUN([RC_SYS_DEV_FD], [ AC_CACHE_CHECK(for /dev/fd, rc_cv_sys_dev_fd, diff --git a/config.h-dist b/config.h-dist @@ -1,204 +0,0 @@ -/* Copy config.h-dist to config.h and edit config.h, don't edit this file */ - -/* - * Configuration parameters for rc. Suggested defaults are at the bottom - * of this file (you should probably look at those first to see if your - * system matches one of them; you can search for the beginning of the - * defaults section by looking for the string "#ifndef CUSTOM"). If you - * want to override the suggested defaults, define the macro CUSTOM. -#define CUSTOM - */ - -/* - * (Note that certain default settings redefine this macro) - * DEFAULTPATH the default search path that rc uses when it is started - * without either a $PATH or $path environment variable. You must pick - * something sensible for your system if you don't like the path shown - * below. - */ -#define DEFAULTPATH "/usr/ucb", "/usr/bin", "/bin", "." - -/* - * Define the macro NODIRENT if your system has <sys/dir.h> but not - * <dirent.h>. (e.g., NeXT-OS and RISCos) -#define NODIRENT - */ - -/* - * Define the macro SVSIGS if your system has System V signal semantics, - * i.e., if "slow" system calls are interrupted rather than resumed - * after returning from an interrupt handler. (If you are not sure what - * this means, see the man page for signal(2). In any case, it is probably - * safe to leave this macro undefined.) -#define SVSIGS - */ - -/* - * Define the macro NOCMDARG if you do not have /dev/fd or fifos on your - * system. You may also want to define this if you have broken fifos. -#define NOCMDARG - */ - -/* - * Define TMPDIR if you need to have rc create its fifos in a directory - * other than /tmp. For example, if you have a Sun with /tmp mounted - * as a ramdisk (type "tmpfs") then you cannot use fifos in /tmp (sigh). -#define TMPDIR "/var/tmp" - */ - -/* - * Define the macro DEVFD if your system supports /dev/fd. -#define DEVFD - */ - -/* - * Define the macro NOLIMITS if your system does not support Berkeley - * limits. -#define NOLIMITS - */ - -/* - * Define the macro NOSIGCLD if your system uses SIGCLD in the System - * V way. (e.g., sgi's Irix) -#define NOSIGCLD - */ - -/* - * Define the macro READLINE if you want rc to call GNU readline - * instead of read(2) on interactive shells. -#define READLINE - */ - -/* - * Define the macro NOEXECVE if your Unix does not interpret #! in the - * kernel, and uncomment the EXECVE variable in the Makefile. -#define NOEXECVE - */ - -/* - * If you want rc to default to some interpreter for files which don't - * have a legal #! on the first line, define the macro DEFAULTINTERP. -#define DEFAULTINTERP "/bin/sh" - */ - -/* - * If your /bin/sh (or another program you care about) rejects environment - * variables with special characters in them (such as ':' or '-'), rc can - * put out ugly variable names using [_0-9a-zA-Z] that encode the real name; - * define PROTECT_ENV for this hack. (Known offenders: every sh I have tried; - * SunOS (silently discards), NeXT (aborts with error), SGI (aborts with - * error), Ultrix (sh seems to work, sh5 aborts with error)) -#define PROTECT_ENV - */ - -/* - * Define the macro NOECHO if you wish to omit rc's echo builtin from the - * compile. -#define NOECHO - */ - -/* - * Define the NOJOB if you do *not* wish rc to perform backgrounding - * as if it were a job-control shell; that is, if you do *not* wish - * it to put a command spawned in the background into a new process - * group. Since most systems support job control and since there are - * many broken programs that do not behave correctly when backgrounded - * in a v7 non-job-control fashion, rc by default performs a job- - * control-like backgrounding. -#define NOJOB - */ - -/* Beginning of defaults section: */ - -#ifndef CUSTOM - -/* - * Suggested settings for Sun, NeXT and sgi (machines here at TAMU): - */ - -#ifdef NeXT /* Used on NextOS 2.1 */ -#define NODIRENT -#define PROTECT_ENV -#define NOCMDARG -#endif - -#ifdef sgi /* Used on Irix 3.3.[12] */ -#define SVSIGS -#define NOSIGCLD -#define PROTECT_ENV -#undef DEFAULTPATH -#define DEFAULTPATH "/usr/bsd", "/usr/sbin", "/usr/bin", "/bin", "." -#endif - -#ifdef sun /* Used on SunOS 4.1.1 */ -#define PROTECT_ENV -#undef DEFAULTPATH -#define DEFAULTPATH "/usr/ucb", "/usr/bin", "." -#endif - -/* - * Suggested settings for HP300 running 4.3BSD-utah (DWS): - */ - -#if defined(hp300) && !defined(hpux) -#define NODIRENT -#define NOCMDARG -#define DEFAULTINTERP "/bin/sh" -#define PROTECT_ENV -#endif - -/* - * Suggested settings for Ultrix - */ - -#ifdef ultrix -#define PROTECT_ENV -#define DEFAULTINTERP "/bin/sh" /* so /bin/true can work */ -#endif - -/* - * Suggested settings for RISCos 4.52 - */ - -/* - This doesn't work without interfering with other MIPS-based - systems' configuration. Please do it by hand. -*/ - -#if defined(host_mips) && defined(MIPSEB) && defined(SYSTYPE_BSD43) -#define NODIRENT -#define PROTECT_ENV -#endif - -/* - * Suggested settings for AIX - */ - -#ifdef _AIX -#define PROTECT_ENV -#endif - -/* - * Suggested settings for OSF/1 1.0 - */ - -#ifdef OSF1 -#define PROTECT_ENV -#endif - -/* - * Suggested settings for Unicos XXX - */ - -#ifdef cray -#define PROTECT_ENV -#define NOLIMITS -#define word _word -#define DEFAULTINTERP "/bin/sh" -#endif - -#endif /* CUSTOM */ - -#ifndef TMPDIR -#define TMPDIR "/tmp" -#endif diff --git a/configure.ac b/configure.ac @@ -63,8 +63,6 @@ RC_TYPE_RLIM_T RC_TYPE_SIG_ATOMIC_T -RC_SYS_V_SIGCLD - dnl Does the kernel handle `#! /interpreter'? AC_SYS_INTERPRETER case "$ac_cv_sys_interpreter" in diff --git a/fn.c b/fn.c @@ -29,10 +29,7 @@ extern void inithandler() { null.type = nBody; null.u[0].p = null.u[1].p = NULL; for (i = 1; i < NUMOFSIGNALS; i++) -#if HAVE_SYSV_SIGCLD - if (i != SIGCLD) -#endif - if (sighandlers[i] == SIG_IGN) + if (i != SIGCHLD && sighandlers[i] == SIG_IGN) fnassign(signals[i].name, NULL); /* ignore incoming ignored signals */ if (interactive || sighandlers[SIGINT] != SIG_IGN) { def_sigint = sigint; @@ -151,10 +148,8 @@ extern void fnassign(char *name, Node *def) { new->def = newdef; new->extdef = NULL; if (strncmp(name, "sig", conststrlen("sig")) == 0) { /* slight optimization */ -#if HAVE_SYSV_SIGCLD /* System V machines treat SIGCLD very specially */ - if (streq(name, "sigcld")) - rc_error("can't trap SIGCLD"); -#endif + if (streq(name, "sigchld") || streq(name, "sigcld")) + rc_error("can't trap SIGCHLD"); if (streq(name, "sigexit")) runexit = TRUE; for (i = 1; i < NUMOFSIGNALS; i++) /* zero is a bogus signal */ diff --git a/glom.c b/glom.c @@ -266,7 +266,7 @@ static List *backq(Node *ifs, Node *n) { bq = bqinput(glom(ifs), p[0]); close(p[0]); rc_wait4(pid, &sp, TRUE); - statprint(-1, sp); + setstatus(-1, sp); varassign("bqstatus", word(strstatus(sp), NULL), FALSE); sigchk(); return bq; diff --git a/rc.h b/rc.h @@ -347,7 +347,6 @@ extern void set(bool); extern void setstatus(pid_t, int); extern List *sgetstatus(void); extern void setpipestatus(int [], int); -extern void statprint(pid_t, int); extern void ssetstatus(char **); extern char *strstatus(int s); diff --git a/signal.c b/signal.c @@ -83,14 +83,12 @@ extern void initsignal() { void (*h)(int); int i; -#if HAVE_SYSV_SIGCLD - /* Ensure that SIGCLD is not SIG_IGN. Solaris's rshd does this. :-( */ - h = sys_signal(SIGCLD, SIG_IGN); + /* Ensure that SIGCHLD is not SIG_IGN. Solaris's rshd does this. :-( */ + h = sys_signal(SIGCHLD, SIG_IGN); if (h != SIG_IGN && h != SIG_ERR) - sys_signal(SIGCLD, h); + sys_signal(SIGCHLD, h); else - sys_signal(SIGCLD, SIG_DFL); -#endif + sys_signal(SIGCHLD, SIG_DFL); for (i = 1; i < NUMOFSIGNALS; i++) { #ifdef SIGKILL diff --git a/status.c b/status.c @@ -7,6 +7,8 @@ /* status == the wait() value of the last command in the pipeline, or the last command */ +static void statprint(pid_t, int); + static int statuses[512]; static int pipelength = 1; @@ -49,8 +51,8 @@ extern void set(bool code) { extern void setpipestatus(int stats[], int num) { int i; for (i = 0; i < (pipelength = num); i++) { - statprint(-1, stats[i]); statuses[i] = stats[i]; + statprint(-1, stats[i]); } } @@ -64,7 +66,7 @@ extern void setstatus(pid_t pid, int i) { /* print a message if termination was with a signal, and if the child dumped core. exit on error if -e is set */ -extern void statprint(pid_t pid, int i) { +static void statprint(pid_t pid, int i) { if (WIFSIGNALED(i)) { int t = WTERMSIG(i); char *msg = ((t > 0) && (t < NUMOFSIGNALS) ? signals[WTERMSIG(i)].msg : ""); diff --git a/testcld.c b/testcld.c @@ -1,19 +0,0 @@ -#include <errno.h> -#include <signal.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <unistd.h> -int main(void) { - int i; - sigset(SIGCLD, SIG_IGN); - switch (fork()) { - case -1: - return 1; - case 0: - return 0; - default: - sleep(1); - if (wait(&i) == -1 && errno == ECHILD) return 0; - else return 1; - } -} diff --git a/trip.rc b/trip.rc @@ -690,3 +690,13 @@ if (! ~ $X YYY) { A=``($nl){ $rc -c 'mkdir / >[2=1] | tr a-z A-Z' } B=``($nl){ $rc -c '>[2=1] mkdir / | tr a-z A-Z' } ~ $A $B || fail counter intuitive redirection bug, $A '!=' $B + +# test for github issue #40 +$rc -ec 'false | false' +if (~ $status 0) { + fail '"rc -e" exits with zero status when command in pipeline returns non-zero' +} +$rc -ec 'X=`{false}' +if (~ $status 0) { + fail '"rc -e" exits with zero status when backquote command returns non-zero' +}