xref: /freebsd/bin/sh/TOUR (revision 4b88c807ea9c629dc5691abc7e3cac9ea0d776dd)
14b88c807SRodney W. Grimes#	@(#)TOUR	8.1 (Berkeley) 5/31/93
24b88c807SRodney W. Grimes
34b88c807SRodney W. GrimesNOTE -- This is the original TOUR paper distributed with ash and
44b88c807SRodney W. Grimesdoes not represent the current state of the shell.  It is provided anyway
54b88c807SRodney W. Grimessince it provides helpful information for how the shell is structured,
64b88c807SRodney W. Grimesbut be warned that things have changed -- the current shell is
74b88c807SRodney W. Grimesstill under development.
84b88c807SRodney W. Grimes
94b88c807SRodney W. Grimes================================================================
104b88c807SRodney W. Grimes
114b88c807SRodney W. Grimes                       A Tour through Ash
124b88c807SRodney W. Grimes
134b88c807SRodney W. Grimes               Copyright 1989 by Kenneth Almquist.
144b88c807SRodney W. Grimes
154b88c807SRodney W. Grimes
164b88c807SRodney W. GrimesDIRECTORIES:  The subdirectory bltin contains commands which can
174b88c807SRodney W. Grimesbe compiled stand-alone.  The rest of the source is in the main
184b88c807SRodney W. Grimesash directory.
194b88c807SRodney W. Grimes
204b88c807SRodney W. GrimesSOURCE CODE GENERATORS:  Files whose names begin with "mk" are
214b88c807SRodney W. Grimesprograms that generate source code.  A complete list of these
224b88c807SRodney W. Grimesprograms is:
234b88c807SRodney W. Grimes
244b88c807SRodney W. Grimes        program         intput files        generates
254b88c807SRodney W. Grimes        -------         ------------        ---------
264b88c807SRodney W. Grimes        mkbuiltins      builtins            builtins.h builtins.c
274b88c807SRodney W. Grimes        mkinit          *.c                 init.c
284b88c807SRodney W. Grimes        mknodes         nodetypes           nodes.h nodes.c
294b88c807SRodney W. Grimes        mksignames          -               signames.h signames.c
304b88c807SRodney W. Grimes        mksyntax            -               syntax.h syntax.c
314b88c807SRodney W. Grimes        mktokens            -               token.def
324b88c807SRodney W. Grimes        bltin/mkexpr    unary_op binary_op  operators.h operators.c
334b88c807SRodney W. Grimes
344b88c807SRodney W. GrimesThere are undoubtedly too many of these.  Mkinit searches all the
354b88c807SRodney W. GrimesC source files for entries looking like:
364b88c807SRodney W. Grimes
374b88c807SRodney W. Grimes        INIT {
384b88c807SRodney W. Grimes              x = 1;    /* executed during initialization */
394b88c807SRodney W. Grimes        }
404b88c807SRodney W. Grimes
414b88c807SRodney W. Grimes        RESET {
424b88c807SRodney W. Grimes              x = 2;    /* executed when the shell does a longjmp
434b88c807SRodney W. Grimes                           back to the main command loop */
444b88c807SRodney W. Grimes        }
454b88c807SRodney W. Grimes
464b88c807SRodney W. Grimes        SHELLPROC {
474b88c807SRodney W. Grimes              x = 3;    /* executed when the shell runs a shell procedure */
484b88c807SRodney W. Grimes        }
494b88c807SRodney W. Grimes
504b88c807SRodney W. GrimesIt pulls this code out into routines which are when particular
514b88c807SRodney W. Grimesevents occur.  The intent is to improve modularity by isolating
524b88c807SRodney W. Grimesthe information about which modules need to be explicitly
534b88c807SRodney W. Grimesinitialized/reset within the modules themselves.
544b88c807SRodney W. Grimes
554b88c807SRodney W. GrimesMkinit recognizes several constructs for placing declarations in
564b88c807SRodney W. Grimesthe init.c file.
574b88c807SRodney W. Grimes        INCLUDE "file.h"
584b88c807SRodney W. Grimesincludes a file.  The storage class MKINIT makes a declaration
594b88c807SRodney W. Grimesavailable in the init.c file, for example:
604b88c807SRodney W. Grimes        MKINIT int funcnest;    /* depth of function calls */
614b88c807SRodney W. GrimesMKINIT alone on a line introduces a structure or union declara-
624b88c807SRodney W. Grimestion:
634b88c807SRodney W. Grimes        MKINIT
644b88c807SRodney W. Grimes        struct redirtab {
654b88c807SRodney W. Grimes              short renamed[10];
664b88c807SRodney W. Grimes        };
674b88c807SRodney W. GrimesPreprocessor #define statements are copied to init.c without any
684b88c807SRodney W. Grimesspecial action to request this.
694b88c807SRodney W. Grimes
704b88c807SRodney W. GrimesINDENTATION:  The ash source is indented in multiples of six
714b88c807SRodney W. Grimesspaces.  The only study that I have heard of on the subject con-
724b88c807SRodney W. Grimescluded that the optimal amount to indent is in the range of four
734b88c807SRodney W. Grimesto six spaces.  I use six spaces since it is not too big a jump
744b88c807SRodney W. Grimesfrom the widely used eight spaces.  If you really hate six space
754b88c807SRodney W. Grimesindentation, use the adjind (source included) program to change
764b88c807SRodney W. Grimesit to something else.
774b88c807SRodney W. Grimes
784b88c807SRodney W. GrimesEXCEPTIONS:  Code for dealing with exceptions appears in
794b88c807SRodney W. Grimesexceptions.c.  The C language doesn't include exception handling,
804b88c807SRodney W. Grimesso I implement it using setjmp and longjmp.  The global variable
814b88c807SRodney W. Grimesexception contains the type of exception.  EXERROR is raised by
824b88c807SRodney W. Grimescalling error.  EXINT is an interrupt.  EXSHELLPROC is an excep-
834b88c807SRodney W. Grimestion which is raised when a shell procedure is invoked.  The pur-
844b88c807SRodney W. Grimespose of EXSHELLPROC is to perform the cleanup actions associated
854b88c807SRodney W. Grimeswith other exceptions.  After these cleanup actions, the shell
864b88c807SRodney W. Grimescan interpret a shell procedure itself without exec'ing a new
874b88c807SRodney W. Grimescopy of the shell.
884b88c807SRodney W. Grimes
894b88c807SRodney W. GrimesINTERRUPTS:  In an interactive shell, an interrupt will cause an
904b88c807SRodney W. GrimesEXINT exception to return to the main command loop.  (Exception:
914b88c807SRodney W. GrimesEXINT is not raised if the user traps interrupts using the trap
924b88c807SRodney W. Grimescommand.)  The INTOFF and INTON macros (defined in exception.h)
934b88c807SRodney W. Grimesprovide uninterruptable critical sections.  Between the execution
944b88c807SRodney W. Grimesof INTOFF and the execution of INTON, interrupt signals will be
954b88c807SRodney W. Grimesheld for later delivery.  INTOFF and INTON can be nested.
964b88c807SRodney W. Grimes
974b88c807SRodney W. GrimesMEMALLOC.C:  Memalloc.c defines versions of malloc and realloc
984b88c807SRodney W. Grimeswhich call error when there is no memory left.  It also defines a
994b88c807SRodney W. Grimesstack oriented memory allocation scheme.  Allocating off a stack
1004b88c807SRodney W. Grimesis probably more efficient than allocation using malloc, but the
1014b88c807SRodney W. Grimesbig advantage is that when an exception occurs all we have to do
1024b88c807SRodney W. Grimesto free up the memory in use at the time of the exception is to
1034b88c807SRodney W. Grimesrestore the stack pointer.  The stack is implemented using a
1044b88c807SRodney W. Grimeslinked list of blocks.
1054b88c807SRodney W. Grimes
1064b88c807SRodney W. GrimesSTPUTC:  If the stack were contiguous, it would be easy to store
1074b88c807SRodney W. Grimesstrings on the stack without knowing in advance how long the
1084b88c807SRodney W. Grimesstring was going to be:
1094b88c807SRodney W. Grimes        p = stackptr;
1104b88c807SRodney W. Grimes        *p++ = c;       /* repeated as many times as needed */
1114b88c807SRodney W. Grimes        stackptr = p;
1124b88c807SRodney W. GrimesThe folloing three macros (defined in memalloc.h) perform these
1134b88c807SRodney W. Grimesoperations, but grow the stack if you run off the end:
1144b88c807SRodney W. Grimes        STARTSTACKSTR(p);
1154b88c807SRodney W. Grimes        STPUTC(c, p);   /* repeated as many times as needed */
1164b88c807SRodney W. Grimes        grabstackstr(p);
1174b88c807SRodney W. Grimes
1184b88c807SRodney W. GrimesWe now start a top-down look at the code:
1194b88c807SRodney W. Grimes
1204b88c807SRodney W. GrimesMAIN.C:  The main routine performs some initialization, executes
1214b88c807SRodney W. Grimesthe user's profile if necessary, and calls cmdloop.  Cmdloop is
1224b88c807SRodney W. Grimesrepeatedly parses and executes commands.
1234b88c807SRodney W. Grimes
1244b88c807SRodney W. GrimesOPTIONS.C:  This file contains the option processing code.  It is
1254b88c807SRodney W. Grimescalled from main to parse the shell arguments when the shell is
1264b88c807SRodney W. Grimesinvoked, and it also contains the set builtin.  The -i and -j op-
1274b88c807SRodney W. Grimestions (the latter turns on job control) require changes in signal
1284b88c807SRodney W. Grimeshandling.  The routines setjobctl (in jobs.c) and setinteractive
1294b88c807SRodney W. Grimes(in trap.c) are called to handle changes to these options.
1304b88c807SRodney W. Grimes
1314b88c807SRodney W. GrimesPARSING:  The parser code is all in parser.c.  A recursive des-
1324b88c807SRodney W. Grimescent parser is used.  Syntax tables (generated by mksyntax) are
1334b88c807SRodney W. Grimesused to classify characters during lexical analysis.  There are
1344b88c807SRodney W. Grimesthree tables:  one for normal use, one for use when inside single
1354b88c807SRodney W. Grimesquotes, and one for use when inside double quotes.  The tables
1364b88c807SRodney W. Grimesare machine dependent because they are indexed by character vari-
1374b88c807SRodney W. Grimesables and the range of a char varies from machine to machine.
1384b88c807SRodney W. Grimes
1394b88c807SRodney W. GrimesPARSE OUTPUT:  The output of the parser consists of a tree of
1404b88c807SRodney W. Grimesnodes.  The various types of nodes are defined in the file node-
1414b88c807SRodney W. Grimestypes.
1424b88c807SRodney W. Grimes
1434b88c807SRodney W. GrimesNodes of type NARG are used to represent both words and the con-
1444b88c807SRodney W. Grimestents of here documents.  An early version of ash kept the con-
1454b88c807SRodney W. Grimestents of here documents in temporary files, but keeping here do-
1464b88c807SRodney W. Grimescuments in memory typically results in significantly better per-
1474b88c807SRodney W. Grimesformance.  It would have been nice to make it an option to use
1484b88c807SRodney W. Grimestemporary files for here documents, for the benefit of small
1494b88c807SRodney W. Grimesmachines, but the code to keep track of when to delete the tem-
1504b88c807SRodney W. Grimesporary files was complex and I never fixed all the bugs in it.
1514b88c807SRodney W. Grimes(AT&T has been maintaining the Bourne shell for more than ten
1524b88c807SRodney W. Grimesyears, and to the best of my knowledge they still haven't gotten
1534b88c807SRodney W. Grimesit to handle temporary files correctly in obscure cases.)
1544b88c807SRodney W. Grimes
1554b88c807SRodney W. GrimesThe text field of a NARG structure points to the text of the
1564b88c807SRodney W. Grimesword.  The text consists of ordinary characters and a number of
1574b88c807SRodney W. Grimesspecial codes defined in parser.h.  The special codes are:
1584b88c807SRodney W. Grimes
1594b88c807SRodney W. Grimes        CTLVAR              Variable substitution
1604b88c807SRodney W. Grimes        CTLENDVAR           End of variable substitution
1614b88c807SRodney W. Grimes        CTLBACKQ            Command substitution
1624b88c807SRodney W. Grimes        CTLBACKQ|CTLQUOTE   Command substitution inside double quotes
1634b88c807SRodney W. Grimes        CTLESC              Escape next character
1644b88c807SRodney W. Grimes
1654b88c807SRodney W. GrimesA variable substitution contains the following elements:
1664b88c807SRodney W. Grimes
1674b88c807SRodney W. Grimes        CTLVAR type name '=' [ alternative-text CTLENDVAR ]
1684b88c807SRodney W. Grimes
1694b88c807SRodney W. GrimesThe type field is a single character specifying the type of sub-
1704b88c807SRodney W. Grimesstitution.  The possible types are:
1714b88c807SRodney W. Grimes
1724b88c807SRodney W. Grimes        VSNORMAL            $var
1734b88c807SRodney W. Grimes        VSMINUS             ${var-text}
1744b88c807SRodney W. Grimes        VSMINUS|VSNUL       ${var:-text}
1754b88c807SRodney W. Grimes        VSPLUS              ${var+text}
1764b88c807SRodney W. Grimes        VSPLUS|VSNUL        ${var:+text}
1774b88c807SRodney W. Grimes        VSQUESTION          ${var?text}
1784b88c807SRodney W. Grimes        VSQUESTION|VSNUL    ${var:?text}
1794b88c807SRodney W. Grimes        VSASSIGN            ${var=text}
1804b88c807SRodney W. Grimes        VSASSIGN|VSNUL      ${var=text}
1814b88c807SRodney W. Grimes
1824b88c807SRodney W. GrimesIn addition, the type field will have the VSQUOTE flag set if the
1834b88c807SRodney W. Grimesvariable is enclosed in double quotes.  The name of the variable
1844b88c807SRodney W. Grimescomes next, terminated by an equals sign.  If the type is not
1854b88c807SRodney W. GrimesVSNORMAL, then the text field in the substitution follows, ter-
1864b88c807SRodney W. Grimesminated by a CTLENDVAR byte.
1874b88c807SRodney W. Grimes
1884b88c807SRodney W. GrimesCommands in back quotes are parsed and stored in a linked list.
1894b88c807SRodney W. GrimesThe locations of these commands in the string are indicated by
1904b88c807SRodney W. GrimesCTLBACKQ and CTLBACKQ+CTLQUOTE characters, depending upon whether
1914b88c807SRodney W. Grimesthe back quotes were enclosed in double quotes.
1924b88c807SRodney W. Grimes
1934b88c807SRodney W. GrimesThe character CTLESC escapes the next character, so that in case
1944b88c807SRodney W. Grimesany of the CTL characters mentioned above appear in the input,
1954b88c807SRodney W. Grimesthey can be passed through transparently.  CTLESC is also used to
1964b88c807SRodney W. Grimesescape '*', '?', '[', and '!' characters which were quoted by the
1974b88c807SRodney W. Grimesuser and thus should not be used for file name generation.
1984b88c807SRodney W. Grimes
1994b88c807SRodney W. GrimesCTLESC characters have proved to be particularly tricky to get
2004b88c807SRodney W. Grimesright.  In the case of here documents which are not subject to
2014b88c807SRodney W. Grimesvariable and command substitution, the parser doesn't insert any
2024b88c807SRodney W. GrimesCTLESC characters to begin with (so the contents of the text
2034b88c807SRodney W. Grimesfield can be written without any processing).  Other here docu-
2044b88c807SRodney W. Grimesments, and words which are not subject to splitting and file name
2054b88c807SRodney W. Grimesgeneration, have the CTLESC characters removed during the vari-
2064b88c807SRodney W. Grimesable and command substitution phase.  Words which are subject
2074b88c807SRodney W. Grimessplitting and file name generation have the CTLESC characters re-
2084b88c807SRodney W. Grimesmoved as part of the file name phase.
2094b88c807SRodney W. Grimes
2104b88c807SRodney W. GrimesEXECUTION:  Command execution is handled by the following files:
2114b88c807SRodney W. Grimes        eval.c     The top level routines.
2124b88c807SRodney W. Grimes        redir.c    Code to handle redirection of input and output.
2134b88c807SRodney W. Grimes        jobs.c     Code to handle forking, waiting, and job control.
2144b88c807SRodney W. Grimes        exec.c     Code to to path searches and the actual exec sys call.
2154b88c807SRodney W. Grimes        expand.c   Code to evaluate arguments.
2164b88c807SRodney W. Grimes        var.c      Maintains the variable symbol table.  Called from expand.c.
2174b88c807SRodney W. Grimes
2184b88c807SRodney W. GrimesEVAL.C:  Evaltree recursively executes a parse tree.  The exit
2194b88c807SRodney W. Grimesstatus is returned in the global variable exitstatus.  The alter-
2204b88c807SRodney W. Grimesnative entry evalbackcmd is called to evaluate commands in back
2214b88c807SRodney W. Grimesquotes.  It saves the result in memory if the command is a buil-
2224b88c807SRodney W. Grimestin; otherwise it forks off a child to execute the command and
2234b88c807SRodney W. Grimesconnects the standard output of the child to a pipe.
2244b88c807SRodney W. Grimes
2254b88c807SRodney W. GrimesJOBS.C:  To create a process, you call makejob to return a job
2264b88c807SRodney W. Grimesstructure, and then call forkshell (passing the job structure as
2274b88c807SRodney W. Grimesan argument) to create the process.  Waitforjob waits for a job
2284b88c807SRodney W. Grimesto complete.  These routines take care of process groups if job
2294b88c807SRodney W. Grimescontrol is defined.
2304b88c807SRodney W. Grimes
2314b88c807SRodney W. GrimesREDIR.C:  Ash allows file descriptors to be redirected and then
2324b88c807SRodney W. Grimesrestored without forking off a child process.  This is accom-
2334b88c807SRodney W. Grimesplished by duplicating the original file descriptors.  The redir-
2344b88c807SRodney W. Grimestab structure records where the file descriptors have be dupli-
2354b88c807SRodney W. Grimescated to.
2364b88c807SRodney W. Grimes
2374b88c807SRodney W. GrimesEXEC.C:  The routine find_command locates a command, and enters
2384b88c807SRodney W. Grimesthe command in the hash table if it is not already there.  The
2394b88c807SRodney W. Grimesthird argument specifies whether it is to print an error message
2404b88c807SRodney W. Grimesif the command is not found.  (When a pipeline is set up,
2414b88c807SRodney W. Grimesfind_command is called for all the commands in the pipeline be-
2424b88c807SRodney W. Grimesfore any forking is done, so to get the commands into the hash
2434b88c807SRodney W. Grimestable of the parent process.  But to make command hashing as
2444b88c807SRodney W. Grimestransparent as possible, we silently ignore errors at that point
2454b88c807SRodney W. Grimesand only print error messages if the command cannot be found
2464b88c807SRodney W. Grimeslater.)
2474b88c807SRodney W. Grimes
2484b88c807SRodney W. GrimesThe routine shellexec is the interface to the exec system call.
2494b88c807SRodney W. Grimes
2504b88c807SRodney W. GrimesEXPAND.C:  Arguments are processed in three passes.  The first
2514b88c807SRodney W. Grimes(performed by the routine argstr) performs variable and command
2524b88c807SRodney W. Grimessubstitution.  The second (ifsbreakup) performs word splitting
2534b88c807SRodney W. Grimesand the third (expandmeta) performs file name generation.  If the
2544b88c807SRodney W. Grimes"/u" directory is simulated, then when "/u/username" is replaced
2554b88c807SRodney W. Grimesby the user's home directory, the flag "didudir" is set.  This
2564b88c807SRodney W. Grimestells the cd command that it should print out the directory name,
2574b88c807SRodney W. Grimesjust as it would if the "/u" directory were implemented using
2584b88c807SRodney W. Grimessymbolic links.
2594b88c807SRodney W. Grimes
2604b88c807SRodney W. GrimesVAR.C:  Variables are stored in a hash table.  Probably we should
2614b88c807SRodney W. Grimesswitch to extensible hashing.  The variable name is stored in the
2624b88c807SRodney W. Grimessame string as the value (using the format "name=value") so that
2634b88c807SRodney W. Grimesno string copying is needed to create the environment of a com-
2644b88c807SRodney W. Grimesmand.  Variables which the shell references internally are preal-
2654b88c807SRodney W. Grimeslocated so that the shell can reference the values of these vari-
2664b88c807SRodney W. Grimesables without doing a lookup.
2674b88c807SRodney W. Grimes
2684b88c807SRodney W. GrimesWhen a program is run, the code in eval.c sticks any environment
2694b88c807SRodney W. Grimesvariables which precede the command (as in "PATH=xxx command") in
2704b88c807SRodney W. Grimesthe variable table as the simplest way to strip duplicates, and
2714b88c807SRodney W. Grimesthen calls "environment" to get the value of the environment.
2724b88c807SRodney W. GrimesThere are two consequences of this.  First, if an assignment to
2734b88c807SRodney W. GrimesPATH precedes the command, the value of PATH before the assign-
2744b88c807SRodney W. Grimesment must be remembered and passed to shellexec.  Second, if the
2754b88c807SRodney W. Grimesprogram turns out to be a shell procedure, the strings from the
2764b88c807SRodney W. Grimesenvironment variables which preceded the command must be pulled
2774b88c807SRodney W. Grimesout of the table and replaced with strings obtained from malloc,
2784b88c807SRodney W. Grimessince the former will automatically be freed when the stack (see
2794b88c807SRodney W. Grimesthe entry on memalloc.c) is emptied.
2804b88c807SRodney W. Grimes
2814b88c807SRodney W. GrimesBUILTIN COMMANDS:  The procedures for handling these are scat-
2824b88c807SRodney W. Grimestered throughout the code, depending on which location appears
2834b88c807SRodney W. Grimesmost appropriate.  They can be recognized because their names al-
2844b88c807SRodney W. Grimesways end in "cmd".  The mapping from names to procedures is
2854b88c807SRodney W. Grimesspecified in the file builtins, which is processed by the mkbuil-
2864b88c807SRodney W. Grimestins command.
2874b88c807SRodney W. Grimes
2884b88c807SRodney W. GrimesA builtin command is invoked with argc and argv set up like a
2894b88c807SRodney W. Grimesnormal program.  A builtin command is allowed to overwrite its
2904b88c807SRodney W. Grimesarguments.  Builtin routines can call nextopt to do option pars-
2914b88c807SRodney W. Grimesing.  This is kind of like getopt, but you don't pass argc and
2924b88c807SRodney W. Grimesargv to it.  Builtin routines can also call error.  This routine
2934b88c807SRodney W. Grimesnormally terminates the shell (or returns to the main command
2944b88c807SRodney W. Grimesloop if the shell is interactive), but when called from a builtin
2954b88c807SRodney W. Grimescommand it causes the builtin command to terminate with an exit
2964b88c807SRodney W. Grimesstatus of 2.
2974b88c807SRodney W. Grimes
2984b88c807SRodney W. GrimesThe directory bltins contains commands which can be compiled in-
2994b88c807SRodney W. Grimesdependently but can also be built into the shell for efficiency
3004b88c807SRodney W. Grimesreasons.  The makefile in this directory compiles these programs
3014b88c807SRodney W. Grimesin the normal fashion (so that they can be run regardless of
3024b88c807SRodney W. Grimeswhether the invoker is ash), but also creates a library named
3034b88c807SRodney W. Grimesbltinlib.a which can be linked with ash.  The header file bltin.h
3044b88c807SRodney W. Grimestakes care of most of the differences between the ash and the
3054b88c807SRodney W. Grimesstand-alone environment.  The user should call the main routine
3064b88c807SRodney W. Grimes"main", and #define main to be the name of the routine to use
3074b88c807SRodney W. Grimeswhen the program is linked into ash.  This #define should appear
3084b88c807SRodney W. Grimesbefore bltin.h is included; bltin.h will #undef main if the pro-
3094b88c807SRodney W. Grimesgram is to be compiled stand-alone.
3104b88c807SRodney W. Grimes
3114b88c807SRodney W. GrimesCD.C:  This file defines the cd and pwd builtins.  The pwd com-
3124b88c807SRodney W. Grimesmand runs /bin/pwd the first time it is invoked (unless the user
3134b88c807SRodney W. Grimeshas already done a cd to an absolute pathname), but then
3144b88c807SRodney W. Grimesremembers the current directory and updates it when the cd com-
3154b88c807SRodney W. Grimesmand is run, so subsequent pwd commands run very fast.  The main
3164b88c807SRodney W. Grimescomplication in the cd command is in the docd command, which
3174b88c807SRodney W. Grimesresolves symbolic links into actual names and informs the user
3184b88c807SRodney W. Grimeswhere the user ended up if he crossed a symbolic link.
3194b88c807SRodney W. Grimes
3204b88c807SRodney W. GrimesSIGNALS:  Trap.c implements the trap command.  The routine set-
3214b88c807SRodney W. Grimessignal figures out what action should be taken when a signal is
3224b88c807SRodney W. Grimesreceived and invokes the signal system call to set the signal ac-
3234b88c807SRodney W. Grimestion appropriately.  When a signal that a user has set a trap for
3244b88c807SRodney W. Grimesis caught, the routine "onsig" sets a flag.  The routine dotrap
3254b88c807SRodney W. Grimesis called at appropriate points to actually handle the signal.
3264b88c807SRodney W. GrimesWhen an interrupt is caught and no trap has been set for that
3274b88c807SRodney W. Grimessignal, the routine "onint" in error.c is called.
3284b88c807SRodney W. Grimes
3294b88c807SRodney W. GrimesOUTPUT:  Ash uses it's own output routines.  There are three out-
3304b88c807SRodney W. Grimesput structures allocated.  "Output" represents the standard out-
3314b88c807SRodney W. Grimesput, "errout" the standard error, and "memout" contains output
3324b88c807SRodney W. Grimeswhich is to be stored in memory.  This last is used when a buil-
3334b88c807SRodney W. Grimestin command appears in backquotes, to allow its output to be col-
3344b88c807SRodney W. Grimeslected without doing any I/O through the UNIX operating system.
3354b88c807SRodney W. GrimesThe variables out1 and out2 normally point to output and errout,
3364b88c807SRodney W. Grimesrespectively, but they are set to point to memout when appropri-
3374b88c807SRodney W. Grimesate inside backquotes.
3384b88c807SRodney W. Grimes
3394b88c807SRodney W. GrimesINPUT:  The basic input routine is pgetc, which reads from the
3404b88c807SRodney W. Grimescurrent input file.  There is a stack of input files; the current
3414b88c807SRodney W. Grimesinput file is the top file on this stack.  The code allows the
3424b88c807SRodney W. Grimesinput to come from a string rather than a file.  (This is for the
3434b88c807SRodney W. Grimes-c option and the "." and eval builtin commands.)  The global
3444b88c807SRodney W. Grimesvariable plinno is saved and restored when files are pushed and
3454b88c807SRodney W. Grimespopped from the stack.  The parser routines store the number of
3464b88c807SRodney W. Grimesthe current line in this variable.
3474b88c807SRodney W. Grimes
3484b88c807SRodney W. GrimesDEBUGGING:  If DEBUG is defined in shell.h, then the shell will
3494b88c807SRodney W. Grimeswrite debugging information to the file $HOME/trace.  Most of
3504b88c807SRodney W. Grimesthis is done using the TRACE macro, which takes a set of printf
3514b88c807SRodney W. Grimesarguments inside two sets of parenthesis.  Example:
3524b88c807SRodney W. Grimes"TRACE(("n=%d0, n))".  The double parenthesis are necessary be-
3534b88c807SRodney W. Grimescause the preprocessor can't handle functions with a variable
3544b88c807SRodney W. Grimesnumber of arguments.  Defining DEBUG also causes the shell to
3554b88c807SRodney W. Grimesgenerate a core dump if it is sent a quit signal.  The tracing
3564b88c807SRodney W. Grimescode is in show.c.
357