The following list describes the changes made to the original source code for the Sixth Edition (V6) UNIX Thompson shell and global command in porting them to run on modern UNIX systems. ------------------------------------------------------------------------------- [etsh-current] (development): * Work In Progress ( see https://etsh.io/src/current/ ) ------------------------------------------------------------------------------- [etsh-4.9.0] (latest): sh6.c, defs.h: * Increased size of line buffer & word pointer array. Previously, line only allowed a maximum of 2042 characters in each command line. It now allows 2063 and gives a "Too many characters" error at 2064 and beyond. For word, instead of allowing a maximum of 1018 arguments/words per command line and giving "Too many args" at 1019 and beyond, it now allows 1026 and errors at 1027 and beyond. glob.c, sh6.c, sh.h, err.h, defs.h: * Had what amounted to being a cleanup fest of sorts... Without going into too much detail, this provided a good opportunity to revisit, check, and fix a couple of problems (not problems). Many of the cleanups were because of reports by splint(1) only when the shell was in full DEBUG mode. This gave me a chance to change some splint annotations. if.[1c]: * For the if(1) - conditional command of sh6/tsh, made == a synonym for =. 1) The rationale is simple; 'if s1 == s2 echo equal' evaluates the expression for equality; 'if s1 = s2 echo equal' does too, but it looks like an assignment. 2) In effect, this improves if(1) syntax compatibility between sh6/tsh and csh/tcsh. ------------------------------------------------------------------------------- [etsh-4.8.0]: sh6.c: * Added 3 comments in main() to allow easier comparison with osh.c . ------------------------------------------------------------------------------- [etsh-4.7.0]: *: * Changed v6shell (dot) org references to etsh (dot) io, and v6shell.org references to etsh.io too, almost a s/v6shell.org/etsh.io/ in effect, but not quite. * No code changes. sh6.1: * Reworded the description of how an interactive shell prompts the user for the sake of clarity. ------------------------------------------------------------------------------- [etsh-4.6.0]: if.1, if.c: * Added two new primaries, -n to test for non-zero length string & -z to test for zero length string, like the same primaries found in test(1). ------------------------------------------------------------------------------- [etsh-4.5.1]: * No changes. ------------------------------------------------------------------------------- [etsh-4.5.0]: * See CHANGES. ------------------------------------------------------------------------------- [osh-4.4.0]: [fgis]*.1: * Changed osh and sh6 references to match their binary names set in *.1.out by configure. fd2.c, glob.c, goto.c, if.c, sh6.c: * No code changes. ------------------------------------------------------------------------------- [osh-4.3.2]: * No changes. ------------------------------------------------------------------------------- [osh-4.3.1]: [fgis]*.1: * s/General Commands/General Commands Manual/ fd2.c, glob.c, goto.c, if.c, sh6.c: * No code changes. ------------------------------------------------------------------------------- [osh-4.3.0]: * Changed LIBEXECDIR layout to support both sh6 & osh. The sh6(1) external utilities moved into a new sh6 subdirectory. A new osh subdirectory exists for osh support scripts & files; these files came (and will be removed) from the V6Scripts Collection. mkconfig, sh6.c, goto.c: * Disabled sh6 compilation on Ubuntu 16.(04|10). sh6.c: * Updated sh_magic() & xgetc() to make it behave more like osh. This protects the user and her / his terminal from getting fouled up if/when accidentally trying to execute binary files as shell scripts / command files. ------------------------------------------------------------------------------- [osh-4.2.1]: * No changes. ------------------------------------------------------------------------------- [osh-4.2.0]: * No changes. ------------------------------------------------------------------------------- [osh-20160108]: * No changes. ------------------------------------------------------------------------------- [osh-20150115]: sh6.c: * Silenced a GCC warning (-Wmaybe-uninitialized) in execute(). ------------------------------------------------------------------------------- [osh-20141024]: * No changes. ------------------------------------------------------------------------------- [osh-20140820]: Makefile: * Added LIBEXECDIR, and changed glob6 to glob . * Updated so libexec directory & utilities only install for sh6 . * Added README.libexec; install it into LIBEXECDIR as README . INSTALL, NOTES: * Updated as needed to document changes. defs.h, fd2.c, glob.c, if.c, sh6.c: * Changed how sh6 finds its external utilities (glob, fd2, goto, if) and how its external utilities that invoke external utilities (glob, fd2, if) find fd2, goto, and if. NOTE: goto is a special case since it invokes nothing. In short, PATH is no longer searched. LIBEXECDIR is used instead. See INSTALL, NOTES, and defs.h for further info. sh6.1: * Added info about LIBEXECDIR to the sh6 manual page. glob.[1c]: * Moved / renamed glob6.[1c] to glob.[1c] . ------------------------------------------------------------------------------- [osh-20140410]: * No changes. ------------------------------------------------------------------------------- [osh-20131109]: sh6.1: * Changed `LICENSE' to LICENSE to match the other manual pages. ------------------------------------------------------------------------------- [osh-20130331]: * No changes. ------------------------------------------------------------------------------- [osh-20120604]: sh6: * Added missing `Command line overflow' diagnostic. sh6.1: * Mirrored osh.1 changes where appropriate. ------------------------------------------------------------------------------- [osh-20120102]: err.h: * Added DEBUG_GLOB definition (undefined by default) for printf debugging in sh6.c and glob6.c if/when needed. sh6.1: * Removed sed(1) from "SEE ALSO" section. ------------------------------------------------------------------------------- [osh-20111129-p1]: * No changes. ------------------------------------------------------------------------------- [osh-20111129]: * No changes. ------------------------------------------------------------------------------- [osh-20111027]: sh6.c, glob6.c: * Updated to better align w/ osh code w/o changing visible behavior. *6.1: * Updated to match style changes in other manual pages. ------------------------------------------------------------------------------- [osh-20100430]: * No user-visible changes. ------------------------------------------------------------------------------- [osh-20100228]: * No user-visible changes. ------------------------------------------------------------------------------- [osh-20091218]: * No user-visible changes. ------------------------------------------------------------------------------- [osh-20091127]: * No user-visible changes. ------------------------------------------------------------------------------- [osh-20091122]: sh6.c: * Increased apid[] buffer size to 33 via DOLMAX; this allows $$ to correctly represent shell's process ID on systems where process IDs > 99999 are possible. glob6.c: * Changed ERR_ALTOOLONG to ERR_E2BIG. *6.1: * Added COPYRIGHT section headings, and added copyright notices. ------------------------------------------------------------------------------- [osh-20091029]: sh6.c: * Wrap WCOREDUMP(s) w/ #ifdef WCOREDUMP ... #endif . sh6.1: * Change example in "I/O redirection" subsection that could confuse new users. ------------------------------------------------------------------------------- [osh-20090527]: sh6.c: * Replaced err(), prn(), prs(), and xputc() w/ err() and fd_print() from err.c . * Added sh_errexit() to handle all error exit scenarios for the shell. This function is called by err(). * Copied prsig() from osh.c; changed pwait() to use it for printing termination messages. glob6.c: * Replaced gerr() w/ err() and ut_errexit() from err.c . ------------------------------------------------------------------------------- [osh-20081213]: * No changes. ------------------------------------------------------------------------------- [osh-20081122]: sh6.c: * Fixed a bug introduced in osh-20081026 where the shell incorrectly prints a process ID w/ an empty termination message upon receipt of the SIGINT signal in certain cases. For example: % sleep 10 | sleep 20 | sleep 30 ; wait ^C 2845: 2846: This example should only print three newlines to the standard error on SIGINT, not one newline and two process IDs w/ empty messages. Now, it behaves as expected. ------------------------------------------------------------------------------- [osh-20081026]: * Moved common definitions for these programs to "defs.h". sh6.c: * Included "sh.h" for needed declarations. * Synced `struct tnode' w/ osh.c by changing the order of the `nav' and `nflags' members. * Changed calls to err() to use the diagnostics defined in "defs.h". glob6.c: * Added a base reallocation multiplier to gavnew(). This doubles the number of new arguments for which to reallocate memory when the current allocation will not be large enough for the resulting argument vector. This reduces the number of realloc()s required for very large argument vectors while allowing the first malloc() to be a relatively small allocation for up to 126 matching file-name arguments. * Changed calls to gerr() to use the diagnostics defined in "defs.h". ------------------------------------------------------------------------------- [osh-20080629]: sh6.c: * Changed the way that the shell deals w/ the SIGTERM signal so that it only sets SIGTERM to its default action for child processes if it was set to its default action when the shell started. * Changed the code to use sasignal() instead of signal(3). sh6.1.in: * Updated the documentation as needed to reflect changes to the code. ------------------------------------------------------------------------------- [osh-20080109]: * No user-visible changes. ------------------------------------------------------------------------------- [osh-20070707]: * No user-visible changes. ------------------------------------------------------------------------------- [osh-20070324]: * No changes. ------------------------------------------------------------------------------- [osh-20070321]: * Imported the project into a local subversion repository. * Changed the all of the code to "#include " and to use the "bool" data-type macro where appropriate. * User-visible changes? None. ------------------------------------------------------------------------------- [osh-20070131]: sh6.c: * Changed the way SIGINT and SIGQUIT are handled so that the shell's child processes also ignore these signals when the shell and its parent process do. See the "Signals" subsection of sh6(1) for a complete description of the new behavior. Notice that this is the same behavior found in osh(1). glob6.c: * Changed the glob6 non-zero exit status so that it is always 2 when any error is encountered. This preserves compatibility w/ the original, which never caused the shell to terminate a command file when a globbing error occurred. ------------------------------------------------------------------------------- [osh-20061230]: sh6.c 1.3 (jneitzel) 2006/09/15: * The shell now ignores any `#!shell' sequence which occurs as the first line of a regular file. For example, the first line might be `#!/usr/local/bin/sh6', `#!/usr/bin/env sh6', or similar. However, it is important to notice that the original Thompson shell did not do anything of the sort. This change simply adds a degree of convenience and flexibility for the user. * After the shell is invoked and initializes itself, it closes unneeded file descriptors. Changed when this is done so that it does not break x-only scripts if they are supported on a particular UNIX system. * The shell no longer exits w/ an explicit non-zero status if a read(2) from the input file descriptor fails. It now exits silently w/ the current value of the global variable status in such a case. * The shell now exits silently w/ a zero status if the input file descriptor refers to a directory. The reason for this change is because invoking the shell as `sh6 file', `sh6 file', and `>>file' so that the user can quote it if needed. * Parse each command line into a dynamically allocated tree of tnode structures rather than using a statically allocated intptr_t buffer. Remember that malloc(3) did not exist in Sixth Edition UNIX; alloc(III) did exist, but /bin/sh did not use it. glob6.c 1.3 (jneitzel) 2006/09/23: * Improved the quoting behavior for the sake of convenience, flexibility, and usability. * Improved the behavior of `[...]' range matching (e.g., `[a-z]') so that it adheres to the documentation (see glob6(1)). This means that an invalid range such as `[z-a]' matches nothing and that `[a-m-z]' is equivalent to `[a-mz-]' instead of `[a-z]'. * Dynamically allocate memory for the generated argument list rather than using statically allocated buffers. The total length of the generated argument list is limited to a maximum of ARG_MAX bytes. An `Arg list too long' diagnostic is printed if this limit is exceeded or if pexec() fails and sets errno to E2BIG. Of course, `Out of memory' is printed if glob6 runs out of memory. Remember that malloc(3) did not exist in Sixth Edition UNIX; alloc(III) did exist, but /etc/glob did not use it. ------------------------------------------------------------------------------- [osh-060124]: This is the initial public release for the following ports of the original Sixth Edition UNIX source code. sh6.c 1.2 (jneitzel) 2006/01/09: * Deny set-ID execution. If the effective user (group) ID of the sh6 process is not equal to its real user (group) ID, it shall now print a diagnostic and exit with a non-zero status. * Use geteuid(2) instead of getuid(2) to determine whether to print the `% ' prompt for a regular user or the `# ' prompt for the superuser. * Cause the shell to ignore SIGINT, SIGQUIT, and SIGTERM when invoked as an interactive shell. The original Thompson shell did not do this. In Sixth Edition UNIX, the login(1) utility invoked the shell in the following way: execl("/bin/sh", "-", (char *)0); ... This caused the invoked login shell to ignore SIGINT and SIGQUIT. However, this was not the case for a non-login interactive shell invoked by a user. * When invoked as `cat file | grep h ... since `cat' will never write to the created file. This fix causes the shell to silently ignore the ambiguous redirect, adhering to the behavior originally documented in sh(1) (see sh6(1)). * The shell no longer breaks pipelines of the following form: % ( ( echo hello ) | ( cat ) | ( grep h ) ) >file & ... This fix further limits when `/dev/null' is opened as input for `&' commands so that doing so cannot replace the read end of a pipe previously set up by the shell, adhering to the behavior originally documented in sh(1) (see sh6(1)). * Added explicit error detection in those cases where the original Thompson shell did not do so. For example, the original Thompson shell did not check the value returned by dup(2) or pipe(2). * Changed all of the close(2)/dup(2) sequences for file descriptors 0 and 1 to simply call dup2(2) instead. * Changed all of the calls to exit(3) which happen in the child process after a successful call to fork(2) to _exit(2) instead. * Added `exit' as a special command which is built into the shell. Its usage is the same as that of the external `exit' utility found in Sixth Edition UNIX. * Define explicit exit status for special commands, external commands, and shell errors. * Removed the `: too large' diagnostic, and added a `: cannot execute' diagnostic for external-command execution errors. The `No shell!' and `: not found' diagnostics, however, are unchanged. * Use pexec() (see pexec.h) for external command execution to give more flexible and predictable command search behavior. glob6.c 1.2 (jneitzel) 2006/01/09: * Deny set-ID execution. If the effective user (group) ID of the glob6 process is not equal to its real user (group) ID, it shall now print a diagnostic and exit with a non-zero status. * Increased the size of the argument-list buffers to allow generation of longer argument lists. * Added a `Pattern too long' diagnostic for those cases where the total length of a pattern argument is >= PATH_MAX (or 1024). If such an error is encountered, glob6 exits with a non-zero status. * Handle quoted arguments specially so that path names containing blanks can be successfully globbed. * Use pexec() (see pexec.h) for command execution to give more flexible and predictable command search behavior. ------------------------------------------------------------------------------- [Unreleased]: The following ports of the original Sixth Edition UNIX source code were never released to the public. sh6.c 1.1 (jneitzel) 2004/01/26: * Changed the source file name from `sh.c' to `sh6.c' and the resulting binary name from `sh' to `sh6' to avoid name conflict and confusion with the system shell, sh(1), on modern UNIX systems. * Transformed the source code from K&R C into ANSI C. * This is nothing more than a simple port to modern UNIX systems. It is now 64-bit clean. At least, this is true for the 64-bit systems to which the porter has access. * Removed support for the shell's accounting of process times (see times(3)) which allowed the shell to record command execution data in a log file. * Fixed a buffer overflow in the word() function. glob6.c 1.1 (jneitzel) 2004/01/26: * Changed the source file name from `glob.c' to `glob6.c' and the resulting binary name from `glob' to `glob6', matching the similar change to the name of the shell (see above). * Transformed the source code from K&R C into ANSI C. * This is nothing more than a simple port to modern UNIX systems. * Fixed possible overflow of the argument-list buffers in the cat() function. ------------------------------------------------------------------------------- [Original]: Here is some pertinent information about the original files. The following description refers to Sixth Edition (V6) UNIX obtained from: http://www.tuhs.org/Archive/PDP-11/Distributions/research/Dennis_v6/ ... A portion of the `http://www.tuhs.org/Archive/PDP-11/Distributions/DETAILS' file reads as follows: Dennis_v6 --------- v6root.gz, v6src.gz and v6doc.gz are a set of three RK05 images of Sixth Edition with root, /usr and documentation, from Dennis Ritchie. The tape bootstraps are not included. The most recent timestamp on any file is July 19th 1975. v6root.tar.gz, v6src.tar.gz and v6doc.tar.gz are tar archives of the three RK05 images. ... The following files and the corresponding manual pages were all obtained from the tar archives described above: sh.c: What: Original source code for the Sixth Edition (V6) UNIX Thompson shell Date: July 17, 1975 From: Sixth Edition UNIX /usr/source/s2/sh.c glob.c: What: Original source code for the Sixth Edition (V6) UNIX global command Date: May 14, 1975 From: Sixth Edition UNIX /usr/source/s1/glob.c Jeffrey Allen Neitzel 2017/11/22 @(#)$Id: 752b52533aeb864007b9603cc0a7ca199f538a87 $