CHANGES -*- mode: indented-text -*- ($Revision: 1.4 $) ======= 0.9-alpha2 to 0.9beta --------------------- Prototypes are only provided if they are not in the standard header files. Es no longer provides its own strerror. If there is a strerror, it is used. If not, we try a hack with sys_errlist. Hopefully one of these two will be there. Es now supports building in directories that are not the source directory. This follows the standard GNU $(srcdir) conventions. The POSIX sigsetjmp problem appeared again in the form of a macro in some versions of linux. Therefore, there is yet another little conditional around the setjmp and longjmp macros to make sure that all is ok. 0.9-alpha1 to 0.9-alpha2 ----------------------- Es now uses GNU autoconf rather than the config.h/stdenv.h model. Another version of getenv. Some libraries and operating systems do funny things with getenv, making the back mentioned below fail, dumping core in getopt (linux and GNU getopt) and before main(!) (FreeBSD 2.1.0) demonstrated this. Variable argument lists for variable arity C functions are not lvalues. This occurs, at least, on the powerpc (see the GCC header files for an example of what it does). This memcpy's those, and assigns the others. The type used for bsd limits is extracted from the header files. This is necessary because FreeBSD (and likely other BSD 4.4 systems) use quad_t rather than long to represent the values in the rlimit structure. This could, possibly, become a problem as more operating systems go `64 bit' POSIX systems provide sigsetjmp and siglongjmp. These are exactly like setjmp and longjmp except that setjmp and longjmp do not restore signals. On systems on which these functions are available, they are used. There are a number of patches to fix `little' bugs. 0.84 to 0.9-alpha1 ------------------ A version of getenv() that looks at the current environment now exists for readline, so it can get $HOME and $TERM accurately. Interaction with readline has been somewhat improved, but there still appear to be bugs lurking. A large number of portability suggestions sent in by users were incorporated. Still, the config.h/stdenv.h model is inadequate, and should be revisited. A new pattern extraction operator, ~~, has been added. It's use is similar to ~, except that instead of returning true or false, for all subjects that match a pattern, the part of the subject that matches each wildcard in the pattern is returned. This was added instead of the various regular expression or variable munging ideas; it leverages off of the pattern matching es already does. For example: ; echo <={ ~~ (foo.c foo.x bar.h) *.[ch] } foo c bar h ; A stripped-down $&read primtive has been added. The %read builtin returns either the empty list (in the case of end-of-file) or a single element string with up to one line of data read from standard input (including possible redirections). %read reads one character at a time in order to not read more data out of a pipe than it should. The terminating newline (if present) is not included in the returned string. (I had solicited opinions for other features, but let's see about the utility of the simple version first.) In addition to the traditional (some would say hackish) rules about putting ']' and '-' as literal characters in character ranges (put ']' at the beginning or '-' at either end to use them literally), quoting can be used to the same effect. For example, where [a-z] matches a range, [a'-'z] matches the three characters 'a', '-', or 'z'. (A few hard to hit bugs with pattern matching were fixed, as well.) The while builtin in 0.84 unintentionally blocked the return exception, making while difficult to use in loops. This was fixed by changing catch to call the exception handling function without catching the return exception. The for loop now only catches the break exception in its body, not the definitons. The old behavior was silly. The '=' character is now allowed in variables if PROTECT_ENV is on. The C version of the exception handling macros has been changed to something that is compatible with the restrictions on where setjmp may appear in ANSI C. The macrology is also (probably) a bit easier to understand now. A trailing slash in a wildcard pattern now only matches directories portably. It used to depend on what opendir() did if you passed it a non-directory, I think. Control-A can be safely exported and imported in environment variables. It (and control-B) cannot be imported correctly from programs other than es. var and whatis now print error messages rather than throwing errors. limit now prints all its results on standard output instead of standard error. Assignment returns the values that were assigned, so multiple assignment statments to the same value can be chained with x = <={ y = <={ z = foo bar } } path and home are now on the default noexport list, because you want to track any changes made to HOME and PATH made by other programs. The apids function is now gone. Use <=%apids if you need it. true, false, eval, unwind-protect, and %one are now functions, not primitives. Printing from things like var has been much improved. Errors in a .esrc file don't cause the shell to exit anymore. Function names are now looked up first among the lexically scoped variables, bringing es all that much closer to Scheme. Function names that look like absolute path names are legal, so you can spoof something like /bin/rm if you want. (Use with caution!) $&backquote now returns the exit status of its subprocess as its first argument. %backquote puts this in the variable $bqstatus. The various $&open primitives have been replaced by one primitive, $&openfile, the first argument of which determines how the file should be opened. See initial.es for details. $cdpath searching has moved out of initial.es into sample code. The variable max-eval-depth sets a limit on how deep recursion can go in es; if the depth is exceeded, an error is thrown. Let and local now do parallel (or simultaneous) evaluation of the expressions on their right hand sides. That is, all the right hand sides in such a statement are evaluated before any variables are bound. (This is like Lisp's let instead of the old let* behavior.) Assignments, binding forms (let, local, for), and variable references now permit using multiple variables at once time. For example: ; foo = a b ; $foo = 1 2 3 4 ; echo $a 1 ; echo $b 2 3 4 ; echo $$foo 1 2 3 4 ; let ((b a) = 9 8 7) echo $$foo 8 7 9 ; echo $a 1 ; %and and %or now return the value of the last term they evaluated, as they did prior to version 0.84. Four-digit umask values are now legal, and error checking on umask syntax is a little more thorough. Still no symbolic umasks. [implementation] Assertions about the Ref*() constructs are now enabled separately from the rest of the assertions -- the Ref assertions enormously increase the size of the executable, but are effectively compile-time checks. [implementation] Responsibility for making sure that lists are not clobbered by being shared when one is used destructively has been moved: it is now the responsibility of anything that calls eval() to make sure that either the value is not modified or to make a copy itself. See uses of listcopy() in the code for where we think that is. [implementation] gcdisable() used to serve two purposes: to turn off the garbage collector and to initiate a garbage collection if a certain amount of space was not available. the function has now been split into two functions: gcdisable() and gcreserve(). some typos in strings and header comments were fixed, thanks to Derek Burns. 0.83 to 0.84 ------------ the primitives are now documented in es.1. thanks to suggestions from Noah Friedman, while is no longer a primitive and cdpath searching is now from es code rather than in $&cd. (Similarly, %not, %and, and %or are now builtin functions, not primitives.) some of the usage messages in prim-*.c contained % rather than %% in strings that were passed to fail, causing panics. fixed, thanks to Pete Ho. es should port easier to linux (thanks to Jeremy Fitzhardinge), HP/UX (thanks to Rich Salz and Ken Stone), and AIX (thanks to DaviD Sanderson). sig, for 0 < n && n < NSIG is now accepted as a valid signal name. two new forms of values for $signals are now accepted: /signal means ignore the signal in the current shell but don't propagate catching it to child processes and .signal means use ``special'' signal handling for that signal, where ``special'' means print an extra newline for sigint. (the ``.'' prefix allowed on sigint only.) note that now you should probably do things like local (signals = $signals sigfoo -sigbar) ... rather than local (signals = sigfoo -sigbar) ... or you will lose normal shell signal handling for sigint, sigquit, and sigterm. (this set of changes was made solely to clean up signal.c and the extra functionality it implies is only incidental.) the var builtin now prints ``var = '' rather than ``var is undefined'' for undefined variables. the whatis builtin now prints a line for all of its arguments rather than raising an exception if one is not found. some garbage collector bugs that could have caused crashes were fixed. (i believe that some more may be lurking out there, but i am unable to reproduce them.) 0.82 to 0.83 ------------ there's now an debugger for es scripts, called, appropriately enough, esdebug. it presents a vaguely gdb-like interface; there are minimal help and usage messages, and that's the sum total of documentation for it right now, but it looks like it could be useful. so far i've used esdebug on some trivial scripts and my .esrc; the two things i think it can't debug are initial.es (at least in the environment in which it runs) and esdebug itself, which is a shame because esdebug is the most complex es script i've written to date. note that esdebug not an essential piece of the shell, and was hacked together over about 3 hours. in fact, esdebug probably has more bugs than any script it is pointed at, but i think it's (at very least) a good example of what you can do with es, and potentially a useful tool. (this tool was inspired by some recent postings in comp.unix.shell, by the way.) one feature was added to es to support esdebug: it's a primitive named $&noreturn which takes as its arguments a lambda and the arguments to the lambda. it runs the lambda exactly as the normal evaluation mechanism would except that the lambda does not catch the return exception. the part of the build process which extracts signal names and signal messages from /usr/include/sys/signal.h. we'd like to thank Tom Culliton, Arnold Robbins, Rich Salz, and DaviD Sanderson for their suggestions and code, as well as the rest of the list for the large number of signal.h files which i now have. thanks to help from Steve Kilbane and Steven Orr, this release of es should now run out of the box on Solaris 2 and SCO ODT 1.1. esrc.haahr is now provided as an example. a reasonably major bug with reference sharing where there should have been value sharing was fixed. the bug involved the list constants true and false. the simplest to way to trigger the bug is echo <=$&true <=$&true initial.es now contains detailed comments on what it's doing, at the suggestion of Arnold Robbins. patches from Loren Rittle were installed in dump.c to get rid of some version of gcc's ``warning frenzy.'' defaults for Irix no longer include USE_SIGACTION, since es does not seem to catch any signals with sigaction() on SGI machines. fixed a bug that had reappeared, where the file descriptor that commands were being read from could get confused by an exec {redirection}. es -v now echoes the input as the characters are scanned, rather than when they are read. for programs reading from a tty device, this is the same as before, but for programs running from files the output comes at a more sensible time. es -e now exits on error exceptions as well as false return values. es -x now works. before, it printed commands twice without evaluating them. it's still not very useful. the '|' token was renamed PIPE in parse.y and token.c to work around a bug in the yacc that comes with the (value added, expensive) SPARCcompiler tools. initial.es now contains comments that explain what's going on. the function strdup() in utils.c, which was unused, was removed. 0.8 to 0.82 ----------- BIG CHANGE: the <> operator was renamed <= to make way for <>file. (see below.) when you install this version of es, please be sure to look for <> in any es scripts and especially your .esrc; if, like me, you had <> in your environment, you will need to (at very least) re-run your .esrc. the new redirections <>file and <>>file can now be used for ``open file for reading and writing'' and ``open file for reading and appending,'' and correspond to the new hook functions %open-write and %open-append. the file is, by default, opened on file descriptor 0 for compatibility with old shells that (unbeknownst to me) implemented this syntax; use <>[n] and <>>[n] for other file descriptors. due to suggestions from the es list, the fact that historical and posix shells accept the notation <>file for ``open file for reading and writing,'' and my obsession with completeness, many more forms of redirection are supported. es now recognizes the following redirections and hook functions: cmd < file %open 0 file {cmd} cmd > file %create 1 file {cmd} cmd >> file %append 1 file {cmd} cmd <> file %open-write 0 file {cmd} cmd <>> file %open-append 0 file {cmd} cmd >< file %open-create 1 file {cmd} cmd >>< file %open-append 1 file {cmd} note that the first character determines whether the file descriptor used is 0 or 1. you can of course, use the [n] notation with these operators to override the defaults. on some machines, ps would print garbage entries for es or its child processes. i think this is fixed, but let us know if you see the problem happening. some portability changes for the RS/6000 (by DaviD W. Sanderson) and SGI machines (by Chuck Rendleman) were incorporated. es now catches errors in redirections better. previous versions printed usage messages for the primitives $&open, $&create, and $&append for the conditions that now generate the (hopefully more informative) messages null filename in redirection too many files in redirection the %one primitive is used to make sure that these messages are triggered. many man page bugs were fixed thanks to Arnold Robbins. signal handling was significantly revamped. the list $signals now can have an additional form, -signame, which ignores the appropriate signal. also, removing a signal from $signals now restores it to default behavior rather than ignoring it. ignored signals are properly inherited from the state of the signals. es now supports POSIX-style sigaction(2) if the compile-time flag USE_SIGACTION is defined. fixed a bug where the default %interactive-loop silently ignored signals that it shouldn't have. in 0.79 and 0.8, a signal coming in while %interactive-loop was in its exception-catching routine would cause the shell to exit. (this is a new twist on the old signal comes in while signal handler is running problem.) this was ``fixed'' by preventing any delivery of signals while the handler of a catch routine was running. i'm not sure that this is a good thing. signals now should be delivered immediately after the catcher finishes running, which means right before the body starts again in the retry case. wait now does not print ``pid: '' alone when background jobs complete. a new builtin %run was added. %run takes a program and an argv list, including argv[0], and execs the program. this is the only way in es to set the argv[0] of a called program. (as a consequence of adding this operator, es is now bullet-proofed to not dump core in the case where it is passed a null argv array.) local () definitions of variables to the empty list no longer cause the variables to be exported as the null string. absolute path names used with cd do not cause %cdpathsearch to be invoked. some declarations in prim-sys.c and version.c were written to work around bugs in some versions of IBM's rs6000 compiler. limits were added to match the ones listed in Richard Stevens's Advanced Unix Programming. a cputime limit of hh:mm:ss is now interpreted as hours, minutes and seconds. mm:ss is still interpreted as minutes and seconds. in addition, bad suffixes on limits are now caught. fixed the example of fork in the man page to use es rather than rc syntax. access -l will now report true for symbolic links; it used to always report false. oops. whatis was broken and accepted any absolute filename as a valid without checking the executable bit. fixed. when the wait builtin was made interruptible, it broke the handling of control-c. that's fixed now. we'd like to thank Pete Ho and Loren James Rittle for finding many of the bugs in this release. 0.79 to 0.8 ----------- there's now a man page. i believe that it's up to date. a new hook function, %exec-failure, was added. if a call to execve(2) fails, %exec-failure is called with the full path name of the program that couldn't be run and the full argv array (including argv[0], which might be identical to the first argument.) if %exec-failure doesn't exist or returns, an error message is printed and the child process exits. for example, to emulate the behavior of old shells, one can use fn %exec-failure file argv0 args { exec /bin/sh $file $args } a default %exec-failure is provided conditionally for machines which lack #!-support in their execve; see KERNEL_POUNDBANG for details. the retry builtin was removed. the functionality is still there, just use ``throw retry.'' retrying is not a common enough case to waste the name of a command. $apid is not exported by default. -e and eval seem to work more reliably now. error exceptions now have an additional piece of information. the second word (the one after ``error'') is now the name of the primitive or other routine which caused the error. there is no guarantee that this piece of information is correct, but it may be useful. i've sprinkled the NOTREACHED macro (see stdenv.h) through the source, which should shut off some warnings on some systems. Tconv (the format routine for %T) calls itself recursively less often than it used to. \x constants are now interpreted correctly. the $&background primitive now just backgrounds a process. printing of the pid and setting $apid is now done in the function which calls the primitive, which is defined in initial.es. a new builtin, %is-interactive, was added. it returns true if and only if the enclosing interpreter context is interactive. the initialization process has changed radically. the shell script mkinitial used to turn initial.es into a string that was linked into the binary. now, es is built with a two-phase process: first, a special version of the interpreter (called esdump), which is lacking initial.es, is built. esdump is used to translate initial.es into initial.c, which creates the same in-memory layout would have been obtained by running initial.es, except that most of the data is put into the text segment. the downside: the executable is large by about 10% and building es takes long. the upside: it starts up faster, it uses less memory (because many data structures no longer live in garbage collector space, which requires 2 copies of all data when collecting), and garbage collects faster (much less data has to be scanned). this code may be less portable than the version that preceeded it, so let us know, especially if esdump panics. some definitions from var.c were pulled out into the new var.h header file. fixed a bug where a line consisting of () alone would cause the interpreter to raise an assertion failure. several crashing bugs (a spurious assertion failure in the splitting code following a control-c and an incorrect use of nprint("%L") in the top-level error catcher) were fixed. a new hook fn %cdpathsearch, analagous to %pathsearch, was added for cd. a new builtin, access, which is similar to test from other shells, was added. the name is different because the semantics are somewhat different. access is now used to implement the default form of path searching built in to the shell. (the primitive $&pathsearch has been dropped; see initial.es or the forthcoming manual page for details.) in addition, whatis now triggers calls to %pathsearch if need be. a new builtin, unwind-protect, was added for the most common case of exception handling: required cleanup code. standard use is unwind-protect { body } { cleanup } where cleanup is executed when body finishes, regardless of it is by successful completion or because an exception was raised. if body completes successfully, the exit status of the unwind-protect is the exit status of body; otherwise, the exception is passed through after the cleanup is run, unless cleanup itself causes an exception. a new builtin, result, was added. effectively, it is the identity function: all it does is return its argument as its exit status. result is similar to return, except it does not affect control flow. (and does not use the exception mechanism.) >{} and <{} (aka %readfrom and %writeto) are now implemented using temporary files on systems that don't have /dev/fd. /dev/fd will still work better and be cleaner on the systems that support it, but this should cover 99% of all the cases otherwise. wait is now interruptible by control-c. the mechanism for declaring a variable not exported has changed. now, all the variables on the list $noexport are not exported. also, a new space for variables, internal has been added. internal variables are those defined in initial.es; they are not exported unless redefined, but do not appear on the $noexport list. also, $&vars does not include internal definitions, though they can be found in $&internals. . now takes argument -e, -x, -v, and -n just like the shell itself. a getopt like mechanism, esopt(), was introduced. a new control-flow builtin ``forever'' was added. this was not needed for completeness sake, and i still recommend the use of ``while {} body'' for most purposes. however, the read-eval-print loop had the wrong behavior when the user typed ``break'' at the command line because it was implemented with a while loop. forever completely ignores exceptions. (a similar problem still exists when you pass a code fragment including a return to a function rather than to a primitive. maybe the people who want first-class continuations or at least lexical scoping for break/return do have a point.) the use of the default exception handler by main has been cleaned up a bit. the implementation of dynamic variable binding has changed a bit, but this should not be a user-visible change. for loops now correctly catch the ``break'' exception. they used to catch ``return'' by mistake. a bug was fixed where slashes in some filenames that used ~ expansion were replaced with 'r'. the internal flags parent and exitonfalse were coalesced into one mask rather than the two separate Booleans, and parent was replaced by eval_inchild, which has the opposite sense. 0.74 to 0.79 ------------ the >{} and <{} constructs are now supported (if your system has /dev/fd) by the builtins %readfrom and %writeto. you must define the preprocessor variable DEVFD to turn on this feature. the limit builtin (ala csh and rc) and a time builtin were added. to enable them, turn on the BSD_LIMITS flag. for those you opposed to things like time in a shell, the reason it was included is that we wanted to be able to time es code fragments without doing the ``time es -c $x'' we used to do and without the extra overhead for a new invocation of the shell. see the pipeline timing example in our usenix paper for details. the bug with control-c from the interactive loop prompt was fixed. ~ expansion now uses the builtin function %home, which is implemented by default by the primitive $&home but can be replaced. it takes either zero (for current user) or one (named user) argument, and returns (not prints) the home directory, which must be a one element list. $&home uses getpwnam(), but those of you who want to do something special here can now. the builtin command ``apids'' serves the purpose of the rc special variable $apids: it is a list of the current set of background jobs which have not yet completed. note that the list is returned in the exit status not to standard out, so use echo <>apids for the old rc form echo $apids the builtin ``wait'' was added with similar semantics to the same command in rc and sh. 0.7 to 0.74 ----------- the function which one must replace for spoofing the path-searching mechanism is now %pathsearch and not %whatis. %pathsearch is called in more limited circumstances than %whatis was, because the old form was a bit of a performance drag and was too easy to screw up the shell with. here's a bit of experimental code which does autoloading of shell functions: autoload = ~/bin/es let (search = $fn-%pathsearch) fn %pathsearch prog { if {/bin/test -f $autoload/$prog} { . $autoload/$prog if {!~ $#(fn-$prog) 0} { return $(fn-$prog) } } $search $prog } the prompt is now '; ' and not ';; '. rc users beware. on the suggestion of readers of the list, the meanings of let and local were switched; that is, let now introduces a lexical binding and local a dynamic binding. this is more consistent with scheme. the prompt function has been renamed %prompt to be consistent with other function invoked by es internals. the input scheme has been completely revised to support user-written read-eval-print loops. see the function %read-eval-print in initial.es for details. DefineTag() has been redone to avoid some compiler bugs where a forward declaration for a static was not allowed. es now works with editline; it probably works with readline but we haven't tested that yet. we think we've gotten rid of all the problems with spaces around identifiers for those people with stone age vintage preprocessors. redirections, closes, and dups do not automatically fork() now. they are deferred until a fork() happens. the main consequence of this is that builtins with redirections are now done in the context of the original shell. [this change perturbed a lot of code in es, and may have introduced a lot of bugs. please let us know right away if you think you've found a bug that is related to redirection, duping, or closing.] the makefile for the distribution was cleaned up and renamed Makefile. 0.68 to 0.7 ----------- a bug where the garbage collector was just plain broken when lots of data was allocated between two collections has been fixed. (there still may be a garbage collector bug related to large allocations, but i haven't been able to reproduce it.) there's now a trip.es (converted from a subset of trip.rc) which tests some of the shell's basic mechanisms. we need a more sophisticated trip to test the parts of es that aren't in the rc subset. heredocs are now supported. following comments to the list, things are now safer if a file descriptor mentioned in a redirection, dup, close, or pipes is already in used by es. the new primitive $&newfd (in es on an experimental basis only) returns as its exit status a file descriptor that is not currently in use. in prior versions, strings longer than 512 or 1536 bytes (depending on the underlying malloc implementation) were exported badly if at all. there is a new predefined function vars which is similar to rc's whatis without arguments. it takes the following arguments: -v print variables other than fn- and set- prefixed ones -f print functions (variables with fn- prefixes) -s print settor functions (variables with set- prefixes) -e print exported variables -p print noexport variables if none of -v, -f, and -s are specified, -v is assumed. if neither of -e or -p is specified, -e is specified. note that vars does not print lexically scoped variables. there is a new predefined function var which prints function names in a manner suitable for re-entry into the shell, ala rc's whatis. it is based on the primitive $&var. (var does not work with lexically scoped variables.) the environment, along with the results of $&vars and $&primitives, are now sorted. isnoexport var (primitive $&isnoexport) returns true if the variable is marked noexport. the primitive $&vars returns all of the currently defined variables. (other than those which are lexically scoped.) the primitive $&primitives (which used to print its output) now returns as its exit status the names of all of the es primitives. ($&version has been modified similarly.) -e and -x are now implemented, with the usual meanings that one expects for them in a shell. (this is one place in the language where it's going to take some experience to tell if all the nits are out. if you use -e or -x regularly with other shells, please start trying them here.) the old GCDEBUG compile time option has been split into three options. GCVERBOSE provides information on the operation of the garbage collector. GCALWAYS does a collection at every allocation. GCPROTECT invalidates pages that do not contain live data; this option requires operating system support beyond what is needed for the rest of the shell. GCDEBUG still turns on all three options. based on a suggestion from the list, %fsplit with '' as a separator string now splits between each character. the parser has been cleaned up. it may be a little bit slower, in order to make some things clearer. in particular, the rewriting of redirections has changed significantly. there are several new configuration options in config.h. see that file and their uses for more details but do -DUSE_CONST=0 if you don't have or like const -DUSE_VOLATILE=0 if you don't have or like volatile -DUSE_STDARG=0 if you want to try -DVOID_SIGNALS=0 if signal handlers should return int since include files seem to be a major issue with respect to portability, most includes of system files have moved to stdenv.h. if you need to rearrange things or add #ifdefs in here, please send us mail, and we will try to make things work better in the next release. we're getting to a point where out-of-the-box portability is important. the path searching machinery is now available (and replacable) through the hook %whatis. for example, path-cache = local (whatis = <>{%whatis %whatis}) fn %whatis prog { local (what-it-is = <>{$whatis $prog}) { if {!~ $prog (/* $path-cache) && ~ $what-it-is(1) /*} { path-cache = $path-cache $prog fn-$prog = $what-it-is } return $what-it-is } } fn recache { if {~ $#* 0} { * = $path-cache path-cache = } for (i = $*) fn-$i = } provides a cache for the search path, similar to that built in to many shells. [warning: if you do replace %whatis, ensure that the replacement code never calls an external program except by using an absolute pathname, or you will loop forever calling whatis. powerful tools are often sharp.] signals listed on the variable $signals are now trapped: when one is received by the shell it throws an exception of the name ``signal '' that can be caught by the catch primitive. closures containing strings with single quotes are now exported properly. in earlier versions of es, closures bound variables improperly, capturing old values: the first time a closure was turned into a string was also the last time, which was incorrect. es now flushes the string forms all old closures whenever a lexically bound variable is modified. internal syntax for exporting closures changed. the old syntax was a variation on lambda forms; the new syntax uses a binding form %closure which is similar to local. for loop variables are now exported properly. ~ and ~user are now recognized by the globber, bringing joy and new purpose into the lives former c-shell users. the syntax for closing files now works. also, es is more robust in the presence of having some of its file descriptors closed. 0.67 to 0.68 ------------ verbose gc debugging conditional use of "sig_atomic_t", for non-ANSI environments conditional use of Reiser-cpp semantics for token pasting and string-izing fix for gc foward() of a vector (this fixes most, if not all, of the crashes that were reported) added GCDEBUG support for sun memory protection (via valloc & mprotect) fixed a couple of omissions in initial.es fix for a word consing bug in the parser fix for a redirection node bug in the parser initial.es now runs after exception handlers have been enabled