rc

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

commit e11c7df86144bed383ac6bbeaecc3017d18b37db
parent 671e1e2d1599aa8c5f1010b3fe75c151c56a7403
Author: Toby Goodwin <tjg@star.le.ac.uk>
Date:   Mon, 11 Jan 1999 10:55:18 +0000

beta: rc-1.5b4

Diffstat:
AAUTHORS | 34++++++++++++++++++++++++++++++++++
DCHANGES | 278-------------------------------------------------------------------------------
ACOPYING | 26++++++++++++++++++++++++++
DCOPYRIGHT | 26--------------------------
AChangeLog | 531+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AINSTALL | 167+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AMakefile.am | 69+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
DMakefile.in | 80-------------------------------------------------------------------------------
ANEWS | 50++++++++++++++++++++++++++++++++++++++++++++++++++
MREADME | 191+++++++------------------------------------------------------------------------
Aacconfig.h | 80+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aacinclude.m4 | 206+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Maddon.c | 33++++++++++++++++++---------------
Maddon.h | 49+++++++++++++++++++++----------------------------
Mbuiltins.c | 15++++++++-------
Aconfig.h-dist | 204+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dconfig.h.in | 44--------------------------------------------
Dconfigure | 2541-------------------------------------------------------------------------------
Aconfigure.ac | 200+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dconfigure.in | 287-------------------------------------------------------------------------------
Dcpp | 38--------------------------------------
Mexcept.c | 4++--
Mexec.c | 16++++++----------
Mexecve.c | 6+++---
Mfn.c | 19++++++++++---------
Mfootobar.c | 10+++++-----
Agetgroups.h | 10++++++++++
Mgetopt.c | 73+++++++++++++++++++++++++++++++++++++------------------------------------
Mglob.c | 3+--
Mglom.c | 17++++++++++++-----
Dgroup.h | 9---------
Mhash.c | 10+++++-----
Ahistory.1 | 243+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ahistory.c | 339+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dhistory/history.1 | 234-------------------------------------------------------------------------------
Dhistory/history.c | 341-------------------------------------------------------------------------------
Minput.c | 99+++++++++++++++++++++++++++++++++++++++----------------------------------------
Dinstall-sh | 250-------------------------------------------------------------------------------
Mjbwrap.h | 22++++++++++++++++++----
Mlex.c | 12+-----------
Mmain.c | 10++++++++--
Dmksignal | 76----------------------------------------------------------------------------
Amksignal.c | 238+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mnalloc.c | 7++-----
Mopen.c | 22+++++++++++++++++++++-
Mparse.y | 4+---
Mprint.c | 141+++++++++++++------------------------------------------------------------------
Mproto.h | 70+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
Mrc.1 | 61+++++++++++++++++++++++++++++++++++++++++++++----------------
Mrc.h | 114++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
Mrlimit.h | 36++++++++++++++++++------------------
Msignal.c | 53+++++++++++++++++++++++++++++++++++++----------------
Mstatus.c | 23+++++++++++++----------
Asystem-bsd.c | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asystem.c | 10++++++++++
Mtrip.rc | 0
Atripping.c | 33+++++++++++++++++++++++++++++++++
Mutils.c | 42++----------------------------------------
Mvar.c | 8+++-----
Dversion.c | 1-
Aversion.c.in | 1+
Mwait.c | 94+++++++++++++++++++++++++++++++++++++++----------------------------------------
Await.h | 23+++++++++++++++++++++++
Mwalk.c | 5+++--
Mwhich.c | 26+++++++++++++++-----------
Dy.tab.c | 1070-------------------------------------------------------------------------------
Dy.tab.h | 33---------------------------------
67 files changed, 3104 insertions(+), 6023 deletions(-)

diff --git a/AUTHORS b/AUTHORS @@ -0,0 +1,34 @@ +The current maintainer of rc is Tim Goodwin <tjg@star.le.ac.uk>. Please +send all bug reports to him. + +This shell was written by me, Byron Rakitzis, but kudos go to Paul Haahr +for letting me know what a shell should do and for contributing certain +bits and pieces to rc (notably the limits code, print.c, most of which.c +and the backquote redirection code), and to Hugh Redelmeier for running +rc through his fussy ANSI compiler and thereby provoking interesting +discussions about portability, and also for providing many valuable +suggestions for improving rc's code in general. Finally, many thanks +go to David Sanderson, for reworking the man page to format well with +troff, and for providing many suggestions both for rc and its man page. + +Thanks to Boyd Roberts for the original history.c, and to Hugh again for +re-working parts of that code. + +Of course, without Tom Duff's design of the original rc, I could not +have written this shell (though I probably would have written *a* +shell). Almost all of the features, with minor exceptions, have been +implemented as described in the Unix v10 manuals. Hats off to td for +designing a C-like, minimal but very useful shell. + +Tom Duff has kindly given permission for the paper he wrote for UKUUG to +be distributed with this version of rc (called "plan9.ps" in the same +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. + +Tim would like to thank these people for their contributions since he +took over maintenance of rc. Arvid Requate, Bengt Kleberg, Brynjulv +Hauksson, Byron Rakitzis, Chris Siebenmann, David Swasey, 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. diff --git a/CHANGES b/CHANGES @@ -1,278 +0,0 @@ -Changes since 1.2: (Too many to count!) - -A memory stomping bug was fixed (provoked by assigning a variable -to its old value plus something else). - -Better signal handling; a real signal handler which manages a queue -of pending signals was added. - -rc now ignores SIGQUIT and traps SIGINT even in non-interactive -mode. Thus, - - rc ed.sh - -will not do mysterious things if the shell script "ed.sh" calls a -command like "ed" and then you hit ^C. - -rc now opens 0, 1, 2 on /dev/null if they are inherited closed. -rc -o prevents this. - -A couple of stupid O(n^2) string appends were replaced with O(n) -loops. This should make foo=`{cat /etc/termcap} bar=$^foo a little -faster :-) - -Returning a list of signals from a function is now legal, so "return -$status" should always work. - -The code has been revised, new printing routines have been added. - -rc no longer uses redundant braces when exporting functions. - -A first stab at a verification suite has been added (trip.rc). -(someone, please help me make this comprehensive!) - -rc -p now does not initialize functions from the environment. This -should make it easier to write shell scripts that don't need to -assume anything about the environment. - -Inherited ignored signals are now ignored in the current shell and -passed on ignored to the child processes. whatis -s also reflects -this information. - -A file descriptor leak in the /dev/fd implementation of >{} was -fixed. - -A variable set to '' was not imported from the environment; this -has been fixed. - -Changes since 1.3beta: - -New Makefile/config.h setup. - -builtin echo may now be conditionally included out, to use a Goldwynism. - -builtin exit takes any legal exit status. If the status is not all zeros, -rc exits with 1. (having "exit sigiot" produce a core dump would be going -a little far, I think.) - -limit does not append a unit after a zero limit; 0g was too confusing. - -exec > /nonexistentfile does not cause rc to exit any more. - -If a noninteractive rc is started with sigint ignored, rc does not install -its own signal handler. - -error messages produced by rc in a subshell were cleaned up. (rc erroneously -reset the 'interactive' flag after a fork) - -print.c was cleaned up a little; no functionality was changed, but should -be more portable now. - -a bug in rc-1.3beta (not previous versions) was fixed: setting the first -element of $path to '' caused PATH to be exported as '':etc.. - -getopt's "illegal option" message was gratuitously changed to something -less abrupt. - -some dead code was removed from input.c - -%term was changed to %token in parse.y; apparently newer yacc's don't grok -%term any more. - -a race condition in the signal handler was fixed. - -the variable in for() was getting evaluated each time through the loop -(e.g., for (`{echo i;date>[1=2]} in 1 2 3)echo $i would print the date -three times). This was cleaned up. - -a redundant fork() was removed from walk.c; this showed up when running -a braced command with a redirection in the background. e.g., {a;b}>c& - -man pages for history and rc were cleaned up by david (thanks). - -rc set SIGQUIT and SIGTERM to SIG_DFL on background jobs---even when -trying to do old-style backgrounding (i.e., don't use process groups, -just ignore SIGINT & SIGQUIT & SIGTERM). - -$0 is now changed to the name of the signal when entering a signal -handler. Thus it's possible to write code like - - fn sigint sigterm sigquit { - switch ($0) { - case sigint - ... - case sigterm - ... - -wait with no arguments now prints the pid of any and all children -that died with a signal. e.g., - - ; wait - 25321: terminated - 25325: terminated - -as opposed to - - ; wait - terminated - -An error saving/restoring state in the input stream code would -cause rc to exit with the (erroneous) command: - - eval '|[a' - -FIFO's were not removed in a backgrounded command, e.g., - - cat <{echo hi}& - -Changes since rc-1.4beta: - -getopt was renamed to rc_getopt to avoid libc collisions. - -$cdpath with a / in it caused a cd to sometimes have two //'s at the -front of the path. This is reserved by POSIX, so I changed it to skip -one of the /'s. - -signal handling now emulates sh in the way I described in a previous -message: the race condition present in older rc's whereby some SIGINTs -got lost is now gone; any SIGINT received during a wait() is acted upon -at the end of the wait(), unless of course SIGINT is being deliberately -ignored. - -getopt was renamed to avoid naming conflicts with libc. Also a sound -move since rc_getopt is no longer quite libc-getopt compatible; I had -to add in a mechanism for resetting getopt. - -signal handler code in fn.c was cleaned up; there were several bugs -in rc-1.4beta, notably the shell sometimes spawned background jobs -with SIGTERM ignored. I took the opportunity to make things a little -cleaner here. - -a quasi-memory leak in the code for while() was fixed: a long-running -while that had rc commands allocating memory in it could cause the -shell to grow without bounds. I fixed this by placing the while loop -(*and* test!) inside a new allocation arena each time through the loop. - -A new configuration parameter, NOJOB, was added to allow you to force -v7-style backgrounding (no setpgrp, ignore SIGINT and SIGTERM). - -The FIFO code was reworked a little. It should be more robust now--- -FIFOs get removed at the end of the command of the argument list -that they were on: - - fn foo {echo $*; cat $*} - foo<{echo hi} - -now works as expected. Also FIFO names are pushed onto the exception -stack so that their removal occurs in the face of exceptions and so -on. - -A memory leak in treefree() was plugged up --- the root node of a -function was not getting freed. - -Changes since rc-1.4: - -General changes: - - Some small memory leaks/uninit references revealed by Purify. - - $bqstatus for querying the exit status of a backquote. - - Globbing through unreadable directories. - - More options to whatis. - - History append which always re-opens the file (avoids - inconsistencies over multiple NFS-mounted accesses to - $history). - - Support "rc -s". - ---------- - -Makefile: Added comment referring to README for yacc/malloc problem. - -uiltins.c: Added more options to whatis, protected rlimit prototypes - with #ifndef SYSVR4, renamed SIGCHK to sigchk. - -except.c: Patched nl_on_intr printing to happen only in interactive - shells. - -exec.c: Added comment explaining nl_on_intr variable, renamed SIGCHK - to sigchk. - -fn.c: Replaced by-hand consing of exception stack etc. for signal - handler execution with call to funcall(). Replaced fun2str - call with call on print routines. - -footobar.c: Got rid of memory leak in get_name(), parenthesize count, - flat and var nodes for correctness in unparsing, removed - list2str, made get_name use nalloc space, merge in a - better parse_var from es. - -glob.c: Split out a test so that closedir is called correctly, renamed - SIGCHK to sigchk. - -glom.c: Added bqstatus, renamed SIGCHK to sigchk, removed spurious - setsigdefaults, patched uninit memory reference, rename - "clear" to "memzero", wait for bq subproc to finish on EINTR. - -hash.c: Added options to function/variable print code. - -history/history.c: Added '@' to the list of chars which can precede an - ignored '-'. - -input.c: Got rid of tiny memory leak in closefds, got rid of uninit - memory reference in popinput, moved nul ignored check into - realgchar(), changed history append to always reopen the - history file, replaced SIGCHK with sigchk. Freed memory - returned by call to readline(). - -lex.c: Corrected typo in comment, moved nul character ignore code - to input routines. - -main.c: Added -s flag. - -nalloc.c: Added convenience feature to erealloc. (Allow NULL parameter) - -print.c: Changed use of va_start so broken compilers can compile - print code. - -proto.h: Added fake memset. - -rc.h: Replaced clear() function prototype with a macro call on - memset(), removed SIGCHK, fixed prototypes. - -signal.c: Removed unconditional exit in catcher code, renamed SIGCHK - to sigchk. - -status.c: Rewrite sgetstatus breaking out strstatus so that bqstatus - can be set from glom routines. - -utils.c: Got rid of clear() (use memset from C library), rename SIGCHK - to sigchk. - -var.c: Got rid of memory leak in listassign(), converted list2str() - call to something using the print routines. - -version.c: New version string. - -wait.c: Got rid of memory leak in rc_fork, renamed SIGCHK to sigchk. - -walk.c: Fixed pre-redirection bug, removed spurious setsigdefaults(), - renamed SIGCHK to sigchk. - - -Changes since rc-1.5beta1 - - Configuration: rc now uses GNU autoconf. - - Portability: mksignal works on HPUX 10. - - Portability: resources can be (quad_t). - - Bug: if rc was started with SIGCLD == SIG_IGN (e.g. by Solaris's - rshd) it would loop. Fixed by resetting SIGCLD to SIG_DFL if it - was SIG_IGN when rc was started. - - Portability: POSIXish systems don't have NGROUPS. diff --git a/COPYING b/COPYING @@ -0,0 +1,26 @@ +/* + * Copyright 1991, 1999 Byron Rakitzis. All rights reserved. + * + * This software is not subject to any license of the American Telephone + * and Telegraph Company or of the Regents of the University of California. + * + * Permission is granted to anyone to use this software for any purpose on + * any computer system, and to alter it and redistribute it freely, subject + * to the following restrictions: + * + * 1. The author is not responsible for the consequences of use of this + * software, no matter how awful, even if they arise from flaws in it. + * + * 2. The origin of this software must not be misrepresented, either by + * explicit claim or by omission. Since few users ever read sources, + * credits must appear in the documentation. + * + * 3. Altered versions must be plainly marked as such, and must not be + * misrepresented as being the original software. Since few users + * ever read sources, credits must appear in the documentation. + * + * 4. This notice may not be removed or altered. + * + * [this copyright notice is adapted from Henry Spencer's + * "awf" copyright notice.] + */ diff --git a/COPYRIGHT b/COPYRIGHT @@ -1,26 +0,0 @@ -/* - * Copyright 1991 Byron Rakitzis. All rights reserved. - * - * This software is not subject to any license of the American Telephone - * and Telegraph Company or of the Regents of the University of California. - * - * Permission is granted to anyone to use this software for any purpose on - * any computer system, and to alter it and redistribute it freely, subject - * to the following restrictions: - * - * 1. The author is not responsible for the consequences of use of this - * software, no matter how awful, even if they arise from flaws in it. - * - * 2. The origin of this software must not be misrepresented, either by - * explicit claim or by omission. Since few users ever read sources, - * credits must appear in the documentation. - * - * 3. Altered versions must be plainly marked as such, and must not be - * misrepresented as being the original software. Since few users - * ever read sources, credits must appear in the documentation. - * - * 4. This notice may not be removed or altered. - * - * [this copyright notice is adapted from Henry Spencer's - * "awf" copyright notice.] - */ diff --git a/ChangeLog b/ChangeLog @@ -0,0 +1,531 @@ +Changes since 1.2: (Too many to count!) + +A memory stomping bug was fixed (provoked by assigning a variable +to its old value plus something else). + +Better signal handling; a real signal handler which manages a queue +of pending signals was added. + +rc now ignores SIGQUIT and traps SIGINT even in non-interactive +mode. Thus, + + rc ed.sh + +will not do mysterious things if the shell script "ed.sh" calls a +command like "ed" and then you hit ^C. + +rc now opens 0, 1, 2 on /dev/null if they are inherited closed. +rc -o prevents this. + +A couple of stupid O(n^2) string appends were replaced with O(n) +loops. This should make foo=`{cat /etc/termcap} bar=$^foo a little +faster :-) + +Returning a list of signals from a function is now legal, so "return +$status" should always work. + +The code has been revised, new printing routines have been added. + +rc no longer uses redundant braces when exporting functions. + +A first stab at a verification suite has been added (trip.rc). +(someone, please help me make this comprehensive!) + +rc -p now does not initialize functions from the environment. This +should make it easier to write shell scripts that don't need to +assume anything about the environment. + +Inherited ignored signals are now ignored in the current shell and +passed on ignored to the child processes. whatis -s also reflects +this information. + +A file descriptor leak in the /dev/fd implementation of >{} was +fixed. + +A variable set to '' was not imported from the environment; this +has been fixed. + +Changes since 1.3beta: + +New Makefile/config.h setup. + +builtin echo may now be conditionally included out, to use a Goldwynism. + +builtin exit takes any legal exit status. If the status is not all zeros, +rc exits with 1. (having "exit sigiot" produce a core dump would be going +a little far, I think.) + +limit does not append a unit after a zero limit; 0g was too confusing. + +exec > /nonexistentfile does not cause rc to exit any more. + +If a noninteractive rc is started with sigint ignored, rc does not install +its own signal handler. + +error messages produced by rc in a subshell were cleaned up. (rc erroneously +reset the 'interactive' flag after a fork) + +print.c was cleaned up a little; no functionality was changed, but should +be more portable now. + +a bug in rc-1.3beta (not previous versions) was fixed: setting the first +element of $path to '' caused PATH to be exported as '':etc.. + +getopt's "illegal option" message was gratuitously changed to something +less abrupt. + +some dead code was removed from input.c + +%term was changed to %token in parse.y; apparently newer yacc's don't grok +%term any more. + +a race condition in the signal handler was fixed. + +the variable in for() was getting evaluated each time through the loop +(e.g., for (`{echo i;date>[1=2]} in 1 2 3)echo $i would print the date +three times). This was cleaned up. + +a redundant fork() was removed from walk.c; this showed up when running +a braced command with a redirection in the background. e.g., {a;b}>c& + +man pages for history and rc were cleaned up by david (thanks). + +rc set SIGQUIT and SIGTERM to SIG_DFL on background jobs---even when +trying to do old-style backgrounding (i.e., don't use process groups, +just ignore SIGINT & SIGQUIT & SIGTERM). + +$0 is now changed to the name of the signal when entering a signal +handler. Thus it's possible to write code like + + fn sigint sigterm sigquit { + switch ($0) { + case sigint + ... + case sigterm + ... + +wait with no arguments now prints the pid of any and all children +that died with a signal. e.g., + + ; wait + 25321: terminated + 25325: terminated + +as opposed to + + ; wait + terminated + +An error saving/restoring state in the input stream code would +cause rc to exit with the (erroneous) command: + + eval '|[a' + +FIFO's were not removed in a backgrounded command, e.g., + + cat <{echo hi}& + +Changes since rc-1.4beta: + +getopt was renamed to rc_getopt to avoid libc collisions. + +$cdpath with a / in it caused a cd to sometimes have two //'s at the +front of the path. This is reserved by POSIX, so I changed it to skip +one of the /'s. + +signal handling now emulates sh in the way I described in a previous +message: the race condition present in older rc's whereby some SIGINTs +got lost is now gone; any SIGINT received during a wait() is acted upon +at the end of the wait(), unless of course SIGINT is being deliberately +ignored. + +getopt was renamed to avoid naming conflicts with libc. Also a sound +move since rc_getopt is no longer quite libc-getopt compatible; I had +to add in a mechanism for resetting getopt. + +signal handler code in fn.c was cleaned up; there were several bugs +in rc-1.4beta, notably the shell sometimes spawned background jobs +with SIGTERM ignored. I took the opportunity to make things a little +cleaner here. + +a quasi-memory leak in the code for while() was fixed: a long-running +while that had rc commands allocating memory in it could cause the +shell to grow without bounds. I fixed this by placing the while loop +(*and* test!) inside a new allocation arena each time through the loop. + +A new configuration parameter, NOJOB, was added to allow you to force +v7-style backgrounding (no setpgrp, ignore SIGINT and SIGTERM). + +The FIFO code was reworked a little. It should be more robust now--- +FIFOs get removed at the end of the command of the argument list +that they were on: + + fn foo {echo $*; cat $*} + foo<{echo hi} + +now works as expected. Also FIFO names are pushed onto the exception +stack so that their removal occurs in the face of exceptions and so +on. + +A memory leak in treefree() was plugged up --- the root node of a +function was not getting freed. + +Changes since rc-1.4: + +General changes: + + Some small memory leaks/uninit references revealed by Purify. + + $bqstatus for querying the exit status of a backquote. + + Globbing through unreadable directories. + + More options to whatis. + + History append which always re-opens the file (avoids + inconsistencies over multiple NFS-mounted accesses to + $history). + + Support "rc -s". + +--------- + +Makefile: Added comment referring to README for yacc/malloc problem. + +uiltins.c: Added more options to whatis, protected rlimit prototypes + with #ifndef SYSVR4, renamed SIGCHK to sigchk. + +except.c: Patched nl_on_intr printing to happen only in interactive + shells. + +exec.c: Added comment explaining nl_on_intr variable, renamed SIGCHK + to sigchk. + +fn.c: Replaced by-hand consing of exception stack etc. for signal + handler execution with call to funcall(). Replaced fun2str + call with call on print routines. + +footobar.c: Got rid of memory leak in get_name(), parenthesize count, + flat and var nodes for correctness in unparsing, removed + list2str, made get_name use nalloc space, merge in a + better parse_var from es. + +glob.c: Split out a test so that closedir is called correctly, renamed + SIGCHK to sigchk. + +glom.c: Added bqstatus, renamed SIGCHK to sigchk, removed spurious + setsigdefaults, patched uninit memory reference, rename + "clear" to "memzero", wait for bq subproc to finish on EINTR. + +hash.c: Added options to function/variable print code. + +history/history.c: Added '@' to the list of chars which can precede an + ignored '-'. + +input.c: Got rid of tiny memory leak in closefds, got rid of uninit + memory reference in popinput, moved nul ignored check into + realgchar(), changed history append to always reopen the + history file, replaced SIGCHK with sigchk. Freed memory + returned by call to readline(). + +lex.c: Corrected typo in comment, moved nul character ignore code + to input routines. + +main.c: Added -s flag. + +nalloc.c: Added convenience feature to erealloc. (Allow NULL parameter) + +print.c: Changed use of va_start so broken compilers can compile + print code. + +proto.h: Added fake memset. + +rc.h: Replaced clear() function prototype with a macro call on + memset(), removed SIGCHK, fixed prototypes. + +signal.c: Removed unconditional exit in catcher code, renamed SIGCHK + to sigchk. + +status.c: Rewrite sgetstatus breaking out strstatus so that bqstatus + can be set from glom routines. + +utils.c: Got rid of clear() (use memset from C library), rename SIGCHK + to sigchk. + +var.c: Got rid of memory leak in listassign(), converted list2str() + call to something using the print routines. + +version.c: New version string. + +wait.c: Got rid of memory leak in rc_fork, renamed SIGCHK to sigchk. + +walk.c: Fixed pre-redirection bug, removed spurious setsigdefaults(), + renamed SIGCHK to sigchk. + + +Changes since rc-1.5beta1 + + Configuration: rc now uses GNU autoconf. + + Portability: mksignal works on HPUX 10. + + Portability: resources can be (quad_t). + + Bug: if rc was started with SIGCLD == SIG_IGN (e.g. by Solaris's + rshd) it would loop. Fixed by resetting SIGCLD to SIG_DFL if it + was SIG_IGN when rc was started. + + Portability: POSIXish systems don't have NGROUPS. + +Changes since rc-1.5b2 + + Configuration: rc now uses GNU automake. + + Portability: use sigsetjmp() when available. + + Portability: improve tests for quad_t. + + Configuration: don't leave FIFOs in /tmp when configuring. + + Configuration: let configure find `-ltermcap' when using readline. + + Configuration: pick up default path from config.cache. + + Bug: sense of most HAVE_RESTARTABLE_SYSCALLS tests was wrong. + + Bug: print prompts with `-i', even with editline / readline. + + Testing: just say `false' (not `/bin/false'). + + Bug: confusion over gid_t versus GETGROUPS_T in which.c. + + Feature: `-V' option added to report version number. + + Configuration: remove version.c; `id' is defined in main.c now. + + Bug: clear list of living children after fork(); `{ ls & wait } |cat' + no longer hangs or panics. + + Testing: add regression test for above. + + Tidiness: all the system call wrappers to prevent calls being + restarted now live in system-bsd.c. The configure script decides + whether to build system.c or system-bsd.c. Also, signal.c is more + careful to only declare slowbuf if it will be needed. + + Tidiness: similarly, configure decides whether to build execve.c or + not. + + Portability: test for ssize_t and use it where available; use long if + there's no ssize_t. + + Portability: use sigsetjmp where it's available and appropriate. If + no sigsetjmp, just use sigjmp; this probably fails in a traditional + SysV environment. + + Portability: test explicitly for SysV SIGCLD semantics. Main (and + dubious) benefit is that you can now define a function called `sigcld' + on systems where there is no signal called SIGCLD! + + Bug: rc has its own memory allocator; don't use malloc directly. + + Bug: the rc_wait() wrapper is only needed on systems which restart + system calls. On Linux, in particular, the wrapper leads to a race + which causes rc to hang (or panic in later versions). Other systems + apparently don't exercise this race. + + Bug: waitforall() must return if rc_wait4() returns with errno == + EINTR. Otherwise, the rc builtin `wait' cannot be interrupted if + there are background processes (although apparently only if there is a + handler for SIGINT). + + Portability: dreadful hack to track down the real locations of + signal.h to find signal names. rc now builds under CygWin32! + + Portability: replace above dreadful hack with mksignal.c, contributed + by Vincent Broman. + + Portability: use POSIX wait() macros (WIFEXITED and friends). + Unfortunately, POSIX omitted to supply WIFDUMPED, so this doesn't buy + a great deal. + + Distribution: remove the dependencies of y.tab.[ch] on parse.y from + Makefile.am. The justification for this is that, unless you're + hacking on rc's grammar, there's no reason to use anything other + than the distributed files (which were generated with byacc and very + lightly edited to silence a few gcc warnings). + + Enhancement: the example in addon.c wasn't very useful, since it + depended on files which weren't included with the distribution. There + is now a working, if trivial, example. + + Tidiness: the code was compiled with as many gcc warnings enabled as + I could find. Very few problems turned up. Some unused function + arguments were removed. Where unused arguments could not be removed + (because the function is one of a set that must all have the same + prototype), they were renamed to `ignore'. + + Portability: some versions of readline define the name `Function', + which rc also uses. Its use in rc has been renamed to `rc_Function'. + + Documentation: the `history' man page didn't explain what end of line + does in editing mode. It now does. + + Bug: the interaction with readline was broken, particularly with + respect to signal handling. I've incorporated some changes from Tom + Culliton which should sort this out. Unfortunately, we now have 3 + different code paths for readline 2.1, readline 2.2, and editline :-(. + + Configuration: if you say `--with-readline' or `--with-editline' it is + now an error if the appropriate library is not found. + + Bug: rc didn't work on RedHat 5 systems. This is because of + peculiarities in the handling of signals and system calls on this + system (the C library attempts to fake restartable system calls). + The fix involves testing at configure time for sigaction() and + SA_INTERRUPT: if both exist, we set up sys_signal() to be an "always + interrupt" wrapper around sigaction(). (If we don't have sigaction(), + we use signal() and check for restartable system calls as usual.) + + Portability: on AIX, lconv is defined by the system header files. + Rename lconv in print.c to avoid the clash. + + Testing: add a test that `cd' prints the new directory if we are + interactive and the directory was found via $cdpath. + +1998-07-23 + + Testing: fix silly typo in above test. + + Configuration: `--with-vrl' added to support Gert-Jan Vons's readline + library. + +1998-07-24 + + Portability: the autoconf macro AC_FUNC_SETPGRP doesn't work on OSF1: that + system supports arguments to setpgrp(), but also has a prototype in + <unistd.h> to say that it is void. Fix this by defining our own + RC_FUNC_SETPGRP for now. + + Bug: <sys/wait.h> was included twice in some source files. + + Configuration: automake wants `make distclean' to remove *.tab.c. + Rename y.tab.[ch] to parse.[ch] to avoid this. + +1998-07-27 + + Portability: on Ultrix, `make trip' fails with `malloc: Invalid + argument'. Problem is that getgroups(0, NULL) in which.c returns -1. + Add new configure test to check for POSIX getgroups() and fall back to + NGROUPS if it's not available. The magic is done by "getgroups.h". + + Tidiness: extract <sys/wait.h> magic into "wait.h". + +1998-10-20 + + Tidiness: include prototype for add_history() when doing editline. + + Documentation: document the `-V' flag and mention Linux's + /proc/self/fd as alternative to /dev/fd. + +1998-10-21 + + Bug: shells need to be prepared for bogus applications to have set + their input file descriptor to non-blocking, and set it back. + + Tidiness: <sys/types.h> is in "proto.h", so nothing else needs to + include it explicitly. + + Documentation: document the ^A bug. + +1998-10-22 + + Tidiness: makenonblock() was a rather poor choice of name for + a function which makes a file descriptor *not* nonblocking :-). + +1998-10-26 + + Portability: apparently some systems declare `char *basename(const + char *)' in system header files. Changing our basename() (in + history.c) to match this prototype allows it to be compiled on such + systems, and is harmless. (Harmless, that is, if no system declares + `char *basename(char *)'.) + +1998-10-28 + + Bug: system-bsd.c needs to include "wait.h". + + Warnings: some versions of gcc warn about "ambiguous" `else' clauses. + + Portability: assigning va_list objects doesn't work everywhere (Linux + on the PowerPC, specifically). Use the C 9x invention va_copy() + instead, if it exists, otherwise fall back to assignment. + + Documentation: help HP-UX users by mentioning that you need `cc -Ae'. + Also, HP-UX make will build rc in a separate directory. + + Tidiness: remove unused functions from print.c. Anybody wanting to + use this library in another project should follow the pointer in the + documentation to an improved version. + +1998-10-29 + + Bug: the "null character ignored" warning was printed with the wrong + line number. Fix by adding an offset argument to pr_error. + + Portability: work around readline's broken treatment of a non-blocking + input file descriptor. + + Testing: add `testing' auxiliary program; use `testing' to generate + null character on the fly (since it's a nuisance having a literal + null character in trip.rc); reset sigexit in `fn fail'; add test for + nonblocking input file descriptor; fix test for cdpath. + + Portability: include <sys/types.h> before <sys/stat.h>. + +1998-10-30 + + Portability: rename basename() to rc_basename(), since the former is + quite widespread, and has a variety of different definitions (none of + them, of course, static). + + Portability: work around i386 GCC 2.7.2.3 optimization bug triggered + by a (really quite simple) expression in history.c. + +1998-12-04 + + Bug: a debugging statement was left in history.c by mistake. + + Bug: `history' needs to check for `me' character preceded by `/', as + well as all the other options. An invocation like ../rc-1.5/- no + longer loops. + + Documentation: it seems better to have but a single URL in the README + file, which indirects to the other places of interest. + +1998-12-08 + + Portability: use AM_PROG_CC_STDC. This obviates the need for a + special hack on HP-UX. + + Documentation: document all the flags to `whatis'. + +1998-12-09 + + Tidiness: latest autoconf version has fixed AC_FUNC_SETPGRP, so we + no longer need to supply our own. + + Portability: test for va_copy() needs to include <stdarg.h>. + +1998-12-10 + + Tidiness: move most of the configure.in nastiness into acinclude.m4. + +1998-12-11 + + Tidiness: the release date now only needs to be changed in one place. + +1999-01-05 + + Documentation: the Bell Labs rc now has the list flattening operator, + but spelt $"foo. diff --git a/INSTALL b/INSTALL @@ -0,0 +1,167 @@ +COMPILING + +rc uses GNU autoconf and automake. The following commands are all you +need to configure, build, test, and install rc. + + $ sh configure + $ make + $ make trip + # make install + +This will build rc in the source directory (see below for details on how +to build rc in a different directory). + +BUILD AND CONFIGURATION OPTIONS + +There are lots of options you can give to configure to modify rc's +behaviour. You can also select a command line history library to +link against---see the README file for details of where to find these +libraries. For a summary of all options, run `sh configure --help'. + +You can specify Makefile variables by setting the corresponding +environment variables. For example, you might want to set `CC=cc', to +prevent configure looking for gcc, or set an initial value for `LIBS', +as in the example below. It is a good idea to specify static linking +(unless you are linking against a dynamic readline library)---if you are +using gcc, you can do this by setting `CFLAGS=-static'. + +Here are the configure options you may want to use, in approximately +descending order of usefulness. + + --with-editline + + This option tells rc to use the editline package (see the README file + 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. + + LIBS=-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. + + --with-readline + + This option tells rc to use the GNU readline package, which is similar + 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. + + LIBS=-L/usr/gnu/lib sh configure --with-readline + + --with-history + + Use this option if you want to build and install the programs that + support a crude history mechanism. + +You can't use more than one of `--with-editline', `--with-vrl', and +`--with-readline' at the same time. If you have any of these you +probably don't want to bother with `--with-history'. + + --prefix /path + + By default, `prefix' is /usr/local, which means that `make install' + installs rc (and possibly the history programs) in /usr/local/bin, and + man pages in /usr/local/man/man1. Use this option to change where + `make install' puts things. + + --disable-builtin-echo + + By default, the `echo' command is builtin to rc for reasons of + efficiency and portability (of rc scripts). It is the only builtin + which is not essential, and purists may wish to omit it. Note that + `make trip' will fail if you disable builtin echo and your system's + `echo' does not understand `-n' to suppress newline. + + --with-addon + --with-addon=foo.c + + On the other hand, non-purists may wish to add extra builtin commands. + An example is included in the files addon.c and addon.h, which will + only be built if you specify `--with-addon'. If your addons are + in another file, you can specify that instead (but beware that the + interface file is still addon.h). + + --disable-def-interp + --enable-def-interp=/bin/foo + + By default, a program that fails with "Exec format error" is handed to + /bin/sh. This does the Right Thing for scripts that start with `:' to + indicate that they are sh scripts. You can disable this behaviour + entirely, or specify a different default interpreter. + + --disable-def-path + --enable-def-path "/usr/local/bin","/usr/bin" + + By default, if rc is started with no PATH, it uses a default path. + 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 . + + You can disable this, or specify a different default path. Note that + the quote marks (") must be seen by configure; unless you are already + using rc, you will probably need to quote them to your shell. + + --disable-job + + By default, rc puts backgrounded processes into a new process group, + as though it were a job control shell (it isn't). This is usually + needed to work around bugs in application programs which install + signal handlers for the keyboard signals without checking whether the + signal was being ignored. This option disables the default behaviour, + making rc behave like a traditional sh. You are unlikely to want this + option on any Unix system. + + --disable-protect-env + + By default, rc encodes special characters in environment variables. + This is necessary on all known Unix systems to prevent sh either + dying or discarding the variables. This option disables the default + behaviour. You are unlikely to want this option on any Unix system. + +After you've built rc, I recommend that you run it through a test script +to gain some confidence that all is working well. Type `make trip' to +do this. This will produce some output, and should end with "trip is +complete". If the trip instead ends with "trip took a wrong turn..." +please contact the maintainer. + +BUILDING IN ANOTHER DIRECTORY + +If you have a suitable `make', you can build rc in a different directory +from where the sources are held. This is particularly useful if you +are building rc for multiple architectures. All you need do is specify +the path to the configure script in the first step. Suitable `make's +include GNU, HP-UX, and SunOS, but not Irix, nor Ultrix, nor UnixWare. + +COMPILATION WARNINGS + +If your C compiler is gcc, the option `-Wall' is turned on. This may +produce a few warnings. + +Warnings about "implicit declaration" of system functions may occur if +your system's include files are deficient---they are usually harmless. + +There is a warning about "variable `n' might be clobbered" in walk.c. +I'm not sure how serious this warning is, nor how to eliminate it. + +On some systems there are warnings about "passing arg 2 of `getgroups' +from incompatible pointer type" in which.c. I believe this is due to an +incorrect declaration of `getgroups()' in those systems' header files. + +Any other warnings should be reported to the maintainer. + +OLD C + +rc needs an ISO C (89) compiler, or at least one that has a reasonable +understanding of function prototypes, `<stdarg.h>', `void', and +`volatile'. If you really need to compile rc with an ancient C +compiler, please contact the maintainer. diff --git a/Makefile.am b/Makefile.am @@ -0,0 +1,69 @@ +## Process this file with automake to produce Makefile.in + +if AMC_ADDON +ADDON = @ADDON@ +endif + +if AMC_HISTORY +man_MANS = rc.1 history.1 +HISTORY = history +else +man_MANS = rc.1 +endif + +if AMC_NO_HASHBANG +EXECVE = execve.o +endif + +if AMC_READLINE +READLINE = readline.o +endif + +if AMC_RESTART +SYSTEM = system-bsd.o +else +SYSTEM = system.o +endif + +bin_PROGRAMS = rc +noinst_PROGRAMS = mksignal 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 + +EXTRA_rc_SOURCES = addon.c execve.c readline.c system.c system-bsd.c + +rc_DEPENDENCIES = sigmsgs.o $(ADDON) $(EXECVE) $(READLINE) $(SYSTEM) +rc_LDADD = sigmsgs.o $(ADDON) $(EXECVE) $(READLINE) $(SYSTEM) + +noinst_HEADERS = getgroups.h jbwrap.h parse.h proto.h rc.h rlimit.h wait.h + +BUILT_SOURCES = sigmsgs.c + +EXTRA_DIST = EXAMPLES RELDATE addon.c addon.h history.1 parse.y rc.1 trip.rc + +sigmsgs.c sigmsgs.h: mksignal + ./mksignal + +CONFIGURE_DEPENDENCIES = RELDATE + +# 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 +# dependency expressed, since the distributed parse.[ch] (generated with +# byacc, and lightly edited to remove a couple of gcc warnings) are +# portable (I hope). +#parse.c parse.h: $(srcdir)/parse.y +# $(YACC) -d $(srcdir)/parse.y +# mv y.tab.c parse.c +# mv y.tab.h parse.h + +trip: rc tripping + ./rc -p < $(srcdir)/trip.rc + +install-exec-hook: +if AMC_HISTORY + $(LN) history - ;\ + $(INSTALL_PROGRAM) - $(bindir) ;\ + rm -f $(bindir)/--; $(LN) $(bindir)/- $(bindir)/-- ;\ + rm -f $(bindir)/-p; $(LN) $(bindir)/- $(bindir)/-p ;\ + rm -f $(bindir)/--p; $(LN) $(bindir)/- $(bindir)/--p +endif diff --git a/Makefile.in b/Makefile.in @@ -1,80 +0,0 @@ -# Makefile.in for rc. - -SHELL=/bin/sh - -bindir=@bindir@ -exec_prefix=@exec_prefix@ -mandir=@mandir@ -prefix=@prefix@ - -CC=@CC@ -CFLAGS=@CFLAGS@ -LDFLAGS=@CFLAGS@ -LIBS=@LIBS@ - -INSTALL=@INSTALL@ -INSTALL_DATA=@INSTALL_DATA@ -INSTALL_PROGRAM=@INSTALL_PROGRAM@ -LN=@LN@ -YACC=@YACC@ - -HISTORY=@HISTORY@ - -OBJS=@ADDON@ builtins.o except.o exec.o @EXECVE@ fn.o footobar.o getopt.o \ - glob.o glom.o hash.o heredoc.o input.o lex.o list.o main.o match.o \ - nalloc.o open.o print.o redir.o sigmsgs.o signal.o status.o tree.o \ - utils.o var.o version.o wait.o walk.o which.o y.tab.o - -all: rc $(HISTORY) - -rc: $(OBJS) - $(CC) -o $@ $(OBJS) $(LDFLAGS) $(LIBS) - -sigmsgs.c: mksignal - sh mksignal @SIGNAL_H@ - -y.tab.c: parse.y - $(YACC) -d parse.y - -trip: rc - ./rc -p < trip.rc - -clean: force - rm -f rc $(HISTORY) - *.o *.tab.* sigmsgs.* config.cache config.log - -cleaner: clean - rm -f config.status config.h Makefile - -cleanest: cleaner - rm -f configure - -history: force - cd history; make CC="$(CC)" $(HISTORYMAKEFLAGS) - -install: all - $(INSTALL_PROGRAM) rc $(bindir) - $(INSTALL_DATA) rc.1 $(mandir)/man1/rc.1 - case "x$(HISTORY)" in \ - x) \ - ;; \ - *) \ - $(LN) $(HISTORY) - ;\ - $(INSTALL_PROGRAM) - $(bindir) ;\ - $(LN) $(bindir)/- $(bindir)/-- ;\ - $(LN) $(bindir)/- $(bindir)/-p ;\ - $(LN) $(bindir)/- $(bindir)/--p ;\ - $(INSTALL_DATA) history/history.1 $(mandir)/man1/history.1 \ - ;; \ - esac - -force: - -# dependencies: - -$(OBJS): config.h proto.h rc.h -sigmsgs.h: sigmsgs.c -lex.o y.tab.o: y.tab.c - -builtins.o except.o exec.o input.o signal.o utils.o wait.o walk.o: jbwrap.h -builtins.o: rlimit.h -builtins.o fn.o hash.o signal.o status.o: sigmsgs.h diff --git a/NEWS b/NEWS @@ -0,0 +1,50 @@ +Since rc-1.5b2 was released, many fixes have been made to the +autoconfiguration code, some of them critical. One problem (which I +introduced) was found in minutes with ElectricFence: I had spent several +hours failing to find it with other tools. + +Two bugs in rc itself, one of them trivial, were fixed. + +rc now uses GNU automake. Although I feel that automake is sticking +plaster to mend a broken leg, it has made my job as maintainer easier. +(Errm, apart from tracking down bugs in automake itself, and Perl, that +is.) For people building rc, it's now possible (depending on your +flavour of `make') to build in a separate directory from the source. + +Creeping featurism: rc now has a `-V' switch to report its version +number. + +The detection of signal names has been completely revised. Vincent +Broman suggested this, and contributed mksignal.c. + +The interaction with readline has been redone, principally to work +around bugs in the readline library. Tom Culliton persuaded me of +the need for this, and his patches to an earlier version of rc became +readline.c. + +I rewrote addon.[ch] to provide a more useful example of adding extra +builtins. + +The rc build system no longer considers running `yacc': parse.y is for +information only. The supplied y.tab.[ch] were built with Berkeley +`yacc', and lightly edited to remove a few gcc warnings. This idea was +suggested by Gert-Jan Vons. + +Binaries of rc-1.5b4 are typically a few kilobytes smaller than 1.5b2. +I believe this is due to improved autoconfiguration: we are now much +more careful only to include code that will be used. + +Support for vrl (another lightweight "readline"-style library) was +added. + +rc can now deal with a bogus application that sets its stdin to +non-blocking mode. + +See ChangeLog for more details. + +What happened to rc-1.5b3? There were a couple of releases to people +who'd found bugs in rc-1.5b2 that were called b3. To avoid any +possibility of confusion, I have named this beta release rc-1.5b4. + +Tim Goodwin +1999-01-11 diff --git a/README b/README @@ -1,136 +1,18 @@ -This is release 1.5b2 of rc. +This is a snapshot release of rc-1.5. The file RELDATE identifies the +date of the snapshot. -Read COPYRIGHT for copying information. All files are +See COPYING for copying information. All files are - Copyright 1991, 1997 Byron Rakitzis. + Copyright 1991, 1999 Byron Rakitzis. -COMPILING +See INSTALL for build and installation information. -rc was written in portable ANSI C. If you don't have an ANSI compiler -like gcc or something close (e.g., sgi's cc) read further down on -how to convert rc's source to old C. - -The following commands are all you need to configure, build, -test, and install rc. - - $ sh configure - $ make - $ make trip - # make install - -There are lots of options you can give to configure to modify rc's -behaviour. You can also select a command line history library to link -against. For a summary of all options, run `sh configure --help'. - -You can specify Makefile variables by setting the corresponding -environment variables. For example, you might want to set `CC=cc', to -prevent configure looking for gcc, or set an initial value for `LIBS', -as in the example below. - -Here are the configure options you may want to use, in approximately -descending order of usefulness. - - --with-editline - - This option tells rc to use Simmule Turner's and Rich $alz's editline - package, which you can get from the following location. This is - essentially a lightweight version of GNU readline, providing EMACS - style command line editing and history. - - ftp://ftp.pipex.net/people/tim/editline.tar.gz - - 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 directory and then running this configure - command. - - LIBS=-L. sh configure --with-editline - - --with-readline - - This option tells rc to use the GNU readline package, which is similar - to editline, 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). You probably need to tell the compiler to link with - the termcap library if you're using readline. For example, here is - the configure command the maintainer uses to build rc with readline. - - LIBS=-ltermcap sh configure --with-readline - - --enable-history - - Use this option if you want to build and install the programs that - support a crude history mechanism. - -You can't use `--with-editline' and `--with-readline' together, of course, -and if you have either of those you probably don't want to bother with -`--enable-history'. - - --prefix=/path - - By default, `prefix' is /usr/local, which means that `make install' - installs rc (and possibly the history programs) in /usr/local/bin, and - man pages in /usr/local/man/man1. Use this option to change where - `make install' puts things. - - --disable-builtin-echo - - By default, the `echo' command is builtin to rc for efficiency reasons. - It is the only builtin which is not essential, and purists may wish - to omit it. - - --disable-def-interp - --enable-def-interp=/bin/foo - - By default, a program that fails with "Exec format error" is handed to - /bin/sh. This does the Right Thing for scripts that start with `:' to - indicate that they are sh scripts. You can disable this behaviour - entirely, or specify a different default interpreter. - - --disable-def-path - --enable-def-path="/usr/local/bin","/usr/bin" - - By default, if rc is started with no PATH, it uses a default path. - 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 . - - You can disable this, or specify a different default path. Note - that the quote marks (") must be seen by configure; you will - probably need to quote them to your shell. (Not if it's already - rc, but then you will need to quote the `='.) - - --disable-job - - By default, rc puts backgrounded processes into a new process group, - as though it were a job control shell (it isn't). This is usually - needed to work around bugs in application programs which install - signal handlers for the keyboard signals without checking whether the - signal was being ignored. This option disables the default behaviour, - making rc behave like a traditional sh. You are unlikely to want this - option on any Unix system. - - --disable-protect-env - - By default, rc encodes special characters in environment variables. - This is necessary on all known Unix systems to prevent sh either - dying or discarding the variables. This option disables the default - behaviour. You are unlikely to want this option on any Unix system. - -After you've built rc, you may wish to run it through a test script -to see that everything is ok. Type `make trip' for this. This will -produce some output, and end with "trip is complete". If the trip ends -with "trip took a wrong turn..." please contact the maintainer. (If -you've built in either of the command line history libraries, the trip -will fail near the end with `trip took a wrong turn: dot -i'.) BUGS -Send bug reports to <tim@uk.uu.net> (<tgoodwin@cygnus.co.uk> after -1997-07-27). If a core dump is generated, sending a backtrace will -help a great deal. You can get a backtrace like this. +Send bug reports to <tjg@star.le.ac.uk>. If a core dump is generated, +sending a backtrace will help a great deal. You can get a backtrace +like this. ; gdb rc core (gdb) where @@ -140,58 +22,19 @@ help a great deal. You can get a backtrace like this. Also, always report the machine, OS (`uname -a'), and compiler used to make rc; this information is extremely valuable. + FEEPING CREATURISM See the end of the man page, under "INCOMPATABILITIES" for (known?) differences from the "real" rc. Most of these changes were necessary -to get rc to work in a reasonable fashion on a real (i.e. commercial, +to get rc to work in a reasonable fashion on a real (i.e. commercial, non-Labs) Unix system; a few were changes motivated by concern about some inadequacies in the original design. -YACC - -The yacc that Sun ships with SunOS 4.1.1 calls malloc() to allocate -space for the state stack, and requires a call to YYACCEPT or YYABORT to -free this memory. This means that if rc takes an interrupt while parsing -a command (say, if ^C is typed), yacc will leak away this memory. The -solution is to use a yacc which statically allocates this array, such -as the yacc in the BSD distribution. Berkeley yacc-generated y.tab.c -and y.tab.h are shipped with rc in case you cannot get hold of Berkeley -yacc. - -OLD C - -If you need to convert rc's source into K&R C, you need to run the -source through a filter called "unproto", posted in comp.sources.misc. -A sample "cpp" shell script that I used to run unproto under SunOS is -supplied with rc. - -CREDITS - -This shell was written by me, Byron Rakitzis, but kudos go to Paul Haahr -for letting me know what a shell should do and for contributing certain -bits and pieces to rc (notably the limits code, print.c, most of which.c -and the backquote redirection code), and to Hugh Redelmeier for running -rc through his fussy ANSI compiler and thereby provoking interesting -discussions about portability, and also for providing many valuable -suggestions for improving rc's code in general. Finally, many thanks -go to David Sanderson, for reworking the man page to format well with -troff, and for providing many suggestions both for rc and its man page. - -Thanks to Boyd Roberts for the original history.c, and to Hugh again for -re-working parts of that code. - -Of course, without Tom Duff's design of the original rc, I could not -have written this shell (though I probably would have written *a* -shell). Almost of all of the features, with minor exceptions, have been -implemented as described in the Unix v10 manuals. Hats off to td for -designing a C-like, minimal but very useful shell. - -Tom Duff has kindly given permission for the paper he wrote for UKUUG to -be distributed with this version of rc (called "plan9.ps" in the same -ftp 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. - -The current maintainer of rc is Tim Goodwin, <tim@uk.uu.net> -(<tgoodwin@cygnus.co.uk> after 1997-07-27). + +WWW + +More information on releases of rc can be found at this web page. + + http://www.star.le.ac.uk/~tjg/rc/ + diff --git a/acconfig.h b/acconfig.h @@ -0,0 +1,80 @@ +/* Define to a suitable ssize_t. */ +#undef ssize_t + +/* Define to a suitable sig_atomic_t. */ +#undef sig_atomic_t + +/* Define if you want rc to hand off exec errors to (e.g.) /bin/sh. */ +#undef DEFAULTINTERP + +/* Define to the default path used if $PATH is empty when rc starts. */ +#undef DEFAULTPATH + +/* Define if your kernel has SysV special SIGCLD semantics. */ +#undef HAVE_SYSV_SIGCLD + +/* Define if your kernel supports `#!' magic numbers. */ +#undef HASH_BANG + +/* Define if you have /dev/fd. */ +#undef HAVE_DEV_FD + +/* Define if you have /proc/self/fd. */ +#undef HAVE_PROC_SELF_FD + +/* Define if you have named pipes. */ +#undef HAVE_FIFO + +/* Define if quad_t is a native type. */ +#undef HAVE_QUAD_T + +/* Define if you have rlim_t. */ +#undef HAVE_RLIM_T + +/* Define if you have sigsetjmp(). */ +#undef HAVE_SIGSETJMP + +/* Define if you want rc to encode strange characters in the environment. */ +#undef PROTECT_ENV + +/* Define if you have extra builtins. */ +#undef RC_ADDON + +/* Define if you want echo as a builtin. */ +#undef RC_ECHO + +/* Define if you want rc to support broken apps, like a job control shell. */ +#undef RC_JOB + +/* Define if you want to use editline. */ +#undef EDITLINE + +/* Define if you want to use GNU readline. */ +#undef READLINE + +/* Define if you have the older readline, with rl_deprep_terminal. */ +#undef READLINE_OLD + +/* Define if RLIMIT_foo defines need _KERNEL. */ +#undef RLIMIT_NEEDS_KERNEL + +/* Define if rlim_t is quad_t. */ +#undef RLIM_T_IS_QUAD_T + +/* Define to package name. */ +#undef PACKAGE + +/* Define to version. */ +#undef VERSION + +/* Define to release date. */ +#undef RELDATE + +/* Define if you have SA_INTERRUPT (and sigaction()). */ +#undef HAVE_SA_INTERRUPT + +/* Define if you have POSIX getgroups(). */ +#undef HAVE_POSIX_GETGROUPS + +/* Define if you have va_copy(). */ +#undef HAVE_VA_COPY diff --git a/acinclude.m4 b/acinclude.m4 @@ -0,0 +1,206 @@ +dnl This macro sets HAVE_POSIX_GETGROUPS if the +dnl getgroups() function accepts a zero first argument. +AC_DEFUN(RC_FUNC_GETGROUPS, [ + AC_CACHE_CHECK(for POSIX getgroups, rc_cv_func_posix_getgroups, AC_TRY_RUN([ +#include <sys/types.h> +#include <unistd.h> +int main(void) { + return getgroups(0, (void *)0) == -1; +} + ], rc_cv_func_posix_getgroups=yes, rc_cv_func_posix_getgroups=no, rc_cv_func_posix_getgroups=yes)) + case "$rc_cv_func_posix_getgroups" in + yes) AC_DEFINE(HAVE_POSIX_GETGROUPS) ;; + esac +]) + + +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, [ + AC_CACHE_CHECK(for sigsetjmp, rc_cv_sigsetjmp, + AC_TRY_LINK([ +#include <setjmp.h> + ], [ +sigjmp_buf e; +sigsetjmp(e, 1); + ], rc_cv_sigsetjmp=yes, rc_cv_sigsetjmp=no)) + case "$rc_cv_sigsetjmp" in + yes) AC_DEFINE(HAVE_SIGSETJMP) ;; + esac +]) + +dnl HPUX needs _KERNEL defined to pick up RLIMIT_foo defines. (Why?) +AC_DEFUN(RC_NEED_KERNEL, [ + AC_CACHE_CHECK(if _KERNEL is required for RLIMIT defines, rc_cv_kernel_rlimit, + AC_TRY_COMPILE([ +#include <sys/types.h> +#include <sys/resource.h> + ], [ +int f; +f = RLIMIT_DATA; + ], rc_cv_kernel_rlimit=no, [ AC_TRY_COMPILE([ +#include <sys/types.h> +#define _KERNEL +#include <sys/resource.h> +#undef _KERNEL + ], [ +int f; +f = RLIMIT_DATA; + ], rc_cv_kernel_rlimit=yes, rc_cv_kernel_rlimit=no)])) + case "$rc_cv_kernel_rlimit" in + yes) AC_DEFINE(RLIMIT_NEEDS_KERNEL) ;; + esac +]) + +dnl Look for rlim_t in sys/types.h and sys/resource.h +AC_DEFUN(RC_TYPE_RLIM_T, [ + AC_CACHE_CHECK(for rlim_t, rc_cv_have_rlim_t, + AC_EGREP_CPP(rlim_t, [ +#include <sys/types.h> +#if RLIMIT_NEEDS_KERNEL +#define _KERNEL +#endif +#include <sys/resource.h> + ], rc_cv_have_rlim_t=yes, rc_cv_have_rlim_t=no)) + + case "$rc_cv_have_rlim_t" in + yes) AC_DEFINE(HAVE_RLIM_T) ;; + no) AC_CACHE_CHECK(for native quad_t, rc_cv_have_quad_t, + AC_TRY_COMPILE([ +#include <sys/types.h> + ], [ +typedef quad_t align_t; +align_t a; +a = (quad_t)0; + ], rc_cv_have_quad_t=yes, rc_cv_have_quad_t=no)) + + case "$rc_cv_have_quad_t" in + yes) AC_DEFINE(HAVE_QUAD_T) + AC_CACHE_CHECK(if rlimit values are quad_t, rc_cv_rlim_t_is_quad_t, + AC_TRY_RUN([ +#include <sys/types.h> +#include <sys/time.h> +#include <sys/types.h> +#if RLIMIT_NEEDS_KERNEL +#define _KERNEL +#endif +#include <sys/resource.h> +#if RLIMIT_NEEDS_KERNEL +#undef _KERNEL +#endif +main(){ + struct rlimit rl; + exit(sizeof rl.rlim_cur != sizeof(quad_t)); +} + ], rc_cv_rlim_t_is_quad_t=yes, rc_cv_rlim_t_is_quad_t=no, $ac_cv_type_quad_t)) + + case "$rc_cv_rlim_t_is_quad_t" in + yes) AC_DEFINE(RLIM_T_IS_QUAD_T) ;; + esac + ;; + esac + ;; + esac +]) + + +dnl Check type of sig_atomic_t. +AC_DEFUN(RC_TYPE_SIG_ATOMIC_T, [ + AC_CACHE_CHECK(for sig_atomic_t, rc_cv_sig_atomic_t, + AC_EGREP_HEADER(sig_atomic_t, signal.h, + rc_cv_sig_atomic_t=yes, rc_cv_sig_atomic_t=no)) + case "$rc_cv_sig_atomic_t" in + no) AC_DEFINE(sig_atomic_t, int) ;; + esac +]) + + +dnl Check for sigaction and SA_INTERRUPT +AC_DEFUN(RC_FUNC_SIGACTION, [ + AC_CACHE_CHECK(for sigaction and SA_INTERRUPT, rc_cv_sa_int, + AC_TRY_COMPILE([ +#include <signal.h> + ], [ +struct sigaction foo; +foo.sa_flags = SA_INTERRUPT; +sigaction(SIGINT, 0, 0); + ], rc_cv_sa_int=yes, rc_cv_sa_int=no + ) + ) +]) + + +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? +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; + sigset(SIGCLD, SIG_IGN); + switch (fork()) { + case -1: + return 1; + case 0: + return 0; + default: + 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) ;; + 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, + if test -d /dev/fd && test -r /dev/fd/0; then + rc_cv_sys_dev_fd=yes + elif test -d /proc/self/fd && test -r /proc/self/fd/0; then + rc_cv_sys_dev_fd=odd + else + rc_cv_sys_dev_fd=no + fi + ) +]) + + +dnl Can mknod make FIFOs? +AC_DEFUN(RC_SYS_MKNOD_FIFO, [ + AC_CACHE_CHECK(for mknod FIFOs, rc_cv_sys_fifo, + AC_TRY_RUN([ +#include <sys/types.h> +#include <sys/stat.h> + +main() { + exit(mknod("/tmp/rc$$.0", S_IFIFO | 0666, 0) != 0); +} + ], rc_cv_sys_fifo=yes, rc_cv_sys_fifo=no, rc_cv_sys_fifo=no)) + rm -f /tmp/rc$$.0 + case "$rc_cv_sys_fifo" in + yes) AC_DEFINE(HAVE_FIFO) ;; + esac +]) diff --git a/addon.c b/addon.c @@ -1,22 +1,25 @@ /* - This file contains the implementations of any locally defined - builtins. + This file is NOT BUILT by default. Together with addon.h, it + provides an example of how to add new builtins to rc. */ -#ifdef DWS - -/* - This is what DaviD Sanderson (dws@cs.wisc.edu) uses. -*/ +#include "rc.h" +#include "addon.h" -#include <sys/types.h> -#include <sys/file.h> -#include <sys/stat.h> +void b_sum(char **av) { + long sum = 0; -#include "rc.h" /* for bool TRUE, FALSE */ -#include "addon.h" + while (*++av) + sum += atol(*av); + fprint(1, "%ld\n", sum); + set(TRUE); +} -#include "addon/access.c" -#include "addon/test.c" +void b_prod(char **av) { + long sum = 1; -#endif + while (*++av) + sum *= atol(*av); + fprint(1, "%ld\n", sum); + set(TRUE); +} diff --git a/addon.h b/addon.h @@ -1,38 +1,31 @@ /* - This file is the interface to the rest of rc for any locally - defined addon builtins. By default there are none. - The interface consists of the following macro. - - ADDONS A comma-separated list of pairs of function pointers - and string literals. - - The addon functions must also have proper prototypes in this file. - The builtins all have the form: - + This file is NOT BUILT by default. Together with addon.c, it + provides an example of how to add new builtins to rc. + + To define a new builtin, it must appear in the macro ADDONS, which + is a comma-separated list of pairs of function pointers (the + implementation of the new builtin) and string literals (the name of + the new builtin). + + Any new builtin functions must also have proper prototypes in this + file. This is always of the same form. + void b_NAME(char **av); - - Builtins report their exit status using set(TRUE) or set(FALSE). - - Example: - - #define ADDONS { b_test, "test" }, - extern void b_test(char **av); -*/ -#define ADDONS /* no addons by default */ + The first argument, av[0], is the name of the builtin. The last + argument is followed by a NULL pointer. -#ifdef DWS + Builtins report their exit status using set(TRUE) or set(FALSE). -/* - This is what DaviD Sanderson (dws@cs.wisc.edu) uses. */ -#undef ADDONS -#define ADDONS { b_access, "access" },\ - { b_test, "test" },\ - { b_test, "[" }, +#if RC_ADDON + +#define ADDONS \ + { b_sum, "+" }, \ + { b_prod, "x" }, -extern void b_access(char **av); -extern void b_test(char **av); +extern void b_sum(char **av); +extern void b_prod(char **av); #endif diff --git a/builtins.c b/builtins.c @@ -10,15 +10,14 @@ #include "rc.h" #include <sys/ioctl.h> +#include <sys/stat.h> #include <setjmp.h> #include <errno.h> -#include "jbwrap.h" -#include "sigmsgs.h" #include "addon.h" +#include "jbwrap.h" #include "rlimit.h" - -extern int umask(int); +#include "sigmsgs.h" static void b_break(char **), b_cd(char **), b_eval(char **), b_exit(char **), b_newpgrp(char **), b_return(char **), b_shift(char **), b_umask(char **), @@ -55,7 +54,9 @@ static struct { { b_wait, "wait" }, { b_whatis, "whatis" }, { b_dot, "." }, +#ifdef ADDONS ADDONS +#endif }; extern builtin_t *isbuiltin(char *s) { @@ -72,7 +73,7 @@ extern void funcall(char **av) { Jbwrap j; Estack e1, e2; Edata jreturn, star; - if (setjmp(j.j)) + if (sigsetjmp(j.j, 1)) return; starassign(*av, av+1, TRUE); jreturn.jb = &j; @@ -97,7 +98,7 @@ static void badnum(char *num) { /* a dummy command. (exec() performs "exec" simply by not forking) */ -extern void b_exec(char **av) { +extern void b_exec(char **ignore) { } #if RC_ECHO @@ -244,7 +245,7 @@ static void b_shift(char **av) { /* dud function */ -extern void b_builtin(char **av) { +extern void b_builtin(char **ignore) { } /* wait for a given process, or all outstanding processes */ diff --git a/config.h-dist b/config.h-dist @@ -0,0 +1,204 @@ +/* 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/config.h.in b/config.h.in @@ -1,44 +0,0 @@ -/* Header files */ -#undef STDC_HEADERS - -#undef HAVE_SYS_RESOURCE_H -#undef RLIMIT_NEEDS_KERNEL -#undef HAVE_SYS_TIME_H -#undef HAVE_UNISTD_H - -#undef HAVE_DIRENT_H -#undef HAVE_SYS_NDIR_H -#undef HAVE_SYS_DIR_H -#undef HAVE_NDIR_H - -/* Functions */ -#undef HAVE_GETGROUPS -#undef HAVE_SETPGRP -#undef HAVE_SETRLIMIT - -/* Types */ -#undef HAVE_GID_T -#undef HAVE_RLIM_T -#undef HAVE_QUAD_T -#undef RLIM_T_IS_QUAD_T -#undef GETGROUPS_T -#undef gid_t -#undef pid_t -#undef size_t -#undef uid_t - -/* OS features */ -#undef HASH_BANG -#undef HAVE_DEV_FD -#undef HAVE_FIFO -#undef HAVE_PROC_SELF_FD -#undef HAVE_RESTARTABLE_SYSCALLS -#undef SETPGRP_VOID - -/* rc features */ -#undef DEFAULTINTERP -#undef DEFAULTPATH -#undef RC_ECHO -#undef RC_JOB -#undef PROTECT_ENV -#undef READLINE diff --git a/configure b/configure @@ -1,2541 +0,0 @@ -#! /bin/sh - -# Guess values for system-dependent variables and create Makefiles. -# Generated automatically using autoconf version 2.12 -# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. -# -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. - -# Defaults: -ac_help= -ac_default_prefix=/usr/local -# Any additions from configure.in: -ac_help="$ac_help - --disable-builtin-echo Don't include \`echo' as a builtin" -ac_help="$ac_help - --disable-job Don't do job-control-style backgrounding" -ac_help="$ac_help - --disable-protect-env Don't protect environment names" -ac_help="$ac_help - --enable-def-interp=/bin/foo - Use /bin/foo as default interpreter [/bin/sh]" -ac_help="$ac_help - --enable-def-path=\"/usr/local/bin/\",\"/usr/bin\" - Default path [All of these that exist - (/usr/local/bin /usr/bin /usr/ucb /bin .)]" -ac_help="$ac_help - --enable-history Build history subprograms" -ac_help="$ac_help - --with-addon Extra builtins, from addon.c " -ac_help="$ac_help - --with-editline Simmule Turner's line editing" -ac_help="$ac_help - --with-readline Bloated GNU line editing" - -# Initialize some variables set by options. -# The variables have the same names as the options, with -# dashes changed to underlines. -build=NONE -cache_file=./config.cache -exec_prefix=NONE -host=NONE -no_create= -nonopt=NONE -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -target=NONE -verbose= -x_includes=NONE -x_libraries=NONE -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datadir='${prefix}/share' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -libdir='${exec_prefix}/lib' -includedir='${prefix}/include' -oldincludedir='/usr/include' -infodir='${prefix}/info' -mandir='${prefix}/man' - -# Initialize some other variables. -subdirs= -MFLAGS= MAKEFLAGS= -# Maximum number of lines to put in a shell here document. -ac_max_here_lines=12 - -ac_prev= -for ac_option -do - - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval "$ac_prev=\$ac_option" - ac_prev= - continue - fi - - case "$ac_option" in - -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; - *) ac_optarg= ;; - esac - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case "$ac_option" in - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir="$ac_optarg" ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build="$ac_optarg" ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file="$ac_optarg" ;; - - -datadir | --datadir | --datadi | --datad | --data | --dat | --da) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ - | --da=*) - datadir="$ac_optarg" ;; - - -disable-* | --disable-*) - ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then - { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } - fi - ac_feature=`echo $ac_feature| sed 's/-/_/g'` - eval "enable_${ac_feature}=no" ;; - - -enable-* | --enable-*) - ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then - { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } - fi - ac_feature=`echo $ac_feature| sed 's/-/_/g'` - case "$ac_option" in - *=*) ;; - *) ac_optarg=yes ;; - esac - eval "enable_${ac_feature}='$ac_optarg'" ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix="$ac_optarg" ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he) - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat << EOF -Usage: configure [options] [host] -Options: [defaults in brackets after descriptions] -Configuration: - --cache-file=FILE cache test results in FILE - --help print this message - --no-create do not create output files - --quiet, --silent do not print \`checking...' messages - --version print the version of autoconf that created configure -Directory and file names: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [same as prefix] - --bindir=DIR user executables in DIR [EPREFIX/bin] - --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] - --libexecdir=DIR program executables in DIR [EPREFIX/libexec] - --datadir=DIR read-only architecture-independent data in DIR - [PREFIX/share] - --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data in DIR - [PREFIX/com] - --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] - --libdir=DIR object code libraries in DIR [EPREFIX/lib] - --includedir=DIR C header files in DIR [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] - --infodir=DIR info documentation in DIR [PREFIX/info] - --mandir=DIR man documentation in DIR [PREFIX/man] - --srcdir=DIR find the sources in DIR [configure dir or ..] - --program-prefix=PREFIX prepend PREFIX to installed program names - --program-suffix=SUFFIX append SUFFIX to installed program names - --program-transform-name=PROGRAM - run sed PROGRAM on installed program names -EOF - cat << EOF -Host type: - --build=BUILD configure for building on BUILD [BUILD=HOST] - --host=HOST configure for HOST [guessed] - --target=TARGET configure for TARGET [TARGET=HOST] -Features and packages: - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] - --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --x-includes=DIR X include files are in DIR - --x-libraries=DIR X library files are in DIR -EOF - if test -n "$ac_help"; then - echo "--enable and --with options recognized:$ac_help" - fi - exit 0 ;; - - -host | --host | --hos | --ho) - ac_prev=host ;; - -host=* | --host=* | --hos=* | --ho=*) - host="$ac_optarg" ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir="$ac_optarg" ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir="$ac_optarg" ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir="$ac_optarg" ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir="$ac_optarg" ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst \ - | --locals | --local | --loca | --loc | --lo) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* \ - | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) - localstatedir="$ac_optarg" ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir="$ac_optarg" ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir="$ac_optarg" ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix="$ac_optarg" ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix="$ac_optarg" ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix="$ac_optarg" ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name="$ac_optarg" ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir="$ac_optarg" ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir="$ac_optarg" ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site="$ac_optarg" ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir="$ac_optarg" ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir="$ac_optarg" ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target="$ac_optarg" ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers) - echo "configure generated by autoconf version 2.12" - exit 0 ;; - - -with-* | --with-*) - ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then - { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } - fi - ac_package=`echo $ac_package| sed 's/-/_/g'` - case "$ac_option" in - *=*) ;; - *) ac_optarg=yes ;; - esac - eval "with_${ac_package}='$ac_optarg'" ;; - - -without-* | --without-*) - ac_package=`echo $ac_option|sed -e 's/-*without-//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then - { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } - fi - ac_package=`echo $ac_package| sed 's/-/_/g'` - eval "with_${ac_package}=no" ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes="$ac_optarg" ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries="$ac_optarg" ;; - - -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } - ;; - - *) - if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then - echo "configure: warning: $ac_option: invalid host type" 1>&2 - fi - if test "x$nonopt" != xNONE; then - { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } - fi - nonopt="$ac_option" - ;; - - esac -done - -if test -n "$ac_prev"; then - { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } -fi - -trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 - -# File descriptor usage: -# 0 standard input -# 1 file creation -# 2 errors and warnings -# 3 some systems may open it to /dev/tty -# 4 used on the Kubota Titan -# 6 checking for... messages and results -# 5 compiler messages saved in config.log -if test "$silent" = yes; then - exec 6>/dev/null -else - exec 6>&1 -fi -exec 5>./config.log - -echo "\ -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. -" 1>&5 - -# Strip out --no-create and --no-recursion so they do not pile up. -# Also quote any args containing shell metacharacters. -ac_configure_args= -for ac_arg -do - case "$ac_arg" in - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c) ;; - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; - *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) - ac_configure_args="$ac_configure_args '$ac_arg'" ;; - *) ac_configure_args="$ac_configure_args $ac_arg" ;; - esac -done - -# NLS nuisances. -# Only set these to C if already set. These must not be set unconditionally -# because not all systems understand e.g. LANG=C (notably SCO). -# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! -# Non-C LC_CTYPE values break the ctype check. -if test "${LANG+set}" = set; then LANG=C; export LANG; fi -if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi -if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi -if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -rf conftest* confdefs.h -# AIX cpp loses on an empty file, so make sure it contains at least a newline. -echo > confdefs.h - -# A filename unique to this package, relative to the directory that -# configure is in, which we can look for to find out if srcdir is correct. -ac_unique_file=rc.h - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then its parent. - ac_prog=$0 - ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` - test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. - srcdir=$ac_confdir - if test ! -r $srcdir/$ac_unique_file; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r $srcdir/$ac_unique_file; then - if test "$ac_srcdir_defaulted" = yes; then - { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } - else - { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } - fi -fi -srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` - -# Prefer explicitly selected file to automatically selected ones. -if test -z "$CONFIG_SITE"; then - if test "x$prefix" != xNONE; then - CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" - else - CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" - fi -fi -for ac_site_file in $CONFIG_SITE; do - if test -r "$ac_site_file"; then - echo "loading site script $ac_site_file" - . "$ac_site_file" - fi -done - -if test -r "$cache_file"; then - echo "loading cache $cache_file" - . $cache_file -else - echo "creating cache $cache_file" - > $cache_file -fi - -ac_ext=c -# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. -ac_cpp='$CPP $CPPFLAGS' -ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' -cross_compiling=$ac_cv_prog_cc_cross - -if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then - # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. - if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then - ac_n= ac_c=' -' ac_t=' ' - else - ac_n=-n ac_c= ac_t= - fi -else - ac_n= ac_c='\c' ac_t= -fi - - - - - -# Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:549: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - for ac_dir in $PATH; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_CC="gcc" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -CC="$ac_cv_prog_CC" -if test -n "$CC"; then - echo "$ac_t""$CC" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:578: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - ac_prog_rejected=no - for ac_dir in $PATH; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - break - fi - done - IFS="$ac_save_ifs" -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# -gt 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - set dummy "$ac_dir/$ac_word" "$@" - shift - ac_cv_prog_CC="$@" - fi -fi -fi -fi -CC="$ac_cv_prog_CC" -if test -n "$CC"; then - echo "$ac_t""$CC" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - - test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } -fi - -echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 -echo "configure:626: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 - -ac_ext=c -# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. -ac_cpp='$CPP $CPPFLAGS' -ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' -cross_compiling=$ac_cv_prog_cc_cross - -cat > conftest.$ac_ext <<EOF -#line 636 "configure" -#include "confdefs.h" -main(){return(0);} -EOF -if { (eval echo configure:640: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then - ac_cv_prog_cc_works=yes - # If we can't run a trivial program, we are probably using a cross compiler. - if (./conftest; exit) 2>/dev/null; then - ac_cv_prog_cc_cross=no - else - ac_cv_prog_cc_cross=yes - fi -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - ac_cv_prog_cc_works=no -fi -rm -fr conftest* - -echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 -if test $ac_cv_prog_cc_works = no; then - { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } -fi -echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 -echo "configure:660: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 -echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 -cross_compiling=$ac_cv_prog_cc_cross - -echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 -echo "configure:665: checking whether we are using GNU C" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.c <<EOF -#ifdef __GNUC__ - yes; -#endif -EOF -if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:674: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then - ac_cv_prog_gcc=yes -else - ac_cv_prog_gcc=no -fi -fi - -echo "$ac_t""$ac_cv_prog_gcc" 1>&6 - -if test $ac_cv_prog_gcc = yes; then - GCC=yes - ac_test_CFLAGS="${CFLAGS+set}" - ac_save_CFLAGS="$CFLAGS" - CFLAGS= - echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 -echo "configure:689: checking whether ${CC-cc} accepts -g" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - echo 'void f(){}' > conftest.c -if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then - ac_cv_prog_cc_g=yes -else - ac_cv_prog_cc_g=no -fi -rm -f conftest* - -fi - -echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 - if test "$ac_test_CFLAGS" = set; then - CFLAGS="$ac_save_CFLAGS" - elif test $ac_cv_prog_cc_g = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-O2" - fi -else - GCC= - test "${CFLAGS+set}" = set || CFLAGS="-g" -fi - -case "x$GCC" in -xyes) - CFLAGS="-Wall $CFLAGS" - ;; -esac - -ac_aux_dir= -for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do - if test -f $ac_dir/install-sh; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f $ac_dir/install.sh; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - fi -done -if test -z "$ac_aux_dir"; then - { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } -fi -ac_config_guess=$ac_aux_dir/config.guess -ac_config_sub=$ac_aux_dir/config.sub -ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. - -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# ./install, which can be erroneously created by make from ./install.sh. -echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -echo "configure:752: checking for a BSD compatible install" >&5 -if test -z "$INSTALL"; then -if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="${IFS}:" - for ac_dir in $PATH; do - # Account for people who put trailing slashes in PATH elements. - case "$ac_dir/" in - /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - for ac_prog in ginstall installbsd scoinst install; do - if test -f $ac_dir/$ac_prog; then - if test $ac_prog = install && - grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - # OSF/1 installbsd also uses dspmsg, but is usable. - : - else - ac_cv_path_install="$ac_dir/$ac_prog -c" - break 2 - fi - fi - done - ;; - esac - done - IFS="$ac_save_IFS" - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL="$ac_cv_path_install" - else - # As a last resort, use the slow shell script. We don't cache a - # path for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the path is relative. - INSTALL="$ac_install_sh" - fi -fi -echo "$ac_t""$INSTALL" 1>&6 - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - -for ac_prog in 'bison -y' byacc -do -# Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:806: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$YACC"; then - ac_cv_prog_YACC="$YACC" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - for ac_dir in $PATH; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_YACC="$ac_prog" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -YACC="$ac_cv_prog_YACC" -if test -n "$YACC"; then - echo "$ac_t""$YACC" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -test -n "$YACC" && break -done -test -n "$YACC" || YACC="yacc" - -for ac_prog in ln cp -do -# Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:840: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_LN'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$LN"; then - ac_cv_prog_LN="$LN" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - for ac_dir in $PATH; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_LN="$ac_prog" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -LN="$ac_cv_prog_LN" -if test -n "$LN"; then - echo "$ac_t""$LN" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -test -n "$LN" && break -done - - -echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 -echo "configure:870: checking how to run the C preprocessor" >&5 -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then -if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - # This must be in double quotes, not single quotes, because CPP may get - # substituted into the Makefile and "${CC-cc}" will confuse make. - CPP="${CC-cc} -E" - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. - cat > conftest.$ac_ext <<EOF -#line 885 "configure" -#include "confdefs.h" -#include <assert.h> -Syntax Error -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:891: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out` -if test -z "$ac_err"; then - : -else - echo "$ac_err" >&5 - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - CPP="${CC-cc} -E -traditional-cpp" - cat > conftest.$ac_ext <<EOF -#line 902 "configure" -#include "confdefs.h" -#include <assert.h> -Syntax Error -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:908: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out` -if test -z "$ac_err"; then - : -else - echo "$ac_err" >&5 - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - CPP=/lib/cpp -fi -rm -f conftest* -fi -rm -f conftest* - ac_cv_prog_CPP="$CPP" -fi - CPP="$ac_cv_prog_CPP" -else - ac_cv_prog_CPP="$CPP" -fi -echo "$ac_t""$CPP" 1>&6 - -for ac_hdr in sys/resource.h sys/time.h sys/types.h unistd.h -do -ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` -echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:934: checking for $ac_hdr" >&5 -if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext <<EOF -#line 939 "configure" -#include "confdefs.h" -#include <$ac_hdr> -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:944: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out` -if test -z "$ac_err"; then - rm -rf conftest* - eval "ac_cv_header_$ac_safe=yes" -else - echo "$ac_err" >&5 - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_header_$ac_safe=no" -fi -rm -f conftest* -fi -if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then - echo "$ac_t""yes" 1>&6 - ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` - cat >> confdefs.h <<EOF -#define $ac_tr_hdr 1 -EOF - -else - echo "$ac_t""no" 1>&6 -fi -done - -ac_header_dirent=no -for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h -do -ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` -echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6 -echo "configure:975: checking for $ac_hdr that defines DIR" >&5 -if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext <<EOF -#line 980 "configure" -#include "confdefs.h" -#include <sys/types.h> -#include <$ac_hdr> -int main() { -DIR *dirp = 0; -; return 0; } -EOF -if { (eval echo configure:988: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then - rm -rf conftest* - eval "ac_cv_header_dirent_$ac_safe=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_header_dirent_$ac_safe=no" -fi -rm -f conftest* -fi -if eval "test \"`echo '$ac_cv_header_dirent_'$ac_safe`\" = yes"; then - echo "$ac_t""yes" 1>&6 - ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` - cat >> confdefs.h <<EOF -#define $ac_tr_hdr 1 -EOF - ac_header_dirent=$ac_hdr; break -else - echo "$ac_t""no" 1>&6 -fi -done -# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. -if test $ac_header_dirent = dirent.h; then -echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6 -echo "configure:1013: checking for opendir in -ldir" >&5 -ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'` -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_save_LIBS="$LIBS" -LIBS="-ldir $LIBS" -cat > conftest.$ac_ext <<EOF -#line 1021 "configure" -#include "confdefs.h" -/* Override any gcc2 internal prototype to avoid an error. */ -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char opendir(); - -int main() { -opendir() -; return 0; } -EOF -if { (eval echo configure:1032: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=no" -fi -rm -f conftest* -LIBS="$ac_save_LIBS" - -fi -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then - echo "$ac_t""yes" 1>&6 - LIBS="$LIBS -ldir" -else - echo "$ac_t""no" 1>&6 -fi - -else -echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6 -echo "configure:1054: checking for opendir in -lx" >&5 -ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'` -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_save_LIBS="$LIBS" -LIBS="-lx $LIBS" -cat > conftest.$ac_ext <<EOF -#line 1062 "configure" -#include "confdefs.h" -/* Override any gcc2 internal prototype to avoid an error. */ -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char opendir(); - -int main() { -opendir() -; return 0; } -EOF -if { (eval echo configure:1073: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=no" -fi -rm -f conftest* -LIBS="$ac_save_LIBS" - -fi -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then - echo "$ac_t""yes" 1>&6 - LIBS="$LIBS -lx" -else - echo "$ac_t""no" 1>&6 -fi - -fi - -echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 -echo "configure:1096: checking for ANSI C header files" >&5 -if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext <<EOF -#line 1101 "configure" -#include "confdefs.h" -#include <stdlib.h> -#include <stdarg.h> -#include <string.h> -#include <float.h> -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1109: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out` -if test -z "$ac_err"; then - rm -rf conftest* - ac_cv_header_stdc=yes -else - echo "$ac_err" >&5 - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - ac_cv_header_stdc=no -fi -rm -f conftest* - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. -cat > conftest.$ac_ext <<EOF -#line 1126 "configure" -#include "confdefs.h" -#include <string.h> -EOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - egrep "memchr" >/dev/null 2>&1; then - : -else - rm -rf conftest* - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. -cat > conftest.$ac_ext <<EOF -#line 1144 "configure" -#include "confdefs.h" -#include <stdlib.h> -EOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - egrep "free" >/dev/null 2>&1; then - : -else - rm -rf conftest* - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. -if test "$cross_compiling" = yes; then - : -else - cat > conftest.$ac_ext <<EOF -#line 1165 "configure" -#include "confdefs.h" -#include <ctype.h> -#define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int main () { int i; for (i = 0; i < 256; i++) -if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); -exit (0); } - -EOF -if { (eval echo configure:1176: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null -then - : -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -fr conftest* - ac_cv_header_stdc=no -fi -rm -fr conftest* -fi - -fi -fi - -echo "$ac_t""$ac_cv_header_stdc" 1>&6 -if test $ac_cv_header_stdc = yes; then - cat >> confdefs.h <<\EOF -#define STDC_HEADERS 1 -EOF - -fi - - -echo $ac_n "checking for signal names in <sys/signal.h>""... $ac_c" 1>&6 -echo "configure:1201: checking for signal names in <sys/signal.h>" >&5 -if eval "test \"`echo '$''{'rc_cv_sys_signal_h'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if grep SIGINT /usr/include/sys/signal.h >/dev/null 2>&1; then - rc_cv_sys_signal_h=yes - else - rc_cv_sys_signal_h=no - fi -fi - -echo "$ac_t""$rc_cv_sys_signal_h" 1>&6 - -case "x$rc_cv_sys_signal_h" in -xyes) - SIGNAL_H=/usr/include/sys/signal.h - ;; -xno) - echo $ac_n "checking for signal names in <asm/signal.h>""... $ac_c" 1>&6 -echo "configure:1220: checking for signal names in <asm/signal.h>" >&5 -if eval "test \"`echo '$''{'rc_cv_asm_signal_h'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if grep SIGINT /usr/include/asm/signal.h >/dev/null 2>&1; then - rc_cv_asm_signal_h=yes - else - rc_cv_asm_signal_h=no - fi -fi - -echo "$ac_t""$rc_cv_asm_signal_h" 1>&6 - - case "x$rc_cv_asm_signal_h" in - xyes) - SIGNAL_H=/usr/include/asm/signal.h - ;; - xno) - { echo "configure: error: Can't find signal names in <sys/signal.h> or <asm/signal.h>" 1>&2; exit 1; } - ;; - esac - ;; -esac - - -echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6 -echo "configure:1246: checking for uid_t in sys/types.h" >&5 -if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext <<EOF -#line 1251 "configure" -#include "confdefs.h" -#include <sys/types.h> -EOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - egrep "uid_t" >/dev/null 2>&1; then - rm -rf conftest* - ac_cv_type_uid_t=yes -else - rm -rf conftest* - ac_cv_type_uid_t=no -fi -rm -f conftest* - -fi - -echo "$ac_t""$ac_cv_type_uid_t" 1>&6 -if test $ac_cv_type_uid_t = no; then - cat >> confdefs.h <<\EOF -#define uid_t int -EOF - - cat >> confdefs.h <<\EOF -#define gid_t int -EOF - -fi - -echo $ac_n "checking type of array argument to getgroups""... $ac_c" 1>&6 -echo "configure:1280: checking type of array argument to getgroups" >&5 -if eval "test \"`echo '$''{'ac_cv_type_getgroups'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test "$cross_compiling" = yes; then - ac_cv_type_getgroups=cross -else - cat > conftest.$ac_ext <<EOF -#line 1288 "configure" -#include "confdefs.h" - -/* Thanks to Mike Rendell for this test. */ -#include <sys/types.h> -#define NGID 256 -#undef MAX -#define MAX(x, y) ((x) > (y) ? (x) : (y)) -main() -{ - gid_t gidset[NGID]; - int i, n; - union { gid_t gval; long lval; } val; - - val.lval = -1; - for (i = 0; i < NGID; i++) - gidset[i] = val.gval; - n = getgroups (sizeof (gidset) / MAX (sizeof (int), sizeof (gid_t)) - 1, - gidset); - /* Exit non-zero if getgroups seems to require an array of ints. This - happens when gid_t is short but getgroups modifies an array of ints. */ - exit ((n > 0 && gidset[n] != val.gval) ? 1 : 0); -} - -EOF -if { (eval echo configure:1313: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null -then - ac_cv_type_getgroups=gid_t -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -fr conftest* - ac_cv_type_getgroups=int -fi -rm -fr conftest* -fi - -if test $ac_cv_type_getgroups = cross; then - cat > conftest.$ac_ext <<EOF -#line 1327 "configure" -#include "confdefs.h" -#include <unistd.h> -EOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - egrep "getgroups.*int.*gid_t" >/dev/null 2>&1; then - rm -rf conftest* - ac_cv_type_getgroups=gid_t -else - rm -rf conftest* - ac_cv_type_getgroups=int -fi -rm -f conftest* - -fi -fi - -echo "$ac_t""$ac_cv_type_getgroups" 1>&6 -cat >> confdefs.h <<EOF -#define GETGROUPS_T $ac_cv_type_getgroups -EOF - - -echo $ac_n "checking for pid_t""... $ac_c" 1>&6 -echo "configure:1351: checking for pid_t" >&5 -if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext <<EOF -#line 1356 "configure" -#include "confdefs.h" -#include <sys/types.h> -#if STDC_HEADERS -#include <stdlib.h> -#include <stddef.h> -#endif -EOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - egrep "pid_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then - rm -rf conftest* - ac_cv_type_pid_t=yes -else - rm -rf conftest* - ac_cv_type_pid_t=no -fi -rm -f conftest* - -fi -echo "$ac_t""$ac_cv_type_pid_t" 1>&6 -if test $ac_cv_type_pid_t = no; then - cat >> confdefs.h <<\EOF -#define pid_t int -EOF - -fi - -echo $ac_n "checking for size_t""... $ac_c" 1>&6 -echo "configure:1384: checking for size_t" >&5 -if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext <<EOF -#line 1389 "configure" -#include "confdefs.h" -#include <sys/types.h> -#if STDC_HEADERS -#include <stdlib.h> -#include <stddef.h> -#endif -EOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - egrep "size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then - rm -rf conftest* - ac_cv_type_size_t=yes -else - rm -rf conftest* - ac_cv_type_size_t=no -fi -rm -f conftest* - -fi -echo "$ac_t""$ac_cv_type_size_t" 1>&6 -if test $ac_cv_type_size_t = no; then - cat >> confdefs.h <<\EOF -#define size_t unsigned -EOF - -fi - -echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6 -echo "configure:1417: checking for uid_t in sys/types.h" >&5 -if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext <<EOF -#line 1422 "configure" -#include "confdefs.h" -#include <sys/types.h> -EOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - egrep "uid_t" >/dev/null 2>&1; then - rm -rf conftest* - ac_cv_type_uid_t=yes -else - rm -rf conftest* - ac_cv_type_uid_t=no -fi -rm -f conftest* - -fi - -echo "$ac_t""$ac_cv_type_uid_t" 1>&6 -if test $ac_cv_type_uid_t = no; then - cat >> confdefs.h <<\EOF -#define uid_t int -EOF - - cat >> confdefs.h <<\EOF -#define gid_t int -EOF - -fi - - -for ac_func in getgroups setpgrp setrlimit -do -echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:1454: checking for $ac_func" >&5 -if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext <<EOF -#line 1459 "configure" -#include "confdefs.h" -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func(); below. */ -#include <assert.h> -/* Override any gcc2 internal prototype to avoid an error. */ -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func(); - -int main() { - -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -$ac_func(); -#endif - -; return 0; } -EOF -if { (eval echo configure:1482: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then - rm -rf conftest* - eval "ac_cv_func_$ac_func=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_func_$ac_func=no" -fi -rm -f conftest* -fi - -if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then - echo "$ac_t""yes" 1>&6 - ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` - cat >> confdefs.h <<EOF -#define $ac_tr_func 1 -EOF - -else - echo "$ac_t""no" 1>&6 -fi -done - - -echo $ac_n "checking whether setpgrp takes no argument""... $ac_c" 1>&6 -echo "configure:1508: checking whether setpgrp takes no argument" >&5 -if eval "test \"`echo '$''{'ac_cv_func_setpgrp_void'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test "$cross_compiling" = yes; then - { echo "configure: error: cannot check setpgrp if cross compiling" 1>&2; exit 1; } -else - cat > conftest.$ac_ext <<EOF -#line 1516 "configure" -#include "confdefs.h" - -/* - * If this system has a BSD-style setpgrp, which takes arguments, exit - * successfully. - */ -main() -{ - if (setpgrp(1,1) == -1) - exit(0); - else - exit(1); -} - -EOF -if { (eval echo configure:1532: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null -then - ac_cv_func_setpgrp_void=no -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -fr conftest* - ac_cv_func_setpgrp_void=yes -fi -rm -fr conftest* -fi - - -fi - -echo "$ac_t""$ac_cv_func_setpgrp_void" 1>&6 -if test $ac_cv_func_setpgrp_void = yes; then - cat >> confdefs.h <<\EOF -#define SETPGRP_VOID 1 -EOF - -fi - - -echo $ac_n "checking if _KERNEL is required for RLIMIT defines""... $ac_c" 1>&6 -echo "configure:1557: checking if _KERNEL is required for RLIMIT defines" >&5 -if eval "test \"`echo '$''{'rc_cv_kernel_rlimit'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext <<EOF -#line 1562 "configure" -#include "confdefs.h" - -#include <sys/types.h> -#include <sys/resource.h> - -int main() { - -int f; -f = RLIMIT_DATA; - -; return 0; } -EOF -if { (eval echo configure:1575: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then - rm -rf conftest* - rc_cv_kernel_rlimit=no -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - cat > conftest.$ac_ext <<EOF -#line 1583 "configure" -#include "confdefs.h" - -#include <sys/types.h> -#define _KERNEL -#include <sys/resource.h> -#undef _KERNEL - -int main() { - -int f; -f = RLIMIT_DATA; - -; return 0; } -EOF -if { (eval echo configure:1598: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then - rm -rf conftest* - rc_cv_kernel_rlimit=yes -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - rc_cv_kernel_rlimit=no -fi -rm -f conftest* -fi -rm -f conftest* -fi - -echo "$ac_t""$rc_cv_kernel_rlimit" 1>&6 -case "x$rc_cv_kernel_rlimit" in -xyes) - cat >> confdefs.h <<\EOF -#define RLIMIT_NEEDS_KERNEL 1 -EOF - - ;; -esac - -echo $ac_n "checking for rlim_t""... $ac_c" 1>&6 -echo "configure:1623: checking for rlim_t" >&5 -if eval "test \"`echo '$''{'rc_cv_have_rlim_t'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext <<EOF -#line 1628 "configure" -#include "confdefs.h" - -#include <sys/types.h> -#if RLIMIT_NEEDS_KERNEL -#define _KERNEL -#endif -#include <sys/resource.h> - -EOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - egrep "rlim_t" >/dev/null 2>&1; then - rm -rf conftest* - rc_cv_have_rlim_t=yes -else - rm -rf conftest* - rc_cv_have_rlim_t=no -fi -rm -f conftest* - -fi - -echo "$ac_t""$rc_cv_have_rlim_t" 1>&6 - -case "x$rc_cv_have_rlim_t" in -xyes) - cat >> confdefs.h <<\EOF -#define HAVE_RLIM_T 1 -EOF - - ;; -xno) - echo $ac_n "checking for native quad_t""... $ac_c" 1>&6 -echo "configure:1661: checking for native quad_t" >&5 -if eval "test \"`echo '$''{'rc_cv_have_quad_t'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test "$cross_compiling" = yes; then - { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } -else - cat > conftest.$ac_ext <<EOF -#line 1669 "configure" -#include "confdefs.h" - -#include <sys/types.h> -main() { - quad_t q; - q = 0; - exit((int) q); -} - -EOF -if { (eval echo configure:1680: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null -then - rc_cv_have_quad_t=yes -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -fr conftest* - rc_cv_have_quad_t=no -fi -rm -fr conftest* -fi - -fi - -echo "$ac_t""$rc_cv_have_quad_t" 1>&6 - - case "x$rc_cv_have_quad_t" in - xyes) - cat >> confdefs.h <<\EOF -#define HAVE_QUAD_T 1 -EOF - - - echo $ac_n "checking if rlimit values are quad_t""... $ac_c" 1>&6 -echo "configure:1704: checking if rlimit values are quad_t" >&5 -if eval "test \"`echo '$''{'rc_cv_rlim_t_is_quad_t'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test "$cross_compiling" = yes; then - $ac_cv_type_quad_t -else - cat > conftest.$ac_ext <<EOF -#line 1712 "configure" -#include "confdefs.h" - -#include <sys/types.h> -#include <sys/time.h> -#include <sys/types.h> -#if RLIMIT_NEEDS_KERNEL -#define _KERNEL -#endif -#include <sys/resource.h> -#if RLIMIT_NEEDS_KERNEL -#undef _KERNEL -#endif -main(){ - struct rlimit rl; - exit(sizeof rl.rlim_cur != sizeof(quad_t)); -} - -EOF -if { (eval echo configure:1731: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null -then - rc_cv_rlim_t_is_quad_t=yes -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -fr conftest* - rc_cv_rlim_t_is_quad_t=no -fi -rm -fr conftest* -fi - -fi - -echo "$ac_t""$rc_cv_rlim_t_is_quad_t" 1>&6 - - case "x$rc_cv_rlim_t_is_quad_t" in - xyes) - cat >> confdefs.h <<\EOF -#define RLIM_T_IS_QUAD_T 1 -EOF - - ;; - esac - ;; - esac - ;; -esac - -echo $ac_n "checking for restartable system calls""... $ac_c" 1>&6 -echo "configure:1761: checking for restartable system calls" >&5 -if eval "test \"`echo '$''{'ac_cv_sys_restartable_syscalls'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test "$cross_compiling" = yes; then - { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } -else - cat > conftest.$ac_ext <<EOF -#line 1769 "configure" -#include "confdefs.h" -/* Exit 0 (true) if wait returns something other than -1, - i.e. the pid of the child, which means that wait was restarted - after getting the signal. */ -#include <sys/types.h> -#include <signal.h> -ucatch (isig) { } -main () { - int i = fork (), status; - if (i == 0) { sleep (3); kill (getppid (), SIGINT); sleep (3); exit (0); } - signal (SIGINT, ucatch); - status = wait(&i); - if (status == -1) wait(&i); - exit (status == -1); -} - -EOF -if { (eval echo configure:1787: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null -then - ac_cv_sys_restartable_syscalls=yes -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -fr conftest* - ac_cv_sys_restartable_syscalls=no -fi -rm -fr conftest* -fi - -fi - -echo "$ac_t""$ac_cv_sys_restartable_syscalls" 1>&6 -if test $ac_cv_sys_restartable_syscalls = yes; then - cat >> confdefs.h <<\EOF -#define HAVE_RESTARTABLE_SYSCALLS 1 -EOF - -fi - - -# Pull the hash mark out of the macro call to avoid m4 problems. -ac_msg="whether #! works in shell scripts" -echo $ac_n "checking $ac_msg""... $ac_c" 1>&6 -echo "configure:1813: checking $ac_msg" >&5 -if eval "test \"`echo '$''{'ac_cv_sys_interpreter'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - echo '#! /bin/cat -exit 69 -' > conftest -chmod u+x conftest -(SHELL=/bin/sh; export SHELL; ./conftest >/dev/null) -if test $? -ne 69; then - ac_cv_sys_interpreter=yes -else - ac_cv_sys_interpreter=no -fi -rm -f conftest -fi - -echo "$ac_t""$ac_cv_sys_interpreter" 1>&6 - -case "x$ac_cv_sys_interpreter" in -xyes) - cat >> confdefs.h <<\EOF -#define HASH_BANG 1 -EOF - - EXECVE='' - ;; -xno) - EXECVE=execve.o -esac - - -echo $ac_n "checking for /dev/fd""... $ac_c" 1>&6 -echo "configure:1846: checking for /dev/fd" >&5 -if eval "test \"`echo '$''{'rc_cv_sys_dev_fd'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -d /dev/fd && test -r /dev/fd/0; then - rc_cv_sys_dev_fd=yes - elif test -d /proc/self/fd && test -r /proc/self/fd/0; then - rc_cv_sys_dev_fd=odd - else - rc_cv_sys_dev_fd=no - fi -fi - -echo "$ac_t""$rc_cv_sys_dev_fd" 1>&6 - -case "x$rc_cv_sys_dev_fd" in -xyes) - cat >> confdefs.h <<\EOF -#define HAVE_DEV_FD 1 -EOF - - ;; -xodd) - cat >> confdefs.h <<\EOF -#define HAVE_PROC_SELF_FD 1 -EOF - - ;; -xno) - echo $ac_n "checking for named pipes""... $ac_c" 1>&6 -echo "configure:1876: checking for named pipes" >&5 -if eval "test \"`echo '$''{'rc_cv_sys_fifo'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat >> confdefs.h <<EOF -#define TMPNAM "/tmp/rc$$.0" -EOF - - if test "$cross_compiling" = yes; then - rc_cv_sys_fifo=no -else - cat > conftest.$ac_ext <<EOF -#line 1888 "configure" -#include "confdefs.h" - -#include <sys/types.h> -#include <sys/stat.h> - -main() { - exit(mknod(TMPNAM, S_IFIFO | 0666, 0) != 0); -} - -EOF -if { (eval echo configure:1899: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null -then - rc_cv_sys_fifo=yes -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -fr conftest* - rc_cv_sys_fifo=no -fi -rm -fr conftest* -fi - -fi - -echo "$ac_t""$rc_cv_sys_fifo" 1>&6 - case "x$rc_cv_sys_fifo" in - xyes) - cat >> confdefs.h <<\EOF -#define HAVE_FIFO 1 -EOF - - ;; - esac -esac - -# Check whether --enable-builtin-echo or --disable-builtin-echo was given. -if test "${enable_builtin_echo+set}" = set; then - enableval="$enable_builtin_echo" - test "x$enableval" != "xno" && cat >> confdefs.h <<\EOF -#define RC_ECHO 1 -EOF - -else - cat >> confdefs.h <<\EOF -#define RC_ECHO 1 -EOF - -fi - - -# Check whether --enable-job or --disable-job was given. -if test "${enable_job+set}" = set; then - enableval="$enable_job" - test "x$enableval" != "xno" && cat >> confdefs.h <<\EOF -#define RC_JOB 1 -EOF - -else - cat >> confdefs.h <<\EOF -#define RC_JOB 1 -EOF - -fi - - -# Check whether --enable-protect-env or --disable-protect-env was given. -if test "${enable_protect_env+set}" = set; then - enableval="$enable_protect_env" - test "x$enableval" != "xno" && cat >> confdefs.h <<\EOF -#define PROTECT_ENV 1 -EOF - -else - cat >> confdefs.h <<\EOF -#define PROTECT_ENV 1 -EOF - -fi - - -# Check whether --enable-def-interp or --disable-def-interp was given. -if test "${enable_def_interp+set}" = set; then - enableval="$enable_def_interp" - - case "x$enableval" in - xno) - ;; - xyes) - cat >> confdefs.h <<\EOF -#define DEFAULTINTERP "/bin/sh" -EOF - - ;; - *) - cat >> confdefs.h <<EOF -#define DEFAULTINTERP "$enableval" -EOF - - esac - -else - cat >> confdefs.h <<\EOF -#define DEFAULTINTERP "/bin/sh" -EOF - -fi - - -# Check whether --enable-def-path or --disable-def-path was given. -if test "${enable_def_path+set}" = set; then - enableval="$enable_def_path" - - case "x$enableval" in - xno|xyes) - ;; - *) - cat >> confdefs.h <<EOF -#define DEFAULTPATH $enableval -EOF - - esac - -else - enable_def_path=yes -fi - - -case "x$enable_def_path" in -xyes) - echo $ac_n "checking extant directories for default path""... $ac_c" 1>&6 -echo "configure:2019: checking extant directories for default path" >&5 -if eval "test \"`echo '$''{'rc_cv_def_path'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - - rc_cv_def_path='' - for i in /usr/local/bin /usr/bin /usr/ucb /bin .; do - if test -d $i; then - case "x$rc_cv_def_path" in - x) - rc_cv_def_path=\"$i\" - ;; - *) - rc_cv_def_path=$rc_cv_def_path,\"$i\" - ;; - esac - fi - done - cat >> confdefs.h <<EOF -#define DEFAULTPATH $rc_cv_def_path -EOF - - -fi - -echo "$ac_t""$rc_cv_def_path" 1>&6 - ;; -esac - -# Check whether --enable-history or --disable-history was given. -if test "${enable_history+set}" = set; then - enableval="$enable_history" - test "x$enableval" != "xno" && rc_history=yes -else - rc_history=no -fi - -case "x$rc_history" in -xyes) - HISTORY=history/history - ;; -esac - - -# Check whether --with-addon or --without-addon was given. -if test "${with_addon+set}" = set; then - withval="$with_addon" - - case "x$withval" in - xyes) - ADDON=addon.o - ;; - xno) - ADDON='' - ;; - *) - ADDON=$withval - ;; - esac - -fi - - - -# Check whether --with-editline or --without-editline was given. -if test "${with_editline+set}" = set; then - withval="$with_editline" - echo $ac_n "checking for readline in -ledit""... $ac_c" 1>&6 -echo "configure:2087: checking for readline in -ledit" >&5 -ac_lib_var=`echo edit'_'readline | sed 'y%./+-%__p_%'` -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_save_LIBS="$LIBS" -LIBS="-ledit $LIBS" -cat > conftest.$ac_ext <<EOF -#line 2095 "configure" -#include "confdefs.h" -/* Override any gcc2 internal prototype to avoid an error. */ -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char readline(); - -int main() { -readline() -; return 0; } -EOF -if { (eval echo configure:2106: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=no" -fi -rm -f conftest* -LIBS="$ac_save_LIBS" - -fi -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then - echo "$ac_t""yes" 1>&6 - cat >> confdefs.h <<\EOF -#define READLINE 1 -EOF - LIBS="$LIBS -ledit" -else - echo "$ac_t""no" 1>&6 -echo "configure: warning: editline library not found" 1>&2 -fi - -fi - - -# Check whether --with-readline or --without-readline was given. -if test "${with_readline+set}" = set; then - withval="$with_readline" - echo $ac_n "checking for readline in -lreadline""... $ac_c" 1>&6 -echo "configure:2137: checking for readline in -lreadline" >&5 -ac_lib_var=`echo readline'_'readline | sed 'y%./+-%__p_%'` -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_save_LIBS="$LIBS" -LIBS="-lreadline $LIBS" -cat > conftest.$ac_ext <<EOF -#line 2145 "configure" -#include "confdefs.h" -/* Override any gcc2 internal prototype to avoid an error. */ -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char readline(); - -int main() { -readline() -; return 0; } -EOF -if { (eval echo configure:2156: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=no" -fi -rm -f conftest* -LIBS="$ac_save_LIBS" - -fi -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then - echo "$ac_t""yes" 1>&6 - cat >> confdefs.h <<\EOF -#define READLINE 1 -EOF - LIBS="$LIBS -lreadline -ltermcap" -else - echo "$ac_t""no" 1>&6 -echo "configure: warning: readline library not found" 1>&2 -fi - -fi - - -trap '' 1 2 15 -cat > confcache <<\EOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs. It is not useful on other systems. -# If it contains results you don't want to keep, you may remove or edit it. -# -# By default, configure uses ./config.cache as the cache file, -# creating it if it does not exist already. You can give configure -# the --cache-file=FILE option to use a different cache file; that is -# what configure does when it calls configure scripts in -# subdirectories, so they share the cache. -# Giving --cache-file=/dev/null disables caching, for debugging configure. -# config.status only pays attention to the cache file if you give it the -# --recheck option to rerun configure. -# -EOF -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, don't put newlines in cache variables' values. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -(set) 2>&1 | - case `(ac_space=' '; set) 2>&1` in - *ac_space=\ *) - # `set' does not quote correctly, so add quotes (double-quote substitution - # turns \\\\ into \\, and sed turns \\ into \). - sed -n \ - -e "s/'/'\\\\''/g" \ - -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" - ;; - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' - ;; - esac >> confcache -if cmp -s $cache_file confcache; then - : -else - if test -w $cache_file; then - echo "updating cache $cache_file" - cat confcache > $cache_file - else - echo "not updating unwritable cache $cache_file" - fi -fi -rm -f confcache - -trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -# Any assignment to VPATH causes Sun make to only execute -# the first set of double-colon rules, so remove it if not needed. -# If there is a colon in the path, we need to keep it. -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' -fi - -trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 - -DEFS=-DHAVE_CONFIG_H - -# Without the "./", some shells look in PATH for config.status. -: ${CONFIG_STATUS=./config.status} - -echo creating $CONFIG_STATUS -rm -f $CONFIG_STATUS -cat > $CONFIG_STATUS <<EOF -#! /bin/sh -# Generated automatically by configure. -# Run this file to recreate the current configuration. -# This directory was configured as follows, -# on host `(hostname || uname -n) 2>/dev/null | sed 1q`: -# -# $0 $ac_configure_args -# -# Compiler output produced by configure, useful for debugging -# configure, is in ./config.log if it exists. - -ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" -for ac_option -do - case "\$ac_option" in - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" - exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; - -version | --version | --versio | --versi | --vers | --ver | --ve | --v) - echo "$CONFIG_STATUS generated by autoconf version 2.12" - exit 0 ;; - -help | --help | --hel | --he | --h) - echo "\$ac_cs_usage"; exit 0 ;; - *) echo "\$ac_cs_usage"; exit 1 ;; - esac -done - -ac_given_srcdir=$srcdir -ac_given_INSTALL="$INSTALL" - -trap 'rm -fr `echo "Makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 -EOF -cat >> $CONFIG_STATUS <<EOF - -# Protect against being on the right side of a sed subst in config.status. -sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g; - s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF -$ac_vpsub -$extrasub -s%@CFLAGS@%$CFLAGS%g -s%@CPPFLAGS@%$CPPFLAGS%g -s%@CXXFLAGS@%$CXXFLAGS%g -s%@DEFS@%$DEFS%g -s%@LDFLAGS@%$LDFLAGS%g -s%@LIBS@%$LIBS%g -s%@exec_prefix@%$exec_prefix%g -s%@prefix@%$prefix%g -s%@program_transform_name@%$program_transform_name%g -s%@bindir@%$bindir%g -s%@sbindir@%$sbindir%g -s%@libexecdir@%$libexecdir%g -s%@datadir@%$datadir%g -s%@sysconfdir@%$sysconfdir%g -s%@sharedstatedir@%$sharedstatedir%g -s%@localstatedir@%$localstatedir%g -s%@libdir@%$libdir%g -s%@includedir@%$includedir%g -s%@oldincludedir@%$oldincludedir%g -s%@infodir@%$infodir%g -s%@mandir@%$mandir%g -s%@CC@%$CC%g -s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g -s%@INSTALL_DATA@%$INSTALL_DATA%g -s%@YACC@%$YACC%g -s%@LN@%$LN%g -s%@CPP@%$CPP%g -s%@SIGNAL_H@%$SIGNAL_H%g -s%@EXECVE@%$EXECVE%g -s%@HISTORY@%$HISTORY%g -s%@ADDON@%$ADDON%g - -CEOF -EOF - -cat >> $CONFIG_STATUS <<\EOF - -# Split the substitutions into bite-sized pieces for seds with -# small command number limits, like on Digital OSF/1 and HP-UX. -ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. -ac_file=1 # Number of current file. -ac_beg=1 # First line for current file. -ac_end=$ac_max_sed_cmds # Line after last line for current file. -ac_more_lines=: -ac_sed_cmds="" -while $ac_more_lines; do - if test $ac_beg -gt 1; then - sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file - else - sed "${ac_end}q" conftest.subs > conftest.s$ac_file - fi - if test ! -s conftest.s$ac_file; then - ac_more_lines=false - rm -f conftest.s$ac_file - else - if test -z "$ac_sed_cmds"; then - ac_sed_cmds="sed -f conftest.s$ac_file" - else - ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" - fi - ac_file=`expr $ac_file + 1` - ac_beg=$ac_end - ac_end=`expr $ac_end + $ac_max_sed_cmds` - fi -done -if test -z "$ac_sed_cmds"; then - ac_sed_cmds=cat -fi -EOF - -cat >> $CONFIG_STATUS <<EOF - -CONFIG_FILES=\${CONFIG_FILES-"Makefile"} -EOF -cat >> $CONFIG_STATUS <<\EOF -for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then - # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". - case "$ac_file" in - *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` - ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; - *) ac_file_in="${ac_file}.in" ;; - esac - - # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. - - # Remove last slash and all that follows it. Not all systems have dirname. - ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` - if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then - # The file is in a subdirectory. - test ! -d "$ac_dir" && mkdir "$ac_dir" - ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" - # A "../" for each directory in $ac_dir_suffix. - ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` - else - ac_dir_suffix= ac_dots= - fi - - case "$ac_given_srcdir" in - .) srcdir=. - if test -z "$ac_dots"; then top_srcdir=. - else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; - /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; - *) # Relative path. - srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" - top_srcdir="$ac_dots$ac_given_srcdir" ;; - esac - - case "$ac_given_INSTALL" in - [/$]*) INSTALL="$ac_given_INSTALL" ;; - *) INSTALL="$ac_dots$ac_given_INSTALL" ;; - esac - - echo creating "$ac_file" - rm -f "$ac_file" - configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." - case "$ac_file" in - *Makefile*) ac_comsub="1i\\ -# $configure_input" ;; - *) ac_comsub= ;; - esac - - ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` - sed -e "$ac_comsub -s%@configure_input@%$configure_input%g -s%@srcdir@%$srcdir%g -s%@top_srcdir@%$top_srcdir%g -s%@INSTALL@%$INSTALL%g -" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file -fi; done -rm -f conftest.s* - -# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where -# NAME is the cpp macro being defined and VALUE is the value it is being given. -# -# ac_d sets the value in "#define NAME VALUE" lines. -ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' -ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' -ac_dC='\3' -ac_dD='%g' -# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". -ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' -ac_uB='\([ ]\)%\1#\2define\3' -ac_uC=' ' -ac_uD='\4%g' -# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". -ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' -ac_eB='$%\1#\2define\3' -ac_eC=' ' -ac_eD='%g' - -if test "${CONFIG_HEADERS+set}" != set; then -EOF -cat >> $CONFIG_STATUS <<EOF - CONFIG_HEADERS="config.h" -EOF -cat >> $CONFIG_STATUS <<\EOF -fi -for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then - # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". - case "$ac_file" in - *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` - ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; - *) ac_file_in="${ac_file}.in" ;; - esac - - echo creating $ac_file - - rm -f conftest.frag conftest.in conftest.out - ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` - cat $ac_file_inputs > conftest.in - -EOF - -# Transform confdefs.h into a sed script conftest.vals that substitutes -# the proper values into config.h.in to produce config.h. And first: -# Protect against being on the right side of a sed subst in config.status. -# Protect against being in an unquoted here document in config.status. -rm -f conftest.vals -cat > conftest.hdr <<\EOF -s/[\\&%]/\\&/g -s%[\\$`]%\\&%g -s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp -s%ac_d%ac_u%gp -s%ac_u%ac_e%gp -EOF -sed -n -f conftest.hdr confdefs.h > conftest.vals -rm -f conftest.hdr - -# This sed command replaces #undef with comments. This is necessary, for -# example, in the case of _POSIX_SOURCE, which is predefined and required -# on some systems where configure will not decide to define it. -cat >> conftest.vals <<\EOF -s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% -EOF - -# Break up conftest.vals because some shells have a limit on -# the size of here documents, and old seds have small limits too. - -rm -f conftest.tail -while : -do - ac_lines=`grep -c . conftest.vals` - # grep -c gives empty output for an empty file on some AIX systems. - if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi - # Write a limited-size here document to conftest.frag. - echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS - sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS - echo 'CEOF - sed -f conftest.frag conftest.in > conftest.out - rm -f conftest.in - mv conftest.out conftest.in -' >> $CONFIG_STATUS - sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail - rm -f conftest.vals - mv conftest.tail conftest.vals -done -rm -f conftest.vals - -cat >> $CONFIG_STATUS <<\EOF - rm -f conftest.frag conftest.h - echo "/* $ac_file. Generated automatically by configure. */" > conftest.h - cat conftest.in >> conftest.h - rm -f conftest.in - if cmp -s $ac_file conftest.h 2>/dev/null; then - echo "$ac_file is unchanged" - rm -f conftest.h - else - # Remove last slash and all that follows it. Not all systems have dirname. - ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` - if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then - # The file is in a subdirectory. - test ! -d "$ac_dir" && mkdir "$ac_dir" - fi - rm -f $ac_file - mv conftest.h $ac_file - fi -fi; done - -EOF -cat >> $CONFIG_STATUS <<EOF - -EOF -cat >> $CONFIG_STATUS <<\EOF - -exit 0 -EOF -chmod +x $CONFIG_STATUS -rm -fr confdefs* $ac_clean_files -test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 - diff --git a/configure.ac b/configure.ac @@ -0,0 +1,200 @@ +dnl Get things going... +AC_INIT(rc.h) + +RELDATE=`cat $srcdir/RELDATE` +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 ...and this one for releases +AM_INIT_AUTOMAKE(rc, 1.5b4) + +AM_CONFIG_HEADER(config.h) + +dnl Anybody using name transformations? +AC_ARG_PROGRAM + +dnl Find a standard C compiler +AC_PROG_CC +AM_PROG_CC_STDC + +dnl If we're using gcc, specify `-Wall'. I've also checked the code +dnl with `-pedantic -W -Wall -Wpointer-arith -Wstrict-prototypes +dnl -Wmissing-prototypes', and checked that all the warnings generated +dnl are harmless. +case "$GCC" in +yes) CFLAGS="-Wall $CFLAGS" ;; +esac + +AC_PROG_CPP +AC_PROG_INSTALL +AC_CHECK_PROGS(LN, ln cp) + +AC_CHECK_HEADERS(sys/resource.h sys/time.h sys/types.h unistd.h) +AC_HEADER_DIRENT +AC_HEADER_STDC +AC_HEADER_SYS_WAIT + +AC_TYPE_GETGROUPS +AC_TYPE_PID_T +AC_TYPE_SIZE_T +AC_TYPE_UID_T +AC_CHECK_TYPE(ssize_t, long) + +AC_CHECK_FUNCS(getgroups setpgrp setrlimit) +RC_FUNC_GETGROUPS + +RC_FUNC_SIGSETJMP + +AC_FUNC_SETPGRP + +RC_NEED_KERNEL + +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. +RC_FUNC_SIGACTION +case "$rc_cv_sa_int" in +yes) AC_DEFINE(HAVE_SA_INTERRUPT) ;; +no) AC_SYS_RESTARTABLE_SYSCALLS ;; +esac +AM_CONDITIONAL(AMC_RESTART, test "$ac_cv_sys_restartable_syscalls" = yes) + +RC_SYS_V_SIGCLD + +dnl Does the kernel handle `#! /interpreter'? +AC_SYS_INTERPRETER +case "$ac_cv_sys_interpreter" in +yes) AC_DEFINE(HASH_BANG) ;; +esac +AM_CONDITIONAL(AMC_NO_HASHBANG, test "$ac_cv_sys_interpreter" = no) + + +dnl What do we do for command arguments? We want /dev/fd or Linux's +dnl /proc/self/fd. Failing that, we'll try for POSIX mkfifo(), or a +dnl mknod() that makes FIFOs. +RC_SYS_DEV_FD +case "$rc_cv_sys_dev_fd" in +yes) AC_DEFINE(HAVE_DEV_FD) ;; +odd) AC_DEFINE(HAVE_PROC_SELF_FD) ;; +no) AC_CHECK_FUNCS(mkfifo) ;; +esac + +case "$ac_cv_func_mkfifo" in +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), + AC_DEFINE(RC_ECHO)) + +AC_ARG_ENABLE(job, [ --disable-job Don't do job-control-style backgrounding], + test "x$enableval" != "xno" && AC_DEFINE(RC_JOB), + AC_DEFINE(RC_JOB)) + +AC_ARG_ENABLE(protect-env, [ --disable-protect-env Don't protect environment names], + test "x$enableval" != "xno" && AC_DEFINE(PROTECT_ENV), + AC_DEFINE(PROTECT_ENV)) + +AC_ARG_ENABLE(def-interp, +[ --enable-def-interp=/bin/foo + Use /bin/foo as default interpreter [/bin/sh]], +[ + case "$enableval" in + no) + ;; + yes) + AC_DEFINE(DEFAULTINTERP, "/bin/sh") + ;; + *) + AC_DEFINE_UNQUOTED(DEFAULTINTERP, "$enableval") + esac +], + AC_DEFINE(DEFAULTINTERP, "/bin/sh")) + +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 .)]], +[ + case "$enableval" in + no|yes) ;; + *) AC_DEFINE_UNQUOTED(DEFAULTPATH, $enableval) ;; + esac +], + enable_def_path=yes) + +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 + if test -d $i; then + case "$rc_cv_def_path" in + '') rc_cv_def_path=\"$i\" ;; + *) rc_cv_def_path=$rc_cv_def_path,\"$i\" ;; + esac + fi + done + ]) + AC_DEFINE_UNQUOTED(DEFAULTPATH, $rc_cv_def_path) + ;; +esac + +AC_ARG_WITH(history, + [ --with-history Build history subprograms],[ + case "$withval" in + yes) rc_history=yes ;; + *) rc_history=no ;; + esac + ], rc_history=no) +AM_CONDITIONAL(AMC_HISTORY, test "$rc_history" = yes) + + +AC_ARG_WITH(addon, [ --with-addon[=foo.c] Extra builtins, from addon.c by default ],[ + case "$withval" in + yes) ADDON=addon.o ;; + no) ADDON='' ;; + *) ADDON=`echo $withval |sed 's/\.c$/\.o/'` ;; + esac +]) +AM_CONDITIONAL(AMC_ADDON, test "$ADDON" != "") +case "$ADDON" in +?*) AC_DEFINE(RC_ADDON) ;; +esac +AC_SUBST(ADDON) + + +AC_ARG_WITH(editline, [ --with-editline Simmule Turner's line editing], + AC_CHECK_LIB(edit, readline, + AC_DEFINE(EDITLINE) LIBS="$LIBS -ledit", + AC_MSG_ERROR(editline library not found))) + +AC_ARG_WITH(vrl, [ --with-vrl Gert-Jan Vons's line editing], + AC_CHECK_LIB(vrl, readline, + AC_DEFINE(EDITLINE) LIBS="$LIBS -lvrl -ltermcap", + AC_MSG_ERROR(vrl library not found), -ltermcap)) + +dnl There are (at least) two incompatible versions of readline, and we +dnl need to know which one we are using. We don't support readline 2.0. +AC_ARG_WITH(readline, [ --with-readline Bloated GNU line editing], [ + AC_CHECK_LIB(readline, readline, [ + AC_DEFINE(READLINE) + LIBS="$LIBS -lreadline -ltermcap" + AC_CHECK_LIB(readline, _rl_clean_up_for_exit, , AC_DEFINE(READLINE_OLD), -ltermcap) + ], AC_MSG_ERROR(readline library not found), -ltermcap) +]) +AM_CONDITIONAL(AMC_READLINE, test "${with_readline+set}" = set) + +dnl For some reason CPPFLAGS doesn't get propagated. +AC_SUBST(CPPFLAGS) + +AC_OUTPUT(Makefile) diff --git a/configure.in b/configure.in @@ -1,287 +0,0 @@ -AC_INIT(rc.h) - -AC_CONFIG_HEADER(config.h) - -AC_PROG_CC -case "x$GCC" in -xyes) - CFLAGS="-Wall $CFLAGS" - ;; -esac - -AC_PROG_INSTALL -AC_PROG_YACC -AC_CHECK_PROGS(LN, ln cp) - -AC_CHECK_HEADERS(sys/resource.h sys/time.h sys/types.h unistd.h) -AC_HEADER_DIRENT -AC_HEADER_STDC - -dnl Linux puts real signal names in /usr/include/asm/signal.h. -AC_CACHE_CHECK(for signal names in <sys/signal.h>, rc_cv_sys_signal_h, - if grep SIGINT /usr/include/sys/signal.h >/dev/null 2>&1; then - rc_cv_sys_signal_h=yes - else - rc_cv_sys_signal_h=no - fi) - -case "x$rc_cv_sys_signal_h" in -xyes) - SIGNAL_H=/usr/include/sys/signal.h - ;; -xno) - AC_CACHE_CHECK(for signal names in <asm/signal.h>, rc_cv_asm_signal_h, - if grep SIGINT /usr/include/asm/signal.h >/dev/null 2>&1; then - rc_cv_asm_signal_h=yes - else - rc_cv_asm_signal_h=no - fi) - - case "x$rc_cv_asm_signal_h" in - xyes) - SIGNAL_H=/usr/include/asm/signal.h - ;; - xno) - AC_MSG_ERROR(Can't find signal names in <sys/signal.h> or <asm/signal.h>) - ;; - esac - ;; -esac -AC_SUBST(SIGNAL_H) - -AC_TYPE_GETGROUPS -AC_TYPE_PID_T -AC_TYPE_SIZE_T -AC_TYPE_UID_T - -AC_CHECK_FUNCS(getgroups setpgrp setrlimit) - -AC_FUNC_SETPGRP - -dnl HPUX needs _KERNEL defined to pick up RLIMIT_foo defines. (Why?) -AC_CACHE_CHECK(if _KERNEL is required for RLIMIT defines, rc_cv_kernel_rlimit, - AC_TRY_COMPILE([ -#include <sys/types.h> -#include <sys/resource.h> - ], [ -int f; -f = RLIMIT_DATA; - ], rc_cv_kernel_rlimit=no, [ AC_TRY_COMPILE([ -#include <sys/types.h> -#define _KERNEL -#include <sys/resource.h> -#undef _KERNEL - ], [ -int f; -f = RLIMIT_DATA; - ], rc_cv_kernel_rlimit=yes, rc_cv_kernel_rlimit=no)])) -case "x$rc_cv_kernel_rlimit" in -xyes) - AC_DEFINE(RLIMIT_NEEDS_KERNEL) - ;; -esac - -dnl Look for rlim_t in sys/types.h and sys/resource.h -AC_CACHE_CHECK(for rlim_t, rc_cv_have_rlim_t, - AC_EGREP_CPP(rlim_t, [ -#include <sys/types.h> -#if RLIMIT_NEEDS_KERNEL -#define _KERNEL -#endif -#include <sys/resource.h> - ], rc_cv_have_rlim_t=yes, rc_cv_have_rlim_t=no)) - -case "x$rc_cv_have_rlim_t" in -xyes) - AC_DEFINE(HAVE_RLIM_T) - ;; -xno) - AC_CACHE_CHECK(for native quad_t, rc_cv_have_quad_t, - AC_TRY_RUN([ -#include <sys/types.h> -main() { - quad_t q; - q = 0; - exit((int) q); -} - ], rc_cv_have_quad_t=yes, rc_cv_have_quad_t=no)) - - case "x$rc_cv_have_quad_t" in - xyes) - AC_DEFINE(HAVE_QUAD_T) - - AC_CACHE_CHECK(if rlimit values are quad_t, rc_cv_rlim_t_is_quad_t, - AC_TRY_RUN([ -#include <sys/types.h> -#include <sys/time.h> -#include <sys/types.h> -#if RLIMIT_NEEDS_KERNEL -#define _KERNEL -#endif -#include <sys/resource.h> -#if RLIMIT_NEEDS_KERNEL -#undef _KERNEL -#endif -main(){ - struct rlimit rl; - exit(sizeof rl.rlim_cur != sizeof(quad_t)); -} - ], rc_cv_rlim_t_is_quad_t=yes, rc_cv_rlim_t_is_quad_t=no, $ac_cv_type_quad_t)) - - case "x$rc_cv_rlim_t_is_quad_t" in - xyes) - AC_DEFINE(RLIM_T_IS_QUAD_T) - ;; - esac - ;; - esac - ;; -esac - -AC_SYS_RESTARTABLE_SYSCALLS - -dnl Does the kernel handle `#! /interpreter'? -AC_SYS_INTERPRETER -case "x$ac_cv_sys_interpreter" in -xyes) - AC_DEFINE(HASH_BANG) - EXECVE='' - ;; -xno) - EXECVE=execve.o -esac -AC_SUBST(EXECVE) - -AC_CACHE_CHECK(for /dev/fd, rc_cv_sys_dev_fd, - if test -d /dev/fd && test -r /dev/fd/0; then - rc_cv_sys_dev_fd=yes - elif test -d /proc/self/fd && test -r /proc/self/fd/0; then - rc_cv_sys_dev_fd=odd - else - rc_cv_sys_dev_fd=no - fi) - -case "x$rc_cv_sys_dev_fd" in -xyes) - AC_DEFINE(HAVE_DEV_FD) - ;; -xodd) - AC_DEFINE(HAVE_PROC_SELF_FD) - ;; -xno) - AC_CACHE_CHECK(for named pipes, rc_cv_sys_fifo, - AC_DEFINE_UNQUOTED(TMPNAM, "/tmp/rc$$.0") - AC_TRY_RUN([ -#include <sys/types.h> -#include <sys/stat.h> - -main() { - exit(mknod(TMPNAM, S_IFIFO | 0666, 0) != 0); -} - ], rc_cv_sys_fifo=yes, rc_cv_sys_fifo=no, rc_cv_sys_fifo=no)) - case "x$rc_cv_sys_fifo" in - xyes) - AC_DEFINE(HAVE_FIFO) - ;; - esac -esac - -AC_ARG_ENABLE(builtin-echo, [ --disable-builtin-echo Don't include \`echo' as a builtin], - test "x$enableval" != "xno" && AC_DEFINE(RC_ECHO), - AC_DEFINE(RC_ECHO)) - -AC_ARG_ENABLE(job, [ --disable-job Don't do job-control-style backgrounding], - test "x$enableval" != "xno" && AC_DEFINE(RC_JOB), - AC_DEFINE(RC_JOB)) - -AC_ARG_ENABLE(protect-env, [ --disable-protect-env Don't protect environment names], - test "x$enableval" != "xno" && AC_DEFINE(PROTECT_ENV), - AC_DEFINE(PROTECT_ENV)) - -AC_ARG_ENABLE(def-interp, -[ --enable-def-interp=/bin/foo - Use /bin/foo as default interpreter [/bin/sh]], -[ - case "x$enableval" in - xno) - ;; - xyes) - AC_DEFINE(DEFAULTINTERP, "/bin/sh") - ;; - *) - AC_DEFINE_UNQUOTED(DEFAULTINTERP, "$enableval") - esac -], - AC_DEFINE(DEFAULTINTERP, "/bin/sh")) - -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 .)]], -[ - case "x$enableval" in - xno|xyes) - ;; - *) - AC_DEFINE_UNQUOTED(DEFAULTPATH, $enableval) - esac -], - enable_def_path=yes) - -case "x$enable_def_path" in -xyes) - 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 - if test -d $i; then - case "x$rc_cv_def_path" in - x) - rc_cv_def_path=\"$i\" - ;; - *) - rc_cv_def_path=$rc_cv_def_path,\"$i\" - ;; - esac - fi - done - AC_DEFINE_UNQUOTED(DEFAULTPATH, $rc_cv_def_path) - ]) - ;; -esac - -AC_ARG_ENABLE(history, [ --enable-history Build history subprograms], - test "x$enableval" != "xno" && rc_history=yes, - rc_history=no) -case "x$rc_history" in -xyes) - HISTORY=history/history - ;; -esac -AC_SUBST(HISTORY) - -AC_ARG_WITH(addon, [ --with-addon Extra builtins, from addon.c ],[ - case "x$withval" in - xyes) - ADDON=addon.o - ;; - xno) - ADDON='' - ;; - *) - ADDON=$withval - ;; - esac - ]) -AC_SUBST(ADDON) - -AC_ARG_WITH(editline, [ --with-editline Simmule Turner's line editing], - AC_CHECK_LIB(edit, readline, - AC_DEFINE(READLINE) LIBS="$LIBS -ledit", - AC_MSG_WARN(editline library not found))) - -AC_ARG_WITH(readline, [ --with-readline Bloated GNU line editing], - AC_CHECK_LIB(readline, readline, - AC_DEFINE(READLINE) LIBS="$LIBS -lreadline -ltermcap", - AC_MSG_WARN(readline library not found))) - -AC_OUTPUT(Makefile) diff --git a/cpp b/cpp @@ -1,38 +0,0 @@ -#!/bin/sh - -# @(#) cpp.sh 1.3 92/01/15 21:53:22 - -# Unprototypeing preprocessor for pre-ANSI C compilers. On some systems, -# this script can be as simple as: -# -# /lib/cpp "$@" | unproto -# -# However, some cc(1) drivers specify output file names on the -# preprocessor command line, so this shell script must be prepared to -# intercept them. Depending on the driver program, the cpp options may -# even go before or after the file name argument(s). The script below -# tries to tackle all these cases. -# -# You may want to add -Ipath_to_stdarg.h_file, -Dvoid=, -Dvolatile=, -# and even -D__STDC__. - -## (This is what I used while testing with the SunOS C compiler. -## Also, I added "-Qpath ." to CFLAGS so that cpp would be -## run out of the current directory. --- Byron) -cpp_args="-I/u/byron/lib/sun4 -Dconst= -Dvolatile=" - -while : -do - case $1 in - "") break;; - -*) cpp_args="$cpp_args $1";; - *) cpp_args="$cpp_args $1" - case $2 in - ""|-*) ;; - *) exec 1> $2 || exit 1; shift;; - esac;; - esac - shift -done - -/lib/cpp $cpp_args | unproto diff --git a/except.c b/except.c @@ -91,7 +91,7 @@ extern void rc_raise(ecodes e) { interactive = estack->interactive; estack = estack->prev; - longjmp(j->j, 1); + siglongjmp(j->j, 1); } } rc_exit(1); /* top of exception stack */ @@ -120,7 +120,7 @@ extern void pop_cmdarg(bool remove) { /* exception handlers */ extern void rc_error(char *s) { - pr_error(s); + pr_error(s, -1); set(FALSE); redirq = NULL; cond = FALSE; /* no longer inside conditional */ diff --git a/exec.c b/exec.c @@ -1,10 +1,9 @@ /* exec.c */ -#include <signal.h> #include <errno.h> -#include <setjmp.h> -#include "rc.h" -#include "jbwrap.h" +#include <signal.h> +#include "rc.h" +#include "wait.h" /* Takes an argument list and does the appropriate thing (calls a builtin, calls a function, etc.) @@ -92,11 +91,7 @@ extern void exec(List *s, bool parent) { return; rc_exit(getstatus()); } -#if HASH_BANG - execve(path, (char * const *) av, (char * const *) ev); -#else - my_execve(path, (char * const *) av, (char * const *) ev); /* bogus, huh? */ -#endif + rc_execve(path, (char * const *) av, (char * const *) ev); #ifdef DEFAULTINTERP if (errno == ENOEXEC) { @@ -105,6 +100,7 @@ extern void exec(List *s, bool parent) { execve(*av, (char * const *) av, (char * const *) ev); } #endif + uerror(*av); rc_exit(1); /* NOTREACHED */ @@ -123,7 +119,7 @@ extern void exec(List *s, bool parent) { prompt, even though there's a SIGINT in its signal vector. */ - if ((stat & 0xff) == 0) + if (WIFEXITED(stat)) nl_on_intr = FALSE; sigchk(); nl_on_intr = TRUE; diff --git a/execve.c b/execve.c @@ -1,8 +1,8 @@ /* execve.c: an execve() for geriatric unices without #! */ /* - NOTE: this file depends on a hack in footobar.c which places two free spots before - av[][] so that execve does not have to call malloc. + NOTE: this file depends on a hack in footobar.c which places two free + spots before av[][] so that execve does not have to call malloc. */ #include <errno.h> @@ -10,7 +10,7 @@ #define giveupif(x) { if (x) goto fail; } -extern int my_execve(const char *path, const char **av, const char **ev) { +extern int rc_execve(char *path, char **av, char **ev) { int fd, len, fst, snd, end; bool noarg; char pb[256]; /* arbitrary but generous limit */ diff --git a/fn.c b/fn.c @@ -26,7 +26,7 @@ extern void inithandler() { null.type = nBody; null.u[0].p = null.u[1].p = NULL; for (i = 1; i < NUMOFSIGNALS; i++) -#ifndef HAVE_RESTARTABLE_SYSCALLS +#if HAVE_SYSV_SIGCLD if (i != SIGCLD) #endif if (sighandlers[i] == SIG_IGN) @@ -133,7 +133,7 @@ static void fn_handler(int s) { /* A dud signal handler for SIGQUIT and SIGTERM */ -static void dud_handler(int s) { +static void dud_handler(int ignore) { } /* @@ -143,12 +143,12 @@ static void dud_handler(int s) { extern void fnassign(char *name, Node *def) { Node *newdef = treecpy(def == NULL ? &null : def, ealloc); /* important to do the treecopy first */ - Function *new = get_fn_place(name); + rc_Function *new = get_fn_place(name); int i; new->def = newdef; new->extdef = NULL; if (strncmp(name, "sig", conststrlen("sig")) == 0) { /* slight optimization */ -#ifndef HAVE_RESTARTABLE_SYSCALLS /* System V machines treat SIGCLD very specially */ +#if HAVE_SYSV_SIGCLD /* System V machines treat SIGCLD very specially */ if (streq(name, "sigcld")) rc_error("can't trap SIGCLD"); #endif @@ -170,7 +170,7 @@ extern void fnassign(char *name, Node *def) { extern void fnassign_string(char *extdef) { char *name = get_name(extdef+3); /* +3 to skip over "fn_" */ - Function *new; + rc_Function *new; if (name == NULL) return; new = get_fn_place(name); @@ -181,7 +181,7 @@ extern void fnassign_string(char *extdef) { /* Return a function in Node form, evaluating an entry from the environment if necessary */ extern Node *fnlookup(char *name) { - Function *look = lookup_fn(name); + rc_Function *look = lookup_fn(name); Node *ret; if (look == NULL) return NULL; /* not found */ @@ -189,7 +189,7 @@ extern Node *fnlookup(char *name) { return look->def; if (look->extdef == NULL) /* function was set to null, e.g., fn foo {} */ return &null; - ret = parse_fn(name, look->extdef); + ret = parse_fn(look->extdef); if (ret == NULL) { efree(look->extdef); look->extdef = NULL; @@ -202,7 +202,7 @@ extern Node *fnlookup(char *name) { /* Return a function in string form (used by makeenv) */ extern char *fnlookup_string(char *name) { - Function *look = lookup_fn(name); + rc_Function *look = lookup_fn(name); if (look == NULL) return NULL; @@ -243,13 +243,14 @@ extern void fnrm(char *name) { extern void whatare_all_signals() { int i; for (i = 1; i < NUMOFSIGNALS; i++) - if (*signals[i].name != '\0') + if (*signals[i].name != '\0') { if (sighandlers[i] == SIG_IGN) fprint(1, "fn %s {}\n", signals[i].name); else if (sighandlers[i] == fn_handler) fprint(1, "fn %S {%T}\n", signals[i].name, handlers[i]); else fprint(1, "fn %s\n", signals[i].name); + } } extern void prettyprint_fn(int fd, char *name, Node *n) { diff --git a/footobar.c b/footobar.c @@ -39,7 +39,7 @@ static bool Dconv(Format *f, int ignore) { /* defaultfd -- return the default fd for a given redirection operation */ -extern int defaultfd(int op) { +static int defaultfd(int op) { return (op == rCreate || op == rAppend) ? 1 : 0; } @@ -221,7 +221,7 @@ extern char *get_name(char *s) { #define skipleft(p) do --p; while (*p != '\0' && *p != '\001'); -extern List *parse_var(char *name, char *extdef) { +extern List *parse_var(char *extdef) { char *endp, *realend, *sepp; List *tailp, *new; @@ -257,7 +257,7 @@ extern List *parse_var(char *name, char *extdef) { #define PREFIX "fn x" #define PRELEN conststrlen(PREFIX) -extern Node *parse_fn(char *name, char *extdef) { +extern Node *parse_fn(char *extdef) { Node *def; char *s, old[PRELEN]; if ((s = strchr(extdef, '=')) == NULL) @@ -269,7 +269,7 @@ extern Node *parse_fn(char *name, char *extdef) { return (def == NULL || def->type != nNewfn) ? NULL : def->u[1].p; } -static bool Aconv(Format *f, int c) { +static bool Aconv(Format *f, int ignore) { char **a = va_arg(f->args, char **); if (*a != NULL) { fmtcat(f, *a); @@ -279,7 +279,7 @@ static bool Aconv(Format *f, int c) { return FALSE; } -static bool Lconv(Format *f, int c) { +static bool Lconv(Format *f, int ignore) { List *l = va_arg(f->args, List *); char *sep = va_arg(f->args, char *); char *fmt = (f->flags & FMT_leftside) ? "%s%s" : "%-S%s"; diff --git a/getgroups.h b/getgroups.h @@ -0,0 +1,10 @@ +#if HAVE_GETGROUPS +#if HAVE_POSIX_GETGROUPS +/* We love POSIX. */ +#else +/* OK, so you've got getgroups, but you don't have the POSIX semantics +of a zero first argument. The conclusion is that you're on a reasonably +pure BSD system, and we can include <sys/param.h> for NGROUPS. */ +#include <sys/param.h> +#endif +#endif diff --git a/getopt.c b/getopt.c @@ -9,42 +9,43 @@ char *rc_optarg; extern int rc_getopt(int argc, char **argv, char *opts) { static int sp = 1; - int c; - char *cp; + int c; + char *cp; if (rc_optind == 0) /* reset rc_getopt() */ rc_optind = sp = 1; - if (sp == 1) - if (rc_optind >= argc || argv[rc_optind][0] != '-' || argv[rc_optind][1] == '\0') { - return -1; - } else if (strcmp(argv[rc_optind], "--") == 0) { - rc_optind++; - return -1; - } - rc_optopt = c = argv[rc_optind][sp]; - if (c == ':' || (cp=strchr(opts, c)) == 0) { - fprint(2, "%s: bad option: -%c\n", argv[0], c); - if (argv[rc_optind][++sp] == '\0') { - rc_optind++; - sp = 1; - } - return '?'; - } - if (*++cp == ':') { - if (argv[rc_optind][sp+1] != '\0') { - rc_optarg = &argv[rc_optind++][sp+1]; - } else if (++rc_optind >= argc) { - fprint(2, "%s: option requires an argument -- %c\n", argv[0], c); - sp = 1; - return '?'; - } else - rc_optarg = argv[rc_optind++]; - sp = 1; - } else { - if (argv[rc_optind][++sp] == '\0') { - sp = 1; - rc_optind++; - } - rc_optarg = NULL; - } - return c; + if (sp == 1) { + if (rc_optind >= argc || argv[rc_optind][0] != '-' || argv[rc_optind][1] == '\0') { + return -1; + } else if (strcmp(argv[rc_optind], "--") == 0) { + rc_optind++; + return -1; + } + } + rc_optopt = c = argv[rc_optind][sp]; + if (c == ':' || (cp=strchr(opts, c)) == 0) { + fprint(2, "%s: bad option: -%c\n", argv[0], c); + if (argv[rc_optind][++sp] == '\0') { + rc_optind++; + sp = 1; + } + return '?'; + } + if (*++cp == ':') { + if (argv[rc_optind][sp+1] != '\0') { + rc_optarg = &argv[rc_optind++][sp+1]; + } else if (++rc_optind >= argc) { + fprint(2, "%s: option requires an argument -- %c\n", argv[0], c); + sp = 1; + return '?'; + } else + rc_optarg = argv[rc_optind++]; + sp = 1; + } else { + if (argv[rc_optind][++sp] == '\0') { + sp = 1; + rc_optind++; + } + rc_optarg = NULL; + } + return c; } diff --git a/glob.c b/glob.c @@ -1,8 +1,7 @@ /* glob.c: rc's (ugly) globber. This code is not elegant, but it works */ -#include <sys/types.h> -#include <sys/stat.h> #include "rc.h" +#include <sys/stat.h> /* Lifted from autoconf documentation.*/ #if HAVE_DIRENT_H diff --git a/glom.c b/glom.c @@ -1,10 +1,10 @@ /* glom.c: builds an argument list out of words, variables, etc. */ -#include <sys/types.h> +#include "rc.h" + #include <sys/stat.h> #include <signal.h> #include <errno.h> -#include "rc.h" static List *backq(Node *, Node *); static List *bqinput(List *, int); @@ -324,6 +324,12 @@ static List *mkcmdarg(Node *n) { #elif HAVE_FIFO +#if HAVE_MKFIFO +/* Have POSIX mkfifo(). */ +#else +#define mkfifo(n,m) mknod(n, S_IFIFO | m, 0) +#endif + static List *mkcmdarg(Node *n) { int fd; char *name; @@ -331,9 +337,10 @@ static List *mkcmdarg(Node *n) { Estack *e = enew(Estack); List *ret = nnew(List); static int fifonumber = 0; + name = nprint("/tmp/rc%d.%d", getpid(), fifonumber++); - if (mknod(name, S_IFIFO | 0666, 0) < 0) { - uerror("mknod"); + if (mkfifo(name, 0666) < 0) { + uerror("mkfifo"); return NULL; } if (rc_fork() == 0) { @@ -360,7 +367,7 @@ static List *mkcmdarg(Node *n) { #else static List *mkcmdarg(Node *n) { - rc_error("named pipes are not supported"); + rc_error("command arguments are not supported"); return NULL; } diff --git a/group.h b/group.h @@ -1,9 +0,0 @@ -/* Solaris / `gcc -ansi' only defines NGROUPS_MAX in <limits.h> if -_POSIX_C_SOURCE is defined. */ -#define _POSIX_C_SOURCE 1 -#include <limits.h> -#undef _POSIX_C_SOURCE - -#if defined(NGROUPS) && !defined(NGROUPS_MAX) -#define NGROUPS_MAX NGROUPS -#endif diff --git a/hash.c b/hash.c @@ -15,7 +15,7 @@ static bool var_exportable(char *); static bool fn_exportable(char *); static int hash(char *, int); static int find(char *, Htab *, int); -static void free_fn(Function *); +static void free_fn(rc_Function *); Htab *fp; Htab *vp; @@ -118,7 +118,7 @@ extern void *lookup(char *s, Htab *ht) { return (ht[h].name == NULL) ? NULL : ht[h].p; } -extern Function *get_fn_place(char *s) { +extern rc_Function *get_fn_place(char *s) { int h = fnfind(s); env_dirty = TRUE; if (fp[h].name == NULL) { @@ -126,7 +126,7 @@ extern Function *get_fn_place(char *s) { h = fnfind(s); fused++; fp[h].name = ecpy(s); - fp[h].p = enew(Function); + fp[h].p = enew(rc_Function); } else free_fn(fp[h].p); return fp[h].p; @@ -205,7 +205,7 @@ extern void delete_var(char *s, bool stack) { } } -static void free_fn(Function *f) { +static void free_fn(rc_Function *f) { treefree(f->def); efree(f->extdef); } @@ -294,7 +294,7 @@ extern void whatare_all_vars(bool showfn, bool showvar) { /* fake getenv() for readline() follows: */ -#if READLINE +#if EDITLINE || READLINE extern char *getenv(const char *name) { List *s; if (name == NULL || vp == NULL || (s = varlookup((char *) name)) == NULL) diff --git a/history.1 b/history.1 @@ -0,0 +1,243 @@ +.\" history.1 +.\"------- +.\" See rc.1 for man page portability notes. +.\"------- +.\" Dd distance to space vertically before a "display" +.\" These are what n/troff use for interparagraph distance +.\"------- +.if t .nr Dd .4v +.if n .nr Dd 1v +.\"------- +.\" Ds begin a display, indented .5 inches from the surrounding text. +.\" +.\" Note that uses of Ds and De may NOT be nested. +.\"------- +.de Ds +.\" .RS \\$1 +.sp \\n(Ddu +.in +0.5i +.nf +.. +.\"------- +.\" De end a display (no trailing vertical spacing) +.\"------- +.de De +.fi +.in +.\" .RE +.. +.\"------- +.\" I stole the Xf macro from the -man macros on my machine (originally +.\" "}S", I renamed it so that it won't conflict). +.\"------- +.\" Set Cf to the name of the constant width font. +.\" It will be "C" or "(CW", typically. +.\" NOTEZ BIEN the lines defining Cf must have no trailing white space: +.\"------- +.if t .ds Cf C +.if n .ds Cf R +.\"------- +.\" Rc - Alternate Roman and Courier +.\"------- +.de Rc +.Xf R \\*(Cf \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" +.. +.\"------- +.\" Ic - Alternate Italic and Courier +.\"------- +.de Ic +.Xf I \\*(Cf \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" +.. +.\"------- +.\" Bc - Alternate Bold and Courier +.\"------- +.de Bc +.Xf B \\*(Cf \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" +.. +.\"------- +.\" Cr - Alternate Courier and Roman +.\"------- +.de Cr +.Xf \\*(Cf R \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" +.. +.\"------- +.\" Ci - Alternate Courier and Italic +.\"------- +.de Ci +.Xf \\*(Cf I \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" +.. +.\"------- +.\" Cb - Alternate Courier and Bold +.\"------- +.de Cb +.Xf \\*(Cf B \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" +.. +.\"------- +.\" Xf - Alternate fonts +.\" +.\" \$1 - first font +.\" \$2 - second font +.\" \$3 - desired word with embedded font changes, built up by recursion +.\" \$4 - text for first font +.\" \$5 - \$9 - remaining args +.\" +.\" Every time we are called: +.\" +.\" If there is something in \$4 +.\" then Call ourself with the fonts switched, +.\" with a new word made of the current word (\$3) and \$4 +.\" rendered in the first font, +.\" and with the remaining args following \$4. +.\" else We are done recursing. \$3 holds the desired output +.\" word. We emit \$3, change to Roman font, and restore +.\" the point size to the default. +.\" fi +.\" +.\" Use Xi to add a little bit of space after italic text. +.\"------- +.de Xf +.ds Xi +.\"------- +.\" I used to test for the italic font both by its font position +.\" and its name. Now just test by its name. +.\" +.\" .if "\\$1"2" .if !"\\$5"" .ds Xi \^ +.\"------- +.if "\\$1"I" .if !"\\$5"" .ds Xi \^ +.\"------- +.\" This is my original code to deal with the recursion. +.\" Evidently some nroffs can't deal with it. +.\"------- +.\" .ie !"\\$4"" \{\ +.\" . Xf \\$2 \\$1 "\\$3\\f\\$1\\$4\\*(Xi" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9" +.\" .\} +.\" .el \{\\$3 +.\" . ft R \" Restore the default font, since we don't know +.\" . \" what the last font change was. +.\" . ps 10 \" Restore the default point size, since it might +.\" . \" have been changed by an argument to this macro. +.\" .\} +.\"------- +.\" Here is more portable (though less pretty) code to deal with +.\" the recursion. +.\"------- +.if !"\\$4"" .Xf \\$2 \\$1 "\\$3\\f\\$1\\$4\\*(Xi" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9" +.if "\\$4"" \\$3\fR\s10 +.. +.TH HISTORY 1 "30 July 1991" +.SH NAME +\-, \-\|\-, \-p, \-\|\-p \- shell history programs +.SH SYNOPSIS +.B \- +.RI [ pattern ...] +.RI [ substitution ...] +.SH DESCRIPTION +This set of programs provides a crude history mechanism for the shell +.IR rc (1). +It is based on the v8 UNIX programs +.IR = , +.IR == , +etc. +.PP +The program +.RI `` \- '' +runs the shell on the command it is requested to find. +The program +.RI `` \-\|\- '' +edits that command first. +The programs +.RI `` \-p '' +and +.RI `` \-\|\-p '' +are similar, except that they print the final command on their standard +output instead of running the shell. +.PP +The commands work by looking for a file +named by the environment variable +.Cr $history , +and by searching for previous commands in this file. +Old commands can be edited, +or simply re-executed according to the rules below: +.PP +A command is searched for by examining the lines in +.Cr $history +in reverse order. +Lines which contain a previous invocation of the history +program itself are ignored. +If one or more +.I pattern +is supplied on the command line, +then the patterns are used as a means of +limiting the search. +Patterns match any substring of a previous command, +and if more than one pattern is present then all patterns must be +matched before a command is selected. +.PP +Substitutions may also be specified on the command line. +These have the syntax: +.Ds +.Ic old : new +.De +.PP +(Note that the +.I old +pattern is used as a search-limiting pattern also.) +Substitutions happen on the first match. +.PP +Finally, if the program was invoked as +.RI `` -- '' +or +.RI `` --p '', +a command may be edited in a crude line-mode fashion. The line to be +edited is printed out, and below it the user supplies modifications to +the command. +.TP +.B any character except those below +Replaces the character above. +.TP +.B space or tab +Skips over the above character(s). +.TP +.B # +Deletes one character. +.TP +.B % +Replaces one character with a space. +.TP +.B ^ +Inserts the rest of the typed line just before the character. +.TP +.B $ +Deletes the rest of the line from that character on, and replaces +it with the rest of the typed line. +.TP +.B + +Appends the rest of the typed line. +.TP +.B \- +Backs up to a previous command satisfying the same matching +constraints. +.TP +.B end of line +If any changes have been made, the command is printed out again for +further editing. If no changes have been made, the command is executed +or printed, and the program exits. +.TP +.B end of file +If an end-of-file is read from the keyboard by the editor, +it aborts with exit status 1 and does not produce any output. +.SH EXAMPLES +The history programs work best when their output is reinterpreted by +the shell using an +.Cr eval +command. +This can be achieved by writing a shell function to perform the +reinterpretation: +.Ds +.Cr "fn - -- {" +.Cr " comm = \`{$0^p $*}" +.Cr " if (! ~ $#comm 0) {" +.Cr " echo $comm >[1=2]" +.Cr " eval $comm" +.Cr " }" +.Cr "}" diff --git a/history.c b/history.c @@ -0,0 +1,339 @@ +/* + history.c -- primitive history mechanism + + Paul Haahr & Byron Rakitzis, July 1991. + + This program mimics the att v8 = and == history programs. + The edit() algorithm was adapted from a similar program + that Boyd Roberts wrote, but otherwise all the code has + been written from scratch. + + edit() was subsequently redone by Hugh Redelmeier in order + to correctly deal with tab characters in the source line. + + BUGS: + There is an implicit assumption that commands are no + more than 1k characters long. +*/ + +#include "rc.h" + +#include <stdio.h> + +static const char id[] = "$Release: @(#)" PACKAGE " " VERSION " " RELDATE " $"; + +#define CHUNKSIZE 65536 + +static struct { + char *old, *new; +} *replace; + +static char **search, *progname, *history; +static char me; /* typically ':' or '-' */ +static bool editit = FALSE, printit = FALSE; +static int nreplace = 0, nsearch = 0; +static FILE *histfile; + +void *ealloc(size_t n) { + void *p = (void *) malloc(n); + if (p == NULL) { + perror("malloc"); + exit(1); + } + return p; +} + +void *erealloc(void *p, size_t n) { + p = (void *) realloc(p, n); + if (p == NULL) { + perror("realloc"); + exit(1); + } + return p; +} + +static char *newstr() { + return ealloc((size_t)1024); +} + +static char *rc_basename(char *s) { + char *t = strrchr(s, '/'); + return (t == NULL) ? s : t + 1; +} + +/* stupid O(n^2) substring matching routine */ + +static char *isin(char *target, char *pattern) { + size_t plen = strlen(pattern); + size_t tlen = strlen(target); + for (; tlen >= plen; target++, --tlen) + if (strncmp(target, pattern, plen) == 0) + return target; + return NULL; +} + +/* replace the first match in the string with "new" */ +static char *sub(char *s, char *old, char *new) { + char *t, *u; + + t = isin(s, old); + u = newstr(); + + *t = '\0'; + while (*old != '\0') + old++, t++; + strcpy(u, s); + strcat(u, new); + strcat(u, t); + return u; +} + +static char *edit(char *s) { + char *final, *f, *end; + int col; + bool ins; + +start: + fprintf(stderr, "%s\n", s); + f = final = newstr(); + end = s + strlen(s); + col = 0; + ins = FALSE; + + for (;; col++) { + int c = getchar(); + + if (c == me && col == 0) { + int peekc = getchar(); + if (peekc == '\n') + return NULL; + ungetc(peekc, stdin); + } + if (c == '\n') { + if (col == 0) + return s; + + while (s < end) /* copy remainder of string */ + *f++ = *s++; + *f = '\0'; + s = final; + goto start; + } else if (ins || s>=end) { + /* col need not be accurate -- tabs need not be interpreted */ + *f++ = c; + } else { + switch (c) { + case '+': + while (s < end) + *f++ = *s++; + *f = '\0'; + continue; + case '%': + c = ' '; + /* FALLTHROUGH */ + default: + *f++ = c; + break; + case EOF: + exit(1); + /* NOTREACHED */ + case ' ': + if (*s == '\t') { + int oldcol = col; + + for (;; col++) { + int peekc; + + if ((col&07) == 07) { + *f++ = '\t'; /* we spaced past a tab */ + break; + } + peekc = getchar(); + if (peekc != ' ') { + ungetc(peekc, stdin); + if (peekc != '\n') { + /* we spaced partially into a tab */ + do { + *f++ = ' '; + oldcol++; + } while (oldcol <= col); + } + break; + } + } + } else { + *f++ = *s; + } + break; + case '#': + break; + case '$': + end = s; /* truncate s */ + continue; /* skip incrementing s */ + case '^': + ins = TRUE; + continue; /* skip incrementing s */ + case '\t': + for (;; col++) { + *f = s<end? *s++ : '\t'; + if (*f++ == '\t') { + col = col | 07; /* advance to before next tabstop */ + } + if ((col&07) == 07) /* stop before tabstop */ + break; + } + continue; /* skip incrementing s */ + } + if (s<end && (*s!='\t' || (col&07)==07)) + s++; + } + } +} + +static char *readhistoryfile(char **last) { + char *buf; + size_t count, size; + long nread; + + if ((history = getenv("history")) == NULL) { + fprintf(stderr, "$history not set\n"); + exit(1); + } + histfile = fopen(history, "r+"); + if (histfile == NULL) { + perror(history); + exit(1); + } + + size = 0; + count = 0; + buf = ealloc(size = CHUNKSIZE); + while ((nread = fread(buf + count, sizeof (char), size - count, histfile)) > 0) { + count += nread; + if (size - count == 0) + buf = erealloc(buf, size *= 4); + } + if (nread == -1) { + perror(history); + exit(1); + } + *last = buf + count; + return buf; +} + +static char *getcommand() { + char *s, *t; + static char *hist = NULL, *last; + + if (hist == NULL) { + hist = readhistoryfile(&last); + *--last = '\0'; /* trim final newline */ + } + +again: s = last; + if (s < hist) + return NULL; + while (*--s != '\n') + if (s <= hist) { + last = hist - 1; + return hist; + } + *s = '\0'; + last = s++; + + /* + * if the command contains the "me" character at the start of the line + * or after any of [`{|()@] then try again + */ + + for (t = s; *t != '\0'; t++) + if (*t == me) { + char *u = t - 1; + while (u >= s && (*u == ' ' || *u == '\t')) + --u; + if (u < s) + goto again; + switch (*u) { + case '`': case '@': + case '(': case ')': + case '{': case '|': + case '/': + goto again; + default: + break; + } + } + return s; +} + +int main(int argc, char **argv) { + int i; + char *s; + + s = progname = rc_basename(argv[0]); + me = *s++; + if (*s == me) { + s++; + editit = TRUE; + } + if (*s == 'p') { + s++; + printit = TRUE; + } +/* Nahh... + if (*s != '\0') { + fprintf(stderr, "\"%s\": bad name for history program\n", progname); + exit(1); + } +*/ + + if (argc > 1) { + replace = ealloc((argc - 1) * sizeof *replace); + search = ealloc((argc - 1) * sizeof *search); + } + for (i = 1; i < argc; i++) + if ((s = strchr(argv[i], ':')) == NULL) + search[nsearch++] = argv[i]; + else { + *(char *)s = '\0'; /* do we confuse ps too much? */ + replace[nreplace].old = argv[i]; + replace[nreplace].new = s + 1; + nreplace++; + } + +next: s = getcommand(); + if (s == NULL) { + fprintf(stderr, "command not matched\n"); + return 1; + } + for (i = 0; i < nsearch; i++) + if (!isin(s, search[i])) + goto next; + for (i = 0; i < nreplace; i++) + if (!isin(s, replace[i].old)) + goto next; + else + s = sub(s, replace[i].old, replace[i].new); + if (editit) { + s = edit(s); + if (s == NULL) + goto next; + } + fseek(histfile, 0, 2); /* 2 == end of file. i.e., append command to $history */ + fprintf(histfile, "%s\n", s); + fclose(histfile); + if (printit) + printf("%s\n", s); + else { + char *shell = getenv("SHELL"); + + if (!editit) + fprintf(stderr, "%s\n", s); + if (shell == NULL) + shell = "/bin/sh"; + execl(shell, rc_basename(shell), "-c", s, NULL); + perror(shell); + exit(1); + } + return 0; +} diff --git a/history/history.1 b/history/history.1 @@ -1,234 +0,0 @@ -.\" history.1 -.\"------- -.\" See rc.1 for man page portability notes. -.\"------- -.\" Dd distance to space vertically before a "display" -.\" These are what n/troff use for interparagraph distance -.\"------- -.if t .nr Dd .4v -.if n .nr Dd 1v -.\"------- -.\" Ds begin a display, indented .5 inches from the surrounding text. -.\" -.\" Note that uses of Ds and De may NOT be nested. -.\"------- -.de Ds -.\" .RS \\$1 -.sp \\n(Ddu -.in +0.5i -.nf -.. -.\"------- -.\" De end a display (no trailing vertical spacing) -.\"------- -.de De -.fi -.in -.\" .RE -.. -.\"------- -.\" I stole the Xf macro from the -man macros on my machine (originally -.\" "}S", I renamed it so that it won't conflict). -.\"------- -.\" Set Cf to the name of the constant width font. -.\" It will be "C" or "(CW", typically. -.\" NOTEZ BIEN the lines defining Cf must have no trailing white space: -.\"------- -.if t .ds Cf C -.if n .ds Cf R -.\"------- -.\" Rc - Alternate Roman and Courier -.\"------- -.de Rc -.Xf R \\*(Cf \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" -.. -.\"------- -.\" Ic - Alternate Italic and Courier -.\"------- -.de Ic -.Xf I \\*(Cf \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" -.. -.\"------- -.\" Bc - Alternate Bold and Courier -.\"------- -.de Bc -.Xf B \\*(Cf \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" -.. -.\"------- -.\" Cr - Alternate Courier and Roman -.\"------- -.de Cr -.Xf \\*(Cf R \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" -.. -.\"------- -.\" Ci - Alternate Courier and Italic -.\"------- -.de Ci -.Xf \\*(Cf I \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" -.. -.\"------- -.\" Cb - Alternate Courier and Bold -.\"------- -.de Cb -.Xf \\*(Cf B \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" -.. -.\"------- -.\" Xf - Alternate fonts -.\" -.\" \$1 - first font -.\" \$2 - second font -.\" \$3 - desired word with embedded font changes, built up by recursion -.\" \$4 - text for first font -.\" \$5 - \$9 - remaining args -.\" -.\" Every time we are called: -.\" -.\" If there is something in \$4 -.\" then Call ourself with the fonts switched, -.\" with a new word made of the current word (\$3) and \$4 -.\" rendered in the first font, -.\" and with the remaining args following \$4. -.\" else We are done recursing. \$3 holds the desired output -.\" word. We emit \$3, change to Roman font, and restore -.\" the point size to the default. -.\" fi -.\" -.\" Use Xi to add a little bit of space after italic text. -.\"------- -.de Xf -.ds Xi -.\"------- -.\" I used to test for the italic font both by its font position -.\" and its name. Now just test by its name. -.\" -.\" .if "\\$1"2" .if !"\\$5"" .ds Xi \^ -.\"------- -.if "\\$1"I" .if !"\\$5"" .ds Xi \^ -.\"------- -.\" This is my original code to deal with the recursion. -.\" Evidently some nroffs can't deal with it. -.\"------- -.\" .ie !"\\$4"" \{\ -.\" . Xf \\$2 \\$1 "\\$3\\f\\$1\\$4\\*(Xi" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9" -.\" .\} -.\" .el \{\\$3 -.\" . ft R \" Restore the default font, since we don't know -.\" . \" what the last font change was. -.\" . ps 10 \" Restore the default point size, since it might -.\" . \" have been changed by an argument to this macro. -.\" .\} -.\"------- -.\" Here is more portable (though less pretty) code to deal with -.\" the recursion. -.\"------- -.if !"\\$4"" .Xf \\$2 \\$1 "\\$3\\f\\$1\\$4\\*(Xi" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9" -.if "\\$4"" \\$3\fR\s10 -.. -.TH HISTORY 1 "30 July 1991" -.SH NAME -\-, \-\|\-, \-p, \-\|\-p \- shell history programs -.SH SYNOPSIS -.B \- -.RI [ pattern ...] -.RI [ substitution ...] -.SH DESCRIPTION -This set of programs provides a crude history mechanism for the shell -.IR rc (1). -It is based on the v8 UNIX programs -.IR = , -.IR == , -etc. -.PP -The program -.RI `` \- '' -runs the shell on the command it is requested to find. -The program -.RI `` \-\|\- '' -edits that command first. -The programs -.RI `` \-p '' -and -.RI `` \-\|\-p '' -are similar, except that they print the final command on their standard -output instead of running the shell. -.PP -The commands work by looking for a file -named by the environment variable -.Cr $history , -and by searching for previous commands in this file. -Old commands can be edited, -or simply re-executed according to the rules below: -.PP -A command is searched for by examining the lines in -.Cr $history -in reverse order. -Lines which contain a previous invocation of the history -program itself are ignored. -If one or more -.I pattern -is supplied on the command line, -then the patterns are used as a means of -limiting the search. -Patterns match any substring of a previous command, -and if more than one pattern is present then all patterns must be -matched before a command is selected. -.PP -Substitutions may also be specified on the command line. -These have the syntax: -.Ds -.Ic old : new -.De -.PP -(Note that the -.I old -pattern is used as a search-limiting pattern also.) -Substitutions happen on the first match. -.PP -Finally, a command may be edited in a crude line-mode fashion: -The line to be edited is printed out, and below it the user -supplies modifications to the command: -.TP -.B any character -Replaces the character above. -.TP -.B space or tab -Skips over the above character(s). -.TP -.B # -Deletes one character. -.TP -.B % -Replaces one character with a space. -.TP -.B ^ -Inserts the rest of the typed line just before the character. -.TP -.B $ -Deletes the rest of the line from that character on, and replaces -it with the rest of the typed line. -.TP -.B + -Appends the rest of the typed line. -.TP -.B \- -Backs up to a previous command satisfying the same matching -constraints. -.TP -.B end of file -If an end-of-file is read from the keyboard by the editor, -it aborts with exit status 1 and does not produce any output. -.SH EXAMPLES -The history programs work best when their output is reinterpreted by -the shell using an -.Cr eval -command. -This can be achieved by writing a shell function to perform the -reinterpretation: -.Ds -.Cr "fn - -- {" -.Cr " comm = \`{$0^p $*}" -.Cr " if (! ~ $#comm 0) {" -.Cr " echo $comm >[1=2]" -.Cr " eval $comm" -.Cr " }" -.Cr "}" diff --git a/history/history.c b/history/history.c @@ -1,341 +0,0 @@ -/* - history.c -- primitive history mechanism - - Paul Haahr & Byron Rakitzis, July 1991. - - This program mimics the att v8 = and == history programs. - The edit() algorithm was adapted from a similar program - that Boyd Roberts wrote, but otherwise all the code has - been written from scratch. - - edit() was subsequently redone by Hugh Redelmeier in order - to correctly deal with tab characters in the source line. - - BUGS: - There is an implicit assumption that commands are no - more than 1k characters long. -*/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -static char *id = "@(#) history.c 8/91"; - -#undef FALSE -#undef TRUE -typedef enum { FALSE, TRUE } bool; - -#define CHUNKSIZE 65536 - -static struct { - char *old, *new; -} *replace; - -static char **search, *progname, *history; -static char me; /* typically ':' or '-' */ -static bool editit = FALSE, printit = FALSE; -static int nreplace = 0, nsearch = 0; -static FILE *fp; - -static void *ealloc(size_t n) { - void *p = (void *) malloc(n); - if (p == NULL) { - perror("malloc"); - exit(1); - } - return p; -} - -static void *erealloc(void *p, size_t n) { - p = (void *) realloc(p, n); - if (p == NULL) { - perror("realloc"); - exit(1); - } - return p; -} - -static char *newstr() { - return ealloc((size_t)1024); -} - -static char *basename(char *s) { - char *t = strrchr(s, '/'); - return (t == NULL) ? s : t + 1; -} - -/* stupid O(n^2) substring matching routine */ - -static char *isin(char *target, char *pattern) { - size_t plen = strlen(pattern); - size_t tlen = strlen(target); - for (; tlen >= plen; target++, --tlen) - if (strncmp(target, pattern, plen) == 0) - return target; - return NULL; -} - -/* replace the first match in the string with "new" */ -static char *sub(char *s, char *old, char *new) { - char *t, *u; - - t = isin(s, old); - u = newstr(); - - *t = '\0'; - while (*old != '\0') - old++, t++; - strcpy(u, s); - strcat(u, new); - strcat(u, t); - return u; -} - -static char *edit(char *s) { - char *final, *f, *end; - int col; - bool ins; - -start: - fprintf(stderr, "%s\n", s); - f = final = newstr(); - end = s + strlen(s); - col = 0; - ins = FALSE; - - for (;; col++) { - int c = getchar(); - - if (c == me && col == 0) { - int peekc = getchar(); - if (peekc == '\n') - return NULL; - ungetc(peekc, stdin); - } - if (c == '\n') { - if (col == 0) - return s; - - while (s < end) /* copy remainder of string */ - *f++ = *s++; - *f = '\0'; - s = final; - goto start; - } else if (ins || s>=end) { - /* col need not be accurate -- tabs need not be interpreted */ - *f++ = c; - } else { - switch (c) { - case '+': - while (s < end) - *f++ = *s++; - *f = '\0'; - continue; - case '%': - c = ' '; - /* FALLTHROUGH */ - default: - *f++ = c; - break; - case EOF: - exit(1); - /* NOTREACHED */ - case ' ': - if (*s == '\t') { - int oldcol = col; - - for (;; col++) { - int peekc; - - if ((col&07) == 07) { - *f++ = '\t'; /* we spaced past a tab */ - break; - } - peekc = getchar(); - if (peekc != ' ') { - ungetc(peekc, stdin); - if (peekc != '\n') { - /* we spaced partially into a tab */ - do { - *f++ = ' '; - oldcol++; - } while (oldcol <= col); - } - break; - } - } - } else { - *f++ = *s; - } - break; - case '#': - break; - case '$': - end = s; /* truncate s */ - continue; /* skip incrementing s */ - case '^': - ins = TRUE; - continue; /* skip incrementing s */ - case '\t': - for (;; col++) { - if ((*f++ = s<end? *s++ : '\t') == '\t') { - col = col | 07; /* advance to before next tabstop */ - } - if ((col&07) == 07) /* stop before tabstop */ - break; - } - continue; /* skip incrementing s */ - } - if (s<end && (*s!='\t' || (col&07)==07)) - s++; - } - } -} - -static char *readhistoryfile(char **last) { - char *buf; - size_t count, size; - long nread; - - if ((history = getenv("history")) == NULL) { - fprintf(stderr, "$history not set\n"); - exit(1); - } - fp = fopen(history, "r+"); - if (fp == NULL) { - perror(history); - exit(1); - } - - size = 0; - count = 0; - buf = ealloc(size = CHUNKSIZE); - while ((nread = fread(buf + count, sizeof (char), size - count, fp)) > 0) { - count += nread; - if (size - count == 0) - buf = erealloc(buf, size *= 4); - } - if (nread == -1) { - perror(history); - exit(1); - } - *last = buf + count; - return buf; -} - -static char *getcommand() { - char *s, *t; - static char *hist = NULL, *last; - - if (hist == NULL) { - hist = readhistoryfile(&last); - *--last = '\0'; /* trim final newline */ - } - -again: s = last; - if (s < hist) - return NULL; - while (*--s != '\n') - if (s <= hist) { - last = hist - 1; - return hist; - } - *s = '\0'; - last = s++; - - /* - * if the command contains the "me" character at the start of the line - * or after any of [`{|()@] then try again - */ - - for (t = s; *t != '\0'; t++) - if (*t == me) { - char *u = t - 1; - while (u >= s && (*u == ' ' || *u == '\t')) - --u; - if (u < s) - goto again; - switch (*u) { - case '`': case '@': - case '(': case ')': - case '{': case '|': - goto again; - default: - break; - } - } - return s; -} - -int main(int argc, char **argv) { - int i; - char *s; - - s = progname = basename(argv[0]); - me = *s++; - if (*s == me) { - s++; - editit = TRUE; - } - if (*s == 'p') { - s++; - printit = TRUE; - } -/* Nahh... - if (*s != '\0') { - fprintf(stderr, "\"%s\": bad name for history program\n", progname); - exit(1); - } -*/ - - if (argc > 1) { - replace = ealloc((argc - 1) * sizeof *replace); - search = ealloc((argc - 1) * sizeof *search); - } - for (i = 1; i < argc; i++) - if ((s = strchr(argv[i], ':')) == NULL) - search[nsearch++] = argv[i]; - else { - *(char *)s = '\0'; /* do we confuse ps too much? */ - replace[nreplace].old = argv[i]; - replace[nreplace].new = s + 1; - nreplace++; - } - -next: s = getcommand(); - if (s == NULL) { - fprintf(stderr, "command not matched\n"); - return 1; - } - for (i = 0; i < nsearch; i++) - if (!isin(s, search[i])) - goto next; - for (i = 0; i < nreplace; i++) - if (!isin(s, replace[i].old)) - goto next; - else - s = sub(s, replace[i].old, replace[i].new); - if (editit) { - s = edit(s); - if (s == NULL) - goto next; - } - fseek(fp, 0, 2); /* 2 == end of file. i.e., append command to $history */ - fprintf(fp, "%s\n", s); - fclose(fp); - if (printit) - printf("%s\n", s); - else { - char *shell = getenv("SHELL"); - - if (!editit) - fprintf(stderr, "%s\n", s); - if (shell == NULL) - shell = "/bin/sh"; - execl(shell, basename(shell), "-c", s, NULL); - perror(shell); - exit(1); - } - return 0; -} diff --git a/input.c b/input.c @@ -1,7 +1,7 @@ /* input.c: i/o routines for files and pseudo-files (strings) */ #include <errno.h> -#include <setjmp.h> + #include "rc.h" #include "jbwrap.h" @@ -20,13 +20,7 @@ typedef struct Input { #define BUFSIZE ((size_t) 256) -#if READLINE -extern char *readline(char *); -extern void add_history(char *); -static char *rlinebuf; -#endif - -char *prompt, *prompt2; +static char *prompt2; bool rcrc; static int dead(void); @@ -46,6 +40,10 @@ static void (*realugchar)(int); int last; +#if EDITLINE || READLINE +static char *rlinebuf, *prompt; +#endif + extern int gchar() { int c; @@ -55,7 +53,7 @@ extern int gchar() { } while ((c = (*realgchar)()) == '\0') - pr_error("warning: null character ignored"); + pr_error("warning: null character ignored", 0); return c; } @@ -68,7 +66,7 @@ static int dead() { return last = EOF; } -static void ugdead(int c) { +static void ugdead(int ignore) { return; } @@ -85,42 +83,20 @@ static int stringgchar() { return last = (inbuf[chars_out] == '\0' ? EOF : inbuf[chars_out++]); } -/* signal-safe readline wrapper */ - -#if READLINE -#ifndef HAVE_RESTARTABLE_SYSCALLS -static char *rc_readline(char *prompt) { - char *r; - interrupt_happened = FALSE; - if (!setjmp(slowbuf.j)) { - slow = TRUE; - if (!interrupt_happened) - r = readline(prompt); - else - r = NULL; - } else - r = NULL; - slow = FALSE; - if (r == NULL) - errno = EINTR; - sigchk(); - return r; -} -#else -#define rc_readline readline -#endif /* HAVE_RESTARTABLE_SYSCALLS */ -#endif /* READLINE */ - /* - read a character from a file-descriptor. If GNU readline is defined, add a newline and doctor - the buffer to look like a regular fdgchar buffer. + read a character from a file-descriptor. If GNU readline is defined, + add a newline and doctor the buffer to look like a regular fdgchar + buffer. */ static int fdgchar() { + if (chars_out >= chars_in + 2) { /* has the buffer been exhausted? if so, replenish it */ while (1) { -#if READLINE - if (interactive && istack->fd == 0) { +#if EDITLINE || READLINE + if (interactive && istack->fd == 0 && isatty(0)) { + /* The readline library doesn't handle read() returning EAGAIN. */ + makeblocking(istack->fd); rlinebuf = rc_readline(prompt); if (rlinebuf == NULL) { chars_in = 0; @@ -136,9 +112,17 @@ static int fdgchar() { } } else #endif - { - long /*ssize_t*/ r = rc_read(istack->fd, inbuf + 2, BUFSIZE); - sigchk(); + { + ssize_t r; + do { + r = rc_read(istack->fd, inbuf + 2, BUFSIZE); + sigchk(); + if (errno == EAGAIN) { + if (!makeblocking(istack->fd)) + panic("not O_NONBLOCK"); + errno = EINTR; + } + } while (r < 0 && errno == EINTR); if (r < 0) { uerror("read"); rc_exit(1); @@ -248,15 +232,17 @@ extern void flushu() { /* the wrapper loop in rc: prompt for commands until EOF, calling yyparse and walk() */ -extern Node *doit(bool execit) { +extern Node *doit(bool clobberexecit) { bool eof; + bool execit ; Jbwrap j; Estack e1, e2; Edata jerror; if (dashen) - execit = FALSE; - setjmp(j.j); + clobberexecit = FALSE; + execit = clobberexecit; + sigsetjmp(j.j, 1); jerror.jb = &j; except(eError, jerror, &e1); for (eof = FALSE; !eof;) { @@ -279,11 +265,12 @@ extern Node *doit(bool execit) { funcall(arglist); } if ((s = varlookup("prompt")) != NULL) { -#if READLINE - prompt = s->w; -#else - fprint(2, "%s", s->w); +#if EDITLINE || READLINE + if (istack->t == iFd && istack->fd == 0 && isatty(0)) + prompt = s->w; + else #endif + fprint(2, "%s", s->w); prompt2 = (s->n == NULL ? "" : s->n->w); } } @@ -361,3 +348,15 @@ extern void closefds() { i->fd = -1; } } + +extern void print_prompt2() { + lineno++; + if (interactive) { +#if EDITLINE || READLINE + if (istack->t == iFd && istack->fd == 0 && isatty(0)) + prompt = prompt2; + else +#endif + fprint(2, "%s", prompt2); + } +} diff --git a/install-sh b/install-sh @@ -1,250 +0,0 @@ -#! /bin/sh -# -# install - install a program, script, or datafile -# This comes from X11R5 (mit/util/scripts/install.sh). -# -# Copyright 1991 by the Massachusetts Institute of Technology -# -# Permission to use, copy, modify, distribute, and sell this software and its -# documentation for any purpose is hereby granted without fee, provided that -# the above copyright notice appear in all copies and that both that -# copyright notice and this permission notice appear in supporting -# documentation, and that the name of M.I.T. not be used in advertising or -# publicity pertaining to distribution of the software without specific, -# written prior permission. M.I.T. makes no representations about the -# suitability of this software for any purpose. It is provided "as is" -# without express or implied warranty. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. It can only install one file at a time, a restriction -# shared with many OS's install programs. - - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit="${DOITPROG-}" - - -# put in absolute paths if you don't have them in your path; or use env. vars. - -mvprog="${MVPROG-mv}" -cpprog="${CPPROG-cp}" -chmodprog="${CHMODPROG-chmod}" -chownprog="${CHOWNPROG-chown}" -chgrpprog="${CHGRPPROG-chgrp}" -stripprog="${STRIPPROG-strip}" -rmprog="${RMPROG-rm}" -mkdirprog="${MKDIRPROG-mkdir}" - -transformbasename="" -transform_arg="" -instcmd="$mvprog" -chmodcmd="$chmodprog 0755" -chowncmd="" -chgrpcmd="" -stripcmd="" -rmcmd="$rmprog -f" -mvcmd="$mvprog" -src="" -dst="" -dir_arg="" - -while [ x"$1" != x ]; do - case $1 in - -c) instcmd="$cpprog" - shift - continue;; - - -d) dir_arg=true - shift - continue;; - - -m) chmodcmd="$chmodprog $2" - shift - shift - continue;; - - -o) chowncmd="$chownprog $2" - shift - shift - continue;; - - -g) chgrpcmd="$chgrpprog $2" - shift - shift - continue;; - - -s) stripcmd="$stripprog" - shift - continue;; - - -t=*) transformarg=`echo $1 | sed 's/-t=//'` - shift - continue;; - - -b=*) transformbasename=`echo $1 | sed 's/-b=//'` - shift - continue;; - - *) if [ x"$src" = x ] - then - src=$1 - else - # this colon is to work around a 386BSD /bin/sh bug - : - dst=$1 - fi - shift - continue;; - esac -done - -if [ x"$src" = x ] -then - echo "install: no input file specified" - exit 1 -else - true -fi - -if [ x"$dir_arg" != x ]; then - dst=$src - src="" - - if [ -d $dst ]; then - instcmd=: - else - instcmd=mkdir - fi -else - -# Waiting for this to be detected by the "$instcmd $src $dsttmp" command -# might cause directories to be created, which would be especially bad -# if $src (and thus $dsttmp) contains '*'. - - if [ -f $src -o -d $src ] - then - true - else - echo "install: $src does not exist" - exit 1 - fi - - if [ x"$dst" = x ] - then - echo "install: no destination specified" - exit 1 - else - true - fi - -# If destination is a directory, append the input filename; if your system -# does not like double slashes in filenames, you may need to add some logic - - if [ -d $dst ] - then - dst="$dst"/`basename $src` - else - true - fi -fi - -## this sed command emulates the dirname command -dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` - -# Make sure that the destination directory exists. -# this part is taken from Noah Friedman's mkinstalldirs script - -# Skip lots of stat calls in the usual case. -if [ ! -d "$dstdir" ]; then -defaultIFS=' -' -IFS="${IFS-${defaultIFS}}" - -oIFS="${IFS}" -# Some sh's can't handle IFS=/ for some reason. -IFS='%' -set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` -IFS="${oIFS}" - -pathcomp='' - -while [ $# -ne 0 ] ; do - pathcomp="${pathcomp}${1}" - shift - - if [ ! -d "${pathcomp}" ] ; - then - $mkdirprog "${pathcomp}" - else - true - fi - - pathcomp="${pathcomp}/" -done -fi - -if [ x"$dir_arg" != x ] -then - $doit $instcmd $dst && - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi -else - -# If we're going to rename the final executable, determine the name now. - - if [ x"$transformarg" = x ] - then - dstfile=`basename $dst` - else - dstfile=`basename $dst $transformbasename | - sed $transformarg`$transformbasename - fi - -# don't allow the sed command to completely eliminate the filename - - if [ x"$dstfile" = x ] - then - dstfile=`basename $dst` - else - true - fi - -# Make a temp file name in the proper directory. - - dsttmp=$dstdir/#inst.$$# - -# Move or copy the file name to the temp name - - $doit $instcmd $src $dsttmp && - - trap "rm -f ${dsttmp}" 0 && - -# and set any options; do chmod last to preserve setuid bits - -# If any of these fail, we abort the whole thing. If we want to -# ignore errors from any of these, just make sure not to ignore -# errors from the above "$doit $instcmd $src $dsttmp" command. - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && - -# Now rename the file to the real destination. - - $doit $rmcmd -f $dstdir/$dstfile && - $doit $mvcmd $dsttmp $dstdir/$dstfile - -fi && - - -exit 0 diff --git a/jbwrap.h b/jbwrap.h @@ -1,9 +1,23 @@ #include <setjmp.h> -/* certain braindamaged environments don't define jmp_buf as an array, so... */ +/* If we have POSIX sigjmp_buf and friends, use them. If we don't, just +use a jmp_buf. This probably fails on a traditional SysV machine, where +jmp_bufs don't preserve signal masks. I'm not worrying about this till +someone reports it as a bug :-). */ + +#if HAVE_SIGSETJMP +#else +#define sigjmp_buf jmp_buf +#define sigsetjmp(x,y) setjmp(x) +#define siglongjmp longjmp +#endif /* HAVE_SIGSETJMP */ + + +/* Certain braindamaged environments don't define jmp_buf as an array, +so wrap it in a structure. Potentially, we could use configure to do +this only where it needs to be done, but the effort is probably not +worth it. */ struct Jbwrap { - jmp_buf j; + sigjmp_buf j; }; - -extern Jbwrap slowbuf; /* for getting out of interrupts while performing slow i/o on BSD */ diff --git a/lex.c b/lex.c @@ -1,7 +1,7 @@ /* lex.c: rc's lexical analyzer */ #include "rc.h" -#include "y.tab.h" +#include "parse.h" /* Special characters (i.e., "non-word") in rc: @@ -336,16 +336,6 @@ extern void inityy() { realbuf = ealloc(bufsize); } -extern void print_prompt2() { - lineno++; -#if READLINE - prompt = prompt2; -#else - if (interactive) - fprint(2, "%s", prompt2); -#endif -} - /* Scan in a pair of integers for redirections like >[2=1]. CLOSED represents a closed file descriptor (i.e., >[2=]) and UNSET represents an undesignated file descriptor (e.g., diff --git a/main.c b/main.c @@ -11,7 +11,9 @@ static bool dashoh; static void assigndefault(char *,...); static void checkfd(int, enum redirtype); -extern void main(int argc, char *argv[], char *envp[]) { +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; initprint(); @@ -19,7 +21,7 @@ extern void main(int argc, char *argv[], char *envp[]) { dollarzero = argv[0]; rc_pid = getpid(); dashell = (*argv[0] == '-'); /* Unix tradition */ - while ((c = rc_getopt(argc, argv, "nolpeivdxsc:")) != -1) + while ((c = rc_getopt(argc, argv, "Vnolpeivdxsc:")) != -1) switch (c) { case 'l': dashell = TRUE; @@ -54,6 +56,9 @@ extern void main(int argc, char *argv[], char *envp[]) { case 'o': dashoh = TRUE; break; + case 'V': + fprint(1, "%s\n", id); + exit(0); case '?': exit(1); } @@ -97,6 +102,7 @@ quitopts: dasheye = FALSE; doit(TRUE); rc_exit(getstatus()); + return 0; /* Never really reached. */ } static void assigndefault(char *name,...) { diff --git a/mksignal b/mksignal @@ -1,76 +0,0 @@ -#!/bin/sh -# generate rc's internal signal table from signal.h - -exec > sigmsgs.c - -echo '#include "sigmsgs.h"' -echo -echo 'Sigmsgs signals[] = {' - -sed ' s/\/\*[ ]*// - s/[ ]*\*\/// - s/([@*+!]) // - s/[ ]*([a-zA-Z,->& ]*)[ ]*// - s/^[ ]*\#[ ]*define/\#define/ - s/[ ]*signal$// - s/_SIG/SIG/g' $1 | -awk ' - BEGIN { - # assign to nomesg["SIGNAME"] to suppress a long message - nomesg["SIGINT"] = 1 - nomesg["SIGPIPE"] = 1 - # assign to mesg["SIGNAME"] to override a message - mesg["SIGHUP"] = "hangup" - mesg["SIGKILL"] = "killed" - mesg["SIGQUIT"] = "quit" - mesg["SIGTERM"] = "terminated" - mesg["SIGURG"] = "urgent condition on i/o channel" - mesg["SIGSTOP"] = "stop signal not from tty" - mesg["SIGTSTP"] = "stopped" - mesg["SIGCONT"] = "continue" - mesg["SIGCHLD"] = "child stop or exit" - mesg["SIGTTIN"] = "background tty read" - mesg["SIGTTOU"] = "background tty write" - # assign to ignore["SIGNAME"] to explicitly ignore a named signal - ignore["SIGMAX"] = 1 - } - $1 == "#define" && $2 == "NSIG" && $3 ~ /^[0-9]+$/ { nsig = $3 } - $1 == "#define" && $2 ~ /^SIG/ && $3 ~ /^[0-9]+$/ && sig[$3] == "" && ignore[$2] == 0 { - sig[$3] = $2 - if ($3 > max) - max = $3 - if (mesg[$2] == "" && nomesg[$2] == 0) { - str = $4 - for (i = 5; i <= NF; i++) - str = str " " $i - mesg[$2] = str - } - } - END { - if (nsig == 0) - nsig = max + 1 - printf " {!!, !!},\n" - for (i = 1; i < nsig; i++) { - if (sig[i] == "") - printf " {!!, !!},\n" - else - printf " {!%s!, !%s!},\n", sig[i], mesg[sig[i]] - } - } -' | -tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ!' 'abcdefghijklmnopqrstuvwxyz"' - -echo '};' - -exec > sigmsgs.h - -echo 'typedef struct {' -echo ' char *name, *msg;' -echo '} Sigmsgs;' -echo 'extern Sigmsgs signals[];' - -grep '^ ' sigmsgs.c | # the thing in quotes is ^<tab> -awk ' - { sum = sum + 1; } - END { print "#define NUMOFSIGNALS", sum } -' diff --git a/mksignal.c b/mksignal.c @@ -0,0 +1,238 @@ +#include <stdio.h> +#include <signal.h> + +#ifdef NSIG +#define NUMSIG NSIG +#else +#define NUMSIG 1 +#endif + +typedef struct { + int signo; + char *signame; + char *sigmsg; +} signaming; + +static signaming signamings[] = { +#ifdef SIGABRT + { SIGABRT, "sigabrt", "abort"}, +#endif +#ifdef SIGALRM + { SIGALRM, "sigalrm", "alarm clock"}, +#endif +#ifdef SIGBREAK + { SIGBREAK, "sigbreak", "break"}, +#endif +#ifdef SIGBUS + { SIGBUS, "sigbus", "bus error"}, +#endif +#ifdef SIGCANCEL + { SIGCANCEL, "sigcancel", "thread cancellation"}, +#endif +#ifdef SIGCHLD + { SIGCHLD, "sigchld", "child stop or exit"}, +#endif +#ifdef SIGCLD + { SIGCLD, "sigcld", "child stop or exit"}, +#endif +#ifdef SIGCONT + { SIGCONT, "sigcont", "continue"}, +#endif +#ifdef SIGDIL + { SIGDIL, "sigdil", "dil signal"}, +#endif +#ifdef SIGEMT + { SIGEMT, "sigemt", "emt instruction"}, +#endif +#ifdef SIGFPE + { SIGFPE, "sigfpe", "floating point error"}, +#endif +#ifdef SIGFREEZE + { SIGFREEZE, "sigfreeze", "cpr freeze"}, +#endif +#ifdef SIGHUP + { SIGHUP, "sighup", "hangup"}, +#endif +#ifdef SIGILL + { SIGILL, "sigill", "illegal instruction"}, +#endif + +/* We don't want a default message for SIGINT. */ +#ifdef SIGINT + { SIGINT, "sigint", ""}, +#endif + +#ifdef SIGIO + { SIGIO, "sigio", "socket i/o possible"}, +#endif +#ifdef SIGIOT + { SIGIOT, "sigiot", "iot instruction"}, +#endif +#ifdef SIGKILL + { SIGKILL, "sigkill", "killed"}, +#endif +#ifdef SIGLOST + { SIGLOST, "siglost", "resource lost"}, +#endif +#ifdef SIGLWP + { SIGLWP, "siglwp", "thread library signal"}, +#endif + +/* By default, SIGPIPEs are silent. */ +#ifdef SIGPIPE + { SIGPIPE, "sigpipe", ""}, +#endif + +#ifdef SIGPOLL + { SIGPOLL, "sigpoll", "pollable event occurred"}, +#endif +#ifdef SIGPROF + { SIGPROF, "sigprof", "profiling timer alarm"}, +#endif +#ifdef SIGPWR + { SIGPWR, "sigpwr", "power-fail restart"}, +#endif +#ifdef SIGQUIT + { SIGQUIT, "sigquit", "quit"}, +#endif +#ifdef SIGSEGV + { SIGSEGV, "sigsegv", "segmentation violation"}, +#endif +#ifdef SIGSTKFLT + { SIGSTKFLT, "sigstkflt", "stack fault"}, +#endif +#ifdef SIGSTOP + { SIGSTOP, "sigstop", "stopped by program"}, +#endif +#ifdef SIGSYS + { SIGSYS, "sigsys", "invalid argument to system call"}, +#endif +#ifdef SIGTERM + { SIGTERM, "sigterm", "terminated"}, +#endif +#ifdef SIGTHAW + { SIGTHAW, "sigthaw", "cpr thaw"}, +#endif +#ifdef SIGTRAP + { SIGTRAP, "sigtrap", "trace trap"}, +#endif +#ifdef SIGTSTP + { SIGTSTP, "sigtstp", "stopped"}, +#endif +#ifdef SIGTTIN + { SIGTTIN, "sigttin", "background tty read"}, +#endif +#ifdef SIGTTOU + { SIGTTOU, "sigttou", "background tty write"}, +#endif +#ifdef SIGURG + { SIGURG, "sigurg", "urgent condition on i/o channel"}, +#endif +#ifdef SIGUSR1 + { SIGUSR1, "sigusr1", "user defined signal 1"}, +#endif +#ifdef SIGUSR2 + { SIGUSR2, "sigusr2", "user defined signal 2"}, +#endif +#ifdef SIGVTALRM + { SIGVTALRM, "sigvtalrm", "virtual timer alarm"}, +#endif +#ifdef SIGWAITING + { SIGWAITING, "sigwaiting", "lwps blocked"}, +#endif +#ifdef SIGWINCH + { SIGWINCH, "sigwinch", "window size change"}, +#endif +#ifdef SIGWINDOW + { SIGWINDOW, "sigwindow", "window size change"}, +#endif +#ifdef SIGXCPU + { SIGXCPU, "sigxcpu", "exceeded cpu time limit"}, +#endif +#ifdef SIGXFSZ + { SIGXFSZ, "sigxfsz", "exceeded file size limit"}, +#endif +#ifdef SIGSAK + { SIGSAK, "sigsak", "secure attention key"}, +#endif +#ifdef SIGSOUND + { SIGSOUND, "sigsound", "hft sound sequence completed"}, +#endif +#ifdef SIGRETRACT + { SIGRETRACT, "sigretract", "hft monitor mode retracted"}, +#endif +#ifdef SIGKAP + { SIGKAP, "sigkap", "keep alive poll"}, +#endif +#ifdef SIGGRANT + { SIGGRANT, "siggrant", "hft monitor mode granted"}, +#endif +#ifdef SIGALRM1 + { SIGALRM1, "sigalrm1", "m:n condition alarm"}, +#endif +#ifdef SIGVIRT + { SIGVIRT, "sigvirt", "virtual time alarm"}, +#endif +#ifdef SIGPRE + { SIGPRE, "sigpre", "programming error"}, +#endif +#ifdef SIGMIGRATE + { SIGMIGRATE, "sigmigrate", "migrate process"}, +#endif +#ifdef SIGDANGER + { SIGDANGER, "sigdanger", "system crash imminent"}, +#endif +#ifdef SIGMSG + { SIGMSG, "sigmsg", "hft input data pending"}, +#endif +#ifdef SIGINFO + { SIGINFO, "siginfo", "information request"}, +#endif + { 0, 0, 0} +}; + +static void barf(char *msg) { + fprintf(stderr, "mksignals: %s\n", msg); + exit(1); +} + +int main(void) { + int maxsig = NUMSIG-1; + int s; + signaming *snp; + FILE *outf; + + for (snp = signamings; snp->signo; ++snp) + if (snp->signo > maxsig) + maxsig = snp->signo; + + outf = fopen("sigmsgs.h", "w"); + if (!outf) barf("could not open sigmsgs.h for writing"); + fprintf(outf, "typedef struct {\n"); + fprintf(outf, "\tchar *name, *msg;\n"); + fprintf(outf, "} Sigmsgs;\n"); + fprintf(outf, "extern Sigmsgs signals[];\n"); + fprintf(outf, "#define NUMOFSIGNALS %d\n", maxsig+1); + if (fclose(outf) == EOF) barf("could not fclose sigmsgs.h after writing"); + + outf = fopen("sigmsgs.c", "w"); + if (!outf) barf("could not open sigmsgs.c for writing"); + fprintf(outf, "#include \"sigmsgs.h\"\n\n"); + fprintf(outf, "Sigmsgs signals[] = {\n"); + fprintf(outf, "\t{\"\",\t\"\"},\n"); + + /* yes, we could avoid the quadratic searching with an aux array. fap. */ + for (s = 1; s <= maxsig; ++s) { + for (snp = signamings; snp->signo && snp->signo != s; ++snp) + /* */; + if (snp->signo) + fprintf(outf, "\t{\"%s\",\t\"%s\"},\n", + snp->signame, snp->sigmsg); + else + fprintf(outf, "\t{\"sigunknown%d\",\t\"unknown signal %d\"},\n", + s, s); + } + fprintf(outf, "};\n"); + if (fclose(outf) == EOF) barf("could not fclose sigmsgs.c after writing"); + return 0; +} diff --git a/nalloc.c b/nalloc.c @@ -111,8 +111,8 @@ extern void restoreblock(Block *old) { /* generic memory allocation functions */ extern void *ealloc(size_t n) { - extern void *malloc(size_t); void *p = malloc(n); + if (p == NULL) { uerror("malloc"); rc_exit(1); @@ -121,8 +121,7 @@ extern void *ealloc(size_t n) { } extern void *erealloc(void *p, size_t n) { - extern void *realloc(void *, size_t); - if (p == NULL) /* convenience feature */ + if (p == NULL) /* erealloc() has POSIX realloc() semantics */ return ealloc(n); if ((p = realloc(p, n)) == NULL) { uerror("realloc"); @@ -132,8 +131,6 @@ extern void *erealloc(void *p, size_t n) { } extern void efree(void *p) { - extern void free(void *); if (p != NULL) free(p); } - diff --git a/open.c b/open.c @@ -1,7 +1,7 @@ /* open.c: to insulate <fcntl.h> from the rest of rc. */ -#include <fcntl.h> #include "rc.h" +#include <fcntl.h> /* Opens a file with the necessary flags. Assumes the following @@ -23,3 +23,23 @@ extern int rc_open(const char *name, redirtype m) { panic("bad mode passed to rc_open"); return open(name, mode_masks[m], 0666); } + +/* make a file descriptor blocking. return value indicates whether +the desciptor was previously set to non-blocking. */ + +extern bool makeblocking(int fd) { + int flags; + + if ((flags = fcntl(fd, F_GETFL)) == -1) { + uerror("fcntl"); + rc_error(NULL); + } + if (! (flags & O_NONBLOCK)) + return FALSE; + flags &= ~O_NONBLOCK; + if (fcntl(fd, F_SETFL, (long) flags) == -1) { + uerror("fcntl"); + rc_error(NULL); + } + return TRUE; +} diff --git a/parse.y b/parse.y @@ -6,9 +6,7 @@ %{ #include "rc.h" -#ifndef lint -#define lint /* hush up gcc -Wall, leave out the dumb sccsid's. */ -#endif + static Node *star, *nolist; Node *parsetree; /* not using yylval because bison declares it as an auto */ %} diff --git a/print.c b/print.c @@ -14,14 +14,14 @@ */ #define Flag(name, flag) \ -static bool name(Format *format, int c) { \ +static bool name(Format *format, int ignore) { \ format->flags |= flag; \ return TRUE; \ } Flag(uconv, FMT_unsigned) Flag(hconv, FMT_short) -Flag(lconv, FMT_long) +Flag(rc_lconv, FMT_long) #if HAVE_QUAD_T Flag(qconv, FMT_quad) @@ -41,7 +41,7 @@ static bool digitconv(Format *format, int c) { return TRUE; } -static bool zeroconv(Format *format, int c) { +static bool zeroconv(Format *format, int ignore) { if (format->flags & (FMT_f1set | FMT_f2set)) return digitconv(format, '0'); format->flags |= FMT_zeropad; @@ -53,7 +53,7 @@ static void pad(Format *format, size_t len, int c) { fmtputc(format, c); } -static bool sconv(Format *format, int c) { +static bool sconv(Format *format, int ignore) { char *s = va_arg(format->args, char *); if ((format->flags & FMT_f1set) == 0) fmtcat(format, s); @@ -151,32 +151,32 @@ static void intconv(Format *format, unsigned int radix, int upper, const char *a pad(format, padding, padchar); } -static bool cconv(Format *format, int c) { +static bool cconv(Format *format, int ignore) { fmtputc(format, va_arg(format->args, int)); return FALSE; } -static bool dconv(Format *format, int c) { +static bool dconv(Format *format, int ignore) { intconv(format, 10, 0, ""); return FALSE; } -static bool oconv(Format *format, int c) { +static bool oconv(Format *format, int ignore) { intconv(format, 8, 0, "0"); return FALSE; } -static bool xconv(Format *format, int c) { +static bool xconv(Format *format, int ignore) { intconv(format, 16, 0, "0x"); return FALSE; } -static bool pctconv(Format *format, int c) { +static bool pctconv(Format *format, int ignore) { fmtputc(format, '%'); return FALSE; } -static bool badconv(Format *format, int c) { +static bool badconv(Format *ignore, int ign0re) { panic("bad conversion character in printfmt"); /* NOTREACHED */ return FALSE; /* hush up gcc -Wall */ @@ -203,7 +203,7 @@ static void inittab(void) { fmttab['u'] = uconv; fmttab['h'] = hconv; - fmttab['l'] = lconv; + fmttab['l'] = rc_lconv; fmttab['#'] = altconv; fmttab['-'] = leftconv; fmttab['.'] = dotconv; @@ -289,16 +289,16 @@ extern int fmtprint(Format *format, const char *fmt,...) { va_list ap, saveargs; va_start(ap, fmt); - saveargs = format->args; - format->args = ap; + va_copy(saveargs, format->args); + va_copy(format->args, ap); n += printfmt(format, fmt); va_end(format->args); - format->args = saveargs; + va_copy(format->args, saveargs); return n + format->flushed; } -static void fprint_flush(Format *format, size_t more) { +static void fprint_flush(Format *format, size_t ignore) { size_t n = format->buf - format->bufbegin; char *buf = format->bufbegin; @@ -320,7 +320,7 @@ extern int fprint(int fd, const char *fmt,...) { format.u.n = fd; va_start(ap, fmt); - format.args = ap; + va_copy(format.args, ap); printfmt(&format, fmt); va_end(format.args); @@ -331,19 +331,20 @@ extern int fprint(int fd, const char *fmt,...) { static void memprint_grow(Format *format, size_t more) { char *buf; size_t len = format->bufend - format->bufbegin + 1; + size_t used = format->buf - format->bufbegin; + len = (len >= more) ? len * 2 : ((len + more) + PRINT_ALLOCSIZE) &~ (PRINT_ALLOCSIZE - 1); if (format->u.n) buf = erealloc(format->bufbegin, len); else { - size_t used = format->buf - format->bufbegin; buf = nalloc(len); memcpy(buf, format->bufbegin, used); } - format->buf = buf + (format->buf - format->bufbegin); + format->buf = buf + used; format->bufbegin = buf; - format->bufend = buf + len - 1; + format->bufend = buf + len - 1; } static char *memprint(Format *format, const char *fmt, char *buf, size_t len) { @@ -364,7 +365,7 @@ extern char *mprint(const char *fmt,...) { format.u.n = 1; va_start(ap, fmt); - format.args = ap; + va_copy(format.args, ap); result = memprint(&format, fmt, ealloc(PRINT_ALLOCSIZE), PRINT_ALLOCSIZE); va_end(format.args); return result; @@ -377,106 +378,8 @@ extern char *nprint(const char *fmt,...) { format.u.n = 0; va_start(ap, fmt); - format.args = ap; + va_copy(format.args, ap); result = memprint(&format, fmt, nalloc(PRINT_ALLOCSIZE), PRINT_ALLOCSIZE); va_end(format.args); return result; } - - -/* THESE ARE UNUSED IN rc */ - -#if 0 - -extern int print(const char *fmt,...) { - char buf[1024]; - Format format; - - format.buf = buf; - format.bufbegin = buf; - format.bufend = buf + sizeof buf; - format.grow = fprint_flush; - format.flushed = 0; - format.u.n = 1; - - va_start(format.args, fmt); - printfmt(&format, fmt); - va_end(format.args); - - fprint_flush(&format, 0); - return format.flushed; -} - -extern int eprint(const char *fmt,...) { - char buf[1024]; - Format format; - - format.buf = buf; - format.bufbegin = buf; - format.bufend = buf + sizeof buf; - format.grow = fprint_flush; - format.flushed = 0; - format.u.n = 2; - - va_start(format.args, fmt); - printfmt(&format, fmt); - va_end(format.args); - - fprint_flush(&format, 0); - return format.flushed; -} - -static void snprint_grow(Format *format, size_t more) { - longjmp(format->u.p, 1); -} - -extern int snprint(char *buf, int buflen, const char *fmt,...) { - int n; - jmp_buf jbuf; - Format format; - - if (setjmp(jbuf)) { - *format.buf = '\0'; - return format.buf - format.bufbegin; - } - - format.buf = buf; - format.bufbegin = buf; - format.bufend = buf + buflen - 1; - format.grow = snprint_grow; - format.flushed = 0; - format.u.p = jbuf; - - va_start(format.args, fmt); - n = printfmt(&format, fmt); - va_end(format.args); - - *format.buf = '\0'; - return n; -} - -extern int sprint(char *buf, const char *fmt,...) { - int n; - jmp_buf jbuf; - Format format; - - if (setjmp(jbuf)) { - *format.buf = '\0'; - return format.buf - format.bufbegin; - } - - format.buf = buf; - format.bufbegin = buf; - format.bufend = buf + SPRINT_BUFSIZ - 1; - format.grow = snprint_grow; - format.flushed = 0; - format.u.p = jbuf; - - va_start(format.args, fmt); - n = printfmt(&format, fmt); - va_end(format.args); - - *format.buf = '\0'; - return n; -} -#endif diff --git a/proto.h b/proto.h @@ -1,25 +1,42 @@ +/* + The idea of this file is to include prototypes for all external + functions that rc uses, either by including the appropriate header + file, or---for older systems---declaring the functions directly. +*/ + +#if HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif + +#include <signal.h> + #if HAVE_QUAD_T typedef quad_t align_t; #else typedef long align_t; #endif -/* If you need to change this, please let the maintainer know. */ -#ifndef SIG_ATOMIC_T -typedef int SIG_ATOMIC_T; -#endif +/* + We need <stdarg.h>. If you really need to build rc on a system which + doesn't have it, please contact the maintainer. +*/ -#if STDC_HEADERS -#include <stdlib.h> -#else -/* fake stdlib.h */ -extern void exit(int); -extern void qsort(void *, size_t, size_t, int (*)(const void *, const void *)); +#include <stdarg.h> + +/* 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) #endif #if STDC_HEADERS + +#include <stdlib.h> #include <string.h> -#else + +#else /* STDC_HEADERS */ + /* fake string.h */ extern int strncmp(const char *, const char *, size_t); extern int strcmp(const char *, const char *); @@ -32,8 +49,39 @@ extern char *strcat(char *, const char *); extern char *strncat(char *, const char *, size_t); extern void *memcpy(void *, const void *, size_t); extern void *memset(void *, int, size_t); + +/* fake stdlib.h */ +extern void exit(int); +extern void free(void *); +extern void *malloc(size_t); +extern void *realloc(void *, size_t); +extern void qsort(void *, size_t, size_t, int (*)(const void *, const void *)); + +#endif /* STDC_HEADERS */ + +#if HAVE_UNISTD_H +#include <unistd.h> #endif +#if HAVE_SETPGRP + +#if SETPGRP_VOID +/* Smells like POSIX: should all be ok. */ +#else +/* BSD: fake it. */ +#define setpgid(pid, pgrp) setpgrp(pid, pgrp) +#define tcsetpgrp(fd, pgrp) ioctl((fd), TIOCSPGRP, &(pgrp)) +#endif + +#else /* HAVE_SETPGRP */ + +/* Nothing doing. */ +#define setpgid() +#define tcsetpgrp() + +#endif /*HAVE_SETPGRP */ + + /* fake errno.h for mips (which doesn't declare errno in errno.h!?!?) */ #ifdef host_mips extern int errno; diff --git a/rc.1 b/rc.1 @@ -35,7 +35,7 @@ .\" troff will supply the correct intersentence spacing, but only if .\" the sentences end at the end of a line. Explicit spaces, if given, .\" are apparently honored and the normal intersentence spacing is -.\" supressed. +.\" suppressed. .\" .\" DaviD W. Sanderson .\"------- @@ -166,7 +166,7 @@ rc \- shell .SH SYNOPSIS .B rc -.RB [ \-eixvldnpo ] +.RB [ \-eixvldnpoV ] .RB [ \-c .IR command ] .RI [ arguments ] @@ -300,6 +300,11 @@ Any further arguments to .I rc are placed in .Cr $* . +.TP +.Cr \-V +This flag causes +.I rc +to print a version string to stdout, and exit immediately. .PP .SH COMMANDS A simple command is a sequence of words, separated by white space @@ -1628,19 +1633,28 @@ is specified, .I rc waits for all child processes to exit. .TP -\fBwhatis \fR[\fB\-s\fR] [\fB\-\|\-\fR] [\fIname ...\fR] +\fBwhatis \fR[\fB\-b\fR] \fR[\fB\-f\fR] \fR[\fB\-p\fR] \fR[\fB\-s\fR] \fR[\fB\-v\fR] [\fB\-\|\-\fR] [\fIname ...\fR] Prints a definition of the named objects. -For variables, their values -are printed; for functions, their definitions are; and for executable -files, path names are printed. +For builtins, +.B builtin +.I foo +is printed; for functions, including signal handlers, their definitions +are printed; for executable files, path names are printed; and for +variables, their values are printed. +The options restrict output to builtins, functions, executable +programs, signal handlers, and variables, respectively. If no +.IR name s +are specified, +.I rc +lists all objects of that type. (This is not permitted for +.BR -p .) Without arguments, .B whatis -prints the values of all shell variables and functions. -With a -.Cr \-s -argument, -.B whatis -also prints out a list of available signals and their handlers (if any). +is equivalent to +.BR "whatis -fv" , +and prints the values of all shell variables and functions. +.TP +\& Note that .B whatis output is suitable for input to @@ -1788,8 +1802,16 @@ The design of this shell has been copied from the .I rc that Tom Duff wrote at Bell Labs. .SH BUGS -On systems that support -.Cr /dev/fd , +Environment variables that contain the ASCII character SOH (also known +as '\\001', or CTRL-A) will be split into lists at that character in +descendant +.IR rc +processes. +.PP +On modern systems that support +.Cr /dev/fd +or +.Cr /proc/self/fd , .Cr <{foo} style redirection is implemented that way. However, on other systems it is implemented with named pipes, @@ -1818,7 +1840,7 @@ notation for flattening should allow for using an arbitrary separating character, not just space. .PP Bug reports should be mailed to -.Cr "byron@archone.tamu.edu" . +.Cr "<tjg@star.le.ac.uk>" . .SH INCOMPATIBILITIES Here is a list of features which distinguish this incarnation of .I rc @@ -1841,12 +1863,19 @@ a backquote must always be followed by a left-brace. This restriction is not present for single-word commands in this .IR rc . .PP +The list flattening operator, +.Cr $^foo , +is spelt +.Cr $"foo +in those versions of the Bell Labs +.IR rc +which have it. +.PP The following are all new with this version of .IR rc : The .Cr \-n option, -the list flattening operator, here strings (they facilitate exporting of functions with here documents into the environment), the diff --git a/rc.h b/rc.h @@ -1,13 +1,4 @@ #include "config.h" - -#if HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif - -#if HAVE_UNISTD_H -#include <unistd.h> -#endif - #include "proto.h" /* datatypes */ @@ -16,31 +7,12 @@ #undef FALSE #undef TRUE -#include <stdarg.h> - -#if HAVE_SETPGRP - -#if SETPGRP_VOID -/* Smells like POSIX: should all be ok. */ -#else -/* BSD: fake it. */ -#define setpgid(pid, pgrp) setpgrp(pid, pgrp) -#define tcsetpgrp(fd, pgrp) ioctl((fd), TIOCSPGRP, &(pgrp)) -#endif - -#else /* HAVE_SETPGRP */ - -/* Nothing doing. */ -#define setpgid -#define tcsetpgrp - -#endif /*HAVE_SETPGRP */ typedef void builtin_t(char **); typedef struct Block Block; typedef struct Dup Dup; typedef struct Estack Estack; -typedef struct Function Function; +typedef struct rc_Function rc_Function; typedef struct Hq Hq; typedef struct Htab Htab; typedef struct Jbwrap Jbwrap; @@ -130,7 +102,7 @@ struct Rq { struct Rq *n; }; -struct Function { +struct rc_Function { Node *def; char *extdef; }; @@ -181,7 +153,7 @@ enum { #define memzero(s, n) memset(s, 0, n) #define enew(x) ((x *) ealloc(sizeof(x))) #define ecpy(x) strcpy((char *) ealloc(strlen(x) + 1), x) -#define lookup_fn(s) ((Function *) lookup(s, fp)) +#define lookup_fn(s) ((rc_Function *) lookup(s, fp)) #define lookup_var(s) ((Variable *) lookup(s, vp)) #define nnew(x) ((x *) nalloc(sizeof(x))) #define ncpy(x) (strcpy((char *) nalloc(strlen(x) + 1), x)) @@ -194,7 +166,6 @@ enum { /* rc prototypes */ /* main.c */ -extern char *prompt, *prompt2; extern Rq *redirq; extern bool dashdee, dashee, dashvee, dashex, dashell, dasheye, dashen, dashpee, interactive; @@ -220,11 +191,18 @@ extern void sigint(int); extern void exec(List *, bool); extern void doredirs(void); +#if HASH_BANG +#define rc_execve execve +#else +/* execve.c */ +extern int my_execve(char *, char **, char **); +#endif + /* footobar.c */ extern char **list2array(List *, bool); extern char *get_name(char *); -extern List *parse_var(char *, char *); -extern Node *parse_fn(char *, char *); +extern List *parse_var(char *); +extern Node *parse_fn(char *); extern void initprint(void); extern void rc_exit(int); /* here for odd reasons; user-defined signal handlers are kept in fn.c */ @@ -251,7 +229,7 @@ extern List *word(char *, char *); /* hash.c */ extern Htab *fp, *vp; extern void *lookup(char *, Htab *); -extern Function *get_fn_place(char *); +extern rc_Function *get_fn_place(char *); extern List *varlookup(char *); extern Node *fnlookup(char *); extern Variable *get_var_place(char *, bool); @@ -282,6 +260,7 @@ extern int heredoc(int); extern int qdoc(Node *, Node *); extern Hq *hq; + /* input.c */ extern void initinput(void); extern Node *parseline(char *); @@ -289,6 +268,7 @@ extern int gchar(void); extern void ugchar(int); extern Node *doit(bool); extern void flushu(void); +extern void print_prompt2(void); extern void pushfd(int); extern void pushstring(char **, bool); extern void popinput(void); @@ -296,12 +276,12 @@ extern void closefds(void); extern int last; extern bool rcrc; + /* lex.c */ extern int yylex(void); extern void inityy(void); extern void yyerror(const char *); extern void scanerror(char *); -extern void print_prompt2(void); extern const char nw[], dnw[]; /* list.c */ @@ -324,6 +304,7 @@ extern void restoreblock(Block *); /* open.c */ extern int rc_open(const char *, redirtype); +extern bool makeblocking(int); /* print.c */ /* @@ -350,21 +331,56 @@ extern char *nprint(const char *fmt,...); *(f)->buf++ = (c);\ } -/* y.tab.c (parse.y) */ +/* parse.c (parse.y) */ extern Node *parsetree; extern int yyparse(void); extern void initparse(void); +/* readline */ + +#if READLINE + +/* Including the real readline .h files is too complicated, so we just +declare what we actually use. */ + +extern void add_history(char *); +extern char *readline(char *); +extern int rl_clear_signals(void); +extern int rl_pending_input; +extern int rl_reset_terminal(char *); + +#if READLINE_OLD +extern void rl_clean_up_for_exit(void); +extern void rl_deprep_terminal(void); +#else +extern void _rl_clean_up_for_exit(void); +extern void (*rl_deprep_term_function)(void); +#endif + +extern char *rc_readline(char *); + +extern volatile sig_atomic_t rl_active; +extern struct Jbwrap rl_buf; +#endif + +#if EDITLINE +extern char *readline(char *); +extern void add_history(char *); +#define rc_readline readline +#endif + + /* redir.c */ extern void doredirs(void); + /* signal.c */ extern void initsignal(void); extern void catcher(int); extern void sigchk(void); extern void (*rc_signal(int, void (*)(int)))(int); extern void (*sighandlers[])(int); -extern volatile SIG_ATOMIC_T slow, interrupt_happened; + /* status.c */ extern int istrue(void); @@ -377,6 +393,23 @@ extern void statprint(pid_t, int); extern void ssetstatus(char **); extern char *strstatus(int s); + +/* system.c or system-bsd.c */ +extern void writeall(int, char *, size_t); + +#if HAVE_RESTARTABLE_SYSCALLS +extern int rc_read(int, char *, size_t); +extern pid_t rc_wait(int *); +extern Jbwrap slowbuf; +extern volatile sig_atomic_t slow; + +#else /* HAVE_RESTARTABLE_SYSCALLS */ + +#define rc_read read +#define rc_wait wait +#endif /* HAVE_RESTARTABLE_SYSCALLS */ + + /* tree.c */ extern Node *mk(int /*nodetype*/,...); extern Node *treecpy(Node *, void *(*)(size_t)); @@ -385,13 +418,11 @@ extern void treefree(Node *); /* utils.c */ extern bool isabsolute(char *); extern int n2u(char *, unsigned int); -extern int rc_read(int, char *, size_t); extern int mvfd(int, int); extern int starstrcmp(const void *, const void *); -extern void pr_error(char *); +extern void pr_error(char *, int); extern void panic(char *); extern void uerror(char *); -extern void writeall(int, char *, size_t); /* wait.c */ extern pid_t rc_fork(void); @@ -403,4 +434,3 @@ extern bool forked; /* walk.c */ extern bool walk(Node *, bool); extern bool cond; - diff --git a/rlimit.h b/rlimit.h @@ -3,40 +3,40 @@ #if HAVE_SETRLIMIT #if HAVE_SYS_RESOURCE_H -# include <sys/time.h> -# if RLIMIT_NEEDS_KERNEL -# define _KERNEL -# endif -# include <sys/resource.h> -# if RLIMIT_NEEDS_KERNEL -# undef _KERNEL -# endif +#include <sys/time.h> +#if RLIMIT_NEEDS_KERNEL +#define _KERNEL +#endif +#include <sys/resource.h> +#if RLIMIT_NEEDS_KERNEL +#undef _KERNEL +#endif #else -# include <sys/times.h> +#include <sys/times.h> #endif #if HAVE_LIMITS_H -# include <limits.h> +#include <limits.h> #endif #ifndef HAVE_RLIM_T -# if RLIM_T_IS_QUAD_T +#if RLIM_T_IS_QUAD_T typedef quad_t rlim_t; -# else +#else typedef long rlim_t; -# endif +#endif #endif #if HAVE_QUAD_T -# define RLIM_CONV quad_t -# define RLIM_FMT "%s \t%qd%s\n" +#define RLIM_CONV quad_t +#define RLIM_FMT "%s \t%qd%s\n" #else -# define RLIM_CONV long -# define RLIM_FMT "%s \t%ld%s\n" +#define RLIM_CONV long +#define RLIM_FMT "%s \t%ld%s\n" #endif #if defined(RLIMIT_OFILE) && !defined (RLIMIT_NOFILE) -# define RLIMIT_NOFILE RLIMIT_OFILE +#define RLIMIT_NOFILE RLIMIT_OFILE #endif #endif /* HAVE_SETRLIMIT */ diff --git a/signal.c b/signal.c @@ -2,32 +2,51 @@ #include <signal.h> #include <setjmp.h> + #include "rc.h" #include "sigmsgs.h" #include "jbwrap.h" -Jbwrap slowbuf; -volatile SIG_ATOMIC_T slow, interrupt_happened; +#if HAVE_SA_INTERRUPT +static void (*sys_signal(int signum, void (*handler)(int)))(int) { + struct sigaction new, old; + + new.sa_handler = handler; + new.sa_flags = SA_INTERRUPT; + sigaction(signum, &new, &old); + return old.sa_handler; +} +#else +#define sys_signal signal +#endif + void (*sighandlers[NUMOFSIGNALS])(int); -static volatile SIG_ATOMIC_T sigcount, caught[NUMOFSIGNALS]; +static volatile sig_atomic_t sigcount, caught[NUMOFSIGNALS]; extern void catcher(int s) { if (caught[s] == 0) { sigcount++; caught[s] = 1; } - signal(s, catcher); - interrupt_happened = TRUE; -#ifndef HAVE_RESTARTABLE_SYSCALLS - if (slow) - longjmp(slowbuf.j, 1); + sys_signal(s, catcher); + +#if READLINE + if (rl_active) + siglongjmp(rl_buf.j, s); +#endif /* READLINE */ + +#if HAVE_RESTARTABLE_SYSCALLS + if (slow) { + siglongjmp(slowbuf.j, s); +} #endif } extern void sigchk() { void (*h)(int); int s, i; + if (sigcount == 0) return; /* ho hum; life as usual */ if (forked) @@ -53,11 +72,11 @@ extern void (*rc_signal(int s, void (*h)(int)))(int) { sigchk(); old = sighandlers[s]; if (h == SIG_DFL || h == SIG_IGN) { - signal(s, h); sighandlers[s] = h; + sys_signal(s, h); } else { sighandlers[s] = h; - signal(s, catcher); + sys_signal(s, catcher); } return old; } @@ -65,16 +84,18 @@ extern void (*rc_signal(int s, void (*h)(int)))(int) { extern void initsignal() { void (*h)(int); int i; + for (i = 1; i < NUMOFSIGNALS; i++) { - if ((h = signal(i, SIG_DFL)) != SIG_DFL) - signal(i, h); + h = sys_signal(i, SIG_DFL); + if (h != SIG_DFL && h != SIG_ERR) + sys_signal(i, h); sighandlers[i] = h; } -#ifdef SIGCLD +#if HAVE_SYSV_SIGCLD /* Ensure that SIGCLD is not SIG_IGN. Solaris's rshd does this. :-( */ - h = signal(SIGCLD, SIG_DFL); - if (h != SIG_IGN) - signal(SIGCLD, h); + h = sys_signal(SIGCLD, SIG_DFL); + if (h != SIG_IGN && h != SIG_ERR) + sys_signal(SIGCLD, h); #endif } diff --git a/status.c b/status.c @@ -2,6 +2,7 @@ #include "rc.h" #include "sigmsgs.h" +#include "wait.h" /* status == the wait() value of the last command in the pipeline, or the last command */ @@ -33,7 +34,9 @@ extern int getstatus() { if (pipelength > 1) return !istrue(); s = statuses[0]; - return (s&0xff) ? 1 : (s >> 8) & 0xff; + if (WIFSIGNALED(s)) + return 1; + return WEXITSTATUS(s); } extern void set(bool code) { @@ -61,11 +64,12 @@ 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) { - if (i & 0xff) { - char *msg = ((i & 0x7f) < NUMOFSIGNALS ? signals[i & 0x7f].msg : ""); + if (WIFSIGNALED(i)) { + int t = WTERMSIG(i); + char *msg = ((t > 0) && (t < NUMOFSIGNALS) ? signals[WTERMSIG(i)].msg : ""); if (pid != -1) fprint(2, "%ld: ", (long)pid); - if (i & 0x80) { + if (myWIFDUMPED(i)) { if (*msg == '\0') fprint(2, "core dumped\n"); else @@ -97,16 +101,15 @@ extern List *sgetstatus() { /* return status as a string (used above and for bqstatus) */ extern char *strstatus(int s) { - int t = s & 0x7f; - - if (t != 0) { - const char *core = (s & 0x80) ? "+core" : ""; - if (t < NUMOFSIGNALS && *signals[t].name != '\0') + if (WIFSIGNALED(s)) { + int t = WTERMSIG(s); + const char *core = myWIFDUMPED(s) ? "+core" : ""; + if ((t > 0) && (t < NUMOFSIGNALS) && *signals[t].name != '\0') return nprint("%s%s", signals[t].name, core); else return nprint("-%d%s", t, core); /* unknown signals are negated */ } else - return nprint("%d", (s >> 8) & 0xff); + return nprint("%d", WEXITSTATUS(s)); } extern void ssetstatus(char **av) { diff --git a/system-bsd.c b/system-bsd.c @@ -0,0 +1,60 @@ +/* signal-safe read and write (for BSD slow devices). writeall() also +allows partial writes */ + +#include <errno.h> + +#include "rc.h" +#include "jbwrap.h" +#include "wait.h" + +Jbwrap slowbuf; +volatile sig_atomic_t slow; + +static char *safe_buf; +static size_t safe_remain; + +extern void writeall(int fd, char *buf, size_t remain) { + int i; + + safe_buf = buf; + safe_remain = remain; + for (i = 0; safe_remain > 0; buf += i, safe_remain -= i) { + if (sigsetjmp(slowbuf.j, 1) == 0) { + slow = TRUE; + if ((i = write(fd, safe_buf, safe_remain)) <= 0) + break; /* abort silently on errors in write() */ + } else + break; + } + slow = FALSE; + sigchk(); +} + +extern int rc_read(int fd, char *buf, size_t n) { + ssize_t r; + + if (sigsetjmp(slowbuf.j, 1) == 0) { + slow = TRUE; + r = read(fd, buf, n); + } else { + errno = EINTR; + r = -1; + } + slow = FALSE; + + return r; +} + +static int r = -1; +extern pid_t rc_wait(int *stat) { + if (sigsetjmp(slowbuf.j, 1) == 0) { + slow = TRUE; + r = wait(stat); + } else { + errno = EINTR; + r = -1; + } + slow = FALSE; + + return r; +} diff --git a/system.c b/system.c @@ -0,0 +1,10 @@ +#include "rc.h" + +extern void writeall(int fd, char *buf, size_t remain) { + int i; + + for (i = 0; remain > 0; buf += i, remain -= i) + if ((i = write(fd, buf, remain)) <= 0) + break; /* abort silently on errors in write() */ + sigchk(); +} diff --git a/trip.rc b/trip.rc Binary files differ. diff --git a/tripping.c b/tripping.c @@ -0,0 +1,33 @@ +/* This is an auxiliary test program for rc. */ + +#include <fcntl.h> +#include <stdio.h> + +void out0(void) { + putchar('t'); putchar('r'); + putchar('\0'); + putchar('u'); putchar('e'); + putchar('\n'); +} + +void makenonblock(void) { + int flags; + + if ((flags = fcntl(0, F_GETFL)) == -1) + perror("fcntl 1"); + flags |= O_NONBLOCK; + if (fcntl(0, F_SETFL, (long) flags) == -1) + perror("fcntl 2"); +} + +int main(int argc, char **argv) { + switch(argv[1][0]) { + case '0': + out0(); + break; + case 'n': + makenonblock(); + break; + } + return 0; +} diff --git a/utils.c b/utils.c @@ -7,12 +7,12 @@ /* print error with line number on noninteractive shells (i.e., scripts) */ -extern void pr_error(char *s) { +extern void pr_error(char *s, int offset) { if (s != NULL) { if (interactive) fprint(2, "%s\n", s); else - fprint(2, "line %d: %s\n", lineno - 1, s); + fprint(2, "line %d: %s\n", lineno + offset, s); } } @@ -65,44 +65,6 @@ extern bool isabsolute(char *path) { return path[0] == '/' || (path[0] == '.' && (path[1] == '/' || (path[1] == '.' && path[2] == '/'))); } -/* signal-safe read and write (for BSD slow devices). writeall also allows partial writes */ - -extern void writeall(int fd, char *buf, size_t remain) { - int i; - for (i = 0; remain > 0; buf += i, remain -= i) { - interrupt_happened = FALSE; - if (!setjmp(slowbuf.j)) { - slow = TRUE; - if (interrupt_happened) - break; - else if ((i = write(fd, buf, remain)) <= 0) - break; /* abort silently on errors in write() */ - } else - break; - slow = FALSE; - } - slow = FALSE; - sigchk(); -} - -extern int rc_read(int fd, char *buf, size_t n) { - long /*ssize_t*/ r; - interrupt_happened = FALSE; - if (!setjmp(slowbuf.j)) { - slow = TRUE; - if (!interrupt_happened) - r = read(fd, buf, n); - else - r = -2; - } else - r = -2; - slow = FALSE; - if (r == -2) { - errno = EINTR; - r = -1; - } - return r; -} /* duplicate a fd and close the old one only if necessary */ diff --git a/var.c b/var.c @@ -18,11 +18,9 @@ extern void varassign(char *name, List *def, bool stack) { new = get_var_place(name, stack); new->def = newdef; new->extdef = NULL; -#if READLINE /* need to reset readline() every time TERM or TERMCAP changes */ - if (interactive && (streq(name, "TERM") || streq(name, "TERMCAP"))) { - extern void rl_reset_terminal(char *); +#if READLINE + if (interactive && (streq(name, "TERM") || streq(name, "TERMCAP"))) rl_reset_terminal(NULL); - } #endif } @@ -85,7 +83,7 @@ extern List *varlookup(char *name) { return look->def; if (look->extdef == NULL) return NULL; /* variable was set to null, e.g., a=() echo foo */ - ret = parse_var(name, look->extdef); + ret = parse_var(look->extdef); if (ret == NULL) { look->extdef = NULL; return NULL; diff --git a/version.c b/version.c @@ -1 +0,0 @@ -const char id[] = "@(#)rc version 1.5b2, 1997-07-01."; diff --git a/version.c.in b/version.c.in @@ -0,0 +1 @@ +const char id[] = "@(#)@PACKAGE@ version @VERSION@, @RELDATE@."; diff --git a/wait.c b/wait.c @@ -1,15 +1,10 @@ -#include "rc.h" - #include <errno.h> -#include <setjmp.h> -#include <sys/wait.h> -#include "jbwrap.h" +#include "rc.h" +#include "wait.h" bool forked = FALSE; -static pid_t rc_wait(int *); - typedef struct Pid Pid; static struct Pid { @@ -21,7 +16,9 @@ static struct Pid { extern pid_t rc_fork() { Pid *new; + struct Pid *p, *q; pid_t pid = fork(); + switch (pid) { case -1: uerror("fork"); @@ -30,6 +27,14 @@ extern pid_t rc_fork() { case 0: forked = TRUE; sigchk(); + p = plist; q = 0; + while (p) { + if (q) efree(q); + q = p; + p = p->n; + } + if (q) efree(q); + plist = 0; return 0; default: new = enew(Pid); @@ -43,34 +48,44 @@ extern pid_t rc_fork() { extern pid_t rc_wait4(pid_t pid, int *stat, bool nointr) { Pid *r, *prev; - int ret; - /* first look for a child which may already have exited */ -again: for (r = plist, prev = NULL; r != NULL; prev = r, r = r->n) + + /* Find the child on the list. */ + for (r = plist, prev = NULL; r != NULL; prev = r, r = r->n) if (r->pid == pid) break; + + /* Uh-oh, not there. */ if (r == NULL) { errno = ECHILD; /* no children */ uerror("wait"); *stat = 0x100; /* exit(1) */ return -1; } - if (r->alive) { - while (pid != (ret = rc_wait(stat))) { - Pid *q; - if (ret < 0) { - if (nointr) - goto again; + + /* If it's still alive, wait() for it. */ + while (r->alive) { + int ret; + Pid *q; + + ret = rc_wait(stat); + + if (ret < 0) { + if (errno == ECHILD) + panic("lost child"); + if (nointr) + continue; + else return ret; - } - for (q = plist; q != NULL; q = q->n) - if (q->pid == ret) { - q->alive = FALSE; - q->stat = *stat; - break; - } } - } else - *stat = r->stat; + + for (q = plist; q != NULL; q = q->n) + if (q->pid == ret) { + q->alive = FALSE; + q->stat = *stat; + break; + } + } + *stat = r->stat; if (prev == NULL) plist = r->n; /* remove element from head of list */ else @@ -97,33 +112,16 @@ extern List *sgetapids() { extern void waitforall() { int stat; + while (plist != NULL) { - int pid = rc_wait4(plist->pid, &stat, FALSE); + pid_t pid = rc_wait4(plist->pid, &stat, FALSE); if (pid > 0) setstatus(pid, stat); - else + else { set(FALSE); + if (errno == EINTR) + return; + } sigchk(); } } - -/* - rc_wait: a wait() wrapper that interfaces wait() w/rc signals. - Note that the signal queue is not checked in this fn; someone - may want to resume the wait() without delivering any signals. -*/ - -static pid_t rc_wait(int *stat) { - int r; - interrupt_happened = FALSE; - if (!setjmp(slowbuf.j)) { - slow = TRUE; - if (!interrupt_happened) - r = wait(stat); - else - r = -1; - } else - r = -1; - slow = FALSE; - return r; -} diff --git a/wait.h b/wait.h @@ -0,0 +1,23 @@ +#if HAVE_SYS_WAIT_H +#include <sys/wait.h> +#endif + +/* Fake the POSIX wait() macros if we don't have them. */ +#ifndef WIFEXITED +#define WIFEXITED(s) (((s) & 0xFF) == 0) +#endif +#ifndef WEXITSTATUS +#define WEXITSTATUS(s) (((unsigned)(s) >> 8) && 0xFF) +#endif +#ifndef WIFSIGNALED +#define WIFSIGNALED(s) (((s) & 0xFF) != 0) +#endif +#ifndef WTERMSIG +#define WTERMSIG(s) ((s) & 0x7F) +#endif + +/* These don't exist in POSIX. */ +#define myWIFDUMPED(s) (((s) & 0x80) != 0) + + + diff --git a/walk.c b/walk.c @@ -108,7 +108,7 @@ top: sigchk(); cond = oldcond; break; } - if (setjmp(j.j)) + if (sigsetjmp(j.j, 1)) break; jbreak.jb = &j; except(eBreak, jbreak, &e1); @@ -131,7 +131,7 @@ top: sigchk(); Jbwrap j; Estack e1, e2; Edata jbreak; - if (setjmp(j.j)) + if (sigsetjmp(j.j, 1)) break; jbreak.jb = &j; except(eBreak, jbreak, &e1); @@ -148,6 +148,7 @@ top: sigchk(); } case nSubshell: if (dofork(TRUE)) { + setsigdefaults(FALSE); walk(n->u[0].p, FALSE); rc_exit(getstatus()); } diff --git a/which.c b/which.c @@ -9,18 +9,17 @@ */ #include "rc.h" + #include <errno.h> -#include <sys/types.h> #include <sys/stat.h> -#include <unistd.h> + +#include "getgroups.h" #define X_USR 0100 #define X_GRP 0010 #define X_OTH 0001 #define X_ALL (X_USR|X_GRP|X_OTH) -extern int stat(const char *, struct stat *); - static bool initialized = FALSE; static uid_t uid; static gid_t gid; @@ -32,7 +31,7 @@ static GETGROUPS_T *gidset; /* determine whether gid lies in gidset */ static int ingidset(gid_t g) { - gid_t i; + int i; for (i = 0; i < ngroups; ++i) if (g == gidset[i]) return 1; @@ -87,12 +86,17 @@ extern char *which(char *name, bool verbose) { uid = geteuid(); gid = getegid(); #if HAVE_GETGROUPS - ngroups = getgroups(0, (gid_t *)0); - gidset = malloc(ngroups * sizeof(gid_t)); - if (!gidset) - uerror("malloc"); - else - getgroups(ngroups, gidset); +#if HAVE_POSIX_GETGROUPS + ngroups = getgroups(0, (GETGROUPS_T *)0); + if (ngroups < 0) { + uerror("getgroups"); + rc_exit(1); + } +#else + ngroups = NGROUPS; +#endif + gidset = ealloc(ngroups * sizeof(GETGROUPS_T)); + getgroups(ngroups, gidset); #endif } if (isabsolute(name)) /* absolute pathname? */ diff --git a/y.tab.c b/y.tab.c @@ -1,1070 +0,0 @@ -#ifndef lint -static char const yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93"; -#endif -#define YYBYACC 1 -#define YYMAJOR 1 -#define YYMINOR 9 -#define YYLEX yylex() -#define YYEMPTY -1 -#define yyclearin (yychar=(YYEMPTY)) -#define yyerrok (yyerrflag=0) -#define YYRECOVERING (yyerrflag!=0) -/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ -#ifdef c_plusplus -#ifndef __cplusplus -#define __cplusplus -#endif -#endif -#ifdef __cplusplus -extern "C" { char *getenv(const char *); } -#else -extern char *getenv(); -extern int yylex(); -extern int yyparse(); -#endif -#define YYPREFIX "yy" -#line 8 "parse.y" -#include "rc.h" -#ifndef lint -#define lint /* hush up gcc -Wall, leave out the dumb sccsid's. */ -#endif -static Node *star, *nolist; -Node *parsetree; /* not using yylval because bison declares it as an auto */ -#line 28 "parse.y" -typedef union { - struct Node *node; - struct Redir redir; - struct Pipe pipe; - struct Dup dup; - struct Word word; - char *keyword; -} YYSTYPE; -#line 43 "y.tab.c" -#define ANDAND 257 -#define BACKBACK 258 -#define BANG 259 -#define CASE 260 -#define COUNT 261 -#define DUP 262 -#define ELSE 263 -#define END 264 -#define FLAT 265 -#define FN 266 -#define FOR 267 -#define IF 268 -#define IN 269 -#define OROR 270 -#define PIPE 271 -#define REDIR 272 -#define SREDIR 273 -#define SUB 274 -#define SUBSHELL 275 -#define SWITCH 276 -#define TWIDDLE 277 -#define WHILE 278 -#define WORD 279 -#define HUH 280 -#define YYERRCODE 256 -const short yylhs[] = { -1, - 0, 0, 22, 22, 8, 8, 13, 13, 3, 3, - 9, 9, 4, 15, 2, 11, 11, 16, 16, 16, - 5, 5, 6, 6, 6, 19, 19, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 24, 24, 18, 18, 18, - 12, 12, 17, 17, 20, 20, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 21, 21, - 14, 14, 14, 23, 23, -}; -const short yylen[] = { 2, - 2, 2, 1, 1, 2, 2, 1, 2, 1, 2, - 1, 2, 3, 3, 3, 0, 2, 1, 2, 2, - 3, 3, 1, 2, 2, 1, 4, 0, 1, 2, - 4, 8, 6, 4, 8, 4, 4, 4, 4, 2, - 2, 3, 3, 3, 2, 0, 1, 1, 2, 2, - 1, 3, 1, 1, 1, 3, 2, 5, 2, 2, - 2, 2, 3, 3, 3, 2, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, - 0, 2, 2, 0, 2, -}; -const short yydefred[] = { 0, - 0, 0, 0, 0, 18, 0, 79, 0, 0, 0, - 0, 0, 0, 0, 0, 67, 0, 0, 81, 0, - 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, - 3, 4, 2, 77, 75, 74, 73, 68, 71, 69, - 0, 78, 72, 76, 70, 54, 53, 55, 0, 47, - 0, 59, 60, 0, 0, 0, 84, 66, 0, 0, - 0, 0, 0, 84, 0, 0, 0, 11, 0, 0, - 62, 61, 0, 0, 30, 0, 84, 84, 84, 5, - 6, 8, 0, 0, 1, 0, 50, 0, 0, 63, - 64, 0, 44, 0, 0, 0, 0, 0, 0, 0, - 0, 79, 13, 12, 10, 65, 82, 0, 17, 0, - 0, 0, 0, 52, 56, 79, 84, 14, 85, 0, - 0, 31, 84, 0, 0, 0, 0, 0, 39, 0, - 0, 84, 0, 58, 84, 0, 0, 0, 0, 0, - 79, 0, 0, 0, 0, 0, 0, 24, 35, 25, - 22, 21, -}; -const short yydgoto[] = { 21, - 46, 22, 66, 23, 142, 143, 67, 68, 69, 47, - 75, 27, 28, 70, 57, 29, 48, 30, 122, 94, - 54, 33, 97, 51, -}; -const short yysindex[] = { 874, - 24, 1001, -82, 1001, 0, 1001, 0, -27, -26, 900, - 1001, -82, -20, -82, -26, 0, 1001, 1134, 0, 900, - 0, 1134, -203, -30, 1134, 0, -55, 24, 1134, 826, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -66, 0, 0, 0, 0, 0, 0, 0, 849, 0, - 1134, 0, 0, 900, 1001, 1134, 0, 0, -52, -52, - 1134, 1001, 1001, 0, -212, -58, 154, 0, 1134, 426, - 0, 0, -196, 1001, 0, -203, 0, 0, 0, 0, - 0, 0, 1001, 1001, 0, -196, 0, -52, 1001, 0, - 0, -196, 0, -52, -38, 36, 502, -196, -36, -52, - 502, 0, 0, 0, 0, 0, 0, -52, 0, 502, - 502, 502, -52, 0, 0, 0, 0, 0, 0, -97, - -234, 0, 0, 1001, -234, 922, -196, -196, 0, 944, - 502, 0, -9, 0, 0, -234, 502, 967, 502, -234, - 0, 967, -45, 154, 967, -234, 448, 0, 0, 0, - 0, 0, -}; -const short yyrindex[] = { 134, - 0, 0, 356, 0, 0, 0, 0, 0, 0, 0, - 0, 356, 0, 1024, 0, 0, 0, 571, 0, 0, - 0, 487, 529, 54, 134, 0, 62, 0, 487, 548, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 487, 0, 0, 712, 0, 142, 0, 0, 14, 38, - 487, 0, 0, 0, -10, 0, -32, 0, 744, 0, - 0, 0, 749, 0, 0, 529, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 763, 0, 86, 0, 0, - 0, 779, 0, 110, 0, 0, -34, 788, 0, 380, - -34, 0, 0, 0, 0, 0, 0, 470, 0, -34, - -34, -34, 404, 0, 0, 0, 0, 0, 0, 529, - 6, 0, 0, 724, 30, 0, 805, 813, 0, 0, - -34, 0, 0, 0, 0, 119, -34, 571, -34, 187, - 0, 571, 0, -44, 571, 396, 0, 0, 0, 0, - 0, 0, -}; -const short yygindex[] = { 0, - 0, 0, -23, 12, 0, -104, 1319, 2, -127, 1307, - 7, 0, 57, 0, 70, -13, 84, 0, 0, 420, - -81, 59, 369, 31, -}; -#define YYTABLESIZE 1464 -const short yytable[] = { 57, - 119, 25, 117, 28, 123, 83, 28, 81, 9, 76, - 145, 50, 55, 56, 145, 26, 87, 145, 124, 62, - 126, 58, 77, 19, 28, 57, 25, 57, 80, 57, - 57, 71, 96, 32, 130, 78, 79, 148, 84, 34, - 150, 89, 61, 26, 63, 105, 26, 20, 57, 19, - 57, 19, 58, 19, 19, 89, 18, 89, 5, 147, - 90, 102, 76, 7, 26, 93, 103, 34, 74, 11, - 34, 48, 19, 20, 79, 20, 118, 20, 20, 149, - 23, 82, 109, 57, 64, 57, 85, 52, 34, 53, - 28, 0, 9, 0, 0, 49, 20, 48, 0, 48, - 65, 48, 48, 72, 0, 0, 76, 0, 120, 19, - 0, 0, 57, 138, 57, 0, 0, 0, 0, 80, - 48, 49, 0, 49, 0, 49, 49, 0, 33, 0, - 26, 0, 91, 20, 0, 0, 19, 0, 19, 0, - 0, 0, 0, 28, 49, 80, 0, 80, 0, 80, - 80, 28, 0, 0, 34, 0, 33, 48, 0, 33, - 20, 0, 20, 104, 5, 132, 0, 114, 80, 0, - 0, 28, 115, 0, 74, 11, 0, 33, 0, 28, - 0, 49, 28, 0, 0, 0, 48, 0, 0, 0, - 0, 81, 28, 0, 0, 0, 27, 0, 0, 0, - 28, 0, 0, 0, 0, 80, 0, 0, 0, 0, - 49, 0, 80, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 28, 0, 27, 0, 77, 27, 0, 28, - 116, 0, 80, 0, 80, 28, 28, 0, 0, 78, - 79, 0, 0, 33, 0, 27, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 0, 57, 57, 57, 57, 57, 26, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 31, 19, 19, - 19, 19, 19, 34, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 27, 20, 20, 20, 20, 20, 7, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, - 48, 0, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, - 49, 49, 49, 49, 49, 46, 80, 80, 80, 80, - 80, 0, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 33, 0, 80, 80, 80, 80, 80, 79, - 28, 46, 0, 46, 0, 46, 46, 28, 28, 0, - 0, 0, 0, 28, 28, 32, 0, 0, 0, 0, - 77, 28, 28, 15, 46, 79, 0, 79, 0, 79, - 79, 49, 0, 78, 79, 0, 0, 0, 0, 59, - 60, 0, 101, 32, 0, 107, 32, 0, 79, 15, - 0, 15, 0, 15, 15, 110, 111, 112, 0, 88, - 27, 46, 0, 0, 32, 0, 0, 151, 0, 0, - 0, 17, 15, 0, 0, 19, 106, 0, 0, 0, - 0, 0, 0, 0, 95, 79, 0, 0, 46, 83, - 46, 99, 100, 17, 0, 131, 0, 19, 0, 108, - 0, 133, 0, 59, 0, 0, 28, 0, 0, 15, - 137, 0, 113, 139, 79, 83, 152, 0, 0, 83, - 83, 119, 0, 0, 0, 0, 0, 0, 0, 0, - 32, 20, 0, 0, 28, 0, 15, 28, 15, 0, - 0, 0, 0, 0, 0, 0, 0, 17, 16, 0, - 0, 19, 0, 20, 0, 28, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, - 0, 0, 0, 0, 0, 83, 16, 0, 0, 16, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 28, 0, 0, 0, 0, 29, 0, 16, 29, 0, - 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, - 0, 0, 0, 0, 0, 0, 29, 0, 28, 0, - 0, 28, 46, 46, 46, 0, 46, 46, 0, 46, - 46, 46, 46, 46, 18, 46, 46, 46, 46, 28, - 46, 46, 46, 46, 46, 0, 79, 79, 79, 79, - 79, 0, 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 0, 16, 79, 79, 79, 79, 79, 32, - 15, 15, 15, 0, 15, 15, 0, 15, 15, 15, - 15, 15, 29, 15, 15, 15, 15, 0, 15, 15, - 15, 15, 15, 2, 34, 35, 4, 0, 36, 0, - 6, 37, 38, 39, 40, 28, 0, 41, 0, 0, - 42, 43, 44, 45, 16, 2, 34, 35, 4, 0, - 36, 0, 6, 37, 38, 39, 40, 0, 0, 41, - 0, 45, 42, 43, 44, 45, 16, 83, 83, 83, - 83, 0, 83, 36, 83, 83, 83, 83, 83, 0, - 0, 83, 0, 28, 83, 83, 83, 83, 83, 45, - 28, 0, 45, 28, 0, 0, 28, 28, 41, 2, - 3, 36, 4, 5, 36, 0, 6, 7, 8, 9, - 45, 0, 40, 10, 11, 0, 12, 13, 14, 15, - 16, 28, 36, 0, 28, 16, 41, 0, 42, 41, - 0, 0, 16, 0, 0, 0, 0, 43, 16, 16, - 40, 0, 28, 40, 29, 0, 0, 41, 0, 0, - 0, 29, 0, 0, 37, 0, 42, 29, 29, 42, - 0, 40, 38, 0, 0, 43, 0, 28, 43, 0, - 0, 0, 0, 0, 0, 0, 45, 42, 0, 0, - 28, 28, 37, 0, 0, 37, 43, 0, 36, 0, - 38, 0, 0, 38, 0, 0, 0, 0, 0, 0, - 0, 17, 0, 37, 0, 19, 0, 0, 28, 0, - 0, 38, 0, 41, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 17, 0, 0, 40, 19, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 42, 0, 0, 0, 0, 0, 17, - 0, 0, 43, 19, 0, 0, 0, 0, 0, 0, - 0, 20, 0, 0, 0, 0, 0, 0, 0, 37, - 0, 0, 0, 0, 0, 17, 0, 38, 0, 19, - 0, 0, 89, 0, 20, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, - 0, 19, 134, 0, 0, 0, 0, 0, 45, 20, - 0, 18, 0, 0, 0, 45, 0, 0, 0, 17, - 36, 45, 45, 19, 135, 0, 0, 36, 0, 0, - 0, 0, 0, 36, 36, 20, 18, 0, 0, 0, - 28, 0, 17, 0, 0, 41, 19, 0, 0, 0, - 0, 0, 41, 28, 28, 0, 0, 20, 41, 40, - 0, 0, 18, 0, 0, 0, 40, 0, 0, 0, - 0, 0, 40, 0, 0, 42, 17, 0, 0, 20, - 19, 0, 42, 0, 43, 0, 0, 0, 42, 0, - 0, 43, 0, 0, 0, 0, 0, 43, 0, 46, - 0, 37, 20, 46, 0, 0, 0, 0, 37, 38, - 0, 0, 0, 0, 37, 0, 38, 0, 0, 0, - 0, 0, 38, 2, 34, 35, 4, 5, 36, 18, - 6, 37, 38, 39, 40, 0, 20, 10, 11, 0, - 42, 43, 44, 45, 16, 0, 2, 34, 35, 4, - 0, 36, 0, 6, 37, 38, 39, 40, 0, 46, - 41, 0, 0, 42, 43, 44, 45, 16, 0, 1, - 0, 2, 3, 0, 4, 5, 0, 0, 6, 7, - 8, 9, 0, 0, 0, 10, 11, 0, 12, 13, - 14, 15, 16, 0, 0, 0, 0, 2, 34, 35, - 4, 0, 36, 0, 6, 37, 38, 39, 40, 17, - 0, 41, 0, 19, 42, 43, 44, 45, 16, 2, - 34, 35, 4, 0, 36, 0, 6, 37, 38, 39, - 40, 0, 0, 41, 0, 0, 42, 43, 44, 45, - 16, 2, 34, 35, 4, 0, 36, 0, 6, 37, - 38, 39, 40, 0, 0, 41, 0, 0, 42, 43, - 44, 45, 16, 0, 2, 3, 141, 4, 5, 20, - 0, 6, 7, 8, 9, 0, 0, 0, 10, 11, - 0, 12, 13, 14, 15, 16, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 18, 0, 2, 34, - 35, 4, 0, 36, 0, 6, 37, 38, 39, 40, - 0, 0, 41, 0, 0, 42, 43, 44, 45, 16, - 0, 46, 46, 46, 46, 0, 46, 0, 46, 46, - 46, 46, 46, 0, 0, 46, 0, 0, 46, 46, - 46, 46, 46, 0, 0, 0, 26, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, - 0, 0, 0, 0, 26, 0, 0, 0, 26, 0, - 0, 26, 0, 0, 0, 26, 0, 0, 0, 0, - 73, 0, 0, 24, 0, 0, 0, 86, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, - 0, 0, 26, 0, 0, 0, 0, 26, 0, 92, - 0, 0, 0, 0, 0, 26, 0, 0, 0, 98, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 3, 0, 4, 5, 0, 0, 6, 7, - 8, 9, 0, 26, 0, 10, 11, 26, 12, 13, - 14, 15, 16, 0, 0, 121, 26, 26, 26, 125, - 0, 0, 0, 0, 0, 0, 0, 0, 127, 128, - 129, 0, 0, 0, 0, 0, 0, 26, 0, 0, - 0, 0, 0, 26, 26, 26, 0, 0, 26, 136, - 0, 26, 0, 0, 0, 140, 144, 146, 0, 0, - 144, 0, 0, 144, -}; -const short yycheck[] = { 10, - 10, 0, 41, 38, 41, 61, 41, 38, 41, 23, - 138, 94, 40, 40, 142, 10, 30, 145, 100, 40, - 102, 10, 257, 10, 59, 36, 25, 38, 59, 40, - 41, 20, 56, 10, 116, 270, 271, 142, 94, 10, - 145, 94, 12, 38, 14, 69, 41, 10, 59, 36, - 61, 38, 41, 40, 41, 94, 123, 94, 262, 141, - 49, 274, 76, 10, 59, 54, 125, 38, 272, 273, - 41, 10, 59, 36, 271, 38, 41, 40, 41, 125, - 125, 25, 76, 94, 15, 96, 28, 4, 59, 6, - 125, -1, 125, -1, -1, 10, 59, 36, -1, 38, - 17, 40, 41, 20, -1, -1, 120, -1, 97, 96, - -1, -1, 123, 123, 125, -1, -1, -1, -1, 10, - 59, 36, -1, 38, -1, 40, 41, -1, 10, -1, - 125, -1, 49, 96, -1, -1, 123, -1, 125, -1, - -1, -1, -1, 10, 59, 36, -1, 38, -1, 40, - 41, 10, -1, -1, 125, -1, 38, 96, -1, 41, - 123, -1, 125, 10, 262, 263, -1, 84, 59, -1, - -1, 38, 89, -1, 272, 273, -1, 59, -1, 38, - -1, 96, 41, -1, -1, -1, 125, -1, -1, -1, - -1, 38, 59, -1, -1, -1, 10, -1, -1, -1, - 59, -1, -1, -1, -1, 96, -1, -1, -1, -1, - 125, -1, 59, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 257, -1, 38, -1, 257, 41, -1, 264, - 269, -1, 123, -1, 125, 270, 271, -1, -1, 270, - 271, -1, -1, 125, -1, 59, 257, 258, 259, 260, - 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, - 271, 272, 273, -1, 275, 276, 277, 278, 279, 264, - 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, - 267, 268, 269, 270, 271, 272, 273, 264, 275, 276, - 277, 278, 279, 264, 257, 258, 259, 260, 261, 262, - 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, - 273, 125, 275, 276, 277, 278, 279, 264, 257, 258, - 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, - 269, 270, 271, 272, 273, -1, 275, 276, 277, 278, - 279, -1, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, -1, - 275, 276, 277, 278, 279, 10, 257, 258, 259, 260, - 261, -1, 263, 264, 265, 266, 267, 268, 269, 270, - 271, 272, 264, -1, 275, 276, 277, 278, 279, 10, - 257, 36, -1, 38, -1, 40, 41, 264, 257, -1, - -1, -1, -1, 270, 271, 10, -1, -1, -1, -1, - 257, 270, 271, 10, 59, 36, -1, 38, -1, 40, - 41, 2, -1, 270, 271, -1, -1, -1, -1, 10, - 11, -1, 64, 38, -1, 10, 41, -1, 59, 36, - -1, 38, -1, 40, 41, 77, 78, 79, -1, 30, - 264, 96, -1, -1, 59, -1, -1, 10, -1, -1, - -1, 36, 59, -1, -1, 40, 41, -1, -1, -1, - -1, -1, -1, -1, 55, 96, -1, -1, 123, 10, - 125, 62, 63, 36, -1, 117, -1, 40, -1, 70, - -1, 123, -1, 74, -1, -1, 10, -1, -1, 96, - 132, -1, 83, 135, 125, 36, 59, -1, -1, 40, - 41, 10, -1, -1, -1, -1, -1, -1, -1, -1, - 125, 96, -1, -1, 38, -1, 123, 41, 125, -1, - -1, -1, -1, -1, -1, -1, -1, 36, 10, -1, - -1, 40, -1, 96, -1, 59, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 10, -1, -1, - -1, -1, -1, -1, -1, 96, 38, -1, -1, 41, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 10, -1, -1, -1, -1, 38, -1, 59, 41, -1, - -1, -1, -1, -1, -1, -1, -1, 96, -1, -1, - -1, -1, -1, -1, -1, -1, 59, -1, 38, -1, - -1, 125, 257, 258, 259, -1, 261, 262, -1, 264, - 265, 266, 267, 268, 123, 270, 271, 272, 273, 59, - 275, 276, 277, 278, 279, -1, 257, 258, 259, 260, - 261, -1, 263, 264, 265, 266, 267, 268, 269, 270, - 271, 272, -1, 125, 275, 276, 277, 278, 279, 264, - 257, 258, 259, -1, 261, 262, -1, 264, 265, 266, - 267, 268, 125, 270, 271, 272, 273, -1, 275, 276, - 277, 278, 279, 258, 259, 260, 261, -1, 263, -1, - 265, 266, 267, 268, 269, 125, -1, 272, -1, -1, - 275, 276, 277, 278, 279, 258, 259, 260, 261, -1, - 263, -1, 265, 266, 267, 268, 269, -1, -1, 272, - -1, 10, 275, 276, 277, 278, 279, 258, 259, 260, - 261, -1, 263, 10, 265, 266, 267, 268, 269, -1, - -1, 272, -1, 257, 275, 276, 277, 278, 279, 38, - 264, -1, 41, 10, -1, -1, 270, 271, 10, 258, - 259, 38, 261, 262, 41, -1, 265, 266, 267, 268, - 59, -1, 10, 272, 273, -1, 275, 276, 277, 278, - 279, 38, 59, -1, 41, 257, 38, -1, 10, 41, - -1, -1, 264, -1, -1, -1, -1, 10, 270, 271, - 38, -1, 59, 41, 257, -1, -1, 59, -1, -1, - -1, 264, -1, -1, 10, -1, 38, 270, 271, 41, - -1, 59, 10, -1, -1, 38, -1, 257, 41, -1, - -1, -1, -1, -1, -1, -1, 125, 59, -1, -1, - 270, 271, 38, -1, -1, 41, 59, -1, 125, -1, - 38, -1, -1, 41, -1, -1, -1, -1, -1, -1, - -1, 36, -1, 59, -1, 40, -1, -1, 125, -1, - -1, 59, -1, 125, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 36, -1, -1, 125, 40, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 125, -1, -1, -1, -1, -1, 36, - -1, -1, 125, 40, -1, -1, -1, -1, -1, -1, - -1, 96, -1, -1, -1, -1, -1, -1, -1, 125, - -1, -1, -1, -1, -1, 36, -1, 125, -1, 40, - -1, -1, 94, -1, 96, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 36, -1, -1, - -1, 40, 41, -1, -1, -1, -1, -1, 257, 96, - -1, 123, -1, -1, -1, 264, -1, -1, -1, 36, - 257, 270, 271, 40, 41, -1, -1, 264, -1, -1, - -1, -1, -1, 270, 271, 96, 123, -1, -1, -1, - 257, -1, 36, -1, -1, 257, 40, -1, -1, -1, - -1, -1, 264, 270, 271, -1, -1, 96, 270, 257, - -1, -1, 123, -1, -1, -1, 264, -1, -1, -1, - -1, -1, 270, -1, -1, 257, 36, -1, -1, 96, - 40, -1, 264, -1, 257, -1, -1, -1, 270, -1, - -1, 264, -1, -1, -1, -1, -1, 270, -1, 36, - -1, 257, 96, 40, -1, -1, -1, -1, 264, 257, - -1, -1, -1, -1, 270, -1, 264, -1, -1, -1, - -1, -1, 270, 258, 259, 260, 261, 262, 263, 123, - 265, 266, 267, 268, 269, -1, 96, 272, 273, -1, - 275, 276, 277, 278, 279, -1, 258, 259, 260, 261, - -1, 263, -1, 265, 266, 267, 268, 269, -1, 96, - 272, -1, -1, 275, 276, 277, 278, 279, -1, 256, - -1, 258, 259, -1, 261, 262, -1, -1, 265, 266, - 267, 268, -1, -1, -1, 272, 273, -1, 275, 276, - 277, 278, 279, -1, -1, -1, -1, 258, 259, 260, - 261, -1, 263, -1, 265, 266, 267, 268, 269, 36, - -1, 272, -1, 40, 275, 276, 277, 278, 279, 258, - 259, 260, 261, -1, 263, -1, 265, 266, 267, 268, - 269, -1, -1, 272, -1, -1, 275, 276, 277, 278, - 279, 258, 259, 260, 261, -1, 263, -1, 265, 266, - 267, 268, 269, -1, -1, 272, -1, -1, 275, 276, - 277, 278, 279, -1, 258, 259, 260, 261, 262, 96, - -1, 265, 266, 267, 268, -1, -1, -1, 272, 273, - -1, 275, 276, 277, 278, 279, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 123, -1, 258, 259, - 260, 261, -1, 263, -1, 265, 266, 267, 268, 269, - -1, -1, 272, -1, -1, 275, 276, 277, 278, 279, - -1, 258, 259, 260, 261, -1, 263, -1, 265, 266, - 267, 268, 269, -1, -1, 272, -1, -1, 275, 276, - 277, 278, 279, -1, -1, -1, 0, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, - -1, -1, -1, -1, 18, -1, -1, -1, 22, -1, - -1, 25, -1, -1, -1, 29, -1, -1, -1, -1, - 22, -1, -1, 25, -1, -1, -1, 29, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 51, -1, -1, - -1, -1, 56, -1, -1, -1, -1, 61, -1, 51, - -1, -1, -1, -1, -1, 69, -1, -1, -1, 61, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 258, 259, -1, 261, 262, -1, -1, 265, 266, - 267, 268, -1, 97, -1, 272, 273, 101, 275, 276, - 277, 278, 279, -1, -1, 97, 110, 111, 112, 101, - -1, -1, -1, -1, -1, -1, -1, -1, 110, 111, - 112, -1, -1, -1, -1, -1, -1, 131, -1, -1, - -1, -1, -1, 137, 138, 139, -1, -1, 142, 131, - -1, 145, -1, -1, -1, 137, 138, 139, -1, -1, - 142, -1, -1, 145, -}; -#define YYFINAL 21 -#ifndef YYDEBUG -#define YYDEBUG 0 -#endif -#define YYMAXTOKEN 280 -#if YYDEBUG -char *yyname[] = { -"end-of-file",0,0,0,0,0,0,0,0,0,"'\\n'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,"'$'",0,"'&'",0,"'('","')'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"';'",0, -"'='",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'^'",0, -"'`'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'{'",0,"'}'",0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,"ANDAND","BACKBACK","BANG","CASE","COUNT","DUP","ELSE","END", -"FLAT","FN","FOR","IF","IN","OROR","PIPE","REDIR","SREDIR","SUB","SUBSHELL", -"SWITCH","TWIDDLE","WHILE","WORD","HUH", -}; -const char * const yyrule[] = { -"$accept : rc", -"rc : line end", -"rc : error end", -"end : END", -"end : '\\n'", -"cmdsa : cmd ';'", -"cmdsa : cmd '&'", -"line : cmd", -"line : cmdsa line", -"body : cmd", -"body : cmdsan body", -"cmdsan : cmdsa", -"cmdsan : cmd '\\n'", -"brace : '{' body '}'", -"paren : '(' body ')'", -"assign : first '=' word", -"epilog :", -"epilog : redir epilog", -"redir : DUP", -"redir : REDIR word", -"redir : SREDIR word", -"case : CASE words ';'", -"case : CASE words '\\n'", -"cbody : cmd", -"cbody : case cbody", -"cbody : cmdsan cbody", -"iftail : cmd", -"iftail : brace ELSE optnl cmd", -"cmd :", -"cmd : simple", -"cmd : brace epilog", -"cmd : IF paren optnl iftail", -"cmd : FOR '(' word IN words ')' optnl cmd", -"cmd : FOR '(' word ')' optnl cmd", -"cmd : WHILE paren optnl cmd", -"cmd : SWITCH '(' word ')' optnl '{' cbody '}'", -"cmd : TWIDDLE optcaret word words", -"cmd : cmd ANDAND optnl cmd", -"cmd : cmd OROR optnl cmd", -"cmd : cmd PIPE optnl cmd", -"cmd : redir cmd", -"cmd : assign cmd", -"cmd : BANG optcaret cmd", -"cmd : SUBSHELL optcaret cmd", -"cmd : FN words brace", -"cmd : FN words", -"optcaret :", -"optcaret : '^'", -"simple : first", -"simple : simple word", -"simple : simple redir", -"first : comword", -"first : first '^' sword", -"sword : comword", -"sword : keyword", -"word : sword", -"word : word '^' sword", -"comword : '$' sword", -"comword : '$' sword SUB words ')'", -"comword : COUNT sword", -"comword : FLAT sword", -"comword : '`' sword", -"comword : '`' brace", -"comword : BACKBACK word brace", -"comword : BACKBACK word sword", -"comword : '(' nlwords ')'", -"comword : REDIR brace", -"comword : WORD", -"keyword : FOR", -"keyword : IN", -"keyword : WHILE", -"keyword : IF", -"keyword : SWITCH", -"keyword : FN", -"keyword : ELSE", -"keyword : CASE", -"keyword : TWIDDLE", -"keyword : BANG", -"keyword : SUBSHELL", -"words :", -"words : words word", -"nlwords :", -"nlwords : nlwords '\\n'", -"nlwords : nlwords word", -"optnl :", -"optnl : optnl '\\n'", -}; -#endif -#ifdef YYSTACKSIZE -#undef YYMAXDEPTH -#define YYMAXDEPTH YYSTACKSIZE -#else -#ifdef YYMAXDEPTH -#define YYSTACKSIZE YYMAXDEPTH -#else -#define YYSTACKSIZE 500 -#define YYMAXDEPTH 500 -#endif -#endif -int yydebug; -int yynerrs; -int yyerrflag; -int yychar; -short *yyssp; -YYSTYPE *yyvsp; -YYSTYPE yyval; -YYSTYPE yylval; -short yyss[YYSTACKSIZE]; -YYSTYPE yyvs[YYSTACKSIZE]; -#define yystacksize YYSTACKSIZE -#line 169 "parse.y" - -void initparse() { - star = treecpy(mk(nVar,mk(nWord,"*",NULL)), ealloc); - nolist = treecpy(mk(nVar,mk(nWord,"ifs",NULL)), ealloc); -} - -#line 590 "y.tab.c" -#define YYABORT goto yyabort -#define YYREJECT goto yyabort -#define YYACCEPT goto yyaccept -#define YYERROR goto yyerrlab - -int -yyparse() -{ - register int yym, yyn, yystate; -#if YYDEBUG - register char *yys; - - if ((yys = getenv("YYDEBUG"))) - { - yyn = *yys; - if (yyn >= '0' && yyn <= '9') - yydebug = yyn - '0'; - } -#endif - - yynerrs = 0; - yyerrflag = 0; - yychar = (-1); - - yyssp = yyss; - yyvsp = yyvs; - *yyssp = yystate = 0; - -yyloop: - if ((yyn = yydefred[yystate])) goto yyreduce; - if (yychar < 0) - { - if ((yychar = yylex()) < 0) yychar = 0; -#if YYDEBUG - if (yydebug) - { - yys = 0; - if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; - if (!yys) yys = "illegal-symbol"; - printf("%sdebug: state %d, reading %d (%s)\n", - YYPREFIX, yystate, yychar, yys); - } -#endif - } - if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && - yyn <= YYTABLESIZE && yycheck[yyn] == yychar) - { -#if YYDEBUG - if (yydebug) - printf("%sdebug: state %d, shifting to state %d\n", - YYPREFIX, yystate, yytable[yyn]); -#endif - if (yyssp >= yyss + yystacksize - 1) - { - goto yyoverflow; - } - *++yyssp = yystate = yytable[yyn]; - *++yyvsp = yylval; - yychar = (-1); - if (yyerrflag > 0) --yyerrflag; - goto yyloop; - } - if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && - yyn <= YYTABLESIZE && yycheck[yyn] == yychar) - { - yyn = yytable[yyn]; - goto yyreduce; - } - if (yyerrflag) goto yyinrecovery; -#if defined(lint) || defined(__GNUC__) - goto yynewerror; -#endif -yynewerror: - yyerror("syntax error"); -#if defined(lint) || defined(__GNUC__) - goto yyerrlab; -#endif -yyerrlab: - ++yynerrs; -yyinrecovery: - if (yyerrflag < 3) - { - yyerrflag = 3; - for (;;) - { - if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 && - yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) - { -#if YYDEBUG - if (yydebug) - printf("%sdebug: state %d, error recovery shifting\ - to state %d\n", YYPREFIX, *yyssp, yytable[yyn]); -#endif - if (yyssp >= yyss + yystacksize - 1) - { - goto yyoverflow; - } - *++yyssp = yystate = yytable[yyn]; - *++yyvsp = yylval; - goto yyloop; - } - else - { -#if YYDEBUG - if (yydebug) - printf("%sdebug: error recovery discarding state %d\n", - YYPREFIX, *yyssp); -#endif - if (yyssp <= yyss) goto yyabort; - --yyssp; - --yyvsp; - } - } - } - else - { - if (yychar == 0) goto yyabort; -#if YYDEBUG - if (yydebug) - { - yys = 0; - if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; - if (!yys) yys = "illegal-symbol"; - printf("%sdebug: state %d, error recovery discards token %d (%s)\n", - YYPREFIX, yystate, yychar, yys); - } -#endif - yychar = (-1); - goto yyloop; - } -yyreduce: -#if YYDEBUG - if (yydebug) - printf("%sdebug: state %d, reducing by rule %d (%s)\n", - YYPREFIX, yystate, yyn, yyrule[yyn]); -#endif - yym = yylen[yyn]; - yyval = yyvsp[1-yym]; - switch (yyn) - { -case 1: -#line 49 "parse.y" -{ parsetree = yyvsp[-1].node; YYACCEPT; } -break; -case 2: -#line 50 "parse.y" -{ yyerrok; parsetree = NULL; YYABORT; } -break; -case 3: -#line 53 "parse.y" -{ if (!heredoc(1)) YYABORT; } -break; -case 4: -#line 54 "parse.y" -{ if (!heredoc(0)) YYABORT; } -break; -case 6: -#line 58 "parse.y" -{ yyval.node = (yyvsp[-1].node != NULL ? mk(nNowait,yyvsp[-1].node) : yyvsp[-1].node); } -break; -case 8: -#line 62 "parse.y" -{ yyval.node = (yyvsp[-1].node != NULL ? mk(nBody,yyvsp[-1].node,yyvsp[0].node) : yyvsp[0].node); } -break; -case 10: -#line 66 "parse.y" -{ yyval.node = (yyvsp[-1].node == NULL ? yyvsp[0].node : yyvsp[0].node == NULL ? yyvsp[-1].node : mk(nBody,yyvsp[-1].node,yyvsp[0].node)); } -break; -case 12: -#line 69 "parse.y" -{ yyval.node = yyvsp[-1].node; if (!heredoc(0)) YYABORT; } -break; -case 13: -#line 71 "parse.y" -{ yyval.node = yyvsp[-1].node; } -break; -case 14: -#line 73 "parse.y" -{ yyval.node = yyvsp[-1].node; } -break; -case 15: -#line 75 "parse.y" -{ yyval.node = mk(nAssign,yyvsp[-2].node,yyvsp[0].node); } -break; -case 16: -#line 77 "parse.y" -{ yyval.node = NULL; } -break; -case 17: -#line 78 "parse.y" -{ yyval.node = mk(nEpilog,yyvsp[-1].node,yyvsp[0].node); } -break; -case 18: -#line 81 "parse.y" -{ yyval.node = mk(nDup,yyvsp[0].dup.type,yyvsp[0].dup.left,yyvsp[0].dup.right); } -break; -case 19: -#line 82 "parse.y" -{ yyval.node = mk(nRedir,yyvsp[-1].redir.type,yyvsp[-1].redir.fd,yyvsp[0].node); - if (yyvsp[-1].redir.type == rHeredoc && !qdoc(yyvsp[0].node, yyval.node)) YYABORT; /* queue heredocs up */ - } -break; -case 20: -#line 85 "parse.y" -{ yyval.node = mk(nRedir,yyvsp[-1].redir.type,yyvsp[-1].redir.fd,yyvsp[0].node); - if (yyvsp[-1].redir.type == rHeredoc && !qdoc(yyvsp[0].node, yyval.node)) YYABORT; /* queue heredocs up */ - } -break; -case 21: -#line 89 "parse.y" -{ yyval.node = mk(nCase, yyvsp[-1].node); } -break; -case 22: -#line 90 "parse.y" -{ yyval.node = mk(nCase, yyvsp[-1].node); } -break; -case 23: -#line 92 "parse.y" -{ yyval.node = mk(nCbody, yyvsp[0].node, NULL); } -break; -case 24: -#line 93 "parse.y" -{ yyval.node = mk(nCbody, yyvsp[-1].node, yyvsp[0].node); } -break; -case 25: -#line 94 "parse.y" -{ yyval.node = mk(nCbody, yyvsp[-1].node, yyvsp[0].node); } -break; -case 27: -#line 97 "parse.y" -{ yyval.node = mk(nElse,yyvsp[-3].node,yyvsp[0].node); } -break; -case 28: -#line 99 "parse.y" -{ yyval.node = NULL; } -break; -case 30: -#line 101 "parse.y" -{ yyval.node = mk(nBrace,yyvsp[-1].node,yyvsp[0].node); } -break; -case 31: -#line 102 "parse.y" -{ yyval.node = mk(nIf,yyvsp[-2].node,yyvsp[0].node); } -break; -case 32: -#line 103 "parse.y" -{ yyval.node = mk(nForin,yyvsp[-5].node,yyvsp[-3].node,yyvsp[0].node); } -break; -case 33: -#line 104 "parse.y" -{ yyval.node = mk(nForin,yyvsp[-3].node,star,yyvsp[0].node); } -break; -case 34: -#line 105 "parse.y" -{ yyval.node = mk(nWhile,yyvsp[-2].node,yyvsp[0].node); } -break; -case 35: -#line 106 "parse.y" -{ yyval.node = mk(nSwitch,yyvsp[-5].node,yyvsp[-1].node); } -break; -case 36: -#line 107 "parse.y" -{ yyval.node = mk(nMatch,yyvsp[-1].node,yyvsp[0].node); } -break; -case 37: -#line 108 "parse.y" -{ yyval.node = mk(nAndalso,yyvsp[-3].node,yyvsp[0].node); } -break; -case 38: -#line 109 "parse.y" -{ yyval.node = mk(nOrelse,yyvsp[-3].node,yyvsp[0].node); } -break; -case 39: -#line 110 "parse.y" -{ yyval.node = mk(nPipe,yyvsp[-2].pipe.left,yyvsp[-2].pipe.right,yyvsp[-3].node,yyvsp[0].node); } -break; -case 40: -#line 111 "parse.y" -{ yyval.node = (yyvsp[0].node != NULL ? mk(nPre,yyvsp[-1].node,yyvsp[0].node) : yyvsp[-1].node); } -break; -case 41: -#line 112 "parse.y" -{ yyval.node = (yyvsp[0].node != NULL ? mk(nPre,yyvsp[-1].node,yyvsp[0].node) : yyvsp[-1].node); } -break; -case 42: -#line 113 "parse.y" -{ yyval.node = mk(nBang,yyvsp[0].node); } -break; -case 43: -#line 114 "parse.y" -{ yyval.node = mk(nSubshell,yyvsp[0].node); } -break; -case 44: -#line 115 "parse.y" -{ yyval.node = mk(nNewfn,yyvsp[-1].node,yyvsp[0].node); } -break; -case 45: -#line 116 "parse.y" -{ yyval.node = mk(nRmfn,yyvsp[0].node); } -break; -case 49: -#line 122 "parse.y" -{ yyval.node = (yyvsp[0].node != NULL ? mk(nArgs,yyvsp[-1].node,yyvsp[0].node) : yyvsp[-1].node); } -break; -case 50: -#line 123 "parse.y" -{ yyval.node = mk(nArgs,yyvsp[-1].node,yyvsp[0].node); } -break; -case 52: -#line 126 "parse.y" -{ yyval.node = mk(nConcat,yyvsp[-2].node,yyvsp[0].node); } -break; -case 54: -#line 129 "parse.y" -{ yyval.node = mk(nWord,yyvsp[0].keyword, NULL); } -break; -case 56: -#line 132 "parse.y" -{ yyval.node = mk(nConcat,yyvsp[-2].node,yyvsp[0].node); } -break; -case 57: -#line 134 "parse.y" -{ yyval.node = mk(nVar,yyvsp[0].node); } -break; -case 58: -#line 135 "parse.y" -{ yyval.node = mk(nVarsub,yyvsp[-3].node,yyvsp[-1].node); } -break; -case 59: -#line 136 "parse.y" -{ yyval.node = mk(nCount,yyvsp[0].node); } -break; -case 60: -#line 137 "parse.y" -{ yyval.node = mk(nFlat, yyvsp[0].node); } -break; -case 61: -#line 138 "parse.y" -{ yyval.node = mk(nBackq,nolist,yyvsp[0].node); } -break; -case 62: -#line 139 "parse.y" -{ yyval.node = mk(nBackq,nolist,yyvsp[0].node); } -break; -case 63: -#line 140 "parse.y" -{ yyval.node = mk(nBackq,yyvsp[-1].node,yyvsp[0].node); } -break; -case 64: -#line 141 "parse.y" -{ yyval.node = mk(nBackq,yyvsp[-1].node,yyvsp[0].node); } -break; -case 65: -#line 142 "parse.y" -{ yyval.node = yyvsp[-1].node; } -break; -case 66: -#line 143 "parse.y" -{ yyval.node = mk(nNmpipe,yyvsp[-1].redir.type,yyvsp[-1].redir.fd,yyvsp[0].node); } -break; -case 67: -#line 144 "parse.y" -{ yyval.node = (yyvsp[0].word.w[0] == '\'') ? mk(nQword, yyvsp[0].word.w+1, NULL) : mk(nWord,yyvsp[0].word.w, yyvsp[0].word.m); } -break; -case 68: -#line 146 "parse.y" -{ yyval.keyword = "for"; } -break; -case 69: -#line 147 "parse.y" -{ yyval.keyword = "in"; } -break; -case 70: -#line 148 "parse.y" -{ yyval.keyword = "while"; } -break; -case 71: -#line 149 "parse.y" -{ yyval.keyword = "if"; } -break; -case 72: -#line 150 "parse.y" -{ yyval.keyword = "switch"; } -break; -case 73: -#line 151 "parse.y" -{ yyval.keyword = "fn"; } -break; -case 74: -#line 152 "parse.y" -{ yyval.keyword = "else"; } -break; -case 75: -#line 153 "parse.y" -{ yyval.keyword = "case"; } -break; -case 76: -#line 154 "parse.y" -{ yyval.keyword = "~"; } -break; -case 77: -#line 155 "parse.y" -{ yyval.keyword = "!"; } -break; -case 78: -#line 156 "parse.y" -{ yyval.keyword = "@"; } -break; -case 79: -#line 158 "parse.y" -{ yyval.node = NULL; } -break; -case 80: -#line 159 "parse.y" -{ yyval.node = (yyvsp[-1].node != NULL ? (yyvsp[0].node != NULL ? mk(nLappend,yyvsp[-1].node,yyvsp[0].node) : yyvsp[-1].node) : yyvsp[0].node); } -break; -case 81: -#line 161 "parse.y" -{ yyval.node = NULL; } -break; -case 83: -#line 163 "parse.y" -{ yyval.node = (yyvsp[-1].node != NULL ? (yyvsp[0].node != NULL ? mk(nLappend,yyvsp[-1].node,yyvsp[0].node) : yyvsp[-1].node) : yyvsp[0].node); } -break; -#line 1015 "y.tab.c" - } - yyssp -= yym; - yystate = *yyssp; - yyvsp -= yym; - yym = yylhs[yyn]; - if (yystate == 0 && yym == 0) - { -#if YYDEBUG - if (yydebug) - printf("%sdebug: after reduction, shifting from state 0 to\ - state %d\n", YYPREFIX, YYFINAL); -#endif - yystate = YYFINAL; - *++yyssp = YYFINAL; - *++yyvsp = yyval; - if (yychar < 0) - { - if ((yychar = yylex()) < 0) yychar = 0; -#if YYDEBUG - if (yydebug) - { - yys = 0; - if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; - if (!yys) yys = "illegal-symbol"; - printf("%sdebug: state %d, reading %d (%s)\n", - YYPREFIX, YYFINAL, yychar, yys); - } -#endif - } - if (yychar == 0) goto yyaccept; - goto yyloop; - } - if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && - yyn <= YYTABLESIZE && yycheck[yyn] == yystate) - yystate = yytable[yyn]; - else - yystate = yydgoto[yym]; -#if YYDEBUG - if (yydebug) - printf("%sdebug: after reduction, shifting from state %d \ -to state %d\n", YYPREFIX, *yyssp, yystate); -#endif - if (yyssp >= yyss + yystacksize - 1) - { - goto yyoverflow; - } - *++yyssp = yystate; - *++yyvsp = yyval; - goto yyloop; -yyoverflow: - yyerror("yacc stack overflow"); -yyabort: - return (1); -yyaccept: - return (0); -} diff --git a/y.tab.h b/y.tab.h @@ -1,33 +0,0 @@ -#define ANDAND 257 -#define BACKBACK 258 -#define BANG 259 -#define CASE 260 -#define COUNT 261 -#define DUP 262 -#define ELSE 263 -#define END 264 -#define FLAT 265 -#define FN 266 -#define FOR 267 -#define IF 268 -#define IN 269 -#define OROR 270 -#define PIPE 271 -#define REDIR 272 -#define SREDIR 273 -#define SUB 274 -#define SUBSHELL 275 -#define SWITCH 276 -#define TWIDDLE 277 -#define WHILE 278 -#define WORD 279 -#define HUH 280 -typedef union { - struct Node *node; - struct Redir redir; - struct Pipe pipe; - struct Dup dup; - struct Word word; - char *keyword; -} YYSTYPE; -extern YYSTYPE yylval;