rc

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

commit 3e9e4d3f8f518f8f467066593ae6f270d97f6d60
parent 3815ffb98e9db3d593219cead05284f983eb6d71
Author: Toby Goodwin <tjg@star.le.ac.uk>
Date:   Wed, 10 Nov 1999 14:55:51 +0000

beta: rc-1.6b1

Diffstat:
MAUTHORS | 9+++++----
MChangeLog | 53++++++++++++++++++++++++++++++++++++++++++++++++++++-
MINSTALL | 16++++++++--------
MMakefile.am | 7+++++--
MREADME | 2+-
Macinclude.m4 | 14--------------
Mconfigure.ac | 18++++++++----------
Mglob.c | 8++------
Mhash.c | 2+-
Minput.c | 2+-
Mmain.c | 7+------
Mprint.c | 12++++++------
Mproto.h | 15++++++++++++---
Mrc.1 | 56+++++++++++++++++++++++++++++++++++++++++++++-----------
Mstatus.c | 3++-
Mtrip.rc | 2+-
Mutils.c | 15++++++++-------
Mvar.c | 9+++++++--
18 files changed, 165 insertions(+), 85 deletions(-)

diff --git a/AUTHORS b/AUTHORS @@ -29,7 +29,8 @@ version of rc presented here differs in some respects. Tim 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, Chris Siebenmann, Dale -Scheetz, David Swasey, Gerry Tomlinson, Gert-Jan Vons, Ian Lance Taylor, -Jeremy Fitzhardinge, Marc Moorcroft, Mark K Gardner, Raymond Venneker, -Rich $alz, Rob Savoye, Scott Schwartz, Stefan Dalibor, Tom Culliton, Tom -Tromey, Vincent Broman, Wolfgang Zekoll. +Scheetz, David Luyer, David Swasey, Donn Cave, Gerry Tomlinson, Gert-Jan +Vons, Ian Lance Taylor, Jeremy Fitzhardinge, Marc Moorcroft, Mark H +Wilkinson, Mark K Gardner, Raymond Venneker, Rich $alz, Rob Savoye, +Scott Schwartz, Stefan Dalibor, Steve Simon, Tom Culliton, Tom Tromey, +Vincent Broman, Wolfgang Zekoll. diff --git a/ChangeLog b/ChangeLog @@ -598,6 +598,57 @@ Changes since rc-1.5b2 Tidiness: `make distclean' now removes sigmsgs.[ch]. -1995-05-28 +1999-05-28 Release: rc-1.6. + +1999-08-19 + + Portability: the proposed C 9x __va_copy() macro is called that, not + va_copy(), as I thought. Furthermore, it is defined to be a macro, so + we don't need to use autoconf to check for it. + +1999-10-11 + + Bug: absolute globs don't need special case in doglob(). Avoids + creating path names like `//tmp', which is a UNC path under CygWin. + +1999-10-12 + + Portability: status.c assumes traditional Unix layout of 0 and 1 exit + statuses in the parent, which is not shared by BeOS. Add mkstatval.c. + +1999-10-13 + + Bug: a read(2) error in fdgchar() should call rc_raise(), not + rc_exit(). This bug is easily tickled on systems (like Linux) which + allow you to open(2) but not read(2) directories: `. /tmp'. In all + previous versions of rc, this caused the shell to exit. + + Portability: use POSIX strerror() where it's available; fake it with + sys_errlist[] where not. + + Feature: replace `-V' with `version' variable. + +1999-10-14 + + Portability: exporting `path' causes indigestion in CygWin. Since + it's virtually impossible for a child `rc' process to inherit `path' + (which I consider a bug, but it's not going to be fixed now), simply + don't export `path'. + + Portability: add /usr/bsd to default default path. + + Documentation: failing to search $path for a `.' command is at least + an incompatibility with Tenth Edition rc, and probably a bug. + +1999-11-10 + + Feature: make `version' a list. + +1999-11-11 + + Documentation: when running configure, you need to set LDFLAGS for + `-L' options, not LIBS. + + Release: rc-1.6b1. diff --git a/INSTALL b/INSTALL @@ -34,17 +34,17 @@ descending order of usefulness. for details) to provide EMACS style command line editing and history. If the editline library is not installed in a standard place, you can tell configure where to find it by setting the environment variable - LIBS. For example, the maintainer builds rc by copying libedit.a into - the rc build directory and then running this configure command. + LDFLAGS. For example, the maintainer builds rc by copying libedit.a + into the rc build directory and then running this configure command. - LIBS=-L. sh ../rc-1.5b3/configure --with-editline + LDFLAGS=-L. sh ../rc-1.5b3/configure --with-editline --with-vrl This option tells rc to use the vrl package (see the README file for details) to provide EMACS style command line editing and history. As for `--with-editline', you may need to set the environment variable - LIBS appropriately. + LDFLAGS appropriately. --with-readline @@ -52,10 +52,10 @@ descending order of usefulness. to editline or vrl, but has many more features. The readline package is over 6 times the size of editline (whether you count lines of code, or the library itself). As for editline, you can set the environment - variable LIBS if your readline library is not installed in a standard - place. + variable LDFLAGS if your readline library is not installed in a + standard place. - LIBS=-L/usr/gnu/lib sh configure --with-readline + LDFLAGS=-L/usr/gnu/lib sh configure --with-readline --with-history @@ -105,7 +105,7 @@ probably don't want to bother with `--with-history'. The default path is constructed at configure time, and consists of each of the following directories that exist, in order. - /usr/local/bin /usr/bin /usr/ucb /bin . + /usr/local/bin /usr/bin /usr/bsd /usr/ucb /bin . You can disable this, or specify a different default path. Note that the quote marks (") must be seen by configure; unless you are already diff --git a/Makefile.am b/Makefile.am @@ -26,7 +26,7 @@ SYSTEM = system.o endif bin_PROGRAMS = rc -noinst_PROGRAMS = mksignal tripping $(HISTORY) +noinst_PROGRAMS = mksignal mkstatval tripping $(HISTORY) rc_SOURCES = builtins.c except.c exec.c fn.c footobar.c getopt.c glob.c glom.c hash.c heredoc.c input.c lex.c list.c main.c match.c nalloc.c open.c parse.c print.c redir.c signal.c status.c tree.c utils.c var.c wait.c walk.c which.c @@ -44,9 +44,12 @@ EXTRA_DIST = EXAMPLES RELDATE addon.c addon.h history.1 parse.y rc.1 trip.rc sigmsgs.c sigmsgs.h: mksignal ./mksignal +statval.h: mkstatval + ./mkstatval > statval.h + CONFIGURE_DEPENDENCIES = RELDATE -DISTCLEANFILES = sigmsgs.c sigmsgs.h +DISTCLEANFILES = sigmsgs.c sigmsgs.h statval.h # Of course, parse.c and parse.h depend on parse.y. However, unless # you're hacking on rc's grammar, it's not useful to have this diff --git a/README b/README @@ -1,4 +1,4 @@ -This is a full release, rc-1.6. +This is beta release rc-1.6b1. See COPYING for copying information. All files are diff --git a/acinclude.m4 b/acinclude.m4 @@ -14,20 +14,6 @@ int main(void) { ]) -dnl Check for va_copy() in <stdarg.h>. This is new in C 9x. -AC_DEFUN(RC_HAVE_VA_COPY, [ - AC_CACHE_CHECK(for va_copy(), rc_cv_have_va_copy, AC_EGREP_CPP(yes, [ -#include <stdarg.h> -#ifdef va_copy -yes -#endif -], rc_cv_have_va_copy=yes, rc_cv_have_va_copy=no)) - case "$rc_cv_have_va_copy" in - yes) AC_DEFINE(HAVE_VA_COPY) ;; - esac -]) - - dnl We can't use AC_CHECK_FUNCS for sigsetjmp(), since it's a macro in dnl some places. AC_DEFUN(RC_FUNC_SIGSETJMP, [ diff --git a/configure.ac b/configure.ac @@ -6,9 +6,9 @@ AC_DEFINE_UNQUOTED(RELDATE, "$RELDATE") dnl Automake stuff. dnl Use this one for snapshots... -dnl AM_INIT_AUTOMAKE(rc, 1.5s`echo $RELDATE |sed 's/-//g'`) +dnl AM_INIT_AUTOMAKE(rc, 1.6s`echo $RELDATE |sed 's/-//g'`) dnl ...and this one for releases -AM_INIT_AUTOMAKE(rc, 1.6) +AM_INIT_AUTOMAKE(rc, 1.6b1) AM_CONFIG_HEADER(config.h) @@ -38,7 +38,7 @@ AC_TYPE_SIZE_T AC_TYPE_UID_T AC_CHECK_TYPE(ssize_t, long) -AC_CHECK_FUNCS(getgroups setpgrp setrlimit) +AC_CHECK_FUNCS(getgroups setpgrp setrlimit strerror) RC_FUNC_GETGROUPS RC_FUNC_SIGSETJMP @@ -51,9 +51,9 @@ RC_TYPE_RLIM_T RC_TYPE_SIG_ATOMIC_T -dnl We prefer system calls that don't restart. If we have sigaction() and -dnl SA_INTERRUPT, we'll use 'em. Otherwise, we check whether -dnl good ol' signal() produces interruptible system calls. +dnl We prefer system calls that don't restart. If we have sigaction() +dnl and SA_INTERRUPT, we'll use 'em. Otherwise, we check whether good +dnl ol' signal() produces interruptible system calls. RC_FUNC_SIGACTION case "$rc_cv_sa_int" in yes) AC_DEFINE(HAVE_SA_INTERRUPT) ;; @@ -86,8 +86,6 @@ yes) AC_DEFINE(HAVE_FIFO) ;; no) RC_SYS_MKNOD_FIFO ;; esac -RC_HAVE_VA_COPY - dnl Now handle arguments. AC_ARG_ENABLE(builtin-echo, [ --disable-builtin-echo Don't include \`echo' as a builtin], test "x$enableval" != "xno" && AC_DEFINE(RC_ECHO), @@ -120,7 +118,7 @@ AC_ARG_ENABLE(def-interp, AC_ARG_ENABLE(def-path, [ --enable-def-path=\"/usr/local/bin/\",\"/usr/bin\" Default path [All of these that exist - (/usr/local/bin /usr/bin /usr/ucb /bin .)]], + (/usr/local/bin /usr/bin /usr/bsd /usr/ucb /bin .)]], [ case "$enableval" in no|yes) ;; @@ -132,7 +130,7 @@ AC_ARG_ENABLE(def-path, case "$enable_def_path" in yes) AC_CACHE_CHECK(extant directories for default path, rc_cv_def_path,[ rc_cv_def_path='' - for i in /usr/local/bin /usr/bin /usr/ucb /bin .; do + for i in /usr/local/bin /usr/bin /usr/bsd /usr/ucb /bin .; do if test -d $i; then case "$rc_cv_def_path" in '') rc_cv_def_path=\"$i\" ;; diff --git a/glob.c b/glob.c @@ -216,12 +216,8 @@ static List *doglob(char *w, char *m) { p = pattern; md = metadir; mp = metapattern; - if (*s == '/') - while (*s == '/') - *d++ = *s++, *md++ = *m++; - else - while (*s != '/' && *s != '\0') - *d++ = *s++, *md++ = *m++; /* get first directory component */ + while (*s != '/' && *s != '\0') + *d++ = *s++, *md++ = *m++; /* get first directory component */ *d = '\0'; /* Special case: no slashes in the pattern, i.e., open the current directory. diff --git a/hash.c b/hash.c @@ -230,7 +230,7 @@ extern void initenv(char **envp) { static bool var_exportable(char *s) { static char *notforexport[] = { - "apid", "pid", "apids", "*", "ifs" + "apid", "apids", "ifs", "path", "pid", "version", "*" }; int i; for (i = 0; i < arraysize(notforexport); i++) diff --git a/input.c b/input.c @@ -125,7 +125,7 @@ static int fdgchar() { } while (r < 0 && errno == EINTR); if (r < 0) { uerror("read"); - rc_exit(1); + rc_raise(eError); } chars_in = (size_t) r; } diff --git a/main.c b/main.c @@ -11,8 +11,6 @@ static bool dashoh; static void assigndefault(char *,...); static void checkfd(int, enum redirtype); -static const char id[] = "$Release: @(#)" PACKAGE " " VERSION " " RELDATE " $"; - extern int main(int argc, char *argv[], char *envp[]) { char *dashsee[2], *dollarzero, *null[1]; int c; @@ -21,7 +19,7 @@ extern int main(int argc, char *argv[], char *envp[]) { dollarzero = argv[0]; rc_pid = getpid(); dashell = (*argv[0] == '-'); /* Unix tradition */ - while ((c = rc_getopt(argc, argv, "c:deilnopsVvx")) != -1) + while ((c = rc_getopt(argc, argv, "c:deilnopsvx")) != -1) switch (c) { case 'c': dashsee[0] = rc_optarg; @@ -50,9 +48,6 @@ extern int main(int argc, char *argv[], char *envp[]) { case 's': dashess = TRUE; break; - case 'V': - fprint(1, "%s\n", id); - exit(0); case 'v': dashvee = TRUE; break; diff --git a/print.c b/print.c @@ -289,11 +289,11 @@ extern int fmtprint(Format *format, const char *fmt,...) { va_list ap, saveargs; va_start(ap, fmt); - va_copy(saveargs, format->args); - va_copy(format->args, ap); + __va_copy(saveargs, format->args); + __va_copy(format->args, ap); n += printfmt(format, fmt); va_end(format->args); - va_copy(format->args, saveargs); + __va_copy(format->args, saveargs); return n + format->flushed; } @@ -320,7 +320,7 @@ extern int fprint(int fd, const char *fmt,...) { format.u.n = fd; va_start(ap, fmt); - va_copy(format.args, ap); + __va_copy(format.args, ap); printfmt(&format, fmt); va_end(format.args); @@ -365,7 +365,7 @@ extern char *mprint(const char *fmt,...) { format.u.n = 1; va_start(ap, fmt); - va_copy(format.args, ap); + __va_copy(format.args, ap); result = memprint(&format, fmt, ealloc(PRINT_ALLOCSIZE), PRINT_ALLOCSIZE); va_end(format.args); return result; @@ -378,7 +378,7 @@ extern char *nprint(const char *fmt,...) { format.u.n = 0; va_start(ap, fmt); - va_copy(format.args, ap); + __va_copy(format.args, ap); result = memprint(&format, fmt, nalloc(PRINT_ALLOCSIZE), PRINT_ALLOCSIZE); va_end(format.args); return result; diff --git a/proto.h b/proto.h @@ -23,11 +23,11 @@ typedef long align_t; #include <stdarg.h> -/* C 9x specifies a va_copy() macro which should be used for copying +/* C 9x specifies a __va_copy() macro which should be used for copying objects of type va_list. Of course, most places don't have this yet, but where it does exist we need to use it. */ -#ifndef va_copy -#define va_copy(x,y) (x)=(y) +#ifndef __va_copy +#define __va_copy(x,y) (x)=(y) #endif #if STDC_HEADERS @@ -59,6 +59,15 @@ extern void qsort(void *, size_t, size_t, int (*)(const void *, const void *)); #endif /* STDC_HEADERS */ +#if HAVE_STRERROR +/* Smells like POSIX. */ +#else +/* Assume BSD-style sys_errlist[]. */ +extern int sys_nerr; +extern char *sys_errlist[]; +#define strerror(x) ((0 <= (x)) && (errno < (x)) ? sys_errlist[x] : (char *)0) +#endif + #if HAVE_UNISTD_H #include <unistd.h> #endif diff --git a/rc.1 b/rc.1 @@ -161,7 +161,7 @@ .if !"\\$4"" .Xf \\$2 \\$1 "\\$3\\f\\$1\\$4\\*(Xi" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9" .if "\\$4"" \\$3\fR\s10 .. -.TH RC 1 "1999-05-28" +.TH RC 1 "1999-11-11" .SH NAME rc \- shell .SH SYNOPSIS @@ -306,11 +306,6 @@ to read from standard input. Any arguments are placed in .Cr $* . .TP -.Cr \-V -This flag causes -.I rc -to print a version string to standard output, and exit immediately. -.TP .Cr \-v This flag causes .I rc @@ -1195,7 +1190,9 @@ as its value. .SH "SPECIAL VARIABLES" Several variables are known to .I rc -and are treated specially. +and are treated specially. In the following list, +``(read only)'' indicates that an attempt to set the +variable will silently have no effect. .TP .Cr * The argument list of @@ -1225,7 +1222,7 @@ command. .Cr apid The process ID of the last process started in the background. .TP -.Cr apids +.Cr apids " (read only)" The process IDs of any background processes which are outstanding or which have died and have not been waited for yet. .TP @@ -1357,7 +1354,7 @@ If this function is set, then it gets executed every time is about to print .Cr "$prompt(1)" . .TP -.Cr status +.Cr status " (read only)" The exit status of the last command. If the command exited with a numeric value, that number is the status. @@ -1380,6 +1377,11 @@ usually sets .Cr $status to .Cr "(0 0)" . +.TP +.Cr version " (read only)" +This variable contains a string which identifies this +version of +.IR rc . .PP The values of .Cr "$path" , @@ -1950,6 +1952,25 @@ processes. .PP List definitions in exported functions are "noisier" than they need to be. .PP +If both +.Cr $PATH +and +.Cr $path +are set, +.I rc +believes the former. Arguably this is a bug: +.I rc +can quite happily deal with path elements that contain +.Cr : , +but such elements will be split at the colon in descendant +.I rc +processes. +.PP +The +.Cr . +command should search +.Cr $path . +.PP Bug reports should be mailed to .Cr "<tjg@star.le.ac.uk>" . .SH INCOMPATIBILITIES @@ -1957,7 +1978,7 @@ Here is a list of features which distinguish this incarnation of .I rc from the one described in the Bell Labs manual pages: .PP -The v10 +The Tenth Edition .I rc does not have the .B else @@ -1971,12 +1992,25 @@ if the preceding .B if test does not succeed. .PP -Backquotes are slightly different in v10 +Backquotes are slightly different in Tenth Edition .IR rc : a backquote must always be followed by a left-brace. This restriction is not present for single-word commands in this .IR rc . .PP +For +.Cr . +.IR file , +the Tenth Edition +.IR rc +searches +.Cr $path +for +.IR file . +This +.I rc +does not; this is a bug. +.PP The list flattening operator, .Cr $^foo , is spelt diff --git a/status.c b/status.c @@ -2,6 +2,7 @@ #include "rc.h" #include "sigmsgs.h" +#include "statval.h" #include "wait.h" /* status == the wait() value of the last command in the pipeline, or the last command */ @@ -40,7 +41,7 @@ extern int getstatus() { } extern void set(bool code) { - setstatus(-1, (!code) << 8); /* exit status 1 == 0x100 */ + setstatus(-1, code ? STATUS0 : STATUS1); } /* take a pipeline and store the exit statuses. Check to see whether any of the children dumped core */ diff --git a/trip.rc b/trip.rc @@ -2,7 +2,7 @@ # Invoke as "path-to-new-rc < trip.rc" rc=$0 -echo tripping $rc +echo tripping $rc $version fn fail { echo >[1=2] trip took a wrong turn: $* diff --git a/utils.c b/utils.c @@ -19,14 +19,15 @@ extern void pr_error(char *s, int offset) { /* our perror */ extern void uerror(char *s) { - extern int sys_nerr; - extern char *sys_errlist[]; - if (errno > sys_nerr) - return; - if (s != NULL) - fprint(2, "%s: %s\n", s, sys_errlist[errno]); + char *err; + + err = strerror(errno); + if (!err) err = "unknown error"; + + if (s) + fprint(2, "%s: %s\n", s, err); else - fprint(2, "%s\n", sys_errlist[errno]); + fprint(2, "%s\n", err); } /* Die horribly. This should never get called. Please let me know if it does. */ diff --git a/var.c b/var.c @@ -57,14 +57,19 @@ extern bool varassign_string(char *extdef) { associated with $status) */ +static List id2 = { "$Release: @(#)" PACKAGE " " VERSION " " RELDATE " $", 0, 0 }; +static List id1 = { VERSION, 0, &id2 }; + extern List *varlookup(char *name) { Variable *look; List *ret, *l; int sub; - if (streq(name, "status")) - return sgetstatus(); if (streq(name, "apids")) return sgetapids(); + if (streq(name, "status")) + return sgetstatus(); + if (streq(name, "version")) + return &id1; if (*name != '\0' && (sub = a2u(name)) != -1) { /* handle $1, $2, etc. */ for (l = varlookup("*"); l != NULL && sub != 0; --sub) l = l->n;