├── ChangeLog ├── Changes.jrm ├── Changes.mlj ├── INSTALL ├── MACHINES ├── MANIFEST ├── Makefile ├── PATCHDATES ├── README ├── ReadMe.jrm ├── ReadMe.sjg ├── ReadMe.vimode ├── bug-report ├── etc ├── ksh.kshrc ├── profile └── sys_config.sh ├── ksh.1 ├── sh ├── ChangeLog ├── Changes ├── Makefile ├── ReadMe ├── alloc.c ├── alloc.h ├── c_ksh.c ├── c_sh.c ├── c_test.c ├── config.h ├── do_ulimit.c ├── edit.c ├── edit.h ├── emacs.c ├── eval.c ├── exec.c ├── expand.h ├── expr.c ├── getopts.c ├── history.c ├── io.c ├── jobs.c ├── lex.c ├── lex.h ├── mail.c ├── main.c ├── misc.c ├── patchlevel.h ├── proto.h ├── sh.h ├── sigact.c ├── sigact.h ├── stdh.h ├── syn.c ├── table.c ├── table.h ├── trace.c ├── trace.h ├── trap.c ├── tree.c ├── tree.h ├── tty.h ├── var.c ├── version.c └── vi.c └── std ├── Makefile ├── mklinks ├── posix ├── ChangeLog ├── Makefile ├── dirent.C ├── dirent.H ├── dirent.h ├── dup2.c ├── fcntl.c ├── fcntl.h ├── fixincludes ├── io.h ├── time.h ├── times.c ├── times.h ├── unistd.c ├── unistd.h └── wait.h └── stdc ├── ChangeLog ├── Makefile ├── clock.c ├── fprintf.c ├── limits.h ├── memchr.c ├── memcmp.c ├── memcpy.c ├── memmove.c ├── memset.c ├── setvbuf.c ├── sprintf.c ├── stdarg.h ├── stddef.h ├── stdio.c ├── stdio.h_std ├── stdio.sed ├── stdlib.h ├── strcat.c ├── strchr.c ├── strcmp.c ├── strcpy.c ├── strcspn.c ├── strerror.c ├── string.h ├── strlen.c ├── strncat.c ├── strncmp.c ├── strncpy.c ├── strpbrk.c ├── strrchr.c ├── strspn.c ├── strstr.c ├── strtok.c ├── time.h ├── types.h └── vprintf.c /ChangeLog: -------------------------------------------------------------------------------- 1 | Sun May 3 17:50:03 1992 Simon J. Gerraty (sjg@zen) 2 | 3 | * Updated MACHINES. 4 | * Placed source under CVS. This should help with processing fixes 5 | from the field. 6 | 7 | Sat Apr 25 10:53:20 1992 Simon J. Gerraty (sjg@zen) 8 | 9 | * Getting ready for 4.3 release. 10 | 11 | Fri Nov 22 22:24:29 1991 Simon J. Gerraty (sjg at zen) 12 | 13 | * Cleaned up the build process slightly. Makefiles in ./std tree 14 | now maintain objects within the libraries rather than simply 15 | building the .o's and archiving them. Of course the make(1) used 16 | must know how to maintain libraries :-) 17 | 18 | * Added bug.report as a template for bug reporting. 19 | 20 | * Source in ./sh can be built independently of ./std tree if 21 | desired. See comments in ./sh/Makefile. 22 | 23 | * As originally distributed some of libstdc.a was not used and 24 | libposix.a was not used at all. On Sun's this highlighted a bug 25 | (incompatibility) in the times() call. Now the ./std/libs are 26 | used fully, and the supplied times() call functions as expected. 27 | 28 | -------------------------------------------------------------------------------- /Changes.jrm: -------------------------------------------------------------------------------- 1 | Changes to the PD ksh since last time: 2 | 3 | - clean up the option configuration stuff. Options in config.h should 4 | now just be #define'd or not, not #define'd to 1 if you want them 5 | and 0 if you don't 6 | 7 | - ksh now uses the shell specified by the variable EXECSHELL to run 8 | shell scripts. If EXECSHELL is unset or null it defaults to 9 | /bin/sh. It does a path lookup on the value, so if you set it to 10 | ``ksh'' the ksh will run all scripts that don't start with #!. It 11 | seems to run most sh scripts fine (now). I'd be very interested to 12 | hear your experiences if you try this out, as for my next trick I'd 13 | like to make ksh just fork itself to run scripts, which would speed 14 | things up, and allow exportable functions and aliases (like he real 15 | ksh). Just to assure you that it can do some hairy sh scripts, both 16 | CC and coco work with ksh. 17 | 18 | EXECSHELL won't work if the system's exec(2) call runs scripts... 19 | 20 | - the ``let'' builtin now evaluates null or unset vars to 0, as per 21 | The Book 22 | 23 | - Various memory allocation/use problems were cleaned up. Hopefully 24 | you'll never see the ``freeing free object'' error again (if you've 25 | ever seen it). 26 | 27 | - the ``test'' builtin is now much more tolerant in parsing its 28 | arguments. This was to make it like the /bin/sh test. 29 | 30 | - Temp files (for here documents or ``fc'') are now mode 0600 31 | 32 | - Some format strings in the tree printing routines got ``expanded'' 33 | into SCCS keywords, so the results of``type '' were 34 | gave you interesting things like the time I last checked in the 35 | file. This has been fixed. 36 | 37 | - ``unset -f'' now really does unset functions. 38 | 39 | - the ``trailing blank or tab in alias definition'' feature now works. 40 | 41 | - A bug in command completion was fixed. Note command completion only 42 | works on commands that have been hashed, so you want to ``set -h'' 43 | in your .kshrc, and you may wish to force hashing of some common 44 | commands with the ``hash'' builtin. 45 | 46 | - ``echo $$ | cat'' now works as in /bin/sh 47 | 48 | Not new features, but newly discovered bugs: 49 | 50 | - Local functions don't work correctly. This shouldn't be much 51 | problem, since sh doesn't have them. 52 | 53 | - Here documents in functions don't work. This is a problem with the 54 | temp file allocation that requires more work to fix than I've gotten 55 | around to doing. So avoid things like: 56 | 57 | foo() { 58 | cat <<- HereDoc 59 | This is a test 60 | HereDoc 61 | } 62 | -------------------------------------------------------------------------------- /Changes.mlj: -------------------------------------------------------------------------------- 1 | I got the pd-ksh from John MacMillan after he indicated that he 2 | had a version of it that had vi editing (I'd seen various versions 3 | with emacs-editing, but none with vi). 4 | 5 | It had a few bugs and areas which were not quite complete. I fixed 6 | (or at least tried) to fix several; there are still some things 7 | which I plan on doing (or at least looking into). 8 | 9 | Bugs fixed (or at least abated): 10 | 11 | vi-mode changes: 12 | - Changed memcpy() to memmove(), which fixed the trashing of 13 | the end of the edit buffer while inserting in the middle 14 | of a line or with use of '#' 15 | - using 'r' replacing the current character with ^@ 16 | - typing ctrl-c resulting in next command being garbled 17 | - lack of support for '-' and '+' (pretty trivial) 18 | - finish adding support for '*' (not entirely sure I'm freeing 19 | malloc'ed memory correctly here, but I haven't had any problems) 20 | - treats '_' as end of a word 21 | 22 | general changes: 23 | - reporting "not found" when a file actually doesn't have 24 | the appropriate execute bit set (now says "cannot execute" 25 | or "not found", as appropriate) 26 | 27 | 28 | Still to do: 29 | 30 | vi changes: 31 | - fix ctrl-r (I've come up with a hack, but it involves 32 | redrawing the screen a lot when it isn't necessary; I 33 | really wouldn't consider this a fix) 34 | - add support for 'v' 35 | 36 | general changes: 37 | - seems to be a memory leak when executing shells in the 38 | current shell; repeatedly executing ". /etc/profile" 39 | increased the size of the program as reported in the 40 | "SZ" field of "ps -l" 41 | - don't give a file its complete pathname in argv[0]; only 42 | its filename (religious issue?) 43 | - history recall should start at the previous command, not 44 | the current one (typing "r r" causes an infinite loop) 45 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | BUILDING THE PD KSH 2 | =================== 3 | 4 | The PD KSH can be built in two ways. The default method uses 5 | the POSIX/ANSI compatability libraries in ./std. The 6 | alternative method is to build the ksh in ./sh without the ./std 7 | tree. The second method should be used only if a) you have a 8 | real POSIX environemnt or b) you have major difficulties with 9 | building the ./std tree. 10 | 11 | I have modified the source slightly to make standalone building 12 | simpler. Using -DNOSTDHDRS avoids attempts to include ANSI 13 | headers that may be lacking. I have built the shell this way on 14 | all Sun platforms and on a Bull DPX/2 (which has good POSIX 15 | support). The config file defines USE_SIGACT so that the shell 16 | will use the XPG3 signalaction() and friends. You should leave 17 | USE_SIGACT defined, sh/sigact.c contains an implementation for 18 | systems that lack this facility. 19 | 20 | It is recommended that you try using the ./std tree first. This 21 | avoids problems like BSD times() calls that do not return an 22 | indication of elapsed time and so on. 23 | 24 | Using ./std: 25 | ------------ 26 | 27 | If you are on a Sun building it quite simple: 28 | 29 | make CONFIG=-D_BSD 30 | 31 | will do it. If you have a sun386 or sun3 and have gcc, it is 32 | worth using, just add CC="gcc -pipe" to the above command line. 33 | If you have SunOS 4.1 or later you probably need to add 34 | -DHAVE_SYS_STDTYPES 35 | 36 | Building on other systems may well be more difficult. 37 | Apparently the creating of the ./std/h tree causes problems on 38 | some systems. 39 | 40 | 41 | Notes on ./std: 42 | --------------- 43 | 44 | I have updated the Makefiles in ./std/stdc and ./tsd/posix to 45 | maintain the objects within the libraries. Ie. 46 | libstdc.a(strstr.o) If your make(1) doesn't know how to do this 47 | then you will need to modify the makefiles accordingly. 48 | 49 | In ReadMe.jrm, John MacMillan recommends being cautious of 50 | std/libstdc.a and using only those routines which your system 51 | lacks. Please note that I have tested virtually none of 52 | ./std/stdc. The Makefile contains target lines for most modules 53 | but most are commented out. I suggest you uncomment _only_ 54 | those that you need. 55 | 56 | On the other hand std/libposix.a seems quite safe, and 57 | indeed provides a better times() call for BSD systems. 58 | 59 | Read ReadMe.jrm for more... 60 | 61 | 62 | Building without ./std: 63 | ----------------------- 64 | 65 | On some systems it might be worth forgetting about ./std/lib* 66 | either because they proved too difficult to build or they seem 67 | unnecessary. As previously indicated I have done this on Sun's 68 | and on a Bull system. On Sun's it is perhaps not a great idea 69 | as you then get the system's times() call which does not behave 70 | the way the shell wants. 71 | 72 | In anycase to build without ./std, you simply cd to ./sh and 73 | either edit the Makefile accordingly, or use an appropriate 74 | command line. For instance: 75 | 76 | Sun with SunOS 4.0: 77 | 78 | cd ./sh 79 | ln -s ../std/stdc/strstr.c . 80 | ln -s ../std/stdc/memmove.c . 81 | make CFLAGS="-D_BSD -DNOSTDHDRS" \ 82 | XOBJS="strstr.o memmove.o" LDLIBS="" LDFLAGS="" 83 | 84 | Note that we still need a couple of functions from ./std/stdc 85 | 86 | On the Bull system which is a POSIX compliant System V machine: 87 | 88 | cd ./sh 89 | make CFLAGS="-D_SYSV" LDLIBS="-lc_s" LDFLAGS="" 90 | make CC=gcc CFLAGS="-D_POSIX_SOURCE" LDLIBS="-lc_s" LDFLAGS="" 91 | 92 | INSTALLING: 93 | =========== 94 | 95 | This is quite simple. 96 | 97 | # cp ./ksh /bin 98 | # chmod 555 /bin/ksh 99 | 100 | The above assumes of course that you don't already have a 101 | /bin/ksh :-) 102 | The manual page ksh.1 should be copied to an appropriate 103 | location. 104 | BSD: 105 | # cp ksh.1 /usr/man/man1 106 | SYSV: 107 | # nroff -man ksh.1 > /usr/catman/u_man/man1/ksh.1 108 | # pack /usr/catman/u_man/man1/ksh.1 109 | 110 | Or something similar. For systems such as Sun's that really 111 | only ship with a C-shell environment, the ./etc directory 112 | contains a useful /etc/profile and /etc/ksh.kshrc file to 113 | provide a suitable environemnt for /bin/sh and /bin/ksh users, 114 | they should work, they are straight of my system and I use them 115 | on Sun,Bull and even an SCO system. 116 | 117 | 118 | PROBLEMS: 119 | ========= 120 | 121 | Clearly building will not be so simple on all systems. 122 | Apparently some of the enum manipulations border on ilegal and 123 | cause some compilers problems. Curiously both gcc -ansi and the 124 | GreenHills compiler on the Bull system are quite picky and did 125 | not complain. Note if you want to use gcc -ansi you may well 126 | need to add some definitions, for instance the following all 127 | work on the sun386: 128 | 129 | CC=cc 130 | CC=gcc 131 | CC=gcc -ansi -Dsun -Di386 -Dsun386 132 | 133 | The last three items on the last line are normally all defined 134 | automatically, but this is disabled when -ansi is used. The 135 | system headers do not work unless they know what architecture is 136 | in use. 137 | 138 | On the Bull DPX/2 I used gcc-2.1, my gcc port will be available 139 | as of release 2.2. To save effort I found it necessary to copy 140 | stdio.h and stdlib.h to gcc's private include directory and edit 141 | them to remove unnecessary #ifdef's and unwanted #include's. 142 | 143 | If you find and fix a problem please fill in a copy of 144 | ./bug-report and e-mail it to pdksh-bug@zen.void.oz.au 145 | 146 | Enjoy! 147 | 148 | Simon J. Gerraty 149 | 150 | -------------------------------------------------------------------------------- /MACHINES: -------------------------------------------------------------------------------- 1 | This file documents some the machines that pdksh has been build 2 | on and notes that apply. 3 | 4 | Notes: 5 | (1) Built and tested by me (sjg), seems ok :-) 6 | (2) Reported ok (may mean earlier version) 7 | (3) Reported no good 8 | (4) Built with ./std/lib* 9 | (5) Built without ./std/lib* 10 | (6) No job control 11 | 12 | If you succesfully build this shell on another system please let 13 | me know. 14 | 15 | System, OS Notes Compiler/Flags 16 | -------------------------- ----- -------------- 17 | sun386, SunOS 4.0.2 1,4 {cc,gcc} -D_BSD 18 | sun4c, SunOS 4.1.1 1,4 {cc,gcc-2.1} -ansi -D_BSD -DHAVE_SYS_STDTYPES 19 | sun3, SunOS 4.0.3 1,4 {cc,gcc} -D_BSD 20 | sun3, SunOS 4.1.1 1,4 {cc,gcc} -ansi -D_BSD -DHAVE_SYS_STDTYPES 21 | Bull DPX/2, B.O.S. 2.00.45 1,5 {cc,gcc-2.1} -ansi -D_POSIX_SOURCE 22 | Bull XPS-100 1,6 cc -D_SYSV -DUSE_SIGNAL 23 | 24 | 25 | NOTES: 26 | The table above sumarizes the config used. {cc,gcc} indicates 27 | either compiler can be used. If gcc-2.1 rather than gcc is 28 | indicated then gcc < 2 may not work. This is at least true of 29 | sun4c (sparc) systems. 30 | 31 | Bull DPX/2: 32 | 33 | pdksh is not needed on this system. It is simply used as a 34 | System V / POSIX test bed. Build without ./std tree. I only 35 | tried with gcc-2.1. -D_SYSV must be left out of CFLAGS for POSIX 36 | functions such as sigaction() to be used. 37 | 38 | Bull XPS-100: 39 | 40 | Be sure to rm std/h/dirent.h std/h/sys/types.h and undef JOBS as 41 | the kernel does not support it. This machine has a sigaction() 42 | implementation that appears to be faulty. A SIGINT terminates 43 | the shell, when using the system's sigaction(). Undefining 44 | USE_SIGACT does the trick. sigact.c can now be forced to build 45 | by defining USE_SIGNAL, but this is not tested on the XPS. 46 | 47 | -------------------------------------------------------------------------------- /MANIFEST: -------------------------------------------------------------------------------- 1 | File Name Archive # Description 2 | ----------------------------------------------------------- 3 | ChangeLog 1 Current change history 4 | Changes.jrm 1 5 | Changes.mlj 1 6 | INSTALL 1 Installation notes 7 | MACHINES 1 Systems the shell has been built on 8 | MANIFEST 1 This shipping list 9 | Makefile 1 10 | PATCHDATES 1 C-News style patch tracking 11 | README 1 Please read 12 | ReadMe.jrm 1 General info and Install instructions 13 | ReadMe.sjg 1 14 | ReadMe.vimode 1 15 | bug-report 1 Bug report template 16 | etc 1 17 | etc/ksh.kshrc 1 global .kshrc 18 | etc/profile 1 19 | etc/sys_config.sh 1 20 | ksh.1 2 Manual page 21 | sh 1 ksh source 22 | sh/ChangeLog 2 Current change list 23 | sh/Changes 1 24 | sh/Makefile 2 25 | sh/ReadMe 1 Original ReadMe (out of date) 26 | sh/alloc.c 2 27 | sh/alloc.h 1 28 | sh/c_ksh.c 3 29 | sh/c_sh.c 3 30 | sh/c_test.c 3 31 | sh/config.h 1 32 | sh/edit.c 3 33 | sh/edit.h 3 34 | sh/emacs.c 4 35 | sh/eval.c 4 36 | sh/exec.c 5 37 | sh/expand.h 3 38 | sh/expr.c 3 39 | sh/getopts.c 5 40 | sh/history.c 5 41 | sh/io.c 5 42 | sh/jobs.c 6 43 | sh/lex.c 5 44 | sh/lex.h 5 45 | sh/mail.c 6 46 | sh/main.c 6 47 | sh/misc.c 6 48 | sh/patchlevel.h 6 version/patch level. 49 | sh/proto.h 1 Prototypes for ANSI compilers. 50 | sh/sh.h 6 51 | sh/sigact.h 6 Header for sigaction() implementation. 52 | sh/sigact.c 6 sigaction() implementation. 53 | sh/stdh.h 6 Centralise std header inclusion. 54 | sh/syn.c 7 55 | sh/table.c 7 56 | sh/table.h 7 57 | sh/trace.c 7 Simple trace facilty 58 | sh/trace.h 7 59 | sh/trap.c 7 60 | sh/tree.c 7 61 | sh/tree.h 7 62 | sh/tty.h 1 63 | sh/do_ulimit.c 7 64 | sh/var.c 8 65 | sh/version.c 3 66 | sh/vi.c 8 67 | std 1 libraries 68 | std/Makefile 3 69 | std/mklinks 1 make symlinks 70 | std/posix 2 71 | std/posix 4 posix lib source 72 | std/posix/ChangeLog 4 change history 73 | std/posix/Makefile 5 74 | std/posix/dirent.C 7 75 | std/posix/dirent.H 7 76 | std/posix/dirent.h 7 77 | std/posix/dup2.c 7 78 | std/posix/fcntl.c 7 79 | std/posix/fcntl.h 7 80 | std/posix/fixincludes 8 81 | std/posix/io.h 8 82 | std/posix/time.h 8 83 | std/posix/times.c 8 84 | std/posix/times.h 8 85 | std/posix/unistd.c 9 86 | std/posix/unistd.h 9 87 | std/posix/wait.h 9 88 | std/stdc 5 stdc lib source 89 | std/stdc/ChangeLog 7 change history 90 | std/stdc/Makefile 9 91 | std/stdc/clock.c 9 92 | std/stdc/fprintf.c 9 93 | std/stdc/limits.h 9 94 | std/stdc/memchr.c 8 95 | std/stdc/memcmp.c 9 96 | std/stdc/memcpy.c 9 97 | std/stdc/memmove.c 9 98 | std/stdc/memset.c 9 99 | std/stdc/setvbuf.c 9 100 | std/stdc/sprintf.c 9 101 | std/stdc/stdarg.h 9 102 | std/stdc/stddef.h 9 103 | std/stdc/stdio.c 9 104 | std/stdc/stdio.h_std 9 105 | std/stdc/stdio.sed 9 106 | std/stdc/stdlib.h 9 107 | std/stdc/strcat.c 9 108 | std/stdc/strchr.c 9 109 | std/stdc/strcmp.c 9 110 | std/stdc/strcpy.c 9 111 | std/stdc/strcspn.c 9 112 | std/stdc/strerror.c 9 113 | std/stdc/string.h 9 114 | std/stdc/strlen.c 9 115 | std/stdc/strncat.c 9 116 | std/stdc/strncmp.c 9 117 | std/stdc/strncpy.c 9 118 | std/stdc/strpbrk.c 9 119 | std/stdc/strrchr.c 9 120 | std/stdc/strspn.c 9 121 | std/stdc/strstr.c 9 122 | std/stdc/strtok.c 9 123 | std/stdc/time.h 9 124 | std/stdc/types.h 9 125 | std/stdc/vprintf.c 9 126 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # PD Bourne/Korn Shell 2 | # $Id: Makefile,v 1.2 1992/04/25 08:17:25 sjg Exp $ 3 | 4 | SHELL = /bin/sh 5 | MAKE = make 6 | CC=gcc -pipe -g -O 7 | LN=ln -s 8 | #LN=ln 9 | #CONFIG= -D_SYSV 10 | CONFIG= -D_BSD 11 | #CONFIG= -D_BSD -DHAVE_SYS_STDTYPES 12 | #CONFIG= -D_V7 13 | #CONFIG= -D_ST /* Atari ST */ 14 | 15 | MANPAGES = ksh.1 16 | #MANDIR=/usr/catman/u_man/man1 17 | #MANDIR=/usr/man/man1 18 | 19 | #INSTALL=bsdinstall 20 | INSTALL=install 21 | 22 | all: ksh 23 | 24 | ksh: libs 25 | ( cd sh ; $(MAKE) 'CC=$(CC)' 'CONFIG=$(CONFIG)' $@ ) 26 | 27 | libs: 28 | ( cd std ; $(MAKE) 'CC=$(CC)' 'CONFIG=$(CONFIG)' 'LN=$(LN)' libs ) 29 | 30 | install: sh/ksh 31 | ( cd sh ; $(INSTALL) -s ksh $(DESTDIR)/bin ) 32 | 33 | sh/ksh: ksh 34 | 35 | inst-man: $(MANPAGES) 36 | $(INSTALL) -c -m 444 $(MANPAGES) $(MANDESTDIR)/man1 37 | 38 | clean clobber: 39 | ( cd std ; $(MAKE) $@ ) 40 | ( cd sh ; $(MAKE) $@ ) 41 | -rm -f *.out 42 | 43 | -------------------------------------------------------------------------------- /PATCHDATES: -------------------------------------------------------------------------------- 1 | # PD ksh Version 4 2 | 09-Nov-91 3 | 10-Nov-91 4 | 25-Nov-91 5 | 25-Apr-92 6 | 26-Apr-92 7 | 27-Apr-92 8 | 12-May-92 9 | 25-Apr-92 10 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Public Domain Korn Shell 2 | Version 4.5 3 | 4 | PD KSH: 5 | 6 | This is the latest version of the PD ksh (pdksh). It is not 7 | intended to be the ultimate shell but rather a usable ksh work 8 | alike. For those of us who have to work on multiple systems it 9 | is nice to have the same user interface on all. I resisted 10 | moving to the ksh on a Bull system at work for nearly a year due 11 | to the lack of a ksh on my Sun systems. When I first picked up 12 | the 3.2 PD KSH a couple of years ago, it took only a few minutes 13 | to convert a C-shell fan to a ksh fan :-) Pdksh is not 100% 14 | compatible with the ksh. Having said that, I use it daily 15 | beside a real ksh88 and find them virtually indistinguishable. 16 | 17 | I only run this shell on sun's and only for interactive use. I 18 | use it on sun4c, sun3 and sun386 systems. The shell itself has 19 | been compiled on each of these both with and without the 20 | POSIX/ANSI compatability libraries in ./std. See the file 21 | MACHINES for details of systems that the shell has been built 22 | on. 23 | 24 | I have released this version of the shell (with the kind 25 | permission of the previous maintainers and major contributors) to 26 | ensure that it is available from usenet archive sites. Of 27 | course it remains in the Public Domain. Equally obviously 28 | neither myself nor any other contributors make any claims of 29 | suitability etc. Ie. NO WARRANTY!!! If you make any changes 30 | and distribute them, please leave your own finger prints in the 31 | source. Its bad enough being flamed for my own bugs let alone 32 | anyone elses :-) 33 | 34 | WHATS NEW: 35 | 36 | This update includes Job Control for System V (POSIX), many bug 37 | fixes and a simple history file mechanism. See sh/ChangeLog. 38 | 39 | HISTORY: 40 | 41 | This shell was written by Eric Gisin. It is based on Charles 42 | Forsyth's public domain V7 shell, which he later contributed to 43 | Minix. John R MacMillan picked up Eric Gisin's version after 44 | Eric moved on to other projects (see ReadMe.jrm). 45 | 46 | Since then there have been many contributors to this shell. 47 | Most have left their fingerprints within the source and various 48 | ReadMe.xxx and Changes.xxx files reflect their input. 49 | 50 | This version is basically that known as Eric Gisin's version 3.3 51 | alpha which I obtained indirectly from John R MacMillan who is 52 | the most recent maintainer. This version has much improved 53 | emacs-mode command line editing (my main contribution) plus 54 | enough extra emacs-mode features to make it difficult to 55 | distinguish from ksh88. Bug fixes from various contributors are 56 | the only other changes from John MacMillan's version. 57 | 58 | I have upped the version number for this release to distinguish 59 | it from the original 3.3 version. This version is much improved 60 | despite the small number of new features. 61 | 62 | INSTALLATION: 63 | 64 | The file INSTALL contains intructions for building and 65 | installing the shell. 66 | 67 | The original instructions indicated that a POSIX compliant 68 | environment and possibly an ANSI compiler are required. I have 69 | used both gcc and native Sun and the GreenHills ANSI compiler 70 | without problems. 71 | 72 | The POSIX/STDC compatability stuff in ./std seems to cause lots 73 | of problems for some systems. This was at least in part because 74 | I distributed it with half the librraies disabled :-), in any 75 | case the shell itself in ./sh can now be compiled without any of 76 | the ./std stuff which makes things much simpler on systems that 77 | have a real POSIX environment. 78 | 79 | Porting to new environemnts can be a real pain. I don't really 80 | plan to make a huge effort in this area since I expect that this 81 | shell will be mainly required on exotic or obscure systems (the 82 | ones that the vendor does not provide a ksh for). Thus the 83 | small "market" does not warrant a C-news or X11 style 84 | portability effort. Of course if people send patches for 85 | various systems I'm happy to try and integrate them. 86 | 87 | ENVIRONMENT: 88 | 89 | My main interest in this shell is for Sun workstations. Every 90 | other UNIX system I use comes with a real ksh. Being a strictly 91 | C-shell environment, some improved profile files are in order on 92 | Sun's. 93 | 94 | The etc directory contains a set of useful environment files. 95 | These are the same files I use on several systems (many use a 96 | real ksh): 97 | ./etc/profile 98 | ./etc/sys_config.sh 99 | ./etc/ksh.kshrc 100 | 101 | The first one is obvious. The second, sys_config.sh is sourced 102 | by /etc/profile and several other scripts. It is used to 103 | determine the system type so that scripts like profile can be 104 | used on multiple platforms. 105 | The third one is also quite useful, add 106 | . /etc/ksh.kshrc 107 | to user's ~/.kshrc to simplify alias management. 108 | 109 | BUGS: 110 | 111 | Many folk have contributed to this shell. 112 | I have attempted to credit (in sh/ChangeLog) the authors of bug 113 | fixes received since the previous release. 114 | There are surely still plenty of bugs to be found/fixed. 115 | 116 | There is a template bug report in bug-report [borrowed from the 117 | X11R5 mit tree], just fill in the blanks and mail to 118 | pdksh-bug@zen.void.oz.au. 119 | 120 | I hope you find this shell as useful as I do... 121 | 122 | Simon J. Gerraty 123 | -------------------------------------------------------------------------------- /ReadMe.jrm: -------------------------------------------------------------------------------- 1 | BUILDING THE PD KSH 2 | =================== 3 | 4 | As usual, there are differences between BSD and System V 5 | versions. Ideally, all you have to do is edit the Makefile in 6 | this directory to set the CONFIG macro to the appropriate value. 7 | (Actually, you may wish to change the CONFIG macro in all 8 | Makefiles; if you always invoke make(1) from here, CONFIG will 9 | be passed down, but if you invoke make(1) from a subdirectory 10 | you'll want the appropriate definition in that Makefile.) 11 | 12 | Of course it's not quite that simple. You may, however, take 13 | solace in the knowledge that it used to be worse. 14 | 15 | The Compatibility Libraries 16 | --------------------------- 17 | 18 | Eric Gisin wrote this shell using ANSI C and POSIX as 19 | portability guidlines. Realizing that nobody had a POSIX 20 | system and almost no one had an ANSI C environment, he provided 21 | minimal compatibility libraries. 22 | 23 | There are two libraries, one for POSIX (libposix.a) and one for 24 | ANSI C (libstdc.a). 25 | 26 | Libposix.a is pretty simple. Nothing in it has ever broken on 27 | me, so I'd just leave it. It provides a version of dup2() for 28 | System V systems. 29 | 30 | Libstdc.a is a bit hairy. I recommend looking at the routines 31 | provided and, and editing the std/stdc Makefile and only 32 | including objects that have routines your system libc.a is 33 | lacking. Various of the provided routines are just plain 34 | flaky, but only when they're not really needed. The other 35 | hairy thing he does is craft an ANSI stdio.h from the system 36 | supplied one and one of his own. Again, it's better than it 37 | used to be, but it's still a hack, and you may have to modify 38 | it by hand. 39 | 40 | You will also need a POSIX compatible set of directory reading 41 | routines. System V.3 systems have this in libc.a. The 42 | std/posix directory provides a something for BSD systems. I 43 | use a slightly modified version of Doug Gwyn's PD version. 44 | 45 | (The ``slightly modified'' is to work around a bug in Gwyn's version. 46 | The POSIX routines are documented as returning failure if the file for 47 | opendir(3) is not a directory. Gwyn attempts to open(2) the file, and 48 | then stats it to see if the file is a directory. However, if the file 49 | is a special file, and the open(2) doesn't return, you're screwed. My 50 | change was to open the file with the O_NDELAY flag, but Gwyn didn't 51 | feel this was portable (true, but I only do it where it works) and 52 | that stat-ing before the open would be too slow (true). The upshot is 53 | if you use his routines unmodified, don't ever do an "ls -l /dev/*/*".) 54 | 55 | The Shell Source 56 | ---------------- 57 | 58 | The source for the shell itself is in the sh directory. There you 59 | will want to edit config.h to determine the configuration options. Vi 60 | mode is in kind of rough shape, but does work. DIRSTACK routines 61 | aren't implemented yet, so again, why bother. SWTCH is a bit arcane, 62 | but it you use shl(1) and you define EMACS or VI you want to define 63 | this. JOBS is really only useful on BSD systems. It might work on 64 | systems that have POSIX job control, but I wouldn't bet on it. 65 | SHARPBANG is only useful on systems where the exec() family don't 66 | honour the #!/prog/path convention. 67 | 68 | This is where the shell gets built so you may wish to change 69 | the OTHERLIBS macro in the Makefile to point to your POSIX 70 | directory routines, or to use -lc_s, or whatever. 71 | 72 | Miscellaneous 73 | ------------- 74 | 75 | The Makefiles that actually compile things use the macro 76 | CCOPTS, so you can change it in individual Makefiles or specify 77 | it on the command line, eg. "make CCOPTS=-O OTHERLIBS=-lc_s". 78 | LDOPTS is used in the Makefile where the ksh is actually built. 79 | 80 | The very first time on a new system, do a "make clobber" 81 | 82 | Good luck. 83 | 84 | Documentation 85 | ------------- 86 | 87 | The ksh.1 is a man page for the PD ksh, although it lags 88 | somewhat behind the code. You get what you pay for. 89 | 90 | The ksh88.1 is a man page for AT&T's ksh88 (the latest version) 91 | provided for comparison. 92 | 93 | History 94 | ------- 95 | 96 | Much of the shell was written by Eric Gisin at the University 97 | of Waterloo, using some pieces of other stuff, notably Charles 98 | Forsythe's V7 shell, and some enhancements from the BRL shell. 99 | He placed it (in a alpha test state) into the public domain 100 | while I was at UW. I snarfed a copy, and got it running on my 101 | UNIXpc, and later some machines at work. I sent Gisin some bug 102 | reports, but he seems to have lost interest in the project. 103 | This may be because he now does some work for MKS, who produce a 104 | commercial version of the ksh for MS-DOS machines, so there may 105 | be a conflict of interest. 106 | 107 | So I gave up on getting future versions, and adopted it. I've 108 | made some enhancements, and quite a few bug fixes, and various 109 | people at work have contributed as well. It remains in the 110 | public domain, although I imagine the people involved would 111 | appreciate leaving their names attached (I'm exempt; I haven't 112 | actually included my name anywhere but here). 113 | 114 | The README in the sh directory is Gisin's, and tells a bit of 115 | the story from his point of view. Note that his compilation 116 | instructions don't really apply anymore. 117 | 118 | John R. MacMillan 119 | -------------------------------------------------------------------------------- /ReadMe.sjg: -------------------------------------------------------------------------------- 1 | HORIZONTAL SCROLLING 2 | ==================== 3 | 4 | I have migrated my 3.2 ksh edit.c mods into the 3.3 ksh 5 | This file describes the mods in general and really only applies 6 | (at this stage) to emacs-mode. I have not touched vi-mode apart 7 | from making it use pprompt() so that '!' is correctly expanded 8 | as in emacs-mode. 9 | 10 | I would prefer to see both vi.c and emacs.c use a common set of 11 | primatives in edit.c - but that looks like a lot of work. 12 | 13 | Basically my mods affect the functions that move the cursor 14 | about and redraw the edit line. 15 | 16 | The input buffer "buf" is pointed to by "xbuf" and its end is 17 | pointed to by "xend". The current position in "xbuf" and end of 18 | the edit line are pointed to by "xcp" and "xep" respectively. 19 | I have added "xbp" which points to the start of a display window 20 | within "xbuf". 21 | 22 | [A] starting position 23 | 24 | buf 25 | |<-------- $COLUMNS --------->| 26 | | |<---- x_displen ------->| 27 | | PS1| 28 | +==========+==============--------+.......+ 29 | |\ \ \ \ 30 | xbuf xbp xcp xep xend 31 | 32 | [B] scrolled 33 | 34 | buf 35 | | |<----- COLUMNS -------->| 36 | | |<----- x_displen ------>| 37 | | 38 | +-----------+==========+==============--------+.......+ 39 | \ \ \ \ \ 40 | xbuf xbp xcp xep xend 41 | 42 | In the above -------- represents the current edit line while 43 | ===== represents that portion which is visible on the screen. 44 | Note that initially xbp == xbuf and PS1 is displayed. 45 | PS1 uses some of the screen width and thus "x_displen" is less 46 | than $COLUMNS. 47 | 48 | Any time that "xcp" moves outside the region bounded by "xbp" 49 | and "xbp" + "x_displen", the function x_adjust() is called to 50 | relocate "xbp" appropriately and redraw the line. 51 | 52 | Excessive I/O is avoided where possible. x_goto() for instance 53 | calculates whether the destination is outside the visible 54 | region, and if so simply adjusts "xcp" and calls x_adjust() 55 | directly. Normally though x_adjust() is called from x_putc(). 56 | 57 | The above mechanism has be updated to use a function x_lastcp() 58 | that returns a pointer that accurately reflects the last 59 | visible char in the edit buffer. That is a more accurate 60 | version of xbp + x_displen which does not account for TABS. 61 | 62 | Other changes 63 | ============= 64 | 65 | I have also added some emacs mode functions. 66 | M-[0-9] 67 | Set a numeric arg (positive only). 68 | Used by all word related commands. 69 | M-_ 70 | M-. 71 | Retrieve word from previous command (default is last 72 | word). Use M-[1-9] to select word. 73 | M-u 74 | M-l 75 | M-c 76 | UPPER,lower,Capitalize word. 77 | 78 | 79 | Commands like delete-word now push the deleted text so that it 80 | may be yanked back into place. 81 | 82 | BUGS? 83 | ===== 84 | 85 | There are bound to be some. Please report same to me: 86 | 87 | Simon J. Gerraty 88 | 89 | -------------------------------------------------------------------------------- /ReadMe.vimode: -------------------------------------------------------------------------------- 1 | 2 | The changes I have made are all relevant to the VI edit mode. The vi-edit 3 | source seems mostly complete, so these changes are minimal. What is available 4 | now is pretty useful. I will make further fixes as I notice the bugs (or 5 | anyone else does). 6 | 7 | A summary of changes follows: 8 | 9 | 1) two changes to turn on the vi-editing feature. 10 | 2) motion edit fix: back space and space bar now do something: have 11 | the same behaviour as the 'h' and 'l' keys. 12 | 3) input edit fix: backspace key now works. 13 | 14 | Known bugs (not fixed yet): 15 | 16 | a) proviso on 1) and 2) above: the backspace key was hardwired to the 17 | key. I have temporarily extended it to include the '^H' or 18 | key. I will generalize this to use whatever key is defined 19 | as the erase character by stty. 20 | 21 | b) the interrupt key does not clear the edit buffer. This means the next 22 | edit command after an interrupt will be garbage. 23 | 24 | c) Same sort of thing as b) occurs for the key. 25 | 26 | d) insertions near the beginning of an edit buffer seem to screw up the rest 27 | of the buffer. 28 | 29 | Known missing features: 30 | 31 | a) search edit commands: [count]-, [count]+ 32 | b) text modification edit commands: P, p, * 33 | c) r (replace) doesn't seem to work too well. 34 | d) tilde does not do anything (should reverse upper to lower and vice versa) 35 | 36 | e) ! in prompt doesn't get expanded to history number 37 | -------------------------------------------------------------------------------- /bug-report: -------------------------------------------------------------------------------- 1 | To: pdksh-bug@zen.void.oz.au 2 | Subject: [area]: [synopsis] [replace with actual area and short description] 3 | 4 | VERSION: 5 | PD KSH: 4.5 12-May-1992 6 | [Official patches will edit this line to indicate the patch level] 7 | 8 | MACHINE and OPERATING SYSTEM: 9 | [e.g. Sparc/SunOS 4.1.1, DECstation 3100/Ultrix 4.2, ...] 10 | 11 | COMPILER: 12 | [e.g. native cc, native ANSI cc, gcc 1.40, ...] 13 | 14 | AREA: 15 | [Area of the source tree affected, 16 | e.g., std/posix, std/stdc, sh] 17 | 18 | SYNOPSIS: 19 | [Brief description of the problem and where it is located] 20 | 21 | DESCRIPTION: 22 | [Detailed description of problem. Please provide as much detail 23 | as you can manage. The more information we have the more likely 24 | a fix] 25 | 26 | SAMPLE FIX: 27 | [Preferred, but not necessary. Please send context diffs (diff -c) 28 | name old file first. eg. diff -c file.c.old file.c] 29 | 30 | [PLEASE make your Subject: line as descriptive as possible. 31 | Subjects like "pdksh bug" or "bug report" are not helpful!] 32 | [Remove all the explanatory text in brackets before mailing.] 33 | [Send to pdksh-bug@zen.void.oz.au] 34 | -------------------------------------------------------------------------------- /etc/ksh.kshrc: -------------------------------------------------------------------------------- 1 | : 2 | # NAME: 3 | # ksh.kshrc - global initialization for ksh 4 | # 5 | # DESCRIPTION: 6 | # Each invocation of /bin/ksh processes the file pointed 7 | # to by $ENV (usually $HOME/.kshrc). 8 | # This file is intended as a global .kshrc file for the 9 | # Korn shell. A user's $HOME/.kshrc file simply requires 10 | # the line: 11 | # . /etc/ksh.kshrc 12 | # at or near the start to pick up the defaults in this 13 | # file which can then be overridden as desired. 14 | # 15 | # SEE ALSO: 16 | # $HOME/.kshrc 17 | # 18 | # RCSid: 19 | # $Id: ksh.kshrc,v 1.2 1992/04/27 07:09:28 sjg Exp $ 20 | # @(#)Copyright (c) 1991 Simon J. Gerraty 21 | # 22 | # This file is provided in the hope that it will 23 | # be of use. There is absolutely NO WARRANTY. 24 | # Permission to copy, redistribute or otherwise 25 | # use this file is hereby granted provided that 26 | # the above copyright notice and this notice are 27 | # left intact. 28 | 29 | case "$-" in 30 | *i*) # we are interactive 31 | # we may have su'ed so reset these 32 | # NOTE: SCO-UNIX doesn't have whoami, 33 | # install whoami.sh 34 | USER=`whoami` 35 | PROMPT="<$USER@$HOSTNAME:!>$ " 36 | PPROMPT='<$USER@$HOSTNAME:$PWD:!>$ ' 37 | PS1=$PPROMPT 38 | # $TTY is the tty we logged in on, 39 | # $tty is that which we are in now (might by pty) 40 | tty=`tty` 41 | tty=`basename $tty` 42 | 43 | set -o ${FCEDIT:-$EDITOR} 44 | 45 | # the PD ksh is not 100% compatible 46 | case "$KSH_VERSION" in 47 | *PD*) # PD ksh 48 | bind ^?=delete-char-backward 49 | bind ^[^?=delete-word-backward 50 | ;; 51 | *) # real ksh ? 52 | ;; 53 | esac 54 | case "$TERM" in 55 | sun*) 56 | if [ "$tty" != console ]; then 57 | ILS='\033]L'; ILE='\033\\' 58 | WLS='\033]l'; WLE='\033\\' 59 | fi 60 | ;; 61 | xterm*) 62 | ILS='\033]1;'; ILE='\007' 63 | WLS='\033]2;xterm: '; WLE='\007' 64 | ;; 65 | *) ;; 66 | esac 67 | # do we want window decorations? 68 | if [ "$ILS" ]; then 69 | wftp () { ilabel "ftp $*"; "ftp" $*; ilabel "$USER@$HOSTNAME"; } 70 | wcd () { "cd" $*; eval stripe; } 71 | ilabel () { print -n "${ILS}$*${ILE}"; } 72 | label () { print -n "${WLS}$*${WLE}"; } 73 | alias stripe='label $USER @ $HOSTNAME \($tty\) - $PWD' 74 | alias cd=wcd 75 | alias ftp=wftp 76 | eval stripe 77 | eval ilabel "$USER@$HOSTNAME" 78 | PS1=$PROMPT 79 | fi 80 | alias ls='ls -CF' 81 | alias h='fc -l | more' 82 | alias quit=exit 83 | alias cls=clear 84 | alias logout=exit 85 | alias bye=exit 86 | 87 | 88 | # add your favourite aliases here 89 | ;; 90 | *) # non-interactive 91 | ;; 92 | esac 93 | # commands for both interactive and non-interactive shells 94 | -------------------------------------------------------------------------------- /etc/profile: -------------------------------------------------------------------------------- 1 | : 2 | # NAME: 3 | # profile - global initialization for sh,ksh 4 | # 5 | # DESCRIPTION: 6 | # This file is processed during login by /bin/sh 7 | # and /bin/ksh. It is used to setup the default user 8 | # environment. It is processed with root privs. 9 | # 10 | # SEE ALSO: 11 | # $HOME/.profile 12 | # /etc/ksh.kshrc 13 | # 14 | # RCSid: 15 | # $Id: profile,v 1.3 1992/05/03 08:28:27 sjg Exp $ 16 | # @(#)Copyright (c) 1991 Simon J. Gerraty 17 | # 18 | # This file is provided in the hope that it will 19 | # be of use. There is absolutely NO WARRANTY. 20 | # Permission to copy, redistribute or otherwise 21 | # use this file is hereby granted provided that 22 | # the above copyright notice and this notice are 23 | # left intact. 24 | 25 | case "$_INIT_" in 26 | *env*) ;; 27 | *) # do these once 28 | _INIT_="$_INIT_"env 29 | export _INIT_ 30 | # sys_config.sh should set ARCH,OS,C,N,HOSTNAME,uname 31 | # we use these in lots of scripts... 32 | [ -f /etc/sys_config.sh ] && . /etc/sys_config.sh 33 | 34 | # pick one of the following for the default umask 35 | # umask 002 # relaxed -rwxrwxr-x 36 | umask 022 # cautious -rwxr-xr-x 37 | # umask 027 # uptight -rwxr-x--- 38 | # umask 077 # paranoid -rwx------ 39 | # you can override the default umask 40 | # for specific groups later... 41 | 42 | if [ -d /local ]; then 43 | LOCAL=/local 44 | else 45 | LOCAL=/usr/local 46 | fi 47 | 48 | # set system specific things, 49 | # eg. set PATH,MANPATH 50 | # override default ulimit if desired. 51 | # defult ulmit is unlimited on SunOS 52 | # and 4Mb for most System V 53 | case $OS in 54 | SunOS) 55 | # On sun's /bin -> /usr/bin so leave it out! 56 | PATH=.:/usr/bin:/usr/ucb:/usr/5bin 57 | MANPATH=/usr/man 58 | defterm=vt220 59 | ;; 60 | SCO-UNIX) 61 | PATH=.:/bin:/usr/bin:/usr/lbin:/usr/dbin:/usr/ldbin 62 | MANPATH=/usr/man 63 | defterm=ansi 64 | ;; 65 | B.O.S.) 66 | PATH=.:/bin:/usr/bin 67 | if [ -d /usr/ucb ]; then 68 | PATH=$PATH:/usr/ucb 69 | fi 70 | MANPATH=/usr/catman 71 | defterm=vt220 72 | SRC_COMPAT=_SYSV 73 | export SRC_COMPAT 74 | ;; 75 | *) 76 | PATH=.:/bin:/usr/bin 77 | if [ -d /usr/ucb ]; then 78 | PATH=$PATH:/usr/ucb 79 | fi 80 | MANPATH=/usr/catman 81 | defterm=vt220 82 | ;; 83 | esac 84 | if [ -d ${LOCAL}/bin ]; then 85 | PATH=$PATH:${LOCAL}/bin 86 | fi 87 | if [ -d $HOME/bin -a "$HOME" != / ]; then 88 | PATH=$PATH:$HOME/bin 89 | fi 90 | if [ -d ${LOCAL}/man ]; then 91 | MANPATH=$MANPATH:${LOCAL}/man 92 | fi 93 | # make sure these are set at least once 94 | LOGNAME=${LOGNAME:-`logname`} 95 | USER=${USER:-$LOGNAME} 96 | 97 | # this is adapted from my whoami.sh 98 | # we expect id to produce output like: 99 | # uid=100(sjg) gid=10(staff) groups=10(staff),... 100 | S='(' 101 | E=')' 102 | GROUP=`id | cut -d= -f3 | \ 103 | sed -e "s;^[^${S}][^${S}]*${S}\([^${E}][^${E}]*\)${E}.*$;\1;"` 104 | 105 | # set some group specific defaults 106 | case "$GROUP" in 107 | staff) # staff deal with things that non-staff 108 | # have no business looking at 109 | umask 027 110 | ;; 111 | extern) # we put external accounts in group "extern" 112 | # give them as much privacy as we can... 113 | umask 077 114 | ulimit 16384 # 8Mb file limit 115 | TMOUT=600 # idle timeout 116 | ;; 117 | esac 118 | 119 | unset S E GROUP 120 | export LOCAL TTY PATH LOGNAME USER 121 | 122 | if [ -t 1 ]; then 123 | TTY=`tty` 124 | TTY=`basename $TTY` 125 | ORGANIZATION="" 126 | COPYRIGHT="Copyright (c) `date +19%y` $ORGANIZATION" 127 | export ORGANIZATION COPYRIGHT 128 | 129 | # set up some env variables 130 | MAIL=/usr/spool/mail/$USER 131 | MAILPATH=/usr/spool/mail/$USER:/etc/motd 132 | EMACSDIR=${LOCAL}/lib/emacs 133 | PAGER=${PAGER:-more} 134 | export MAIL EMACSDIR MANPATH MAILPATH PAGER 135 | 136 | EDITOR=emacs 137 | FCEDIT=${EDITOR} 138 | 139 | PROMPT="<$LOGNAME@$HOSTNAME>$ " 140 | PUBDIR=/usr/spool/uucppublic 141 | export PUBDIR 142 | [ -f /etc/profile.TeX ] && . /etc/profile.TeX 143 | else 144 | TTY=none 145 | fi 146 | 147 | # test (and setup if we are Korn shell) 148 | if [ "$RANDOM" != "$RANDOM" ]; then 149 | # we are Korn shell 150 | SHELL=/bin/ksh 151 | ENV=${HOME%/}/.kshrc 152 | PROMPT="<$LOGNAME@$HOSTNAME:!>$ " 153 | export HISTSIZE HISTFILE ENV 154 | CDPATH=.:$HOME 155 | if [ "$TMOUT" ]; then 156 | typeset -r TMOUT 157 | fi 158 | else 159 | SHELL=/bin/sh 160 | fi 161 | PS1=$PROMPT 162 | export SHELL PS1 EDITOR PATH PROMPT HOSTNAME CDPATH FCEDIT 163 | 164 | ;; 165 | esac 166 | 167 | # login time initialization 168 | case "$_INIT_" in 169 | *log*) ;; 170 | *) _INIT_="$_INIT_"log 171 | 172 | if [ $TTY != none -a "$0" != "-su" -a "$LOGNAME" = "`logname`" -a ! -f ~/.hushlogin ] 173 | then 174 | case $TERM in 175 | network|unknown|dialup|"") 176 | echo $N "Enter terminal type [$defterm]: $C" 1>&2 177 | read tmpterm 178 | TERM=${tmpterm:-$defterm} 179 | ;; 180 | esac 181 | # set up desired tty modes 182 | stty intr '^c' 183 | case $TERM in 184 | wy50) stty erase '^h';; 185 | *) stty erase '^?';; 186 | esac 187 | # welcome first time users 188 | [ -r ${LOCAL}/etc/1stlogin.ann -a ! -f $HOME/... ] && \ 189 | . ${LOCAL}/etc/1stlogin.ann 190 | # not all of the following are appropriate at all sites 191 | # Sun's don't need to cat /etc/motd for instance 192 | case "$OS" in 193 | SunOS) ;; 194 | SCO-UNIX) 195 | [ -s /etc/motd ] && cat /etc/motd 196 | [ -x /usr/bin/mail -a -s "$MAIL" ] && 197 | echo "You have mail." 198 | [ -x /usr/bin/news ] && /usr/bin/news -n 199 | ;; 200 | *) 201 | [ -s /etc/motd ] && cat /etc/motd 202 | if [ -x /usr/bin/mailx ]; then 203 | if mailx -e; then 204 | echo "You have mail." 205 | # show the the headers, this might 206 | # be better done in .profile so they 207 | # can override it. 208 | # mailx -H 209 | fi 210 | fi 211 | [ -x /usr/bin/news ] && /usr/bin/news -n 212 | ;; 213 | esac 214 | [ -x /usr/games/fortune ] && /usr/games/fortune -a 215 | # remind folk who turned on reply.pl to turn it off. 216 | if [ -f $HOME/.forward ]; then 217 | echo "Your mail is being forwarded to:" 218 | cat $HOME/.forward 219 | if [ -f $HOME/.recording ]; then 220 | echo "Perhaps you should run \"reply.pl off\"" 221 | fi 222 | fi 223 | fi 224 | unset tmpterm defterm C N 225 | TERM=${TERM:-unknown} 226 | export TERM TTY 227 | ;; 228 | esac 229 | # Handle X-terminals if necessary 230 | [ -f /etc/profile.X11 ] && . /etc/profile.X11 231 | -------------------------------------------------------------------------------- /etc/sys_config.sh: -------------------------------------------------------------------------------- 1 | : 2 | # NAME: 3 | # sys_config.sh - set system specific variables 4 | # 5 | # SYNOPSIS: 6 | # . /etc/sys_config.sh 7 | # 8 | # DESCRIPTION: 9 | # Source this script into shell scripts that want to handle 10 | # various system types. 11 | # You may well want to edit this on a particular system replacing 12 | # `uname -s` etc with the result. So that the facility will work 13 | # even when in single user mode and uname et al are not available. 14 | # 15 | # SEE ALSO: 16 | # /etc/profile 17 | # 18 | # AMENDED: 19 | # 91/11/05 22:09:08 (rook) 20 | # 21 | # RELEASED: 22 | # 91/11/05 22:09:09 v1.3 23 | # 24 | # SCCSID: 25 | # @(#)sys_config.sh 1.3 91/11/05 22:09:08 (rook) 26 | # 27 | # @(#)Copyright (c) 1991 Simon J. Gerraty 28 | # 29 | # This file is provided in the hope that it will 30 | # be of use. There is absolutely NO WARRANTY. 31 | # Permission to copy, redistribute or otherwise 32 | # use this file is hereby granted provided that 33 | # the above copyright notice and this notice are 34 | # left intact. 35 | # 36 | 37 | # determin machine type 38 | if [ -f /usr/bin/arch ]; then 39 | ARCH=`arch` 40 | elif [ -f /usr/bin/uname -o -f /bin/uname ]; then 41 | ARCH=`uname -m` 42 | fi 43 | # 44 | case "$ARCH" in 45 | sun386) uname=/usr/5bin/uname 46 | OS=SunOS 47 | ;; 48 | *) uname=uname;; 49 | esac 50 | 51 | # set the operating system type 52 | # you can't use `uname -s` with SCO UNIX 53 | # it returns the same string as `uname -n` 54 | # so set it manually 55 | # OS=SCO-UNIX 56 | # The eval below is a workaround for a bug in the PD ksh. 57 | OS=${OS:-`eval $uname -s`} 58 | HOSTNAME=${HOSTNAME:-`eval $uname -n`} 59 | 60 | # set which ever is required to not produce a linefeed 61 | # in an echo(1) 62 | case $OS in 63 | SunOS) C="\c"; N=""; 64 | ;; 65 | *) C="\c"; N="" 66 | ;; 67 | esac 68 | export OS ARCH HOSTNAME C N uname 69 | -------------------------------------------------------------------------------- /sh/Changes: -------------------------------------------------------------------------------- 1 | Fix echo $$ | cat 2 | #if and config option cleanup 3 | Fix let evaluation of null/unset vars 4 | alloc improvement 5 | Fix accidental SCCS keywords 6 | Fix Xstring overwriting in lex.c 7 | Print here doc temp file when printing I/O actions 8 | Add more slack on end of Xstrings 9 | Fix up test(1) parsing 10 | Run shell scripts with EXECSHELL 11 | Make temp files 0600 12 | Make unset -f work 13 | Make trailing blank or tab in alias work 14 | Fix command completion bug 15 | -------------------------------------------------- 16 | Fix "cd / foo" 17 | Fix getopts accidentally resetting itself 18 | -------------------------------------------------- 19 | Fix whence exit codes 20 | -------------------------------------------------------------------------------- /sh/Makefile: -------------------------------------------------------------------------------- 1 | # PD Bourne/Korn Shell 2 | # $Id: Makefile,v 1.2 1992/04/25 08:33:03 sjg Exp $ 3 | 4 | SHELL = /bin/sh 5 | MAKE = make 6 | 7 | LN = ln -s 8 | 9 | # You _can_ build this shell without the ../std tree if your 10 | # system provides a sufficiently POSIX environment, or if your 11 | # BSD system is a Sun or close. If not try ../std. 12 | 13 | # gcc is good value on most mc68k's and sun386's if nothing else. 14 | # if you don't have gcc cc should do 15 | # CC=gcc -pipe 16 | CC=gcc -pipe 17 | 18 | # The following are the defintions used (or thereabouts) 19 | # to build ksh without ../std 20 | # 21 | # sun386 SunOS 4.0.2, sun3 SunOS 4.0.3 22 | # CONFIG=-D_BSD 23 | # XOPTS=-DNOSTDHDRS 24 | # copy these from ../std/stdc or ensure they are in libstdc.a 25 | # XOBJS = memmove.o strstr.o 26 | # 27 | # sun3 SunOS 4.1.1 28 | # CONFIG=-D_BSD 29 | # XOPTS=-DNOSTDHDRS 30 | # copy these from ../std/stdc or ensure they are in libstdc.a 31 | # XOBJS = memmove.o 32 | # 33 | # sun4c (sparc) SunOS 4.1.1 34 | # CC=cc -pipe # don't use gcc 35 | # CONFIG=-D_BSD 36 | # XOPTS=-DNOSTDHDRS 37 | # copy these from ../std/stdc or ensure they are in libstdc.a 38 | # XOBJS = memmove.o 39 | # 40 | # Bull DPX/2 B.O.S. 2.00.45 41 | # CC=gcc -ansi 42 | # CONFIG=-D_POSIX_SOURCE 43 | # XOPTS= 44 | # XOBJS= 45 | # 46 | # Minix-386 1.5.10 with estdio 47 | # CONFIG= -D_BSD -D_MINIX -D_POSIX_SOURCE 48 | # XOPTS= 49 | # XOBJS= 50 | # 51 | 52 | #CONFIG= -D_SYSV 53 | #CONFIG= -D_BSD -DHAVE_SYS_STDTYPES 54 | #CONFIG= -D_BSD 55 | CONFIG=-D_POSIX_SOURCE -D_MINIX 56 | 57 | 58 | STD=../std 59 | INCL=$(STD)/h 60 | #XINCL=-I$(INCL) 61 | #LDOPTS=-L$(STD) 62 | XOBJS= 63 | 64 | # use -O if you trust it :-) 65 | #DBG=-g -O 66 | CFLAGS = $(DBG) $(CONFIG) $(XINCL) $(XOPTS) 67 | 68 | LDFLAGS = $(DBG) $(LDOPTS) 69 | 70 | #COMPATLIBS = -lstdc -lposix 71 | #XLIBS = -lc_s 72 | #XLIBS = -ldirent 73 | LDLIBS = $(COMPATLIBS) $(XLIBS) 74 | 75 | HDRS = sh.h table.h expand.h lex.h tree.h tty.h trace.h 76 | SRCS1 = version.c main.c misc.c trap.c alloc.c io.c \ 77 | syn.c lex.c edit.c emacs.c vi.c history.c tree.c 78 | SRCS2 = exec.c jobs.c \ 79 | c_sh.c c_ksh.c c_test.c getopts.c do_ulimit.c \ 80 | var.c table.c eval.c expr.c mail.c sigact.c trace.c 81 | SRCS = Makefile $(HDRS) $(SRCS1) $(SRCS2) 82 | 83 | OBJS = version.o main.o misc.o \ 84 | syn.o lex.o edit.o emacs.o vi.o tree.o \ 85 | exec.o jobs.o trap.o \ 86 | c_sh.o c_ksh.o c_test.o \ 87 | do_ulimit.o getopts.o expr.o history.o \ 88 | var.o table.o alloc.o io.o eval.o mail.o sigact.o trace.o $(XOBJS) 89 | 90 | ksh: $(OBJS) 91 | $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LDLIBS) 92 | 93 | clean: 94 | rm -f *.o *.out core 95 | 96 | clobber: clean 97 | rm -f ksh 98 | 99 | link: 100 | ($(SHELL) ../std/mklinks ../std/h stdh.h) 101 | 102 | 103 | depend: 104 | makedepend $(CFLAGS) $(SRCS1) $(SRCS2) 105 | 106 | install: 107 | @echo "Try:" 108 | @echo "cp ksh /bin" 109 | @echo "strip /bin/ksh" 110 | @echo "chmod 555 /bin/ksh" 111 | 112 | .c.s: 113 | $(CC) $(CFLAGS) -S -o $@ $< 114 | 115 | asms: $(OBJS:.o=.s) 116 | 117 | 118 | # DO NOT DELETE THIS LINE -- make depend depends on it. 119 | # If this runs make out of memory, delete /usr/include lines. 120 | alloc.o: alloc.c 121 | alloc.o: config.h 122 | alloc.o: sh.h 123 | alloc.o: stdh.h 124 | alloc.o: trace.h 125 | c_ksh.o: c_ksh.c 126 | c_ksh.o: config.h 127 | c_ksh.o: sh.h 128 | c_ksh.o: stdh.h 129 | c_ksh.o: table.h 130 | c_ksh.o: trace.h 131 | c_sh.o: c_sh.c 132 | c_sh.o: config.h 133 | c_sh.o: lex.h 134 | c_sh.o: sh.h 135 | c_sh.o: stdh.h 136 | c_sh.o: table.h 137 | c_sh.o: trace.h 138 | c_sh.o: tree.h 139 | c_test.o: c_test.c 140 | c_test.o: config.h 141 | c_test.o: sh.h 142 | c_test.o: stdh.h 143 | c_test.o: trace.h 144 | edit.o: config.h 145 | edit.o: edit.c 146 | edit.o: edit.h 147 | edit.o: lex.h 148 | edit.o: sh.h 149 | edit.o: stdh.h 150 | edit.o: trace.h 151 | edit.o: tty.h 152 | emacs.o: config.h 153 | emacs.o: edit.h 154 | emacs.o: emacs.c 155 | emacs.o: expand.h 156 | emacs.o: lex.h 157 | emacs.o: sh.h 158 | emacs.o: stdh.h 159 | emacs.o: table.h 160 | emacs.o: trace.h 161 | emacs.o: tree.h 162 | eval.o: config.h 163 | eval.o: eval.c 164 | eval.o: expand.h 165 | eval.o: lex.h 166 | eval.o: sh.h 167 | eval.o: stdh.h 168 | eval.o: table.h 169 | eval.o: trace.h 170 | eval.o: tree.h 171 | exec.o: config.h 172 | exec.o: exec.c 173 | exec.o: lex.h 174 | exec.o: sh.h 175 | exec.o: stdh.h 176 | exec.o: table.h 177 | exec.o: trace.h 178 | exec.o: tree.h 179 | expr.o: config.h 180 | expr.o: expr.c 181 | expr.o: sh.h 182 | expr.o: stdh.h 183 | expr.o: table.h 184 | expr.o: trace.h 185 | getopts.o: config.h 186 | getopts.o: getopts.c 187 | getopts.o: sh.h 188 | getopts.o: stdh.h 189 | getopts.o: table.h 190 | getopts.o: trace.h 191 | history.o: config.h 192 | history.o: history.c 193 | history.o: lex.h 194 | history.o: sh.h 195 | history.o: stdh.h 196 | history.o: trace.h 197 | io.o: config.h 198 | io.o: io.c 199 | io.o: sh.h 200 | io.o: stdh.h 201 | io.o: trace.h 202 | jobs.o: config.h 203 | jobs.o: jobs.c 204 | jobs.o: sh.h 205 | jobs.o: stdh.h 206 | jobs.o: trace.h 207 | jobs.o: tree.h 208 | lex.o: config.h 209 | lex.o: expand.h 210 | lex.o: lex.c 211 | lex.o: lex.h 212 | lex.o: sh.h 213 | lex.o: stdh.h 214 | lex.o: table.h 215 | lex.o: trace.h 216 | lex.o: tree.h 217 | mail.o: config.h 218 | mail.o: mail.c 219 | mail.o: sh.h 220 | mail.o: stdh.h 221 | mail.o: table.h 222 | mail.o: trace.h 223 | main.o: config.h 224 | main.o: lex.h 225 | main.o: main.c 226 | main.o: sh.h 227 | main.o: stdh.h 228 | main.o: table.h 229 | main.o: trace.h 230 | main.o: tree.h 231 | memmove.o: memmove.c 232 | memmove.o: stdh.h 233 | misc.o: config.h 234 | misc.o: expand.h 235 | misc.o: misc.c 236 | misc.o: sh.h 237 | misc.o: stdh.h 238 | misc.o: trace.h 239 | strstr.o: stdh.h 240 | strstr.o: strstr.c 241 | syn.o: config.h 242 | syn.o: expand.h 243 | syn.o: lex.h 244 | syn.o: sh.h 245 | syn.o: stdh.h 246 | syn.o: syn.c 247 | syn.o: table.h 248 | syn.o: trace.h 249 | syn.o: tree.h 250 | sigact.o: sigact.h sigact.c 251 | table.o: config.h 252 | table.o: sh.h 253 | table.o: stdh.h 254 | table.o: table.c 255 | table.o: table.h 256 | table.o: trace.h 257 | times.o: times.c 258 | trace.o: trace.c 259 | trap.o: config.h 260 | trap.o: sh.h 261 | trap.o: stdh.h 262 | trap.o: trace.h 263 | trap.o: trap.c 264 | tree.o: config.h 265 | tree.o: sh.h 266 | tree.o: stdh.h 267 | tree.o: trace.h 268 | tree.o: tree.c 269 | tree.o: tree.h 270 | do_ulimit.o: config.h 271 | do_ulimit.o: sh.h 272 | do_ulimit.o: stdh.h 273 | do_ulimit.o: trace.h 274 | do_ulimit.o: do_ulimit.c 275 | var.o: config.h 276 | var.o: expand.h 277 | var.o: sh.h 278 | var.o: stdh.h 279 | var.o: table.h 280 | var.o: trace.h 281 | var.o: var.c 282 | version.o: config.h 283 | version.o: sh.h 284 | version.o: stdh.h 285 | version.o: trace.h 286 | version.o: version.c 287 | vi.o: config.h 288 | vi.o: edit.h 289 | vi.o: expand.h 290 | vi.o: lex.h 291 | vi.o: sh.h 292 | vi.o: stdh.h 293 | vi.o: table.h 294 | vi.o: trace.h 295 | vi.o: tree.h 296 | vi.o: vi.c 297 | # WARNING: Put nothing here or make depend will gobble it up! 298 | -------------------------------------------------------------------------------- /sh/ReadMe: -------------------------------------------------------------------------------- 1 | Public Domain KornShell 2 | 3 | Quick installation notes for PD KornShell 4 | 5 | PD KornShell can be installed on 4.2+ BSD systems, System V, and 6 | POSIX-compatable systems. The makefiles all define _BSD, change 7 | this to _SYSV, or _POSIX. The makefiles also contain CC=gcc, 8 | delete this if you don't have GNU C. The ksh makefile also 9 | contains some options, including JOBS (BSD/POSIX job control) 10 | and EDIT (emacs command editing). 11 | 12 | PD KornShell assumes you have standard C (ANSI) and POSIX header 13 | files and functions. Since you probably don't, they are provided 14 | in the "std" directory. 15 | 16 | The Alpha test version will probably come as two tar files. 17 | std.tar contains standard C and POSIX emulation and must be 18 | extracted into a directory called std. ksh.tar contains the ksh 19 | source and should be extracted into a directory called src or 20 | ksh. 21 | 22 | See std/ReadMe and install it. Only then can you make ksh in the 23 | "src" directory. 24 | 25 | To clear up questions about the origin of this shell, this shell 26 | is NOT based on the "Minix shell". It is based on Charles 27 | Forsyth's public domain V7 shell, which he later contributed to 28 | Minix. 29 | 30 | I have permission directly from Charles Forsyth to use his shell. 31 | 32 | Eric Gisin, egisin@math.UWaterloo.CA (or Waterloo.EDU) 33 | 34 | Things to do 35 | - add sxt-based job control (see Brown's contribution on the Usenix 87 tape). 36 | - add arrays and variable attributes. 37 | - add MAILPATH and CDPATH. 38 | - add vi editing mode (apparently someone has a PD version). 39 | - add new features described in Korn's book. 40 | 41 | Machines ported to 42 | VAX, 68000, 80386 43 | 44 | OS's ported to 45 | BSD 4.2, BSD 4.3 (with and without YP and NFS 46 | Sys V.3 47 | -------------------------------------------------------------------------------- /sh/alloc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * area-based allocation built on malloc/free 3 | */ 4 | 5 | #ifndef lint 6 | static char *RCSid = "$Id: alloc.c,v 1.2 1992/04/25 08:33:28 sjg Exp $"; 7 | #endif 8 | 9 | #include "stdh.h" 10 | #include 11 | #include "sh.h" 12 | 13 | #define ICELLS 100 /* number of Cells in small Block */ 14 | 15 | typedef union Cell Cell; 16 | typedef struct Block Block; 17 | 18 | /* 19 | * The Cells in a Block are organized as a set of objects. 20 | * Each object (pointed to by dp) begins with a size in (dp-1)->size, 21 | * followed with "size" data Cells. Free objects are 22 | * linked together via dp->next. 23 | */ 24 | 25 | union Cell { 26 | size_t size; 27 | union Cell *next; 28 | struct {int _;} junk; /* alignment */ 29 | }; 30 | 31 | struct Block { 32 | struct Block *next; /* list of Blocks in Area */ 33 | union Cell *free; /* object free list */ 34 | union Cell *last; /* &b.cell[size] */ 35 | union Cell cell [1]; /* [size] Cells for allocation */ 36 | }; 37 | 38 | Block aempty = {&aempty, aempty.cell, aempty.cell}; 39 | 40 | /* create empty Area */ 41 | Area * 42 | ainit(ap) 43 | register Area *ap; 44 | { 45 | ap->free = &aempty; 46 | return ap; 47 | } 48 | 49 | /* free all object in Area */ 50 | void 51 | afreeall(ap) 52 | register Area *ap; 53 | { 54 | register Block *bp; 55 | register Block *tmp; 56 | 57 | bp = ap->free; 58 | if (bp != NULL && bp != &aempty) { 59 | do { 60 | tmp = bp->next; 61 | free((void*)bp); 62 | bp = tmp; 63 | } while (bp != ap->free); 64 | ap->free = &aempty; 65 | } 66 | } 67 | 68 | /* allocate object from Area */ 69 | void * 70 | alloc(size, ap) 71 | size_t size; 72 | register Area *ap; 73 | { 74 | int cells, split; 75 | register Block *bp; 76 | register Cell *dp, *fp, *fpp; 77 | 78 | if (size <= 0) { 79 | aerror(ap, "allocate bad size"); 80 | return NULL; 81 | } 82 | cells = (unsigned)(size - 1) / sizeof(Cell) + 1; 83 | 84 | /* find Cell large enough */ 85 | for (bp = ap->free; ; bp = bp->next) { 86 | for (fpp = NULL, fp = bp->free; 87 | fp != bp->last; fpp = fp, fp = fpp->next) 88 | if ((fp-1)->size >= cells) 89 | goto Found; 90 | 91 | /* wrapped around Block list, create new Block */ 92 | if (bp->next == ap->free) { 93 | bp = (Block*) malloc(offsetof(Block, cell[ICELLS + cells])); 94 | if (bp == NULL) { 95 | aerror(ap, "cannot allocate"); 96 | return NULL; 97 | } 98 | if (ap->free == &aempty) 99 | bp->next = bp; 100 | else { 101 | bp->next = ap->free->next; 102 | ap->free->next = bp; 103 | } 104 | bp->last = bp->cell + ICELLS + cells; 105 | fp = bp->free = bp->cell + 1; /* initial free list */ 106 | (fp-1)->size = ICELLS + cells - 1; 107 | fp->next = bp->last; 108 | fpp = NULL; 109 | break; 110 | } 111 | } 112 | Found: 113 | ap->free = bp; 114 | dp = fp; /* allocated object */ 115 | split = (dp-1)->size - cells; 116 | if (split < 0) 117 | aerror(ap, "allocated object too small"); 118 | if (--split <= 0) { /* allocate all */ 119 | fp = fp->next; 120 | } else { /* allocate head, free tail */ 121 | (fp-1)->size = cells; 122 | fp += cells + 1; 123 | (fp-1)->size = split; 124 | fp->next = dp->next; 125 | } 126 | if (fpp == NULL) 127 | bp->free = fp; 128 | else 129 | fpp->next = fp; 130 | return (void*) dp; 131 | } 132 | 133 | /* change size of object -- like realloc */ 134 | void * 135 | aresize(ptr, size, ap) 136 | register void *ptr; 137 | size_t size; 138 | Area *ap; 139 | { 140 | int cells; 141 | register Cell *dp = (Cell*) ptr; 142 | 143 | if (size <= 0) { 144 | aerror(ap, "allocate bad size"); 145 | return NULL; 146 | } 147 | cells = (unsigned)(size - 1) / sizeof(Cell) + 1; 148 | 149 | if (dp == NULL || (dp-1)->size < cells) { /* enlarge object */ 150 | register Cell *np; 151 | register int i; 152 | void *optr = ptr; 153 | 154 | ptr = alloc(size, ap); 155 | np = (Cell*) ptr; 156 | if (dp != NULL) 157 | for (i = (dp-1)->size; i--; ) 158 | *np++ = *dp++; 159 | afree(optr, ap); 160 | } else { /* shrink object */ 161 | int split; 162 | 163 | split = (dp-1)->size - cells; 164 | if (--split <= 0) /* cannot split */ 165 | ; 166 | else { /* shrink head, free tail */ 167 | (dp-1)->size = cells; 168 | dp += cells + 1; 169 | (dp-1)->size = split; 170 | afree((void*)dp, ap); 171 | } 172 | } 173 | return (void*) ptr; 174 | } 175 | 176 | void 177 | afree(ptr, ap) 178 | void *ptr; 179 | register Area *ap; 180 | { 181 | register Block *bp; 182 | register Cell *fp, *fpp; 183 | register Cell *dp = (Cell*)ptr; 184 | 185 | /* find Block containing Cell */ 186 | for (bp = ap->free; ; bp = bp->next) { 187 | if (bp->cell <= dp && dp < bp->last) 188 | break; 189 | if (bp->next == ap->free) { 190 | aerror(ap, "freeing with invalid area"); 191 | return; 192 | } 193 | } 194 | 195 | /* find position in free list */ 196 | for (fpp = NULL, fp = bp->free; fp < dp; fpp = fp, fp = fpp->next) 197 | ; 198 | 199 | if (fp == dp) { 200 | aerror(ap, "freeing free object"); 201 | return; 202 | } 203 | 204 | /* join object with next */ 205 | if (dp + (dp-1)->size == fp-1) { /* adjacent */ 206 | (dp-1)->size += (fp-1)->size + 1; 207 | dp->next = fp->next; 208 | } else /* non-adjacent */ 209 | dp->next = fp; 210 | 211 | /* join previous with object */ 212 | if (fpp == NULL) 213 | bp->free = dp; 214 | else if (fpp + (fpp-1)->size == dp-1) { /* adjacent */ 215 | (fpp-1)->size += (dp-1)->size + 1; 216 | fpp->next = dp->next; 217 | } else /* non-adjacent */ 218 | fpp->next = dp; 219 | } 220 | 221 | 222 | #if TEST_ALLOC 223 | 224 | Area a; 225 | 226 | main(int argc, char **argv) { 227 | int i; 228 | char *p [9]; 229 | 230 | ainit(&a); 231 | for (i = 0; i < 9; i++) { 232 | p[i] = alloc(124, &a); 233 | printf("alloc: %x\n", p[i]); 234 | } 235 | for (i = 1; i < argc; i++) 236 | afree(p[atoi(argv[i])], &a); 237 | afreeall(&a); 238 | return 0; 239 | } 240 | 241 | void aerror(Area *ap, const char *msg) { 242 | abort(); 243 | } 244 | 245 | #endif 246 | 247 | -------------------------------------------------------------------------------- /sh/alloc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * area-based allocation built on malloc/free 3 | */ 4 | 5 | typedef struct Area { 6 | struct Block *free; /* free list */ 7 | } Area; 8 | 9 | -------------------------------------------------------------------------------- /sh/c_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * test(1); version 7-like -- author Erik Baalbergen 3 | * modified by Eric Gisin to be used as built-in. 4 | * modified by Arnold Robbins to add SVR3 compatibility 5 | * (-x -c -b -p -u -g -k) plus Korn's -L -nt -ot -ef and new -S (socket). 6 | */ 7 | 8 | #ifndef lint 9 | static char *RCSid = "$Id: c_test.c,v 1.2 1992/04/25 08:33:28 sjg Exp $"; 10 | #endif 11 | 12 | #include "stdh.h" 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "sh.h" 18 | 19 | /* test(1) accepts the following grammar: 20 | oexpr ::= aexpr | aexpr "-o" oexpr ; 21 | aexpr ::= nexpr | nexpr "-a" aexpr ; 22 | nexpr ::= primary ! "!" primary 23 | primary ::= unary-operator operand 24 | | operand binary-operator operand 25 | | operand 26 | | "(" oexpr ")" 27 | ; 28 | unary-operator ::= "-r"|"-w"|"-x"|"-f"|"-d"|"-c"|"-b"|"-p"| 29 | "-u"|"-g"|"-k"|"-s"|"-t"|"-z"|"-n"|"-o"|"-O"|"-G"|"-L"|"-S"; 30 | 31 | binary-operator ::= "="|"!="|"-eq"|"-ne"|"-ge"|"-gt"|"-le"|"-lt"| 32 | "-nt"|"-ot"|"-ef"; 33 | operand ::= 34 | */ 35 | 36 | #define EOI 0 37 | #define FILRD 1 38 | #define FILWR 2 39 | #define FILREG 3 40 | #define FILID 4 41 | #define FILGZ 5 42 | #define FILTT 6 43 | #define STZER 7 44 | #define STNZE 8 45 | #define STEQL 9 46 | #define STNEQ 10 47 | #define INTEQ 11 48 | #define INTNE 12 49 | #define INTGE 13 50 | #define INTGT 14 51 | #define INTLE 15 52 | #define INTLT 16 53 | #define UNOT 17 54 | #define BAND 18 55 | #define BOR 19 56 | #define LPAREN 20 57 | #define RPAREN 21 58 | #define OPERAND 22 59 | #define FILEX 23 60 | #define FILCDEV 24 61 | #define FILBDEV 25 62 | #define FILFIFO 26 63 | #define FILSETU 27 64 | #define FILSETG 28 65 | #define FILSTCK 29 66 | #define FILSYM 30 67 | #define FILNT 31 68 | #define FILOT 32 69 | #define FILEQ 33 70 | #define FILSOCK 34 71 | #define FILUID 35 72 | #define FILGID 36 73 | #define OPTION 37 74 | 75 | #define UNOP 1 76 | #define BINOP 2 77 | #define BUNOP 3 78 | #define BBINOP 4 79 | #define PAREN 5 80 | 81 | struct t_op { 82 | char *op_text; 83 | short op_num, op_type; 84 | } const ops [] = { 85 | {"-r", FILRD, UNOP}, 86 | {"-w", FILWR, UNOP}, 87 | {"-x", FILEX, UNOP}, 88 | {"-f", FILREG, UNOP}, 89 | {"-d", FILID, UNOP}, 90 | {"-c", FILCDEV,UNOP}, 91 | {"-b", FILBDEV,UNOP}, 92 | {"-p", FILFIFO,UNOP}, 93 | {"-u", FILSETU,UNOP}, 94 | {"-g", FILSETG,UNOP}, 95 | {"-k", FILSTCK,UNOP}, 96 | {"-s", FILGZ, UNOP}, 97 | {"-t", FILTT, UNOP}, 98 | {"-z", STZER, UNOP}, 99 | {"-n", STNZE, UNOP}, 100 | #if 0 /* conficts with binary -o */ 101 | {"-o", OPTION, UNOP}, 102 | #endif 103 | {"-U", FILUID, UNOP}, 104 | {"-G", FILGID, UNOP}, 105 | {"-L", FILSYM, UNOP}, 106 | {"-S", FILSOCK,UNOP}, 107 | {"=", STEQL, BINOP}, 108 | {"!=", STNEQ, BINOP}, 109 | {"-eq", INTEQ, BINOP}, 110 | {"-ne", INTNE, BINOP}, 111 | {"-ge", INTGE, BINOP}, 112 | {"-gt", INTGT, BINOP}, 113 | {"-le", INTLE, BINOP}, 114 | {"-lt", INTLT, BINOP}, 115 | {"-nt", FILNT, BINOP}, 116 | {"-ot", FILOT, BINOP}, 117 | {"-ef", FILEQ, BINOP}, 118 | {"!", UNOT, BUNOP}, 119 | {"-a", BAND, BBINOP}, 120 | {"-o", BOR, BBINOP}, 121 | {"(", LPAREN, PAREN}, 122 | {")", RPAREN, PAREN}, 123 | {0, 0, 0} 124 | }; 125 | 126 | char **t_wp; 127 | struct t_op const *t_wp_op; 128 | 129 | static void syntax(); 130 | 131 | int 132 | c_test(wp) 133 | char **wp; 134 | { 135 | int res; 136 | 137 | t_wp = wp+1; 138 | if (strcmp(wp[0], "[") == 0) { 139 | while (*wp != NULL) 140 | wp++; 141 | if (strcmp(*--wp, "]") != 0) 142 | errorf("[: missing ]\n"); 143 | *wp = NULL; 144 | } 145 | res = *t_wp == NULL || !oexpr(t_lex(*t_wp)); 146 | 147 | if (*t_wp != NULL && *++t_wp != NULL) 148 | syntax(*t_wp, "unknown operand"); 149 | 150 | return res; 151 | } 152 | 153 | static void 154 | syntax(op, msg) 155 | char *op; 156 | char *msg; 157 | { 158 | if (op && *op) 159 | errorf("test: %s: %s\n", op, msg); 160 | else 161 | errorf("test: %s\n", msg); 162 | } 163 | 164 | oexpr(n) 165 | { 166 | int res; 167 | 168 | res = aexpr(n); 169 | if (t_lex(*++t_wp) == BOR) 170 | return oexpr(t_lex(*++t_wp)) || res; 171 | t_wp--; 172 | return res; 173 | } 174 | 175 | aexpr(n) 176 | { 177 | int res; 178 | 179 | res = nexpr(n); 180 | if (t_lex(*++t_wp) == BAND) 181 | return aexpr(t_lex(*++t_wp)) && res; 182 | t_wp--; 183 | return res; 184 | } 185 | 186 | nexpr(n) 187 | int n; /* token */ 188 | { 189 | if (n == UNOT) 190 | return !nexpr(t_lex(*++t_wp)); 191 | return primary(n); 192 | } 193 | 194 | primary(n) 195 | int n; /* token */ 196 | { 197 | register char *opnd1, *opnd2; 198 | int res; 199 | 200 | if (n == EOI) 201 | syntax(NULL, "argument expected"); 202 | if (n == LPAREN) { 203 | res = oexpr(t_lex(*++t_wp)); 204 | if (t_lex(*++t_wp) != RPAREN) 205 | syntax(NULL, "closing paren expected"); 206 | return res; 207 | } 208 | if (t_wp_op && t_wp_op->op_type == UNOP) { 209 | /* unary expression */ 210 | if (*++t_wp == NULL && n != FILTT) 211 | syntax(t_wp_op->op_text, "argument expected"); 212 | switch (n) { 213 | case OPTION: 214 | return flag[option(*t_wp)]; 215 | case STZER: 216 | return strlen(*t_wp) == 0; 217 | case STNZE: 218 | return strlen(*t_wp) != 0; 219 | case FILTT: 220 | if (!digit(**t_wp)) 221 | return filstat("0", n); 222 | default: /* all other FIL* */ 223 | return filstat(*t_wp, n); 224 | } 225 | } 226 | opnd1 = *t_wp; 227 | (void) t_lex(*++t_wp); 228 | if (t_wp_op && t_wp_op->op_type == BINOP) { 229 | struct t_op const *op = t_wp_op; 230 | 231 | if ((opnd2 = *++t_wp) == (char *)0) 232 | syntax(op->op_text, "argument expected"); 233 | 234 | switch (op->op_num) { 235 | case STEQL: 236 | return strcmp(opnd1, opnd2) == 0; 237 | case STNEQ: 238 | return strcmp(opnd1, opnd2) != 0; 239 | case INTEQ: 240 | return evaluate(opnd1) == evaluate(opnd2); 241 | case INTNE: 242 | return evaluate(opnd1) != evaluate(opnd2); 243 | case INTGE: 244 | return evaluate(opnd1) >= evaluate(opnd2); 245 | case INTGT: 246 | return evaluate(opnd1) > evaluate(opnd2); 247 | case INTLE: 248 | return evaluate(opnd1) <= evaluate(opnd2); 249 | case INTLT: 250 | return evaluate(opnd1) < evaluate(opnd2); 251 | case FILNT: 252 | return newerf (opnd1, opnd2); 253 | case FILOT: 254 | return olderf (opnd1, opnd2); 255 | case FILEQ: 256 | return equalf (opnd1, opnd2); 257 | } 258 | } 259 | t_wp--; 260 | return strlen(opnd1) > 0; 261 | } 262 | 263 | filstat(nm, mode) 264 | char *nm; 265 | { 266 | struct stat s; 267 | 268 | switch (mode) { 269 | case FILRD: 270 | return eaccess(nm, 4) == 0; 271 | case FILWR: 272 | return eaccess(nm, 2) == 0; 273 | case FILEX: 274 | return eaccess(nm, 1) == 0; 275 | case FILREG: 276 | return stat(nm, &s) == 0 && (s.st_mode & S_IFMT) == S_IFREG; 277 | case FILID: 278 | return stat(nm, &s) == 0 && (s.st_mode & S_IFMT) == S_IFDIR; 279 | case FILCDEV: 280 | return stat(nm, &s) == 0 && (s.st_mode & S_IFMT) == S_IFCHR; 281 | case FILBDEV: 282 | return stat(nm, &s) == 0 && (s.st_mode & S_IFMT) == S_IFBLK; 283 | case FILFIFO: 284 | #ifdef S_IFIFO 285 | return stat(nm, &s) == 0 && (s.st_mode & S_IFMT) == S_IFIFO; 286 | #else 287 | return 0; 288 | #endif 289 | case FILSETU: 290 | return stat(nm, &s) == 0 && (s.st_mode & S_ISUID) == S_ISUID; 291 | case FILSETG: 292 | return stat(nm, &s) == 0 && (s.st_mode & S_ISGID) == S_ISGID; 293 | case FILSTCK: 294 | return stat(nm, &s) == 0 && (s.st_mode & S_ISVTX) == S_ISVTX; 295 | case FILGZ: 296 | return stat(nm, &s) == 0 && s.st_size > 0L; 297 | case FILTT: 298 | return isatty(getn(nm)); 299 | case FILUID: 300 | return stat(nm, &s) == 0 && s.st_uid == geteuid(); 301 | case FILGID: 302 | return stat(nm, &s) == 0 && s.st_gid == getegid(); 303 | #ifdef S_IFLNK 304 | case FILSYM: 305 | return lstat(nm, &s) == 0 && (s.st_mode & S_IFMT) == S_IFLNK; 306 | #endif 307 | #ifdef S_IFSOCK 308 | case FILSOCK: 309 | return stat(nm, &s) == 0 && (s.st_mode & S_IFMT) == S_IFSOCK; 310 | #endif 311 | default: 312 | return 1; 313 | } 314 | } 315 | 316 | int 317 | t_lex(s) 318 | register char *s; 319 | { 320 | register struct t_op const *op = ops; 321 | 322 | if (s == 0) { 323 | t_wp_op = (struct t_op *)0; 324 | return EOI; 325 | } 326 | while (op->op_text) { 327 | if (strcmp(s, op->op_text) == 0) { 328 | t_wp_op = op; 329 | return op->op_num; 330 | } 331 | op++; 332 | } 333 | t_wp_op = (struct t_op *)0; 334 | return OPERAND; 335 | } 336 | 337 | newerf (f1, f2) 338 | char *f1, *f2; 339 | { 340 | struct stat b1, b2; 341 | 342 | return (stat (f1, &b1) == 0 && 343 | stat (f2, &b2) == 0 && 344 | b1.st_mtime > b2.st_mtime); 345 | } 346 | 347 | olderf (f1, f2) 348 | char *f1, *f2; 349 | { 350 | struct stat b1, b2; 351 | 352 | return (stat (f1, &b1) == 0 && 353 | stat (f2, &b2) == 0 && 354 | b1.st_mtime < b2.st_mtime); 355 | } 356 | 357 | equalf (f1, f2) 358 | char *f1, *f2; 359 | { 360 | struct stat b1, b2; 361 | 362 | return (stat (f1, &b1) == 0 && 363 | stat (f2, &b2) == 0 && 364 | b1.st_dev == b2.st_dev && 365 | b1.st_ino == b2.st_ino); 366 | } 367 | 368 | -------------------------------------------------------------------------------- /sh/config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Configuration file for the PD ksh 3 | * 4 | * RCSid: $Id: config.h,v 1.3 1992/05/03 08:28:59 sjg Exp $ 5 | */ 6 | 7 | #ifndef _CONFIG_H 8 | #define _CONFIG_H 9 | 10 | /* 11 | * Builtin edit modes 12 | */ 13 | 14 | #define EMACS /* EMACS-like mode */ 15 | #define VI /* vi-like mode */ 16 | #define JOBS /* job control */ 17 | 18 | #ifndef SIGINT 19 | #include 20 | #endif 21 | 22 | /* 23 | * leave USE_SIGACT defined. 24 | * if you don't have sigaction(2) and the 25 | * implementation in sigact.c doesn't work for your system, 26 | * fix it. 27 | * 28 | * Of course if your system has a real sigaction() 29 | * implementation that is faulty! undef JOBS and add USE_SIGNAL 30 | * or whatever does work. You may find it necessary to undef 31 | * USE_SIGACT, if so please report it. 32 | */ 33 | #define USE_SIGACT /* POSIX signal handling */ 34 | /* 35 | * These control how sigact.c implements sigaction() 36 | * If you don't define any of them it will try and work it out 37 | * for itself. The are listed in order of preference (usefulness). 38 | */ 39 | /* #define USE_SIGMASK /* BSD4.2 ? signal handling */ 40 | /* #define USE_SIGSET /* BSD4.1 ? signal handling */ 41 | /* #define USE_SIGNAL /* plain old signal(2) */ 42 | 43 | #if defined(JOBS) && (!defined(SIGCONT) || (defined(_SYSV) && defined(USE_SIGNAL))) 44 | #undef JOBS 45 | #endif 46 | 47 | /* #define FASCIST /* Fascist getopts */ 48 | #define SHARPBANG /* Hack to handle #! */ 49 | /* #define SILLY /* Game of life in EMACS mode */ 50 | /* #define SWTCH /* Handle SWTCH for shl(1) */ 51 | 52 | #endif /* _CONFIG_H */ 53 | -------------------------------------------------------------------------------- /sh/do_ulimit.c: -------------------------------------------------------------------------------- 1 | /* 2 | ulimit -- handle "ulimit" builtin 3 | 4 | Eric Gisin, September 1988 5 | Adapted to PD KornShell. Removed AT&T code. 6 | 7 | last edit: 06-Jun-1987 D A Gwyn 8 | 9 | This started out as the BRL UNIX System V system call emulation 10 | for 4.nBSD, and was later extended by Doug Kingston to handle 11 | the extended 4.nBSD resource limits. It now includes the code 12 | that was originally under case SYSULIMIT in source file "xec.c". 13 | */ 14 | 15 | #ifndef lint 16 | static char *RCSid = "$Id: do_ulimit.c,v 1.2 1992/04/25 08:33:28 sjg Exp $"; 17 | #endif 18 | 19 | #include "stdh.h" 20 | #include 21 | #include 22 | #include 23 | #if defined(_BSD) || defined(_BSD_SYSV) 24 | #include 25 | #include 26 | #else 27 | #define RLIMIT_FSIZE 2 28 | #endif 29 | #include "sh.h" 30 | 31 | extern long ulimit(); 32 | 33 | int 34 | do_ulimit(a1, a2) 35 | char *a1, *a2; 36 | { 37 | register int c; 38 | long i; 39 | #if defined(_BSD) || defined(_BSD_SYSV) 40 | struct rlimit limit; /* data being gotten/set */ 41 | int softonly = 0; /* set => soft limit, clear => hard limit */ 42 | int factor = 1024; /* unit scaling (1K or 1) */ 43 | #endif 44 | int command = RLIMIT_FSIZE; 45 | 46 | if (a1 && (*a1 == '-')) /* DAG -- Gould added first test */ 47 | { c = *++a1; /* DAG */ 48 | #if defined(_BSD) || defined(_BSD_SYSV) 49 | if (c >= 'A' && c <= 'Z') 50 | { 51 | ++softonly; 52 | c += 'a' - 'A'; /* DAG -- map to lower-case */ 53 | } 54 | #endif 55 | switch(c) 56 | { 57 | #if defined(_BSD) || defined(_BSD_SYSV) 58 | case 'c': 59 | command = RLIMIT_CORE; 60 | break; 61 | case 'd': 62 | command = RLIMIT_DATA; 63 | break; 64 | case 'm': 65 | command = RLIMIT_RSS; 66 | break; 67 | case 's': 68 | command = RLIMIT_STACK; 69 | break; 70 | case 't': 71 | factor = 1; 72 | command = RLIMIT_CPU; 73 | break; 74 | #endif /* _BSD || _BSD_SYSV */ 75 | case 'f': 76 | command = RLIMIT_FSIZE; 77 | #if _BSD_SYSV 78 | factor = 512; 79 | #endif 80 | break; 81 | default: 82 | #if _BSD 83 | errorf("Usage: %s [-cdmstf] [limit]\n", "ulimit"); 84 | #else 85 | errorf("Usage: %s [-f] [limit]\n", "ulimit"); 86 | #endif 87 | } 88 | a1 = a2; 89 | } 90 | if (a1) 91 | { 92 | i = 0; 93 | while ((c = *a1++) >= '0' && c <= '9') 94 | { 95 | i = (i * 10) + (long)(c - '0'); 96 | if (i < 0) 97 | goto Error; 98 | } 99 | if (c || i < 0) 100 | goto Error; 101 | } 102 | #if !(defined(_BSD) || defined(_BSD_SYSV)) 103 | else 104 | { 105 | i = -1; 106 | command--; 107 | } 108 | 109 | if ((i = ulimit(command, i)) < 0L) 110 | goto Error; 111 | 112 | if (command != RLIMIT_FSIZE) 113 | shellf("%ld\n", i); 114 | #else /* DPK -- generalized for 4.nBSD: */ 115 | if (getrlimit(command, &limit)) 116 | goto Error; /* errno is already set */ 117 | 118 | if (a1) 119 | { 120 | limit.rlim_cur = i * factor; 121 | 122 | if (!softonly) 123 | limit.rlim_max = limit.rlim_cur; 124 | 125 | if (setrlimit(command, &limit)) 126 | goto Error; 127 | } 128 | else 129 | { 130 | i = softonly ? limit.rlim_cur : limit.rlim_max; 131 | #if _BSD /* DAG -- System V always prints an integer */ 132 | if (i == RLIM_INFINITY) 133 | shellf("unlimited\n"); 134 | else 135 | #endif 136 | shellf("%ld\n", i/factor); 137 | } 138 | #endif /* _BSD || _BSD_SYSV */ 139 | return 0; 140 | 141 | Error: 142 | errorf("bad ulimit\n"); 143 | } 144 | 145 | -------------------------------------------------------------------------------- /sh/edit.h: -------------------------------------------------------------------------------- 1 | /* NAME: 2 | * edit.h - globals for edit modes 3 | * 4 | * DESCRIPTION: 5 | * This header defines various global edit objects. 6 | * 7 | * SEE ALSO: 8 | * 9 | * 10 | * RCSid: 11 | * $Id: edit.h,v 1.2 1992/04/25 08:33:28 sjg Exp $ 12 | * 13 | */ 14 | 15 | /* some useful #defines */ 16 | #ifdef EXTERN 17 | # define _I_(i) = i 18 | #else 19 | # define _I_(i) 20 | # define EXTERN extern 21 | # define EXTERN_DEFINED 22 | #endif 23 | 24 | #define BEL 0x07 25 | 26 | /* 27 | * The following are used for my horizontal scrolling stuff 28 | */ 29 | EXTERN char *xbuf; /* beg input buffer */ 30 | EXTERN char *xend; /* end input buffer */ 31 | EXTERN char *xcp; /* current position */ 32 | EXTERN char *xep; /* current end */ 33 | EXTERN char *xbp; /* start of visible portion of input buffer */ 34 | EXTERN char *xlp; /* last char visible on screen */ 35 | EXTERN int x_adj_ok; 36 | /* 37 | * we use x_adj_done so that functions can tell 38 | * whether x_adjust() has been called while they are active. 39 | */ 40 | EXTERN int x_adj_done; 41 | 42 | EXTERN int x_cols; 43 | EXTERN int x_col; 44 | EXTERN int x_displen; 45 | EXTERN int x_arg; /* general purpose arg */ 46 | 47 | EXTERN int x_do_init; /* set up tty modes */ 48 | EXTERN int ed_erase, ed_kill, ed_werase, ed_intr, ed_quit; 49 | 50 | #ifdef DEBUG 51 | # define _D_(x) x 52 | #else 53 | # define _D_(x) 54 | #endif 55 | 56 | /**** edit.c ****/ 57 | int x_read ARGS((int fd, char *buf, size_t len)); 58 | int x_getc ARGS((void)); 59 | void x_flush ARGS((void)); 60 | void x_adjust ARGS((void)); 61 | void x_putc ARGS((int c)); 62 | int x_debug_info ARGS((void)); 63 | void x_puts ARGS((char *s)); 64 | void x_init ARGS((void)); 65 | bool_t x_mode ARGS((bool_t onoff)); 66 | bool_t x_mode ARGS((bool_t onoff)); 67 | int promptlen ARGS((char *cp)); 68 | 69 | /**** emacs.c ****/ 70 | void x_redraw ARGS((int limit)); 71 | char* x_lastcp ARGS((void)); 72 | EXTERN int xlp_valid _I_(0); 73 | 74 | /* This lot goes at the END */ 75 | /* be sure not to interfere with anyone else's idea about EXTERN */ 76 | #ifdef EXTERN_DEFINED 77 | # undef EXTERN_DEFINED 78 | # undef EXTERN 79 | #endif 80 | /* 81 | * Local Variables: 82 | * version-control:t 83 | * comment-column:40 84 | * End: 85 | */ 86 | -------------------------------------------------------------------------------- /sh/expand.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Expanding strings 3 | */ 4 | 5 | #if 0 /* Usage */ 6 | XString xs; 7 | char *xp; 8 | 9 | Xinit(xs, xp, 128); /* allocate initial string */ 10 | while ((c = generate()) { 11 | Xcheck(xs, xp); /* expand string if neccessary */ 12 | Xput(xs, xp, c); /* add character */ 13 | } 14 | return Xclose(xs, xp); /* resize string */ 15 | #endif 16 | 17 | typedef struct XString { 18 | char *end, *beg; /* end, begin of string */ 19 | #if 1 20 | char *oth, *old; /* togo, adjust */ 21 | #endif 22 | size_t len; /* length */ 23 | } XString; 24 | 25 | typedef char * XStringP; 26 | 27 | /* initialize expandable string */ 28 | #define Xinit(xs, xp, length) { \ 29 | (xs).len = length; \ 30 | (xs).beg = alloc((xs).len + 8, ATEMP); \ 31 | (xs).end = (xs).beg + (xs).len; \ 32 | xp = (xs).beg; \ 33 | } 34 | 35 | /* stuff char into string */ 36 | #define Xput(xs, xp, c) *xp++ = (c) 37 | 38 | /* check for overflow, expand string */ 39 | #define Xcheck(xs, xp) if (xp >= (xs).end) { \ 40 | char *old_beg = (xs).beg; \ 41 | (xs).len += (xs).len; /* double size */ \ 42 | (xs).beg = aresize((xs).beg, (xs).len + 8, ATEMP); \ 43 | (xs).end = (xs).beg + (xs).len; \ 44 | xp = (xs).beg + (xp - old_beg); /* adjust pointer */ \ 45 | } 46 | 47 | /* free string */ 48 | #define Xfree(xs, xp) afree((void*) (xs).beg, ATEMP) 49 | 50 | /* close, return string */ 51 | #define Xclose(xs, xp) (char*) aresize((void*)(xs).beg, \ 52 | (size_t)(xp - (xs).beg), ATEMP) 53 | /* begin of string */ 54 | #define Xstring(xs, xp) ((xs).beg) 55 | 56 | #define Xsavepos(xs, xp) (xp - (xs).beg) 57 | #define Xrestpos(xs, xp, n) ((xs).beg + (n)) 58 | 59 | /* 60 | * expandable vector of generic pointers 61 | */ 62 | 63 | typedef struct XPtrV { 64 | void **cur; /* next avail pointer */ 65 | void **beg, **end; /* begin, end of vector */ 66 | } XPtrV; 67 | 68 | #define XPinit(x, n) { \ 69 | register void **vp; \ 70 | vp = (void**) alloc(sizeofN(void*, n), ATEMP); \ 71 | (x).cur = (x).beg = vp; \ 72 | (x).end = vp + n; \ 73 | } 74 | 75 | #define XPput(x, p) { \ 76 | if ((x).cur >= (x).end) { \ 77 | int n = XPsize(x); \ 78 | (x).beg = (void**) aresize((void*) (x).beg, \ 79 | sizeofN(void*, n*2), ATEMP); \ 80 | (x).cur = (x).beg + n; \ 81 | (x).end = (x).cur + n; \ 82 | } \ 83 | *(x).cur++ = (p); \ 84 | } 85 | 86 | #define XPptrv(x) ((x).beg) 87 | #define XPsize(x) ((x).cur - (x).beg) 88 | 89 | #define XPclose(x) (void**) aresize((void*)(x).beg, \ 90 | sizeofN(void*, XPsize(x)), ATEMP) 91 | 92 | #define XPfree(x) afree((void*) (x).beg, ATEMP) 93 | 94 | -------------------------------------------------------------------------------- /sh/expr.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Korn expression evaluation 3 | */ 4 | 5 | #ifndef lint 6 | static char *RCSid = "$Id: expr.c,v 1.2 1992/04/25 08:33:28 sjg Exp $"; 7 | #endif 8 | 9 | #include "stdh.h" 10 | #include 11 | #include 12 | #include "sh.h" 13 | 14 | #define ef else if /* fashion statement */ 15 | 16 | #define VAR 0x01 17 | #define LIT 0x02 18 | #define LEQ 0x03 19 | #define LNE 0x04 20 | #define LLE 0x05 21 | #define LGE 0x06 22 | 23 | static const char *expression; /* expression being evaluated */ 24 | static const char *tokp; /* lexical position */ 25 | static int tok; /* token from token() */ 26 | static struct tbl *val; /* value from token() */ 27 | 28 | static struct tbl *asn ARGS((void)); 29 | static struct tbl *e6 ARGS((void)); 30 | static struct tbl *e5 ARGS((void)); 31 | static struct tbl *e3 ARGS((void)); 32 | static struct tbl *e2 ARGS((void)); 33 | static struct tbl *e0 ARGS((void)); 34 | static void token ARGS((void)); 35 | static struct tbl *tempvar ARGS((void)); 36 | static struct tbl *intvar ARGS((struct tbl *vp)); 37 | 38 | /* 39 | * parse and evalute expression 40 | */ 41 | void 42 | evalerr(err) 43 | char *err; 44 | { 45 | errorf("%s: %s\n", expression, err); 46 | } 47 | 48 | long 49 | evaluate(expr) 50 | const char *expr; 51 | { 52 | struct tbl *v; 53 | 54 | expression = tokp = expr; 55 | token(); 56 | v = intvar(asn()); 57 | if (!(tok == 0)) 58 | evalerr("bad expression"); 59 | return v->val.i; 60 | } 61 | 62 | static struct tbl * 63 | asn() 64 | { 65 | register struct tbl *vl, *vr; 66 | 67 | vr = vl = e6(); 68 | if ((tok == '=')) { 69 | Area * olastarea = lastarea; 70 | token(); 71 | if ((vl->flag&RDONLY)) /* assign to rvalue */ 72 | evalerr("bad assignment"); 73 | vr = intvar(asn()); 74 | lastarea = olastarea; 75 | setint(vl, vr->val.i); 76 | if ((vl->flag&INTEGER) && vl->type == 0) /* default base? */ 77 | vl->type = vr->type; 78 | } 79 | return vr; 80 | } 81 | 82 | static struct tbl * 83 | e6() 84 | { 85 | register struct tbl *vl, *vr; 86 | 87 | vl = e5(); 88 | while ((tok == LEQ) || (tok == LNE)) { 89 | int op = tok; 90 | token(); 91 | vl = intvar(vl); 92 | vr = intvar(e5()); 93 | vl->val.i = vl->val.i == vr->val.i; 94 | if (op == LNE) 95 | vl->val.i = ! vl->val.i; 96 | } 97 | return vl; 98 | } 99 | 100 | static struct tbl * 101 | e5() 102 | { 103 | register struct tbl *vl, *vr; 104 | 105 | vl = e3(); 106 | while ((tok == LLE) || (tok == '<') || (tok == '>') || (tok == LGE)) { 107 | int op = tok; 108 | token(); 109 | vl = intvar(vl); 110 | vr = intvar(e3()); 111 | if (op == LLE) 112 | vl->val.i = vl->val.i <= vr->val.i; 113 | ef (op == '<') 114 | vl->val.i = vl->val.i < vr->val.i; 115 | ef (op == LGE) 116 | vl->val.i = vl->val.i >= vr->val.i; 117 | ef (op == '>') 118 | vl->val.i = vl->val.i > vr->val.i; 119 | } 120 | return vl; 121 | } 122 | 123 | static struct tbl * 124 | e3() 125 | { 126 | register struct tbl *vl, *vr; 127 | 128 | vl = e2(); 129 | while ((tok == '+') || (tok == '-')) { 130 | int op = tok; 131 | token(); 132 | vl = intvar(vl); 133 | vr = intvar(e2()); 134 | if (op == '+') 135 | vl->val.i += vr->val.i; 136 | ef (op == '-') 137 | vl->val.i -= vr->val.i; 138 | } 139 | return vl; 140 | } 141 | 142 | static struct tbl * 143 | e2() 144 | { 145 | register struct tbl *vl, *vr; 146 | 147 | vl = e0(); 148 | while ((tok == '*') || (tok == '/') || (tok == '%')) { 149 | int op = tok; 150 | token(); 151 | vl = intvar(vl); 152 | vr = intvar(e0()); 153 | if (op != '*' && vr->val.i == 0) 154 | evalerr("zero divisor"); 155 | if (op == '*') 156 | vl->val.i *= vr->val.i; 157 | ef (op == '/') 158 | vl->val.i /= vr->val.i; 159 | ef (op == '%') 160 | vl->val.i %= vr->val.i; 161 | } 162 | return vl; 163 | } 164 | 165 | static struct tbl * 166 | e0() 167 | { 168 | register struct tbl *v; 169 | 170 | if ((tok == '!') || (tok == '-')) { 171 | int op = tok; 172 | token(); 173 | v = intvar(e0()); 174 | if (op == '!') 175 | v->val.i = !v->val.i; 176 | ef (op == '-') 177 | v->val.i = -v->val.i; 178 | } else 179 | if ((tok == '(')) { 180 | token(); 181 | v = asn(); 182 | if (!(tok == ')')) 183 | evalerr("missing )"); 184 | token(); 185 | } else 186 | if ((tok == VAR) || (tok == LIT)) { 187 | v = val; 188 | token(); 189 | } else 190 | evalerr("bad expression"); 191 | return v; 192 | } 193 | 194 | static void 195 | token() 196 | { 197 | register char *cp = (char *) tokp; 198 | register int c, c2; 199 | 200 | /* skip white space */ 201 | do c = *cp++; while (c != '\0' && (c == ' ' || c == '\t')); 202 | tokp = cp-1; 203 | 204 | if (letter(c)) { 205 | for (; letnum(c); c = *cp++) 206 | ; 207 | c = *--cp; 208 | *cp = 0; 209 | val = global(tokp); 210 | *cp = c; 211 | tok = VAR; 212 | } else 213 | if (digit(c)) { 214 | for (; letnum(c) || c == '#'; c = *cp++) 215 | ; 216 | c = *--cp; 217 | *cp = 0; 218 | val = tempvar(); 219 | setstr(val, tokp); 220 | val->flag |= RDONLY; 221 | *cp = c; 222 | tok = LIT; 223 | } else { 224 | c2 = *cp++; 225 | if (c == '=' && c2 == '=') 226 | c = LEQ; 227 | ef (c == '!' && c2 == '=') 228 | c = LNE; 229 | ef (c == '<' && c2 == '=') 230 | c = LLE; 231 | ef (c == '>' && c2 == '=') 232 | c = LGE; 233 | else 234 | cp--; 235 | tok = c; 236 | } 237 | tokp = cp; 238 | } 239 | 240 | static struct tbl * 241 | tempvar() 242 | { 243 | register struct tbl *vp; 244 | 245 | vp = (struct tbl*) alloc(sizeof(struct tbl), ATEMP); 246 | lastarea = ATEMP; 247 | vp->flag = ISSET|INTEGER; 248 | vp->type = 0; 249 | vp->name[0] = '\0'; 250 | return vp; 251 | } 252 | 253 | /* cast (string) variable to temporary integer variable */ 254 | static struct tbl * 255 | intvar(vp) 256 | register struct tbl *vp; 257 | { 258 | register struct tbl *vq; 259 | 260 | vq = tempvar(); 261 | vq->type = 10; 262 | if (strint(vq, vp) == NULL) { 263 | if ((vp->flag&ISSET) && vp->val.s && *(vp->val.s)) { 264 | evalerr("bad number"); 265 | } else { 266 | vq->flag |= (ISSET|INTEGER); 267 | vq->type = 10; 268 | vq->val.i = 0; 269 | } 270 | } 271 | return vq; 272 | } 273 | 274 | -------------------------------------------------------------------------------- /sh/getopts.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Reimplementation of SysVr3 sh builtin command "getopts" for S5R2 shell. 3 | * 4 | * created by Arnold Robbins 5 | * modified by Doug Gwyn 6 | * modified for PD ksh by Eric Gisin 7 | */ 8 | 9 | #ifndef lint 10 | static char *RCSid = "$Id: getopts.c,v 1.2 1992/04/25 08:33:28 sjg Exp $"; 11 | #endif 12 | 13 | #include "stdh.h" 14 | #include 15 | #include 16 | #include "sh.h" 17 | 18 | /* 19 | * The following is derived from getopt() source placed into the public 20 | * domain by AT&T (the only time they're known to have done that). 21 | * 22 | * It has been modified somewhat to fit into the context of the shell. 23 | * 24 | * -D"FASCIST" if you really want to strictly enforce ALL the 25 | * Command Syntax Standard rules (not recommended). 26 | */ 27 | 28 | #define GETOPTEOF (-1) 29 | #define ERR(S, C) shellf("%s%c\n", (S), (C)) 30 | 31 | static int optind; 32 | static char *optarg; 33 | static int sp; 34 | 35 | static int 36 | getopt(argc, argv, opts) 37 | int argc; 38 | register char **argv, *opts; 39 | { 40 | register int c; 41 | register char *cp; 42 | 43 | if (sp == 1) 44 | if (optind >= argc || 45 | argv[optind][0] != '-' || argv[optind][1] == '\0') 46 | return(GETOPTEOF); 47 | else if (strcmp(argv[optind], "--") == 0) { 48 | optind++; 49 | return(GETOPTEOF); 50 | } 51 | c = argv[optind][sp]; 52 | if (c == ':' || (cp=strchr(opts, c)) == NULL) { 53 | ERR("illegal option -- ", c); 54 | if (argv[optind][++sp] == '\0') { 55 | optind++; 56 | sp = 1; 57 | } 58 | optarg = NULL; 59 | return('?'); 60 | } 61 | if (*++cp == ':') { 62 | #ifdef FASCIST 63 | if (sp != 1) { 64 | ERR("option must not be grouped -- ", c ); 65 | optind++; 66 | sp = 1; 67 | optarg = NULL; 68 | return('?'); 69 | } else 70 | #endif 71 | if (argv[optind][sp+1] != '\0') { 72 | #ifdef FASCIST 73 | ERR("option must be followed by whitespace -- ", c ); 74 | optind++; 75 | sp = 1; 76 | optarg = NULL; 77 | return('?'); 78 | #else 79 | optarg = &argv[optind++][sp+1]; 80 | #endif 81 | } else if (++optind >= argc) { 82 | ERR("option requires an argument -- ", c); 83 | sp = 1; 84 | optarg = NULL; 85 | return('?'); 86 | } else 87 | optarg = argv[optind++]; 88 | sp = 1; 89 | } else { 90 | if (argv[optind][++sp] == '\0') { 91 | sp = 1; 92 | optind++; 93 | } 94 | optarg = NULL; 95 | } 96 | return(c); 97 | } 98 | 99 | /* 100 | * The following were created by Arnold Robbins. 101 | */ 102 | 103 | /* resetopts --- magic code for when OPTIND is reset to 1 */ 104 | 105 | void 106 | resetopts () 107 | { 108 | optind = 1; 109 | sp = 1; 110 | } 111 | 112 | int 113 | c_getopts(wp) 114 | char **wp; 115 | { 116 | int ret; 117 | register int argc; 118 | char temp[2]; 119 | char *optstr; /* list of options */ 120 | char *name; /* variable to get flag val */ 121 | char **argv; 122 | 123 | if ((optstr = *++wp) == NULL || (name = *++wp) == NULL) 124 | errorf("missing arguments\n"); 125 | 126 | for (argc = 1; wp[argc] != NULL; argc++) 127 | ; 128 | 129 | if (argc > 1) 130 | ret = getopt(argc, wp, optstr); 131 | else { 132 | if (**(e.loc->argv) == '\0') { 133 | /* 134 | * When c_getopts gets called from comexec() it 135 | * doesn't set up argc/argv in the local block. 136 | * Maybe this should be done in newblock() but 137 | * I'm not sure about the implications, and this 138 | * is the only place I've been bitten so far... 139 | * JRM 140 | */ 141 | argc = e.loc->next->argc; 142 | argv = e.loc->next->argv; 143 | } else { 144 | argc = e.loc->argc; 145 | argv = e.loc->argv; 146 | } 147 | ret = getopt(argc+1, argv, optstr); 148 | 149 | } 150 | 151 | /* 152 | * set the OPTIND variable in any case, to handle "--" skipping 153 | * unless it's 1, which would trigger a reset 154 | */ 155 | 156 | if (optind != 1) 157 | setint(global("OPTIND"), (long)optind); 158 | 159 | if (ret == GETOPTEOF) /* end of args */ 160 | return (1); 161 | 162 | /* 163 | * else, got an arg, set the various shell variables 164 | */ 165 | 166 | if (optarg != NULL) 167 | setstr(global("OPTARG"), optarg); 168 | 169 | temp[0] = (char) ret; 170 | temp[1] = '\0'; 171 | setstr(global(name), temp); 172 | 173 | return (0); 174 | } 175 | -------------------------------------------------------------------------------- /sh/io.c: -------------------------------------------------------------------------------- 1 | /* 2 | * shell buffered IO and formatted output 3 | */ 4 | 5 | #ifndef lint 6 | static char *RCSid = "$Id: io.c,v 1.2 1992/04/25 08:33:28 sjg Exp $"; 7 | #endif 8 | 9 | #include "stdh.h" 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #ifdef __STDC__ 16 | #include 17 | #else 18 | #include 19 | #endif 20 | #include "sh.h" 21 | 22 | #if 0 23 | /* fputc with ^ escaping */ 24 | static void 25 | fzotc(c, f) 26 | register int c; 27 | register FILE *f; 28 | { 29 | if ((c&0x60) == 0) { /* C0|C1 */ 30 | putc((c&0x80) ? '$' : '^', f); 31 | putc((c&0x7F|0x40), f); 32 | } else if ((c&0x7F) == 0x7F) { /* DEL */ 33 | putc((c&0x80) ? '$' : '^', f); 34 | putc('?', f); 35 | } else 36 | putc(c, f); 37 | } 38 | #endif 39 | 40 | /* 41 | * formatted output functions 42 | */ 43 | 44 | /* shellf(...); error() */ 45 | int 46 | #ifdef __STDC__ 47 | errorf(const char *fmt, ...) { 48 | #else 49 | errorf(va_alist) va_dcl 50 | { 51 | char *fmt; 52 | #endif 53 | va_list va; 54 | 55 | #ifdef __STDC__ 56 | va_start(va, fmt); 57 | #else 58 | va_start(va); 59 | fmt = va_arg(va, char *); 60 | #endif 61 | vfprintf(shlout, fmt, va); 62 | va_end(va); 63 | /*fflush(shlout);*/ 64 | error(); 65 | } 66 | 67 | /* printf to shlout (stderr) */ 68 | int 69 | #ifdef __STDC__ 70 | shellf(const char *fmt, ...) { 71 | #else 72 | shellf(va_alist) va_dcl 73 | { 74 | char *fmt; 75 | #endif 76 | va_list va; 77 | 78 | #ifdef __STDC__ 79 | va_start(va, fmt); 80 | #else 81 | va_start(va); 82 | fmt = va_arg(va, char *); 83 | #endif 84 | vfprintf(shlout, fmt, va); 85 | va_end(va); 86 | return 0; 87 | } 88 | 89 | /* 90 | * We have a stdio stream for any open shell file descriptors (0-9) 91 | */ 92 | FILE * shf [NUFILE]; /* map shell fd to FILE * */ 93 | 94 | /* open stream for shell fd */ 95 | void 96 | fopenshf(fd) 97 | int fd; 98 | { 99 | if (shf[fd] != NULL) 100 | return; 101 | if (fd <= 2) 102 | #ifdef _MINIX 103 | /* ? */; 104 | #else 105 | _iob[fd]._flag = 0; /* re-use stdin, stdout, stderr */ 106 | #endif 107 | shf[fd] = fdopen(fd, "r+"); 108 | if (shf[fd] == NULL) 109 | return; 110 | setvbuf(shf[fd], (char*)NULL, _IOFBF, (size_t)BUFSIZ); 111 | } 112 | 113 | /* flush stream assoc with fd */ 114 | /* this must invalidate input and output buffers */ 115 | void 116 | flushshf(fd) 117 | int fd; 118 | { 119 | if (shf[fd] != NULL) { 120 | fseek(shf[fd], 0L, 1); /* V7 derived */ 121 | fflush(shf[fd]); /* standard C */ 122 | } 123 | } 124 | 125 | /* 126 | * move fd from user space (0<=fd<10) to shell space (fd>=10) 127 | */ 128 | int 129 | savefd(fd) 130 | int fd; 131 | { 132 | int nfd; 133 | 134 | if (fd < FDBASE) { 135 | flushshf(fd); 136 | nfd = fcntl(fd, F_DUPFD, FDBASE); 137 | if (nfd < 0) 138 | if (errno == EBADF) 139 | return -1; 140 | else 141 | errorf("too many files open in shell\n"); 142 | #ifdef F_SETFD 143 | (void) fcntl(nfd, F_SETFD, 1); 144 | #else 145 | (void) fd_clexec(ttyfd); 146 | #endif 147 | close(fd); 148 | } else 149 | nfd = fd; 150 | return nfd; 151 | } 152 | 153 | void 154 | restfd(fd, ofd) 155 | int fd, ofd; 156 | { 157 | if (ofd == 0) /* not saved (e.savefd) */ 158 | return; 159 | flushshf(fd); 160 | close(fd); 161 | if (ofd < 0) /* original fd closed */ 162 | return; 163 | (void) fcntl(ofd, F_DUPFD, fd); 164 | close(ofd); 165 | } 166 | 167 | void 168 | openpipe(pv) 169 | register int *pv; 170 | { 171 | if (pipe(pv) < 0) 172 | errorf("can't create pipe - try again\n"); 173 | pv[0] = savefd(pv[0]); 174 | pv[1] = savefd(pv[1]); 175 | } 176 | 177 | void 178 | closepipe(pv) 179 | register int *pv; 180 | { 181 | close(pv[0]); 182 | close(pv[1]); 183 | } 184 | 185 | /* 186 | * temporary files 187 | */ 188 | 189 | struct temp * 190 | maketemp(ap) 191 | Area *ap; 192 | { 193 | register struct temp *tp; 194 | static unsigned int inc = 0; 195 | char path [PATH]; 196 | 197 | sprintf(path, "/tmp/sh%05u%02u", (unsigned)getpid(), inc++); 198 | #if defined(_SYSV) || defined(_BSD) 199 | close(creat(path, 0600)); /* to get appropriate permissions */ 200 | #endif 201 | tp = (struct temp *) alloc(sizeof(struct temp), ap); 202 | tp->next = NULL; 203 | tp->name = strsave(path, ap); 204 | return tp; 205 | } 206 | -------------------------------------------------------------------------------- /sh/lex.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Source input, lexer and parser 3 | */ 4 | 5 | /* $Id: lex.h,v 1.2 1992/04/25 08:33:28 sjg Exp $ */ 6 | 7 | #define IDENT 64 8 | 9 | typedef struct source Source; 10 | struct source { 11 | char *str; /* input pointer */ 12 | int type; /* input type */ 13 | union { 14 | char **strv; /* string [] */ 15 | FILE *file; /* file */ 16 | struct tbl *tblp; /* alias */ 17 | } u; 18 | int line; /* line number */ 19 | char *file; /* input file name */ 20 | int echo; /* echo input to shlout */ 21 | Source *next; /* stacked source */ 22 | }; 23 | 24 | /* Source.type values */ 25 | #define SEOF 0 /* input EOF */ 26 | #define STTY 1 /* terminal input */ 27 | #define SFILE 2 /* file input */ 28 | #define SSTRING 4 /* string */ 29 | #define SWSTR 3 /* string without \n */ 30 | #define SWORDS 5 /* string[] */ 31 | #define SWORDSEP 8 /* string[] seperator */ 32 | #define SALIAS 6 /* alias expansion */ 33 | #define SHIST 7 /* history expansion */ 34 | 35 | Source *pushs ARGS((int stype)); /* push Source */ 36 | struct op *compile ARGS((Source *s)); /* compile tree */ 37 | 38 | /* 39 | * states while lexing word 40 | */ 41 | #define SBASE 0 /* outside any lexical constructs */ 42 | #define SWORD 6 /* implicit quoting for substitute() */ 43 | #define SDPAREN 7 /* inside (( )), implicit quoting */ 44 | #define SSQUOTE 1 /* inside '' */ 45 | #define SDQUOTE 2 /* inside "" */ 46 | #define SBRACE 3 /* inside ${} */ 47 | #define SPAREN 4 /* inside $() */ 48 | #define SBQUOTE 5 /* inside `` */ 49 | 50 | Extern int multiline; /* \n changed to ; */ 51 | 52 | typedef union { 53 | int i; 54 | char *cp; 55 | char **wp; 56 | struct op *o; 57 | struct ioword *iop; 58 | } YYSTYPE; 59 | 60 | #define LWORD 256 61 | #define LOGAND 257 62 | #define LOGOR 258 63 | #define BREAK 259 64 | #define IF 260 65 | #define THEN 261 66 | #define ELSE 262 67 | #define ELIF 263 68 | #define FI 264 69 | #define CASE 265 70 | #define ESAC 266 71 | #define FOR 267 72 | #define WHILE 268 73 | #define UNTIL 269 74 | #define DO 270 75 | #define DONE 271 76 | #define IN 272 77 | #define FUNCTION 273 78 | #define TIME 274 79 | #define REDIR 275 80 | #define MPAREN 276 /* () */ 81 | #define MDPAREN 277 /* (( )) */ 82 | #define YYERRCODE 300 83 | 84 | /* flags to yylex */ 85 | #define CONTIN BIT(0) /* skip new lines to complete command */ 86 | #define ONEWORD BIT(1) /* single word for substitute() */ 87 | #define ALIAS BIT(2) /* recognize alias */ 88 | #define KEYWORD BIT(3) /* recognize keywords */ 89 | #define LETEXPR BIT(4) /* get expression inside (( )) */ 90 | 91 | #define SYNTAXERR zzerr() 92 | #define HERES 10 /* max << in line */ 93 | 94 | Extern char line [LINE+1]; /* input line */ 95 | Extern Source *source; /* yyparse/yylex source */ 96 | Extern YYSTYPE yylval; /* result from yylex */ 97 | Extern int yynerrs; 98 | Extern struct ioword *heres [HERES], **herep; 99 | Extern char ident [IDENT+1]; 100 | 101 | extern int yylex ARGS((int flags)); 102 | extern void yyerror ARGS((const char *msg)); 103 | 104 | #define HISTORY 100 /* size of saved history */ 105 | 106 | extern char *history [HISTORY]; /* saved commands */ 107 | extern char **histptr; /* last history item */ 108 | extern int histpush; /* number of pushed fc commands */ 109 | 110 | extern char **histget(); 111 | extern char **histpos(); 112 | extern int histnum(); 113 | extern char *findhist(); 114 | extern int histN(); 115 | 116 | #ifdef EDIT 117 | 118 | extern void x_init ARGS ((void)); /* setup tty modes */ 119 | extern void x_init_emacs ARGS ((void)); 120 | extern void x_emacs_keys (); 121 | extern void x_bind(); 122 | 123 | extern int x_read ARGS ((int fd, char *buf, size_t len)); 124 | extern int x_emacs ARGS ((char *buf, size_t len)); 125 | extern int x_vi ARGS ((char *buf, size_t len)); 126 | 127 | extern bool_t x_mode ARGS ((bool_t)); /* set/clear cbreak mode */ 128 | extern int x_getc(); /* get tty char */ 129 | extern void x_flush(), x_putc(), x_puts(); /* put tty char */ 130 | 131 | extern int x_cols; /* tty columns */ 132 | 133 | #endif 134 | -------------------------------------------------------------------------------- /sh/mail.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Mailbox checking code by Robert J. Gibson, adapted for PD ksh by 3 | * John R. MacMillan 4 | */ 5 | #ifndef lint 6 | static char *RCSid = "$Id: mail.c,v 1.2 1992/04/25 08:33:28 sjg Exp $"; 7 | #endif 8 | 9 | #include "stdh.h" 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "sh.h" 15 | 16 | #define MBMESSAGE "you have mail in $_" 17 | 18 | typedef struct mbox { 19 | struct mbox *mb_next; /* next mbox in list */ 20 | char *mb_path; /* path to mail file */ 21 | char *mb_msg; /* to announce arrival of new mail */ 22 | unsigned int mb_size; /* size of mail file (bytes) */ 23 | } mbox_t; 24 | 25 | struct mailmsg { 26 | char *msg; /* Text of message */ 27 | struct mailmsg *next; /* Next message */ 28 | }; 29 | 30 | /* 31 | * $MAILPATH is a linked list of mboxes. $MAIL is a treated as a 32 | * special case of $MAILPATH, where the list has only one node. The 33 | * same list is used for both since they are exclusive. 34 | */ 35 | 36 | static mbox_t *mplist = NULL; 37 | static mbox_t mbox = { NULL, NULL, NULL, 0 }; 38 | static long mlastchkd = 0; /* when mail was last checked */ 39 | static struct mailmsg *mmsgs = NULL; /* Messages to be printed */ 40 | #if 0 41 | static void munset(); /* free mlist and mval */ 42 | static mbox_t *mballoc(); /* allocate a new mbox */ 43 | static void maddmsg(); 44 | #endif 45 | static void munset ARGS((mbox_t *mlist)); 46 | static mbox_t * mballoc ARGS((char *p, char *m)); 47 | static void maddmsg ARGS((mbox_t *mbp)); 48 | 49 | void 50 | mcheck() 51 | { 52 | register mbox_t *mbp; 53 | long now; 54 | struct tbl *vp, mailcheck; 55 | struct stat stbuf; 56 | 57 | vp = global("MAILCHECK"); 58 | if (!(vp->flag & ISSET) || strint(&mailcheck, vp) == NULL) 59 | return; 60 | 61 | if (mlastchkd == 0) 62 | mlastchkd = time((long *)0); 63 | 64 | if ((now=time((long *)0)) - mlastchkd >= mailcheck.val.i) { 65 | mlastchkd = now; 66 | 67 | vp = global("MAILPATH"); 68 | if (vp && (vp->flag & ISSET)) 69 | mbp = mplist; 70 | else if ((vp = global("MAIL")) && (vp->flag & ISSET)) 71 | mbp = &mbox; 72 | else 73 | mbp = NULL; 74 | 75 | while (mbp) { 76 | if (stat(mbp->mb_path, &stbuf) == 0 && 77 | (stbuf.st_mode & S_IFMT) == S_IFREG) { 78 | if (mbp->mb_size < stbuf.st_size) 79 | maddmsg( mbp ); 80 | mbp->mb_size = stbuf.st_size; 81 | } else { 82 | /* 83 | * Some mail readers remove the mail 84 | * file if all mail is read. If file 85 | * does not exist, assume this is the 86 | * case and set size to zero. 87 | */ 88 | mbp->mb_size = 0; 89 | } 90 | mbp = mbp->mb_next; 91 | } 92 | } 93 | } 94 | 95 | void 96 | mbset(p) 97 | register char *p; 98 | { 99 | struct stat stbuf; 100 | 101 | if (mbox.mb_msg) 102 | afree((void *)mbox.mb_msg, APERM); 103 | mbox.mb_path = p; 104 | mbox.mb_msg = NULL; 105 | if (stat(p,&stbuf) == 0 && (stbuf.st_mode & S_IFMT) == S_IFREG) 106 | mbox.mb_size = stbuf.st_size; 107 | else 108 | mbox.mb_size = 0; 109 | } 110 | 111 | void 112 | mpset(mptoparse) 113 | register char *mptoparse; 114 | { 115 | register mbox_t *mbp; 116 | register char *mpath, *mmsg, *mval; 117 | 118 | munset( mplist ); 119 | mplist = NULL; 120 | mval = strsave(mptoparse, APERM); 121 | while (mval) { 122 | mpath = mval; 123 | if ((mval = strchr(mval, ':')) != NULL) { 124 | *mval ='\0', mval++; 125 | } 126 | if ((mmsg = strchr(mpath, '?')) != NULL) { 127 | *mmsg = '\0', mmsg++; 128 | } 129 | mbp = mballoc(mpath, mmsg); 130 | mbp->mb_next = mplist; 131 | mplist = mbp; 132 | } 133 | } 134 | 135 | static void 136 | munset(mlist) 137 | register mbox_t *mlist; 138 | { 139 | register mbox_t *mbp; 140 | 141 | while (mlist != NULL) { 142 | mbp = mlist; 143 | mlist = mbp->mb_next; 144 | if (!mlist) 145 | afree((void *)mbp->mb_path, APERM); 146 | afree((void *)mbp, APERM); 147 | } 148 | } 149 | 150 | static mbox_t * 151 | mballoc(p, m) 152 | char *p; 153 | char *m; 154 | { 155 | struct stat stbuf; 156 | register mbox_t *mbp; 157 | 158 | mbp = (mbox_t *)alloc(sizeof(mbox_t), APERM); 159 | mbp->mb_next = NULL; 160 | mbp->mb_path = p; 161 | mbp->mb_msg = m; 162 | if (stat(mbp->mb_path, &stbuf) == 0 && 163 | (stbuf.st_mode & S_IFMT) == S_IFREG) { 164 | mbp->mb_size = stbuf.st_size; 165 | } else { 166 | mbp->mb_size = 0; 167 | } 168 | return(mbp); 169 | } 170 | 171 | void 172 | mprint() 173 | { 174 | struct mailmsg *mm; 175 | 176 | while ((mm = mmsgs) != NULL) { 177 | shellf( "%s\n", mm->msg ); 178 | fflush(shlout); 179 | afree((void *)mm->msg, APERM); 180 | mmsgs = mm->next; 181 | afree((void *)mm, APERM); 182 | } 183 | } 184 | 185 | static void 186 | maddmsg( mbp ) 187 | mbox_t *mbp; 188 | { 189 | struct mailmsg *message; 190 | struct tbl *vp; 191 | 192 | message = (struct mailmsg *)alloc(sizeof(struct mailmsg), APERM); 193 | setstr((vp = typeset("_", LOCAL, 0)), mbp->mb_path); 194 | 195 | if (mbp->mb_msg) 196 | message->msg = strsave(substitute(mbp->mb_msg,0),APERM); 197 | else 198 | message->msg = strsave(substitute(MBMESSAGE,0),APERM); 199 | 200 | unset(vp); 201 | message->next = mmsgs; 202 | mmsgs = message; 203 | } 204 | -------------------------------------------------------------------------------- /sh/patchlevel.h: -------------------------------------------------------------------------------- 1 | /* 2 | * PD KSH 3 | * $Id: patchlevel.h,v 4.5 1992/05/12 09:30:34 sjg Exp $ 4 | */ 5 | #define VERSION 4 6 | #define PATCHLEVEL 5 7 | -------------------------------------------------------------------------------- /sh/proto.h: -------------------------------------------------------------------------------- 1 | /* 2 | * prototypes for PD-KSH 3 | * originally generated using "cproto.c 3.5 92/04/11 19:28:01 cthuang " 4 | * $Id: proto.h,v 1.1 1992/04/25 08:29:02 sjg Exp $ 5 | */ 6 | #ifndef ARGS 7 | #if defined(__STDC__) || defined(__cplusplus) 8 | #define ARGS(s) s 9 | #else 10 | #define ARGS(s) () 11 | #endif 12 | #endif 13 | 14 | /* alloc.c */ 15 | Area * ainit ARGS((Area *ap)); 16 | void afreeall ARGS((Area *ap)); 17 | void * alloc ARGS((size_t size, Area *ap)); 18 | void * aresize ARGS((void *ptr, size_t size, Area *ap)); 19 | void afree ARGS((void *ptr, Area *ap)); 20 | /* c_ksh.c */ 21 | int c_hash ARGS((char **wp)); 22 | int c_cd ARGS((char **wp)); 23 | int c_print ARGS((char **wp)); 24 | int c_whence ARGS((char **wp)); 25 | int c_typeset ARGS((char **wp)); 26 | int c_alias ARGS((char **wp)); 27 | int c_unalias ARGS((char **wp)); 28 | int c_let ARGS((char **wp)); 29 | int c_jobs ARGS((char **wp)); 30 | int c_fgbg ARGS((char **wp)); 31 | int c_kill ARGS((char **wp)); 32 | int c_bind ARGS((char **wp)); 33 | /* c_sh.c */ 34 | int c_label ARGS((char **wp)); 35 | int c_shift ARGS((char **wp)); 36 | int c_umask ARGS((char **wp)); 37 | int c_dot ARGS((char **wp)); 38 | int c_wait ARGS((char **wp)); 39 | int c_read ARGS((char **wp)); 40 | int c_eval ARGS((char **wp)); 41 | int c_trap ARGS((char **wp)); 42 | void setsig ARGS((struct trap *p, void (*f)())); 43 | int c_return ARGS((char **wp)); 44 | int c_brkcont ARGS((char **wp)); 45 | int c_exit ARGS((char **wp)); 46 | int c_set ARGS((char **wp)); 47 | int c_unset ARGS((char **wp)); 48 | int c_ulimit ARGS((char **wp)); 49 | int c_times ARGS((char **wp)); 50 | int timex ARGS((struct op *t, int f)); 51 | int c_exec ARGS((char **wp)); 52 | int c_builtin ARGS((char **wp)); 53 | /* c_test.c */ 54 | int c_test ARGS((char **wp)); 55 | int oexpr ARGS((int n)); 56 | int aexpr ARGS((int n)); 57 | int nexpr ARGS((int n)); 58 | int primary ARGS((int n)); 59 | int filstat ARGS((char *nm, int mode)); 60 | int t_lex ARGS((char *s)); 61 | int newerf ARGS((char *f1, char *f2)); 62 | int olderf ARGS((char *f1, char *f2)); 63 | int equalf ARGS((char *f1, char *f2)); 64 | /* do_ulimit.c */ 65 | int do_ulimit ARGS((char *a1, char *a2)); 66 | /* edit.c */ 67 | int x_read ARGS((int fd, char *buf, size_t len)); 68 | int x_getc ARGS((void)); 69 | void x_flush ARGS((void)); 70 | void x_adjust ARGS((void)); 71 | void x_putc ARGS((int c)); 72 | void x_puts ARGS((char *s)); 73 | void x_init ARGS((void)); 74 | bool_t x_mode ARGS((bool_t onoff)); 75 | int promptlen ARGS((char *cp)); 76 | int init_editmode ARGS((void)); 77 | /* emacs.c */ 78 | int x_emacs ARGS((char *buf, size_t len)); 79 | void x_redraw ARGS((int limit)); 80 | void x_bind ARGS((char *a1, char *a2, int macro)); 81 | void x_init_emacs ARGS((void)); 82 | void x_emacs_keys ARGS((int erase, int kill, int werase, int intr, int quit)); 83 | char * x_lastcp ARGS((void)); 84 | /* eval.c */ 85 | char * substitute ARGS((char const *cp, int f)); 86 | char ** eval ARGS((char **ap, int f)); 87 | char * evalstr ARGS((char *cp, int f)); 88 | /* exec.c */ 89 | int execute ARGS((struct op *t, volatile int flags)); 90 | int shcomexec ARGS((char **wp)); 91 | int define ARGS((char *name, struct op *t)); 92 | int builtin ARGS((char *name, int (*func)())); 93 | struct tbl * findcom ARGS((char *name, int insert)); 94 | int flushcom ARGS((int all)); 95 | char * search ARGS((char *name, char *path, int mode)); 96 | /* expr.c */ 97 | void evalerr ARGS((char *err)); 98 | long evaluate ARGS((const char *expr)); 99 | /* getopts.c */ 100 | void resetopts ARGS((void)); 101 | int c_getopts ARGS((char **wp)); 102 | /* history.c */ 103 | int c_fc ARGS((register char **wp)); 104 | void histbackup ARGS((void)); 105 | void histsave ARGS((char *cmd)); 106 | char ** histget ARGS((char *str)); 107 | char * histrpl ARGS((char *s, char *pat, char *rep, int global)); 108 | void hist_init ARGS((Source *s)); 109 | void hist_finish ARGS((void)); 110 | char ** histpos ARGS((void)); 111 | int histN ARGS((void)); 112 | int histnum ARGS((int n)); 113 | char * findhist ARGS((int start, int fwd, char *str)); 114 | /* io.c */ 115 | int errorf ARGS((const char *fmt, ...)); 116 | int shellf ARGS((const char *fmt, ...)); 117 | void fopenshf ARGS((int fd)); 118 | void flushshf ARGS((int fd)); 119 | int savefd ARGS((int fd)); 120 | void restfd ARGS((int fd, int ofd)); 121 | void openpipe ARGS((int *pv)); 122 | void closepipe ARGS((int *pv)); 123 | struct temp * maketemp ARGS((Area *ap)); 124 | /* jobs.c */ 125 | void j_init ARGS((void)); 126 | void j_exit ARGS((void)); 127 | void j_change ARGS((void)); 128 | int exchild ARGS((struct op *t, int flags)); 129 | int waitlast ARGS((void)); 130 | int j_reapchld ARGS((void)); 131 | int j_reap ARGS((void)); 132 | int waitfor ARGS((int job)); 133 | void j_kill ARGS((int job, int sig)); 134 | int j_resume ARGS((int job, int bg)); 135 | void j_jobs ARGS((void)); 136 | void j_notify ARGS((void)); 137 | int j_lookup ARGS((char *cp)); 138 | int j_stopped ARGS((void)); 139 | /* lex.c */ 140 | int yylex ARGS((int cf)); 141 | int gethere ARGS((void)); 142 | void yyerror ARGS((const char *msg)); 143 | Source * pushs ARGS((int type)); 144 | int pprompt ARGS((char *cp)); 145 | /* mail.c */ 146 | void mcheck ARGS((void)); 147 | void mbset ARGS((char *p)); 148 | void mpset ARGS((char *mptoparse)); 149 | void mprint ARGS((void)); 150 | /* main.c */ 151 | int main ARGS((int argc, char **argv, char **envp)); 152 | int include ARGS((char *name)); 153 | #if 0 154 | int command ARGS((char *comm)); 155 | #endif 156 | int shell ARGS((Source *s)); 157 | void leave ARGS((int rv)); 158 | int error ARGS((void)); 159 | int unwind ARGS((void)); 160 | int newenv ARGS((int type)); 161 | int quitenv ARGS((void)); 162 | void aerror ARGS((Area *ap, const char *msg)); 163 | /* misc.c */ 164 | void setctypes ARGS((/* const */ char *s, int t)); 165 | void initctypes ARGS((void)); 166 | char * ulton ARGS((unsigned long n, int base)); 167 | char * strsave ARGS((char *s, Area *ap)); 168 | int option ARGS((const char *n)); 169 | char * getoptions ARGS((void)); 170 | void printoptions ARGS((void)); 171 | int getn ARGS((char *as)); 172 | char * strerror ARGS((int i)); 173 | int gmatch ARGS((char *s, char *p)); 174 | void qsortp ARGS((void **base, size_t n, int (*f)())); 175 | int qsort1 ARGS((void **base, void **lim, int (*f)())); 176 | int xstrcmp ARGS((void *p1, void *p2)); 177 | void cleanpath ARGS((char *pwd, char *dir, char *clean)); 178 | /* syn.c */ 179 | int yyparse ARGS((void)); 180 | int keywords ARGS((void)); 181 | struct op * compile ARGS((Source *s)); 182 | /* table.c */ 183 | unsigned int hash ARGS((char *n)); 184 | void tinit ARGS((struct table *tp, Area *ap)); 185 | struct tbl * tsearch ARGS((struct table *tp, char *n, unsigned int h)); 186 | struct tbl * tenter ARGS((struct table *tp, char *n, unsigned int h)); 187 | void tdelete ARGS((struct tbl *p)); 188 | void twalk ARGS((struct table *tp)); 189 | struct tbl * tnext ARGS((void)); 190 | struct tbl ** tsort ARGS((struct table *tp)); 191 | /* trace.c */ 192 | /* trap.c */ 193 | Trap * gettrap ARGS((char *name)); 194 | void trapsig ARGS((int i)); 195 | int runtraps ARGS((void)); 196 | int runtrap ARGS((Trap *p)); 197 | int cleartraps ARGS((void)); 198 | int ignoresig ARGS((int i)); 199 | int restoresigs ARGS((void)); 200 | /* tree.c */ 201 | void ptree ARGS((struct op *t, FILE *f)); 202 | int pioact ARGS((FILE *f, struct ioword *iop)); 203 | int fptreef ARGS((FILE *f, char *fmt, ...)); 204 | int snptreef ARGS((char *s, int n, char *fmt, ...)); 205 | struct op * tcopy ARGS((struct op *t, Area *ap)); 206 | char * wdcopy ARGS((char *wp, Area *ap)); 207 | char * wdscan ARGS((char *wp, int c)); 208 | void tfree ARGS((struct op *t, Area *ap)); 209 | /* var.c */ 210 | void newblock ARGS((void)); 211 | void popblock ARGS((void)); 212 | struct tbl * global ARGS((char *n)); 213 | struct tbl * local ARGS((char *n)); 214 | char * strval ARGS((struct tbl *vp)); 215 | long intval ARGS((struct tbl *vp)); 216 | void setstr ARGS((struct tbl *vq, char *s)); 217 | struct tbl * strint ARGS((struct tbl *vq, struct tbl *vp)); 218 | void setint ARGS((struct tbl *vq, long n)); 219 | int import ARGS((char *thing)); 220 | struct tbl * typeset ARGS((char *var, int set, int clr)); 221 | void unset ARGS((struct tbl *vp)); 222 | int isassign ARGS((char *s)); 223 | char ** makenv ARGS((void)); 224 | /* version.c */ 225 | /* vi.c */ 226 | void vi_reset ARGS((char *buf, int len)); 227 | int vi_hook ARGS((int ch)); 228 | int save_cbuf ARGS((void)); 229 | int restore_cbuf ARGS((void)); 230 | int x_vi ARGS((char *buf, size_t len)); 231 | int getch ARGS((void)); 232 | char ** globstr ARGS((char *stuff)); 233 | 234 | 235 | -------------------------------------------------------------------------------- /sh/sh.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Public Domain Bourne/Korn shell 3 | */ 4 | 5 | /* $Id: sh.h,v 1.3 1992/04/25 08:29:52 sjg Exp $ */ 6 | 7 | #include "config.h" 8 | 9 | /* allow for non-Unix linkers. main.c has a "#define Extern " */ 10 | #ifndef Extern 11 | # define Extern extern 12 | #endif 13 | 14 | #ifndef SHELL 15 | #define SHELL "/bin/sh" /* shell to exec scripts */ 16 | #endif 17 | 18 | /* some people object to this use of __STDC__ */ 19 | #ifdef __STDC__ 20 | #define ARGS(args) args /* prototype declaration */ 21 | #else 22 | #define ARGS(args) () /* K&R declaration */ 23 | #ifdef VOID 24 | #define void VOID 25 | #endif 26 | #define const 27 | #define volatile 28 | #endif 29 | 30 | #ifdef _ULTRIX /* Ultrix 2.x gets dup2 wrong */ 31 | int dup2 ARGS ((int, int)); 32 | /* assumes we don't want dup2 return value */ 33 | #define dup2(ofd, nfd) \ 34 | (void) ((dup2)(ofd, nfd), fcntl(nfd, F_SETFD, 0)) 35 | #endif 36 | 37 | #if defined(EMACS) || defined(VI) 38 | #define EDIT 39 | #endif 40 | 41 | typedef int bool_t; 42 | #define FALSE 0 43 | #define TRUE 1 44 | 45 | #define sizeofN(type, n) (sizeof(type) * (n)) 46 | #define BIT(i) (1<<(i)) /* define bit in flag */ 47 | 48 | #define NUFILE 10 /* Number of user-accessible files */ 49 | #define FDBASE 10 /* First file usable by Shell */ 50 | 51 | /* you're not going to run setuid shell scripts, are you? */ 52 | #define eaccess(path, mode) access(path, mode) 53 | 54 | #define MAGIC (char)0x80 /* prefix for ~*?[ during expand */ 55 | #define NOT '!' /* might use ^ */ 56 | 57 | #define LINE 256 /* input line size */ 58 | #define PATH 256 /* pathname size */ 59 | 60 | Extern int kshpid; /* $$, shell pid */ 61 | Extern int exstat; /* exit status */ 62 | Extern int async; /* $!, last &'d pid */ 63 | Extern volatile int sigchld_caught; /* count of dead children */ 64 | 65 | 66 | /* 67 | * Area-based allocation built on malloc/free 68 | */ 69 | 70 | typedef struct Area { 71 | struct Block *free; /* free list */ 72 | } Area; 73 | 74 | extern Area aperm; /* permanent object space */ 75 | #define APERM &aperm 76 | #define ATEMP &e.area 77 | 78 | /* 79 | * parsing & execution environment 80 | */ 81 | Extern struct env { 82 | int type; /* enviroment type - see below */ 83 | Area area; /* temporary allocation area */ 84 | struct block *loc; /* local variables and functions */ 85 | short *savefd; /* original redirected fd's */ 86 | struct env *oenv; /* link to previous enviroment */ 87 | jmp_buf jbuf; /* long jump back to env creator */ 88 | int interactive; /* fd's 0,1,2 are tty */ 89 | struct temp *temps; /* temp files */ 90 | } e; 91 | 92 | #define E_NONE 0 /* dummy enviroment */ 93 | #define E_PARSE 1 /* parsing command # */ 94 | #define E_EXEC 2 /* executing command tree */ 95 | #define E_LOOP 3 /* executing for/while # */ 96 | #define E_TCOM 5 /* executing simple command */ 97 | #define E_FUNC 6 /* executing function */ 98 | #define E_ERRH 7 /* general error handler # */ 99 | /* # indicates env has valid jbuf */ 100 | 101 | /* 102 | * flags 103 | */ 104 | #define FEXPORT FLAG('a') /* -a: allexport */ 105 | #define FERREXIT FLAG('e') /* -e: errexit (quit on error) */ 106 | #define FBGNICE 29 /* bgnice */ 107 | #define FEMACS 30 /* emacs command editing */ 108 | #define FIGNEOF 27 /* ignoreeof (eof does not exit) */ 109 | #define FHASHALL FLAG('h') /* -h: trackall, hashall */ 110 | #define FTALKING FLAG('i') /* -i: interactive (talking type wireless) */ 111 | #define FKEYWORD FLAG('k') /* -k: keyword (name=value anywhere) */ 112 | #define FMARKDIRS 28 /* markdirs */ 113 | #define FMONITOR FLAG('m') /* -m: monitor */ 114 | #define FNOEXEC FLAG('n') /* -n: noexec */ 115 | #define FNOGLOB FLAG('f') /* -f: noglob */ 116 | #define FPRIVILEGED FLAG('p') /* -p: privileged */ 117 | #define FSTDIN FLAG('s') /* -s (invocation): parse stdin */ 118 | #define FNOUNSET FLAG('u') /* -u: nounset (unset vars is error) */ 119 | #define FVERBOSE FLAG('v') /* -v: verbose (echo input) */ 120 | #define FVI 31 /* vi command editing */ 121 | #define FXTRACE FLAG('x') /* -x: (execute) xtrace */ 122 | 123 | #define FLAG(c) (1 + c - 'a') /* map char to flags index */ 124 | #define FLAGS 32 125 | Extern char flag [FLAGS]; 126 | int option ARGS((const char *name)); 127 | char *getoptions ARGS((void)); 128 | void printoptions ARGS((void)); 129 | 130 | extern char null []; /* null value for variable */ 131 | 132 | /* 133 | * other functions 134 | */ 135 | char * substitute ARGS((char const *, int)); 136 | char *search(); 137 | struct tbl *findcom(); 138 | char *strsave ARGS((char *, Area *)); 139 | char *ulton ARGS((unsigned long n, int base)); 140 | int xstrcmp(); 141 | void qsortp ARGS((void **base, size_t n, int (*compare)(void *, void *))); 142 | long evaluate ARGS((const char *expr)); 143 | void resetopts(); 144 | void histsave(); 145 | void histlist(); 146 | 147 | void j_init ARGS((void)); 148 | void j_exit ARGS((void)); 149 | void j_notify ARGS((void)); 150 | void j_kill ARGS((int job, int sig)); 151 | #ifdef JOBS 152 | void j_change ARGS((void)); 153 | int j_resume ARGS((int job, int bg)); 154 | #endif 155 | 156 | /* 157 | * error handling 158 | */ 159 | void leave(); /* abort shell (or fail in subshell) */ 160 | 161 | /* 162 | * library functions 163 | */ 164 | typedef void (*handler_t)(); /* signal handler */ 165 | 166 | /* temp/here files. the file is removed when the struct is freed */ 167 | struct temp { 168 | struct temp * next; 169 | char *name; 170 | }; 171 | struct temp *maketemp ARGS((Area *ap)); 172 | 173 | /* 174 | * stdio and our IO routines 175 | */ 176 | 177 | #ifdef BUFSIZ /* included? */ 178 | extern FILE * shf [NUFILE]; /* map shell fd to FILE */ 179 | #endif 180 | void fopenshf(); 181 | void flushshf(); 182 | 183 | #undef stdin 184 | #undef stdout 185 | 186 | #define stdin shf[0] /* standard input */ 187 | #define stdout shf[1] /* standard output */ 188 | #define shlout shf[2] /* shell output */ 189 | 190 | int shellf ARGS((const char *fmt, ...)); /* fprintf(shlout, ); */ 191 | int errorf ARGS((const char *fmt, ...)); /* fprintf(shlout, ); error(); */ 192 | 193 | /* 194 | * IO control 195 | */ 196 | extern int ttyfd; /* tty fd (original fd 0) */ 197 | 198 | int savefd ARGS((int fd)); /* save user fd */ 199 | void restfd ARGS((int fd, int ofd)); 200 | void openpipe ARGS((int [2])); 201 | void closepipe ARGS((int [2])); 202 | 203 | /* 204 | * trap handlers 205 | */ 206 | typedef struct trap { 207 | int signal; /* signal number */ 208 | char *name; /* short name */ 209 | char *mess; /* descriptive name */ 210 | char *trap; /* trap command */ 211 | int volatile set; /* trap pending */ 212 | int ourtrap; /* not ignored (?) */ 213 | int sig_dfl; /* originally SIG_DFL */ 214 | } Trap; 215 | 216 | #ifndef SIGKILL 217 | #include 218 | #endif /* SIGKILL */ 219 | #ifdef NSIG 220 | #define SIGNALS NSIG 221 | #else 222 | #ifdef _MINIX 223 | #define SIGNALS (_NSIG+1) /* _NSIG is # of signals used, excluding 0. */ 224 | #else 225 | #define SIGNALS 32 226 | #endif /* _MINIX */ 227 | #endif /* NSIG */ 228 | 229 | #ifdef USE_SIGACT /* always use it? */ 230 | #ifndef SA_NOCLDSTOP 231 | # include "sigact.h" /* use sjg's fake sigaction() */ 232 | #endif 233 | Extern struct sigaction Sigact, Sigact_dfl, Sigact_ign, Sigact_trap; 234 | #endif 235 | 236 | Extern int volatile trap; /* traps pending? */ 237 | extern Trap sigtraps[SIGNALS]; 238 | Trap *gettrap ARGS((char *)); /* search for struct trap by number or name */ 239 | void trapsig ARGS((int sig)); /* trap signal handler */ 240 | 241 | /* 242 | * fast character classes 243 | */ 244 | #define C_ALPHA 0x01 /* a-z_A-Z */ 245 | #define C_DIGIT 0x02 /* 0-9 */ 246 | #define C_LEX1 0x04 /* \0 \t\n|&;<>() */ 247 | #define C_VAR1 0x08 /* *@#!$-? */ 248 | #define C_SUBOP 0x40 /* "=-+?#%" */ 249 | #define C_IFS 0x80 /* $IFS */ 250 | 251 | extern char ctypes []; 252 | #if 0 253 | void initctypes ARGS((void)); 254 | void setctypes ARGS((const char*, int type)); 255 | #endif 256 | #define ctype(c, t) !!(ctypes[(unsigned char)(c)]&(t)) 257 | #define letter(c) ctype(c, C_ALPHA) 258 | #define digit(c) ctype(c, C_DIGIT) 259 | #define letnum(c) ctype(c, C_ALPHA|C_DIGIT) 260 | 261 | #include "table.h" 262 | #include "tree.h" 263 | #include "lex.h" 264 | #include "proto.h" 265 | 266 | /* 267 | * 91-07-06 268 | * use my simple debug tracing... 269 | */ 270 | #include "trace.h" 271 | 272 | #ifndef fileno 273 | #define fileno(p) ((p)->_fileno) 274 | #endif 275 | -------------------------------------------------------------------------------- /sh/sigact.c: -------------------------------------------------------------------------------- 1 | /* NAME: 2 | * sigact.c - fake sigaction(2) 3 | * 4 | * SYNOPSIS: 5 | * #include 6 | * #ifndef SA_NOCLDSTOP 7 | * # include "sigact.h" 8 | * #endif 9 | * 10 | * int sigaction(int sig, struct sigaction *act, 11 | * struct sigaction *oact); 12 | * int sigaddset(sigset_t *mask, int sig); 13 | * int sigdelset(sigset_t *mask, int sig); 14 | * int sigemptyset(sigset_t *mask); 15 | * int sigfillset(sigset_t *mask); 16 | * int sigismember(sigset_t *mask, int sig); 17 | * int sigpending(sigset_t *set); 18 | * int sigprocmask(int how, sigset_t *set, sigset_t *oldset); 19 | * int sigsuspend(sigset_t *mask); 20 | * 21 | * DESCRIPTION: 22 | * This is a fake sigaction implementation. It uses 23 | * sigset(2) if available, otherwise it just uses 24 | * signal(2). If it thinks sigaction(2) really exists it 25 | * compiles to almost nothing. 26 | * 27 | * The need for all this is the problems caused by mixing 28 | * signal handling routines in the one process. This 29 | * module allows for a consistent POSIX compliant interface 30 | * to whatever is available. 31 | * 32 | * RETURN VALUE: 33 | * 0==success, -1==failure 34 | * 35 | * FILES: 36 | * None. 37 | * 38 | * SEE ALSO: 39 | * 40 | * 41 | * BUGS: 42 | * Since we fake most of this, don't expect fancy usage to 43 | * work. 44 | * 45 | * COPYRIGHT: 46 | * @(#)Copyright (c) 1992 Simon J. Gerraty 47 | * 48 | * This is free software. It comes with NO WARRANTY. 49 | * Permission to use, modify and distribute this source code 50 | * is granted subject to the following conditions. 51 | * 1/ that that the above copyright notice and this notice 52 | * are preserved in all copies and that due credit be given 53 | * to the author. 54 | * 2/ that any changes to this code are clearly commented 55 | * as such so that the author does get blamed for bugs 56 | * other than his own. 57 | * 58 | * Please send copies of changes and bug-fixes to: 59 | * sjg@zen.void.oz.au 60 | * 61 | */ 62 | #ifndef lint 63 | static char *RCSid = "$Id: sigact.c,v 1.5 1992/05/03 08:29:10 sjg Exp $"; 64 | #endif 65 | /* 66 | * $Log: sigact.c,v $ 67 | * Revision 1.5 1992/05/03 08:29:10 sjg 68 | * Update for Patch05 69 | * 70 | * Revision 1.4 1992/04/29 06:29:13 sjg 71 | * avoid use of #pragma 72 | * 73 | * Revision 1.3 1992/04/26 11:24:43 sjg 74 | * USE_SIGSET corrected in sigsuspend(). 75 | * 76 | * Revision 1.2 1992/04/24 15:04:11 sjg 77 | * now compiles with cc 78 | * 79 | * Revision 1.1 1992/04/24 12:03:58 sjg 80 | * Initial revision 81 | * 82 | */ 83 | 84 | #include 85 | 86 | /* 87 | * some systems have a faulty sigaction() implementation! 88 | * Allow us to bypass it. 89 | */ 90 | #if !defined(SA_NOCLDSTOP) || defined(USE_SIGNAL) || defined(USE_SIGSET) || defined(USE_SIGMASK) 91 | 92 | /* 93 | * if we haven't been told, 94 | * try and guess what we should implement with. 95 | */ 96 | #if !defined(USE_SIGSET) && !defined(USE_SIGMASK) && !defined(USE_SIGNAL) 97 | # if defined(sigmask) || defined(BSD) || defined(_BSD) && !defined(BSD41) 98 | # define USE_SIGMASK 99 | # else 100 | # ifndef NO_SIGSET 101 | # define USE_SIGSET 102 | # else 103 | # define USE_SIGNAL 104 | # endif 105 | # endif 106 | #endif 107 | /* 108 | * if we still don't know, we're in trouble 109 | */ 110 | #if !defined(USE_SIGSET) && !defined(USE_SIGMASK) && !defined(USE_SIGNAL) 111 | error must know what to implement with 112 | #endif 113 | 114 | #include "sigact.h" 115 | 116 | 117 | 118 | int 119 | sigaction(sig, act, oact) 120 | int sig; 121 | struct sigaction *act, *oact; 122 | { 123 | void (*oldh)(); 124 | 125 | if (act) 126 | { 127 | #ifdef USE_SIGSET 128 | oldh = sigset(sig, act->sa_handler); 129 | #else 130 | oldh = signal(sig, act->sa_handler); 131 | #endif 132 | } 133 | else 134 | { 135 | if (oact) 136 | { 137 | #ifdef USE_SIGSET 138 | oldh = sigset(sig, SIG_IGN); 139 | #else 140 | oldh = signal(sig, SIG_IGN); 141 | #endif 142 | if (oldh != SIG_IGN) 143 | { 144 | #ifdef USE_SIGSET 145 | (void) sigset(sig, oldh); 146 | #else 147 | (void) signal(sig, oldh); 148 | #endif 149 | } 150 | } 151 | } 152 | if (oact) 153 | { 154 | oact->sa_handler = oldh; 155 | } 156 | return 0; /* hey we're faking it */ 157 | } 158 | 159 | int 160 | sigaddset(mask, sig) 161 | sigset_t *mask; 162 | int sig; 163 | { 164 | *mask |= sigmask(sig); 165 | return 0; 166 | } 167 | 168 | 169 | int 170 | sigdelset(mask, sig) 171 | sigset_t *mask; 172 | int sig; 173 | { 174 | *mask &= ~(sigmask(sig)); 175 | return 0; 176 | } 177 | 178 | 179 | int 180 | sigemptyset(mask) 181 | sigset_t *mask; 182 | { 183 | *mask = 0; 184 | return 0; 185 | } 186 | 187 | 188 | int 189 | sigfillset(mask) 190 | sigset_t *mask; 191 | { 192 | *mask = ~0; 193 | return 0; 194 | } 195 | 196 | 197 | int 198 | sigismember(mask, sig) 199 | sigset_t *mask; 200 | int sig; 201 | { 202 | return ((*mask) & sigmask(sig)); 203 | } 204 | 205 | 206 | int 207 | sigpending(set) 208 | sigset_t *set; 209 | { 210 | return 0; 211 | } 212 | 213 | 214 | int 215 | sigprocmask(how, set, oldset) 216 | int how; 217 | sigset_t *set, *oldset; 218 | { 219 | #ifdef USE_SIGSET 220 | register int i; 221 | #endif 222 | sigset_t sm; 223 | 224 | #ifdef USE_SIGMASK 225 | sm = sigblock(0); 226 | #else 227 | sm = 0; 228 | #endif 229 | 230 | if (oldset) 231 | *oldset = sm; /* dangerous ? */ 232 | if (set) 233 | { 234 | switch (how) 235 | { 236 | case SIG_BLOCK: 237 | sm |= *set; 238 | break; 239 | case SIG_UNBLOCK: 240 | sm &= ~(*set); 241 | break; 242 | case SIG_SETMASK: 243 | sm = *set; 244 | break; 245 | } 246 | #ifdef USE_SIGMASK 247 | (void) sigsetmask(sm); 248 | #else 249 | # ifdef USE_SIGSET 250 | for (i = 1; i < NSIG; i++) 251 | { 252 | if (how == SIG_UNBLOCK) 253 | { 254 | if (*set & sigmask(i)) 255 | sigrelse(i); 256 | } 257 | else 258 | if (sm & sigmask(i)) 259 | { 260 | sighold(i); 261 | } 262 | } 263 | # endif 264 | #endif 265 | } 266 | return 0; 267 | } 268 | 269 | 270 | int 271 | sigsuspend(mask) 272 | sigset_t *mask; 273 | { 274 | #ifdef USE_SIGSET 275 | int sig = SIGCHLD; /* our default */ 276 | 277 | /* 278 | * add as many tests as you think sensible, but 279 | * SIGALRM, and SIGCHLD are probably the most 280 | * common. 281 | */ 282 | if (*mask & sigmask(SIGALRM)) 283 | sig = SIGALRM; 284 | else 285 | if (*mask & sigmask(SIGPIPE)) 286 | sig = SIGPIPE; 287 | sigpause(sig); 288 | #else 289 | # ifdef USE_SIGMASK 290 | sigpause(mask); 291 | # else 292 | pause(); 293 | # endif 294 | #endif 295 | return 0; 296 | } 297 | 298 | #endif /* ! SA_NOCLDSTOP */ 299 | 300 | 301 | /* This lot (for GNU-Emacs) goes at the end of the file. */ 302 | /* 303 | * Local Variables: 304 | * version-control:t 305 | * comment-column:40 306 | * End: 307 | */ 308 | -------------------------------------------------------------------------------- /sh/sigact.h: -------------------------------------------------------------------------------- 1 | /* NAME: 2 | * sigact.h - sigaction et al 3 | * 4 | * SYNOPSIS: 5 | * #include 6 | * #ifndef SA_NOCLDSTOP 7 | * # include "sigact.h" 8 | * #endif 9 | * 10 | * DESCRIPTION: 11 | * This header is the interface to a fake sigaction(2) implementation. 12 | * Do NOT include this header unless your system does not 13 | * have a real sigaction(2) implementation. 14 | */ 15 | /* 16 | * $Log: sigact.h,v $ 17 | * Revision 1.2 1992/04/24 15:04:11 sjg 18 | * now compiles with cc 19 | * 20 | * Revision 1.1 1992/04/24 12:01:38 sjg 21 | * Initial revision 22 | * 23 | */ 24 | 25 | #ifndef _SIGACT_H 26 | #define _SIGACT_H 27 | 28 | #ifndef ARGS 29 | # if defined(__STDC__) 30 | # define ARGS(p) p 31 | # else 32 | # define ARGS(p) () 33 | # endif 34 | #endif 35 | #ifndef __STDC__ 36 | # define volatile /* can change without warning */ 37 | # define const /* read only */ 38 | #endif 39 | 40 | #ifndef SIGKILL 41 | # include 42 | #endif 43 | #ifndef SA_NOCLDSTOP 44 | /* sa_flags */ 45 | #define SA_NOCLDSTOP 0x0001 /* don't send SIGCHLD on child stop */ 46 | #define SA_RESTART 0x0002 /* re-start I/O */ 47 | 48 | /* sigprocmask flags */ 49 | #define SIG_BLOCK 0x0001 50 | #define SIG_UNBLOCK 0x0002 51 | #define SIG_SETMASK 0x0004 52 | 53 | #ifndef __sys_stdtypes_h 54 | typedef int sigset_t; 55 | #endif 56 | 57 | struct sigaction 58 | { 59 | void (*sa_handler)(); 60 | sigset_t sa_mask; 61 | int sa_flags; 62 | }; 63 | 64 | 65 | int sigaction ARGS(( int sig, struct sigaction *act, struct sigaction *oact )); 66 | int sigaddset ARGS(( sigset_t *mask, int sig )); 67 | int sigdelset ARGS(( sigset_t *mask, int sig )); 68 | int sigemptyset ARGS(( sigset_t *mask )); 69 | int sigfillset ARGS(( sigset_t *mask )); 70 | int sigismember ARGS(( sigset_t *mask, int sig )); 71 | int sigpending ARGS(( sigset_t *set )); 72 | int sigprocmask ARGS(( int how, sigset_t *set, sigset_t *oldset )); 73 | int sigsuspend ARGS(( sigset_t *mask )); 74 | 75 | #ifndef sigmask 76 | #define sigmask(m) (1<<((m)-1)) /* convert SIGnum to mask */ 77 | #endif 78 | #if !defined(NSIG) && defined(_NSIG) 79 | # define NSIG _NSIG 80 | #endif 81 | #endif /* ! SA_NOCLDSTOP */ 82 | #endif /* _SIGACT_H */ 83 | /* 84 | * Local Variables: 85 | * version-control:t 86 | * comment-column:40 87 | * End: 88 | */ 89 | -------------------------------------------------------------------------------- /sh/stdh.h: -------------------------------------------------------------------------------- 1 | /* NAME: 2 | * stdh.h - standard headers 3 | * 4 | * SYNOPSIS: 5 | * #include "stdh.h" 6 | * 7 | * DESCRIPTION: 8 | * We use this header to encapsulate all the stddef et al 9 | * inclusion so that most of the source can ignore the 10 | * problems that their lack might cause. 11 | * 12 | * SEE ALSO: 13 | * 14 | * 15 | * AMENDED: 16 | * 91/11/25 13:33:12 (sjg) 17 | * 18 | * RELEASED: 19 | * 91/11/25 13:33:17 v1.3 20 | * 21 | * SCCSID: 22 | * @(#)stdh.h 1.3 91/11/25 13:33:12 (sjg) 23 | * 24 | */ 25 | 26 | // For S_IFMT 27 | #define _BSD_SOURCE 28 | 29 | #ifndef ARGS 30 | # ifdef __STDC__ 31 | # define ARGS(args) args 32 | # else 33 | # define ARGS(args) () 34 | # ifdef VOID 35 | # define void VOID 36 | # endif 37 | # define const 38 | # define volatile 39 | # endif 40 | #endif 41 | 42 | #include 43 | /* if we have std headers then include them here 44 | * otherwise make allowances 45 | */ 46 | #ifndef NOSTDHDRS 47 | # include 48 | # include 49 | # include 50 | # include 51 | #else 52 | # ifdef HAVE_SYS_STDTYPES 53 | # include 54 | # else 55 | # include 56 | /* just in case they have sys/stdtypes and don't know it 57 | */ 58 | # ifndef __sys_stdtypes_h 59 | #define _PID_T 60 | #define _CLOCK_T 61 | typedef int pid_t; 62 | typedef long clock_t; 63 | # endif 64 | # endif 65 | # ifdef _SYSV 66 | # include 67 | # else 68 | # include 69 | # define strchr index 70 | # define strrchr rindex 71 | # endif 72 | /* just a useful subset of what stdlib.h would have 73 | */ 74 | extern char * getenv ARGS((const char *)); 75 | extern void * malloc ARGS((size_t)); 76 | extern int free ARGS((void *)); 77 | extern int exit ARGS((int)); 78 | 79 | /* these _should_ match ANSI */ 80 | extern char * strstr ARGS((const char *, const char *)); 81 | extern void * memmove ARGS((void *, const void *, size_t)); 82 | extern void * memcpy ARGS((void *, const void *, size_t)); 83 | #endif /* NOSTDHDRS */ 84 | 85 | 86 | #ifndef offsetof 87 | #define offsetof(type,id) ((size_t)&((type*)NULL)->id) 88 | #endif 89 | 90 | -------------------------------------------------------------------------------- /sh/table.c: -------------------------------------------------------------------------------- 1 | #ifndef lint 2 | static char *RCSid = "$Id: table.c,v 1.2 1992/04/25 08:33:28 sjg Exp $"; 3 | #endif 4 | 5 | /* 6 | * dynamic hashed associative table for commands and variables 7 | */ 8 | 9 | #include "stdh.h" 10 | #include 11 | #include 12 | #include "sh.h" 13 | 14 | #define INIT_TBLS 8 /* initial table size (power of 2) */ 15 | 16 | static struct tstate { 17 | int left; 18 | struct tbl **next; 19 | } tstate; 20 | 21 | static void texpand ARGS((struct table *tp, int nsize)); 22 | static int tnamecmp ARGS((void *p1, void *p2)); 23 | 24 | 25 | unsigned int 26 | hash(n) 27 | register char * n; 28 | { 29 | register unsigned int h = 0; 30 | 31 | while (*n != '\0') 32 | h = 2*h + *n++; 33 | return h * 32821; /* scatter bits */ 34 | } 35 | 36 | #if 0 37 | phash(s) char *s; { 38 | printf("%2d: %s\n", hash(s)%32, s); 39 | } 40 | #endif 41 | 42 | void 43 | tinit(tp, ap) 44 | register struct table *tp; 45 | register Area *ap; 46 | { 47 | tp->areap = ap; 48 | tp->size = tp->free = 0; 49 | tp->tbls = NULL; 50 | } 51 | 52 | static void 53 | texpand(tp, nsize) 54 | register struct table *tp; 55 | int nsize; 56 | { 57 | register int i; 58 | register struct tbl *tblp, **p; 59 | register struct tbl **ntblp, **otblp = tp->tbls; 60 | int osize = tp->size; 61 | 62 | ntblp = (struct tbl**) alloc(sizeofN(struct tbl *, nsize), tp->areap); 63 | for (i = 0; i < nsize; i++) 64 | ntblp[i] = NULL; 65 | tp->size = nsize; 66 | tp->free = 8*nsize/10; /* table can get 80% full */ 67 | tp->tbls = ntblp; 68 | if (otblp == NULL) 69 | return; 70 | for (i = 0; i < osize; i++) 71 | if ((tblp = otblp[i]) != NULL) 72 | if ((tblp->flag&DEFINED)) { 73 | for (p = &ntblp[hash(tblp->name) & 74 | (tp->size-1)]; 75 | *p != NULL; p--) 76 | if (p == ntblp) /* wrap */ 77 | p += tp->size; 78 | *p = tblp; 79 | tp->free--; 80 | } else { 81 | afree((void*)tblp, tp->areap); 82 | } 83 | afree((void*)otblp, tp->areap); 84 | } 85 | 86 | struct tbl * 87 | tsearch(tp, n, h) 88 | register struct table *tp; /* table */ 89 | register char *n; /* name to enter */ 90 | unsigned int h; /* hash(n) */ 91 | { 92 | register struct tbl **pp, *p; 93 | 94 | if (tp->size == 0) 95 | return NULL; 96 | 97 | /* search for name in hashed table */ 98 | for (pp = &tp->tbls[h & (tp->size-1)]; (p = *pp) != NULL; pp--) { 99 | if (*p->name == *n && strcmp(p->name, n) == 0 100 | && (p->flag&DEFINED)) 101 | return p; 102 | if (pp == tp->tbls) /* wrap */ 103 | pp += tp->size; 104 | } 105 | 106 | return NULL; 107 | } 108 | 109 | struct tbl * 110 | tenter(tp, n, h) 111 | register struct table *tp; /* table */ 112 | register char *n; /* name to enter */ 113 | unsigned int h; /* hash(n) */ 114 | { 115 | register struct tbl **pp, *p; 116 | register char *cp; 117 | 118 | if (tp->size == 0) 119 | texpand(tp, INIT_TBLS); 120 | Search: 121 | /* search for name in hashed table */ 122 | for (pp = &tp->tbls[h & (tp->size-1)]; (p = *pp) != NULL; pp--) { 123 | if (*p->name == *n && strcmp(p->name, n) == 0) 124 | return p; /* found */ 125 | if (pp == tp->tbls) /* wrap */ 126 | pp += tp->size; 127 | } 128 | 129 | if (tp->free <= 0) { /* too full */ 130 | texpand(tp, 2*tp->size); 131 | goto Search; 132 | } 133 | 134 | /* create new tbl entry */ 135 | for (cp = n; *cp != '\0'; cp++) 136 | ; 137 | p = (struct tbl *) alloc(offsetof(struct tbl, name[(cp-n)+1]), tp->areap); 138 | p->flag = 0; 139 | p->type = 0; 140 | for (cp = p->name; *n != '\0';) 141 | *cp++ = *n++; 142 | *cp = '\0'; 143 | 144 | /* enter in tp->tbls */ 145 | tp->free--; 146 | *pp = p; 147 | return p; 148 | } 149 | 150 | void 151 | tdelete(p) 152 | register struct tbl *p; 153 | { 154 | p->flag = 0; 155 | } 156 | 157 | void 158 | twalk(tp) 159 | register struct table *tp; 160 | { 161 | tstate.left = tp->size; 162 | tstate.next = tp->tbls; 163 | } 164 | 165 | struct tbl * 166 | tnext() 167 | { 168 | while (--tstate.left >= 0) { 169 | struct tbl *p = *tstate.next++; 170 | if (p != NULL && (p->flag&DEFINED)) 171 | return p; 172 | } 173 | return NULL; 174 | } 175 | 176 | static int 177 | tnamecmp(p1, p2) 178 | void *p1, *p2; 179 | { 180 | return strcmp(((struct tbl *)p1)->name, ((struct tbl *)p2)->name); 181 | } 182 | 183 | struct tbl ** 184 | tsort(tp) 185 | register struct table *tp; 186 | { 187 | register int i; 188 | register struct tbl **p, **sp, **dp; 189 | 190 | p = (struct tbl **)alloc(sizeofN(struct tbl *, tp->size+1), ATEMP); 191 | sp = tp->tbls; /* source */ 192 | dp = p; /* dest */ 193 | for (i = 0; i < tp->size; i++) 194 | if ((*dp = *sp++) != NULL && ((*dp)->flag&DEFINED)) 195 | dp++; 196 | i = dp - p; 197 | qsortp((void**)p, (size_t)i, tnamecmp); 198 | p[i] = NULL; 199 | return p; 200 | } 201 | 202 | -------------------------------------------------------------------------------- /sh/table.h: -------------------------------------------------------------------------------- 1 | /* $Id: table.h,v 1.2 1992/04/25 08:33:28 sjg Exp $ */ 2 | 3 | /* 4 | * generic hashed associative table for commands and variables. 5 | */ 6 | 7 | struct table { 8 | Area *areap; /* area to allocate entries */ 9 | int size, free; /* hash size (always 2^^n), free entries */ 10 | struct tbl **tbls; /* hashed table items */ 11 | }; 12 | 13 | struct tbl { /* table item */ 14 | int flag; /* flags */ 15 | int type; /* command type or base, see below */ 16 | union { 17 | char *s; /* string */ 18 | long i; /* integer */ 19 | int (*f) ARGS ((char**)); /* int function */ 20 | struct op *t; /* "function" tree */ 21 | } val; /* value */ 22 | char name[4]; /* name -- variable length */ 23 | }; 24 | 25 | /* flag bits */ 26 | #define ALLOC BIT(0) /* val.s has been allocated */ 27 | #define DEFINED BIT(1) /* is defined in block */ 28 | #define ISSET BIT(2) /* has value, vp->val.[si] */ 29 | #define SPECIAL BIT(3) /* PATH, IFS, SECONDS, etc */ 30 | #define INTEGER BIT(4) /* val.i contains integer value */ 31 | #define RDONLY BIT(8) /* read-only variable */ 32 | #define EXPORT BIT(9) /* exported variable */ 33 | #define LOCAL BIT(10) /* for local typeset() */ 34 | #define TRACE BIT(11) /* trace (-t) */ 35 | #define FUNCT BIT(12) /* function */ 36 | #define EXPALIAS BIT(13) /* expanding this alias */ 37 | 38 | /* command types */ 39 | #define CNONE 0 /* undefined */ 40 | #define CSHELL 1 /* built-in */ 41 | #define CFUNC 2 /* function */ 42 | #define CEXEC 4 /* executable command */ 43 | #define CALIAS 5 /* alias */ 44 | #define CKEYWD 6 /* keyword */ 45 | 46 | void tinit ARGS((struct table *, Area *)); /* initialize table */ 47 | unsigned int hash(); /* name hash function */ 48 | struct tbl *tsearch(); /* table lookup primative */ 49 | struct tbl *tenter(); /* table lookup/enter primative */ 50 | void tdelete(); /* mark tbl entry for deletion */ 51 | void twalk(); /* initialize walk of table */ 52 | struct tbl *tnext(); /* walk table returning table time */ 53 | struct tbl **tsort(); /* sort table entries by name */ 54 | 55 | /* 56 | * activation record for function blocks 57 | */ 58 | struct block { 59 | Area area; /* area to allocate things */ 60 | int argc; /* current $# */ 61 | char ** argv; /* current $* */ 62 | struct table vars; /* local variables */ 63 | struct table funs; /* local functions */ 64 | #if 1 65 | char * error; /* error handler */ 66 | char * exit; /* exit handler */ 67 | #else 68 | struct trap error, exit; 69 | #endif 70 | struct block *next; /* enclosing block */ 71 | }; 72 | 73 | Extern struct block globals; /* global variables and functions */ 74 | Extern struct table commands; /* hashed commands */ 75 | Extern struct table builtins; /* built-in commands */ 76 | Extern struct table lexicals; /* keywords and aliases */ 77 | Extern struct table homedirs; /* homedir() cache */ 78 | 79 | struct builtin { 80 | char *name; 81 | int (*func)(); 82 | }; 83 | 84 | /* these really are externs! Look in table.c for them */ 85 | 86 | extern const struct builtin shbuiltins [], kshbuiltins []; 87 | 88 | /* var spec values */ 89 | #define V_NONE 0 90 | #define V_PATH 1 91 | #define V_IFS 2 92 | #define V_SECONDS 3 93 | #define V_OPTIND 4 94 | #define V_MAIL 5 95 | #define V_MAILPATH 6 96 | #define V_RANDOM 7 97 | 98 | Extern Area *lastarea; /* area of last variable/function looked up */ 99 | Extern char *path; /* PATH value */ 100 | Extern char *prompt; /* PS1 or PS2 */ 101 | 102 | void newblock(); 103 | void popblock(); 104 | struct tbl *global(/* char *s */); 105 | struct tbl *local(/* char *s */); 106 | struct tbl *typeset(/* char *var; int set, clr */); 107 | struct tbl *setvar(/* struct tbl *vdst, *vsrc */); 108 | struct tbl *strint(/* struct tbl *vdst, *vsrc */); 109 | long intval(/* struct tbl *vp */); 110 | void setint(/* struct tbl *vp; long n */); 111 | char *strval(/* struct tbl *vp */); 112 | void setstr(/* struct tbl *vp; char *s */); 113 | void unset(/* struct tbl *vp */); 114 | int import(/* char *s */); 115 | char **makenv(); 116 | int isassign(/* char *s */); 117 | 118 | -------------------------------------------------------------------------------- /sh/trace.c: -------------------------------------------------------------------------------- 1 | /* NAME: 2 | * trace.c - a simple trace facility 3 | * 4 | * SYNOPSIS: 5 | * TRACE(level, (fmt [, ...])); 6 | * 7 | * DESCRIPTION: 8 | * This module provides a simple trace facility via 9 | * a call to checkpoint() which opens a log file and writes 10 | * an entry and closes the log (so that process crashes 11 | * won't destroy the log :-). checkpoint() takes options 12 | * like printf(). If Trace_log is not initialized then 13 | * stderr is used. 14 | * 15 | * The header file trace.h defines a macro TRACE() which 16 | * is useful in that it allows checkpoint to be called 17 | * based on the value of Trace_level, and the calls can be 18 | * eliminated by undefining USE_TRACE. 19 | * 20 | * RETURN VALUE: 21 | * None. 22 | * 23 | * FILES: 24 | * None. 25 | * 26 | * SEE ALSO: 27 | * 28 | * 29 | * BUGS: 30 | * 31 | * 32 | * AMENDED: 33 | * 91/11/22 22:53:56 (sjg) 34 | * 35 | * RELEASED: 36 | * 91/11/22 22:54:17 v1.2 37 | * 38 | * @(#)Copyright (c) 1990 Simon J. Gerraty. 39 | */ 40 | #ifdef USE_TRACE 41 | 42 | #ifndef lint 43 | static char sccs_id[] = "@(#)trace.c 1.2 91/11/22 22:53:56 (sjg)"; 44 | #endif 45 | 46 | /* include files */ 47 | #include 48 | #ifdef __STDC__ 49 | # include 50 | #endif 51 | 52 | #define EXTERN 53 | #include "trace.h" 54 | #undef EXTERN 55 | 56 | /* some useful #defines */ 57 | #ifndef ENTRY 58 | # define ENTRY 59 | # define LOCAL static 60 | # define BOOLEAN int 61 | #endif 62 | #ifndef TRUE 63 | # define TRUE 1 64 | # define FALSE 0 65 | #endif 66 | #ifndef ARGS 67 | # if defined(__STDC__) || defined(PROTO) 68 | # define ARGS(p) p 69 | # else 70 | # define ARGS(p) () 71 | # endif 72 | #endif 73 | 74 | 75 | /* NAME: 76 | * checkpoint - write a logfile entry 77 | * 78 | * SYNOPSIS: 79 | * checkpoint(fmt, ...) 80 | * 81 | * DESCRIPTION: 82 | * This function takes a variable number or args 83 | * like the printf(3S) family of functions. 84 | * 85 | * RETURN VALUE: 86 | * None 87 | */ 88 | extern char * _CDECL strdup ARGS((char *s)); 89 | 90 | #ifdef __STDC__ 91 | # include 92 | 93 | ENTRY void _CDECL 94 | checkpoint(fmt) 95 | char *fmt; 96 | { 97 | int c; 98 | va_list arg_ptr; 99 | FILE *fp; 100 | register char *rcp; 101 | char *mode; 102 | static setup; 103 | 104 | va_start(arg_ptr, fmt); 105 | #else /* __STDC__ */ 106 | # include 107 | 108 | ENTRY void _CDECL 109 | checkpoint(va_alist) 110 | va_dcl 111 | { 112 | extern char *getenv ARGS((char *var)); 113 | char *fmt; 114 | int c; 115 | va_list arg_ptr; 116 | FILE *fp; 117 | register char *rcp; 118 | char *mode; 119 | static setup; 120 | 121 | va_start(arg_ptr); 122 | fmt = va_arg(arg_ptr, char *); 123 | #endif /* __STDC__ */ 124 | 125 | /* 42 is a "magic" number */ 126 | if (setup == 42) 127 | mode = "a"; 128 | else 129 | { 130 | if (Trace_level == 0 && (rcp = getenv("TRACE_LEVEL"))) 131 | Trace_level = atoi(rcp); 132 | if (Trace_log == NULL || *Trace_log == '\0') 133 | { 134 | if (rcp = getenv("TRACE_LOG")) 135 | Trace_log = strdup(rcp); 136 | else 137 | Trace_log = NULL; 138 | } 139 | setup = 42; 140 | mode= "w"; 141 | } 142 | if (Trace_log) 143 | fp = fopen(Trace_log, mode); 144 | else 145 | fp = stderr; 146 | if (fp != (FILE *)NULL) 147 | { 148 | vfprintf(fp, fmt, arg_ptr); 149 | fputc('\n', fp); 150 | if (fp == stderr) 151 | fflush(fp); 152 | else 153 | fclose(fp); 154 | } 155 | } 156 | 157 | #endif /* USE_TRACE */ 158 | 159 | /* This lot (for GNU-Emacs) goes at the end of the file. */ 160 | /* 161 | * Local Variables: 162 | * version-control:t 163 | * comment-column:40 164 | * End: 165 | */ 166 | -------------------------------------------------------------------------------- /sh/trace.h: -------------------------------------------------------------------------------- 1 | /* NAME: 2 | * trace.h - definitions for a simple trace facility 3 | * 4 | * SYNOPSIS: 5 | * #include "trace.h" 6 | * 7 | * DESCRIPTION: 8 | * Defines the macro _TRACE(). 9 | * Also declares Trace_log and Trace_level. 10 | * 11 | * SEE ALSO: 12 | * 13 | * 14 | * AMENDED: 15 | * 91/11/22 22:53:58 (sjg) 16 | * 17 | * RELEASED: 18 | * 91/11/22 22:54:18 v1.2 19 | * 20 | * SCCSID: 21 | * @(#)trace.h 1.2 91/11/22 22:53:58 (sjg) 22 | * 23 | * @(#)Copyright (c) 1990 Simon J. Gerraty. 24 | */ 25 | 26 | /* some useful #defines */ 27 | #ifndef EXTERN 28 | # define EXTERN extern 29 | # define EXTERN_DEFINED 30 | #endif 31 | 32 | #ifndef TRUE 33 | # define TRUE 1 34 | # define FALSE 0 35 | #endif 36 | #ifndef ARGS 37 | # if defined(__STDC__) || defined(PROTO) 38 | # define ARGS(p) p 39 | # else 40 | # define ARGS(p) () 41 | # endif 42 | #endif 43 | 44 | /* 45 | * this garbage is sometimes needed when mixing 46 | * langauges or calling conventions under DOS. 47 | */ 48 | #ifndef _CDECL 49 | # if defined(MSDOS) || defined(MSC) 50 | # ifndef NO_EXT_KEYS 51 | # define _CDECL cdecl 52 | # define _NEAR near 53 | # else 54 | # define _CDECL 55 | # define _NEAR 56 | # endif 57 | # else /* not DrOS */ 58 | # define _CDECL 59 | # define _NEAR 60 | # endif /* DOS */ 61 | #endif /* _CDECL */ 62 | 63 | /* manifest constants */ 64 | 65 | /* struct / union */ 66 | 67 | /* macros */ 68 | 69 | 70 | #ifdef USE_TRACE 71 | EXTERN char * _CDECL Trace_log; 72 | EXTERN int _CDECL Trace_level; 73 | 74 | void _CDECL checkpoint ARGS((char *fmt, ...)); 75 | 76 | /* 77 | * This macro takes a variabel number of args. 78 | * examples: 79 | * _TRACE(5, ("The current Debug level is %d\n", Debug)); 80 | * Note that if more than two args are provided, all but the 81 | * first (which should be an integer indicating the Trace-level 82 | * required for this message to be printed) must be enclosed in 83 | * parenthesis. 84 | */ 85 | # define _TRACE(lev, args) if (Trace_level >= lev) checkpoint args 86 | #else /* don't USE_TRACE */ 87 | /* 88 | * this macro evaluates to a harmless no entry 89 | * loop that most optimizers will remove all together. 90 | */ 91 | # define _TRACE(l, args) while (0) 92 | #endif /* USE_TRACE */ 93 | 94 | 95 | /* This lot goes at the END */ 96 | /* be sure not to interfere with anyone else's idea about EXTERN */ 97 | #ifdef EXTERN_DEFINED 98 | # undef EXTERN_DEFINED 99 | # undef EXTERN 100 | #endif 101 | /* 102 | * Local Variables: 103 | * version-control:t 104 | * comment-column:40 105 | * End: 106 | */ 107 | -------------------------------------------------------------------------------- /sh/trap.c: -------------------------------------------------------------------------------- 1 | /* 2 | * signal handling 3 | */ 4 | 5 | #ifndef lint 6 | static char *RCSid = "$Id: trap.c,v 1.2 1992/04/24 12:01:38 sjg Exp $"; 7 | #endif 8 | 9 | #include "stdh.h" 10 | #include 11 | #include 12 | #include 13 | #include "sh.h" 14 | 15 | Trap sigtraps [SIGNALS] = { 16 | {0, "EXIT", "Signal 0"}, /* todo: belongs in e.loc->exit */ 17 | {SIGHUP, "HUP", "Hangup"}, 18 | {SIGINT, "INT", "Interrupt"}, 19 | {SIGQUIT, "QUIT", "Quit"}, 20 | {SIGILL, "ILL", "Illegal instruction"}, 21 | {SIGTRAP, "TRAP", "Trace trap"}, 22 | #ifdef SIGABRT 23 | {SIGIOT, "ABRT", "Abort"}, 24 | #else 25 | {SIGIOT, "IOT", "IOT instruction"}, 26 | #endif 27 | //{SIGEMT, "EMT", "EMT trap"}, 28 | {SIGBUS, "BUS", "BUS trap"}, 29 | {SIGFPE, "FPE", "Floating exception"}, 30 | {SIGKILL, "KILL", "Killed"}, 31 | #ifdef _MINIX 32 | {SIGUSR1, "USR1", "User defined signal 1"}, 33 | {SIGSEGV, "SEGV", "Memory fault"}, 34 | {SIGUSR2, "USR2", "User defined signal 2"}, 35 | #else 36 | {SIGBUS, "BUS", "Bus error"}, 37 | {SIGSEGV, "SEGV", "Memory fault"}, 38 | {SIGSYS, "SYS", "Bad system call"}, 39 | #endif 40 | {SIGPIPE, "PIPE", "Broken pipe"}, 41 | {SIGALRM, "ALRM", "Alarm clock"}, 42 | {SIGTERM, "TERM", "Terminated"}, 43 | #ifdef _MINIX 44 | {SIGSTKFLT, "STKFLT", "Stack fault"}, 45 | #endif 46 | #ifdef _SYSV 47 | {SIGUSR1, "USR1", "User defined signal 1"}, 48 | {SIGUSR2, "USR2", "User defined signal 2"}, 49 | {SIGCLD, "CLD", "Death of a child"}, 50 | {SIGPWR, "PWR", "Power-fail restart"}, 51 | #ifdef JOBS /* todo: need to be more portable */ 52 | {SIGTSTP, "TSTP", "Stop"}, 53 | {SIGTTIN, "TTIN", "Stop (tty input)"}, 54 | #ifdef SIGPOLL 55 | {SIGPOLL, "POLL", "Pollable event occured"}, 56 | #endif 57 | {SIGSTOP, "STOP", "Stop (signal)"}, 58 | {SIGTTOU, "TTOU", "Stop (tty output)"}, 59 | {SIGCONT, "CONT", "Continue"}, 60 | #endif 61 | #else 62 | #ifdef JOBS /* todo: need to be more portable */ 63 | {SIGURG, "URG", "Urgent condition"}, /* BSDism */ 64 | {SIGSTOP, "STOP", "Stop (signal)"}, 65 | {SIGTSTP, "TSTP", "Stop"}, 66 | {SIGCONT, "CONT", "Continue"}, 67 | {SIGCHLD, "CHLD", "Waiting children"}, 68 | {SIGTTIN, "TTIN", "Stop (tty input)"}, 69 | {SIGTTOU, "TTOU", "Stop (tty output)"}, 70 | #endif 71 | #endif 72 | }; 73 | 74 | Trap * 75 | gettrap(name) 76 | char *name; 77 | { 78 | int i; 79 | register Trap *p; 80 | 81 | if (digit(*name)) { 82 | i = getn(name); 83 | return (0 <= i && i < SIGNALS) ? &sigtraps[getn(name)] : NULL; 84 | } 85 | #if 0 86 | if (strcmp("ERR", name) == 0) 87 | return &e.loc->err; 88 | if (strcmp("EXIT", name) == 0) 89 | return &e.loc->exit; 90 | #endif 91 | for (p = sigtraps, i = SIGNALS; --i >= 0; p++) 92 | if (p->name != NULL && strcmp(p->name, name) == 0) 93 | return p; 94 | return NULL; 95 | } 96 | 97 | /* 98 | * trap signal handler 99 | */ 100 | void 101 | trapsig(i) 102 | int i; 103 | { 104 | trap = sigtraps[i].set = 1; 105 | if (i == SIGINT && e.type == E_PARSE) 106 | /* dangerous but necessary to deal with BSD silly signals */ 107 | longjmp(e.jbuf, 1); 108 | #ifdef USE_SIGACT 109 | sigaction(i, &Sigact_trap, NULL); 110 | #else 111 | (void) signal(i, trapsig); 112 | #endif 113 | } 114 | 115 | /* 116 | * run any pending traps 117 | */ 118 | runtraps() 119 | { 120 | int i; 121 | register Trap *p; 122 | 123 | for (p = sigtraps, i = SIGNALS; --i >= 0; p++) 124 | if (p->set) 125 | runtrap(p); 126 | trap = 0; 127 | } 128 | 129 | runtrap(p) 130 | Trap *p; 131 | { 132 | char *trapstr; 133 | 134 | p->set = 0; 135 | if ((trapstr = p->trap) == NULL) 136 | if (p->signal == SIGINT) 137 | unwind(); /* return to shell() */ 138 | else 139 | return; 140 | if (p->signal == 0) /* ??? */ 141 | p->trap = 0; 142 | command(trapstr); 143 | } 144 | 145 | /* restore signals for children */ 146 | cleartraps() 147 | { 148 | int i; 149 | register Trap *p; 150 | 151 | if ((p = sigtraps)->trap != NULL) { /* Maybe put in exchild() */ 152 | afree((void *)p->trap,APERM); /* Necessary? */ 153 | p->trap = NULL; 154 | } 155 | for (i = SIGNALS, p = sigtraps; --i >= 0; p++) { 156 | p->set = 0; 157 | #ifdef USE_SIGACT 158 | if (p->ourtrap) 159 | { 160 | sigaction(p->signal, &Sigact_ign, &Sigact); 161 | if (Sigact.sa_handler != SIG_IGN) 162 | sigaction(p->signal, &Sigact_dfl, NULL); 163 | } 164 | #else 165 | if (p->ourtrap && signal(p->signal, SIG_IGN) != SIG_IGN) 166 | (void) signal(p->signal, SIG_DFL); 167 | #endif 168 | } 169 | } 170 | 171 | ignoresig(i) 172 | int i; 173 | { 174 | #ifdef USE_SIGACT 175 | sigaction(i, &Sigact_ign, &Sigact); 176 | sigemptyset(&Sigact.sa_mask); 177 | Sigact.sa_flags = 0; 178 | 179 | if (Sigact.sa_handler != SIG_IGN) 180 | sigtraps[i].sig_dfl = 1; 181 | #else 182 | if (signal(i, SIG_IGN) != SIG_IGN) 183 | sigtraps[i].sig_dfl = 1; 184 | #endif 185 | } 186 | 187 | restoresigs() 188 | { 189 | int i; 190 | register Trap *p; 191 | 192 | for (p = sigtraps, i = SIGNALS; --i >= 0; p++) 193 | if (p->sig_dfl) { 194 | p->sig_dfl = 0; 195 | #ifdef USE_SIGACT 196 | sigaction(p->signal, &Sigact_dfl, NULL); 197 | #else 198 | (void) signal(p->signal, SIG_DFL); 199 | #endif 200 | } 201 | } 202 | 203 | -------------------------------------------------------------------------------- /sh/tree.h: -------------------------------------------------------------------------------- 1 | /* 2 | * command trees for compile/execute 3 | */ 4 | 5 | /* $Id: tree.h,v 1.2 1992/04/25 08:33:28 sjg Exp $ */ 6 | 7 | #define NOBLOCK ((struct op *)NULL) 8 | #define NOWORD ((char *)NULL) 9 | #define NOWORDS ((char **)NULL) 10 | 11 | /* 12 | * Description of a command or an operation on commands. 13 | */ 14 | struct op { 15 | int type; /* operation type, see below */ 16 | char **args; /* arguments to a command */ 17 | char **vars; /* variable assignments */ 18 | struct ioword **ioact; /* IO actions (eg, < > >>) */ 19 | struct op *left, *right; /* descendents */ 20 | char *str; /* identifier for case and for (use vars[0]) */ 21 | }; 22 | 23 | /* Tree.type values */ 24 | #define TEOF 0 25 | #define TCOM 1 /* command */ 26 | #define TPAREN 2 /* (c-list) */ 27 | #define TPIPE 3 /* a | b */ 28 | #define TLIST 4 /* a [&;] b */ 29 | #define TOR 5 /* || */ 30 | #define TAND 6 /* && */ 31 | #define TFOR 7 32 | #define TCASE 9 33 | #define TIF 10 34 | #define TWHILE 11 35 | #define TUNTIL 12 36 | #define TELIF 13 37 | #define TPAT 14 /* pattern in case */ 38 | #define TBRACE 15 /* {c-list} */ 39 | #define TASYNC 16 /* c & */ 40 | #define TFUNCT 17 /* function name { command; } */ 41 | #define TTIME 18 /* time pipeline */ 42 | #define TEXEC 19 /* fork/exec eval'd TCOM */ 43 | 44 | /* 45 | * prefix codes for words in command tree 46 | */ 47 | #define EOS 0 /* end of string */ 48 | #define CHAR 1 /* unquoted character */ 49 | #define QCHAR 2 /* quoted character */ 50 | #define COMSUB 3 /* $() substitution (0 terminated) */ 51 | #define OQUOTE 4 /* opening " or ' */ 52 | #define CQUOTE 5 /* closing " or ' */ 53 | #define OSUBST 6 /* opening ${ substitution */ 54 | #define CSUBST 7 /* closing } of above */ 55 | 56 | /* 57 | * IO redirection 58 | */ 59 | struct ioword { 60 | int unit; /* unit affected */ 61 | int flag; /* action (below) */ 62 | char *name; /* file name */ 63 | }; 64 | 65 | /* ioword.flag - type of redirection */ 66 | #define IOTYPE 0xF /* type: bits 0:3 */ 67 | #define IOREAD 0x1 /* < */ 68 | #define IOWRITE 0x2 /* > */ 69 | #define IORDWR 0x3 /* <>: todo */ 70 | #define IOHERE 0x4 /* << (here file) */ 71 | #define IOCAT 0x5 /* >> */ 72 | #define IODUP 0x6 /* <&/>& */ 73 | #define IOEVAL BIT(4) /* expand in << */ 74 | #define IOSKIP BIT(5) /* <<-, skip ^\t* */ 75 | #define IOCLOB BIT(6) /* >!, override -o noclob */ 76 | 77 | /* values for E_LOOP longjmp */ 78 | #define LBREAK 1 79 | #define LCONTIN 2 80 | 81 | /* execute/exchild flags */ 82 | #define XEXEC BIT(0) /* execute without forking */ 83 | #define XFORK BIT(5) /* fork before executing */ 84 | #define XBGND BIT(1) /* command & */ 85 | #define XPIPEI BIT(2) /* input is pipe */ 86 | #define XPIPEO BIT(3) /* output is pipe */ 87 | #define XPIPE (XPIPEI|XPIPEO) /* member of pipe */ 88 | #define XXCOM BIT(4) /* dup2 xcomfd to 1 */ 89 | 90 | /* 91 | * flags to control expansion of words 92 | */ 93 | #define DOBLANK BIT(1) /* perform blank interpretation */ 94 | #define DOGLOB BIT(2) /* expand [?* */ 95 | #define DOPAT BIT(3) /* quote *?[ */ 96 | #define DOTILDE BIT(5) /* expand ~ */ 97 | 98 | #if 0 99 | /* job.c: job control primatives */ 100 | int execute ARGS((struct op *, int flags)); /* execute tree */ 101 | int exchild ARGS((struct op *, int flags)); /* execute tree as child */ 102 | int waitfor ARGS((int job)); /* wait for job completion */ 103 | int waitlast ARGS((void)); /* wait for last job */ 104 | 105 | /* eval.c: word expansion */ 106 | char **eval ARGS((char **wv, int flag)); /* expand words */ 107 | char *evalstr ARGS((char *wp, int flags)); /* expand word */ 108 | char *substitute ARGS((const char *s, int flags)); /* compile and expand string */ 109 | 110 | /* tree.c: command trees */ 111 | void ptree ARGS((struct op *t, FILE *f)); /* print tree */ 112 | char *wdscan ARGS((char *wp, int c)); /* scan word for prefix */ 113 | char *wdcopy ARGS((char *wp, Area *)); /* copy word */ 114 | struct op *tcopy ARGS((struct op *t, Area *)); /* copy tree */ 115 | void tfree ARGS((struct op *t, Area *)); /* free tree */ 116 | #endif 117 | -------------------------------------------------------------------------------- /sh/tty.h: -------------------------------------------------------------------------------- 1 | /* 2 | tty.h -- centralized definitions for a variety of terminal interfaces 3 | 4 | created by DPK, Oct. 1986 5 | 6 | last edit: 30-Jul-1987 D A Gwyn 7 | */ 8 | 9 | #if _BSD_SYSV /* BRL UNIX System V emulation */ 10 | #include /* includes */ 11 | #ifndef NTTYDISC 12 | #define TIOCGETD _IOR( 't', 0, int ) 13 | #define TIOCSETD _IOW( 't', 1, int ) 14 | #define NTTYDISC 2 15 | #endif 16 | #ifndef TIOCSTI 17 | #define TIOCSTI _IOW( 't', 114, char ) 18 | #endif 19 | #ifndef TIOCSPGRP 20 | #define TIOCSPGRP _IOW( 't', 118, int ) 21 | #endif 22 | #else /* !_BSD_SYSV */ 23 | #if _BSD 24 | #ifdef _MINIX 25 | #include 26 | #define TIOCSETN TIOCSETP 27 | #else 28 | #include 29 | #endif 30 | #else 31 | #ifdef mips 32 | #include 33 | #else 34 | #include 35 | #endif 36 | #endif 37 | #endif /* _BSD_SYSV */ 38 | -------------------------------------------------------------------------------- /sh/version.c: -------------------------------------------------------------------------------- 1 | /* 2 | * value of $KSH_VERSION 3 | */ 4 | 5 | #ifndef lint 6 | static char *RCSid = "$Id: version.c,v 1.4 1992/05/12 09:30:37 sjg Exp $"; 7 | #endif 8 | 9 | #include "stdh.h" 10 | #include 11 | #include "sh.h" 12 | #include "patchlevel.h" 13 | 14 | char ksh_version [] = 15 | "KSH_VERSION=@(#)PD KSH v4.5 92/05/12"; 16 | 17 | /*** 18 | $Log: version.c,v $ 19 | * Revision 1.4 1992/05/12 09:30:37 sjg 20 | * see ChangeLog 21 | * 22 | * Revision 1.3 1992/05/03 08:29:20 sjg 23 | * Update for Patch05 24 | * 25 | * Revision 1.2 1992/04/25 08:33:28 sjg 26 | * Added RCS key. 27 | * 28 | * Revision 1.1 1992/04/18 05:51:48 sjg 29 | * Initial revision 30 | * 31 | Version 4.0 91/11/09 sjg 32 | distribution 33 | Revision 3.3 89/03/27 15:52:29 egisin 34 | distribution 35 | 36 | Revision 3.2 88/12/14 20:10:41 egisin 37 | many fixes 38 | 39 | Revision 3.1 88/11/03 09:18:36 egisin 40 | alpha distribution 41 | 42 | Revision 1.3 88/10/20 17:34:03 egisin 43 | added @(#) to ksh_version 44 | 45 | Revision 1.2 88/09/27 19:01:58 egisin 46 | fix version.c 47 | 48 | Revision 1.1 88/09/27 18:59:06 egisin 49 | Initial revision 50 | ***/ 51 | 52 | -------------------------------------------------------------------------------- /std/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Makefile for the compatibility libraries 3 | # 4 | # $Id: Makefile,v 1.2 1992/04/25 08:18:26 sjg Exp $ 5 | # 6 | 7 | SHELL = /bin/sh 8 | MAKE = make 9 | 10 | #CONFIG = -D_SYSV 11 | CONFIG = -D_BSD 12 | 13 | LN = ln 14 | 15 | libs: h libstdc.a libposix.a 16 | 17 | h: 18 | mkdir h 19 | ( cd stdc ; $(MAKE) 'CC=$(CC)' 'CONFIG=$(CONFIG)' 'LN=$(LN)' clobber link ) 20 | ( cd posix ; $(MAKE) 'CC=$(CC)' 'CONFIG=$(CONFIG)' 'LN=$(LN)' clobber link ) 21 | ( cd ../sh ; $(MAKE) 'CC=$(CC)' 'CONFIG=$(CONFIG)' 'LN=$(LN)' link ) 22 | 23 | libstdc.a: FORCED 24 | ( cd stdc ; $(MAKE) 'CC=$(CC)' 'CONFIG=$(CONFIG)' all ) 25 | 26 | libposix.a: FORCED 27 | ( cd posix ; $(MAKE) 'CC=$(CC)' 'CONFIG=$(CONFIG)' all ) 28 | 29 | clean: 30 | -rm -f *.out 31 | ( cd stdc ; $(MAKE) 'CC=$(CC)' 'CONFIG=$(CONFIG)' $@ ) 32 | ( cd posix ; $(MAKE) 'CC=$(CC)' 'CONFIG=$(CONFIG)' $@ ) 33 | 34 | clobber: 35 | -rm -rf h *.a 36 | ( cd stdc ; $(MAKE) 'CC=$(CC)' 'CONFIG=$(CONFIG)' $@ ) 37 | ( cd posix ; $(MAKE) 'CC=$(CC)' 'CONFIG=$(CONFIG)' $@ ) 38 | 39 | FORCED: 40 | -------------------------------------------------------------------------------- /std/mklinks: -------------------------------------------------------------------------------- 1 | : 2 | # Make links 3 | # we do it this way so that we can support symlinks 4 | # easily. 5 | 6 | src=`pwd` 7 | cd $1 8 | shift 9 | LN="${LN:-ln}" 10 | 11 | for f in $* 12 | do 13 | $LN $src/$f . 14 | done 15 | -------------------------------------------------------------------------------- /std/posix/ChangeLog: -------------------------------------------------------------------------------- 1 | Sat Apr 25 14:51:33 1992 Simon J. Gerraty (sjg@zen) 2 | 3 | * Added RCS keys to sources. 4 | 5 | Mon Nov 25 13:17:04 1991 Simon J. Gerraty (sjg at zen) 6 | 7 | * wait.h: use "/./usr/include/sys/wait.h for sun's 8 | 9 | -------------------------------------------------------------------------------- /std/posix/Makefile: -------------------------------------------------------------------------------- 1 | # POSIX P1003.1 compatability 2 | # $Id: Makefile,v 1.2 1992/04/25 08:22:14 sjg Exp $ 3 | 4 | SHELL = /bin/sh 5 | MAKE = make 6 | 7 | #CONFIG = -D_SYSV 8 | CONFIG = -D_BSD 9 | 10 | LN = ln 11 | RANLIB = ranlib # For BSD systems 12 | #RANLIB = echo Updated 13 | 14 | LIB = ../libposix.a 15 | INCL = ../h 16 | 17 | CFLAGS = $(CCOPTS) -I$(INCL) $(CONFIG) 18 | 19 | MISC = Makefile 20 | HDRS = io.h unistd.h fcntl.h dirent.h 21 | SYSHDRS = wait.h time.h times.h 22 | 23 | SRCS = unistd.c fcntl.c times.c dup2.c 24 | OBJS = $(LIB)(unistd.o) \ 25 | $(LIB)(fcntl.o) \ 26 | $(LIB)(times.o) \ 27 | $(LIB)(dup2.o) 28 | 29 | all: $(LIB) 30 | 31 | link: $(HDRS) 32 | [ -d $(INCL) ] || mkdir $(INCL) 33 | [ -d $(INCL)/sys ] || mkdir $(INCL)/sys 34 | ($(SHELL) ../mklinks $(INCL) $(HDRS)) 35 | ($(SHELL) ../mklinks $(INCL)/sys $(SYSHDRS)) 36 | -if [ -r /usr/include/unistd.h ]; then $(RM) $(INCL)/unistd.h; fi 37 | 38 | $(LIB): $(OBJS) 39 | # if you make doesn't know how to put objects in libraries 40 | # then simply make all the .o's and use the following line 41 | # ar r $@ $? 42 | $(RANLIB) $@ 43 | 44 | clean: 45 | -rm -f *.o *.out 46 | 47 | clobber: clean 48 | -rm -f $(LIB) 49 | 50 | fcntl.o: fcntl.h 51 | 52 | times.o: times.h 53 | -------------------------------------------------------------------------------- /std/posix/dirent.C: -------------------------------------------------------------------------------- 1 | /* 2 | * simple implementation of directory(3) routines for V7 and Minix. 3 | * completly untested. not designed to be efficient. 4 | * missing telldir and seekdir. 5 | */ 6 | /* $Id: dirent.C,v 1.2 1992/04/25 08:22:14 sjg Exp $ */ 7 | 8 | #include 9 | #include 10 | 11 | char *malloc(); 12 | 13 | #define DIRSIZ 14 14 | struct direct_v7 15 | { 16 | unsigned short d_ino; 17 | char d_name[DIRSIZ]; 18 | }; 19 | 20 | DIR *opendir(filename) 21 | char *filename; 22 | { 23 | DIR *dirp; 24 | 25 | dirp = (DIR *) malloc(sizeof(DIR)); 26 | if (dirp == NULL) 27 | return NULL; 28 | dirp->fd = open(filename, 0); 29 | if (dirp->fd < 0) { 30 | free((char *) dirp); 31 | return NULL; 32 | } 33 | return dirp; 34 | } 35 | 36 | struct dirent *readdir(dirp) 37 | register DIR *dirp; 38 | { 39 | static struct direct_v7 ent; 40 | 41 | while (read(dirp->fd, (char *)&ent, (int)sizeof(ent)) == sizeof(ent)) 42 | if (ent.d_ino != 0) 43 | goto found; 44 | return (struct dirent *) NULL; 45 | found: 46 | dirp->ent.d_ino = ent.d_ino; 47 | strncpy(dirp->ent.d_name, ent.d_name, DIRSIZ); 48 | return &dirp->ent; 49 | } 50 | 51 | void rewinddir(dirp) 52 | DIR *dirp; 53 | { 54 | lseek(dirp->fd, 0L, 0); 55 | } 56 | 57 | closedir(dirp) 58 | DIR *dirp; 59 | { 60 | close(dirp->fd); 61 | dirp->fd = -1; 62 | free((char *) dirp); 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /std/posix/dirent.H: -------------------------------------------------------------------------------- 1 | /* 2 | -- file system independent directory entry (SVR3) 3 | 4 | last edit: 25-Apr-1987 D A Gwyn 5 | last hack: 14-Aug-1987 Eric Gisin 6 | 7 | prerequisite: 8 | */ 9 | /* $Id: dirent.H,v 1.2 1992/04/25 08:22:14 sjg Exp $ */ 10 | 11 | #define MAXNAMLEN 16 /* maximum filename length */ 12 | 13 | struct dirent /* data from getdents()/readdir() */ 14 | { 15 | long d_ino; /* inode number of entry */ 16 | off_t d_off; /* offset of disk directory entry */ 17 | unsigned short d_reclen; /* length of this record */ 18 | char d_name[MAXNAMLEN]; /* name of file */ 19 | }; 20 | 21 | #ifndef NAME_MAX 22 | #define NAME_MAX (MAXNAMLEN - 1) /* DAG -- added for POSIX */ 23 | #endif 24 | 25 | typedef struct { /* returned by opendir() */ 26 | int fd; 27 | struct dirent ent; 28 | } DIR; 29 | 30 | extern DIR *opendir(); 31 | extern struct dirent *readdir(); 32 | extern off_t telldir(); 33 | extern void seekdir(); 34 | extern void rewinddir(); 35 | extern int closedir(); 36 | 37 | #ifndef NULL 38 | #define NULL 0 /* DAG -- added for convenience */ 39 | #endif 40 | -------------------------------------------------------------------------------- /std/posix/dirent.h: -------------------------------------------------------------------------------- 1 | /* based on BSD */ 2 | 3 | #include 4 | #define dirent direct 5 | 6 | -------------------------------------------------------------------------------- /std/posix/dup2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Cheap imitation of BSD dup2() 3 | */ 4 | /* $Id: dup2.c,v 1.2 1992/04/25 08:22:14 sjg Exp $ */ 5 | 6 | #include 7 | 8 | #if _SYSV 9 | int 10 | dup2( oldd, newd ) 11 | int oldd, newd; 12 | { 13 | int fd; 14 | 15 | if (fcntl( oldd, F_GETFL, 0 ) < 0) 16 | return( -1 ); 17 | 18 | (void) close( newd ); 19 | fd = fcntl( oldd, F_DUPFD, newd ); 20 | 21 | return( (fd > newd) ? -1 : fd ); 22 | } 23 | #endif 24 | -------------------------------------------------------------------------------- /std/posix/fcntl.c: -------------------------------------------------------------------------------- 1 | /* fcntl emulation */ 2 | /* $Id: fcntl.c,v 1.2 1992/04/25 08:22:14 sjg Exp $ */ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #if _V7 10 | 11 | #include 12 | 13 | int 14 | fcntl(fd, cmd, arg) 15 | int fd, cmd, arg; 16 | { 17 | switch (cmd) { 18 | case F_SETFD: /* set fd flags */ 19 | ioctl(fd, (arg&FD_CLEXEC) ? FIOCLEX : FIONCLEX, (char *)NULL); 20 | break; 21 | case F_DUPFD: /* dup fd */ 22 | /* this one is fun. find an unused fd >= arg and dup2 */ 23 | break; 24 | } 25 | return 0; 26 | } 27 | 28 | #endif 29 | 30 | -------------------------------------------------------------------------------- /std/posix/fcntl.h: -------------------------------------------------------------------------------- 1 | /* P1003.1 fcntl/open definitions */ 2 | /* Based on a version by Terrence W. Holm */ 3 | /* for fcntl(2) */ 4 | /* $Id: fcntl.h,v 1.2 1992/04/25 08:22:14 sjg Exp $ */ 5 | 6 | #define F_DUPFD 0 7 | #define F_GETFD 1 8 | #define F_SETFD 2 9 | #define F_GETFL 3 10 | #define F_SETFL 4 11 | 12 | #define FD_CLEXEC 1 /* fcntl F_SETFD close on exec mode */ 13 | 14 | /* for open(2) */ 15 | 16 | #define O_RDONLY 0 17 | #define O_WRONLY 1 18 | #define O_RDWR 2 19 | 20 | #if _BSD 21 | #undef O_RDONLY 22 | #undef O_WRONLY 23 | #undef O_RDWR 24 | #include "/./usr/include/fcntl.h" 25 | #endif 26 | 27 | -------------------------------------------------------------------------------- /std/posix/fixincludes: -------------------------------------------------------------------------------- 1 | # Install modified versions of certain ANSI-incompatible system header files 2 | # which are fixed to work correctly with ANSI C 3 | # and placed in a directory that GNU C will search. 4 | # This works properly on a Sun in system version 3.4; 5 | # for other versions, you had better check. 6 | 7 | mkdir /usr/local/lib/gcc-include 8 | mkdir /usr/local/lib/gcc-include/sys 9 | cp /usr/include/sys/ioctl.h /usr/local/lib/gcc-include/sys/ioctl.h 10 | chmod +w /usr/local/lib/gcc-include/sys/ioctl.h 11 | ex /usr/local/lib/gcc-include/sys/ioctl.h <<\EOF 12 | g/_IO/s/(\(.\),/('\1',/ 13 | g/#define._IO/s/'x'/x/g 14 | wq 15 | EOF 16 | 17 | cp /usr/include/sys/ttychars.h /usr/local/lib/gcc-include/sys/ttychars.h 18 | chmod +w /usr/local/lib/gcc-include/sys/ttychars.h 19 | ex /usr/local/lib/gcc-include/sys/ttychars.h <<\EOF 20 | g/CTRL/s/(\(.\))/('\1')/ 21 | g/#define.CTRL/s/'c'/c/g 22 | wq 23 | EOF 24 | -------------------------------------------------------------------------------- /std/posix/io.h: -------------------------------------------------------------------------------- 1 | /* POSIX IO functions */ 2 | /* $Id: io.h,v 1.2 1992/04/25 08:22:14 sjg Exp $ */ 3 | 4 | /* 5 | * the incomplete type "struct stat" 6 | * will get warnings from GCC, 7 | * errors from Turbo C. Too bad. 8 | */ 9 | 10 | /* include to get this */ 11 | 12 | #if ! _IO_H 13 | #define _IO_H 1 14 | 15 | #include 16 | 17 | #if _ST /* dLibs hack */ 18 | #define unlink remove 19 | #endif 20 | 21 | struct stat; /* create global incompletely-typed structure */ 22 | 23 | int chdir ARGS ((const char *path)); 24 | #ifndef sparc 25 | int umask ARGS ((int mode)); 26 | #endif 27 | 28 | int open ARGS ((const char *path, int flags, ... /*mode*/)); 29 | int creat ARGS ((const char *path, int mode)); 30 | int pipe ARGS ((int pv[2])); 31 | int close ARGS ((int fd)); 32 | 33 | int fcntl ARGS ((int fd, int cmd, int arg)); 34 | int dup ARGS ((int fd)); 35 | int dup2 ARGS ((int ofd, int nfd)); 36 | 37 | int link ARGS ((const char *opath, const char *npath)); 38 | int unlink ARGS ((const char *path)); 39 | int rename ARGS ((const char *opath, const char *npath)); 40 | int mkdir ARGS ((const char *path, int mode)); 41 | 42 | long lseek ARGS ((int fd, long off, int how)); 43 | int read ARGS ((int fd, char *buf, unsigned len)); 44 | int write ARGS ((int fd, char *buf, unsigned len)); 45 | 46 | int access ARGS ((const char *path, int mode)); 47 | int stat ARGS ((const char *path, struct stat *sp)); 48 | int fstat ARGS ((int fd, struct stat *sp)); 49 | 50 | int chmod ARGS ((const char *path, int mode)); 51 | int chown ARGS ((const char *path, int uid)); 52 | int chgrp ARGS ((const char *path, int gid)); 53 | int utime ARGS ((const char *path, long tv[2])); 54 | 55 | #if _BSD || _V7 56 | int ioctl ARGS ((int fd, int cmd, void *argp)); /* BSD is "uns long cmd" */ 57 | #endif 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /std/posix/time.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Replacement for BSD 3 | * because Ultrix screws it up. 4 | */ 5 | /* $Id: time.h,v 1.2 1992/04/25 08:22:14 sjg Exp $ */ 6 | 7 | // struct timeval { 8 | // long tv_sec; #<{(| time_t |)}># 9 | // long tv_usec; #<{(| microsex |)}># 10 | // }; 11 | 12 | struct timezone { 13 | int tz_minuteswest; /* of Greenwinch */ 14 | int tz_dsttime; /* type of dst correction to apply */ 15 | }; 16 | -------------------------------------------------------------------------------- /std/posix/times.c: -------------------------------------------------------------------------------- 1 | /* P1003.1 times emulation */ 2 | /* $Id: times.c,v 1.2 1992/04/25 08:22:14 sjg Exp $ */ 3 | 4 | #include 5 | 6 | #if _BSD 7 | 8 | #include 9 | #include 10 | 11 | static long base_tv_sec = 0; 12 | 13 | clock_t 14 | times(tmsp) 15 | register struct tms *tmsp; 16 | { 17 | struct timeval tv; 18 | struct rusage ru; 19 | 20 | getrusage(RUSAGE_SELF, &ru); 21 | tmsp->tms_utime = ru.ru_utime.tv_sec*CLK_TCK 22 | + (long)ru.ru_utime.tv_usec*CLK_TCK/1000000; 23 | tmsp->tms_stime = ru.ru_stime.tv_sec*CLK_TCK 24 | + (long)ru.ru_stime.tv_usec*CLK_TCK/1000000; 25 | getrusage(RUSAGE_CHILDREN, &ru); 26 | tmsp->tms_cutime = ru.ru_utime.tv_sec*CLK_TCK 27 | + (long)ru.ru_utime.tv_usec*CLK_TCK/1000000; 28 | tmsp->tms_cstime = ru.ru_stime.tv_sec*CLK_TCK 29 | + (long)ru.ru_stime.tv_usec*CLK_TCK/1000000; 30 | 31 | gettimeofday(&tv, (struct timezone *)NULL); 32 | if (base_tv_sec == 0) 33 | base_tv_sec = tv.tv_sec; 34 | tv.tv_sec -= base_tv_sec; /* prevent clock_t overflow */ 35 | return tv.tv_sec*CLK_TCK + (long)tv.tv_usec*CLK_TCK/1000000; 36 | } 37 | 38 | #endif 39 | 40 | #if _V7 41 | 42 | clock_t 43 | times(tmsp) 44 | struct tms *tmsp; 45 | { 46 | struct timeb tb; 47 | 48 | #undef times /* access real times() */ 49 | times(tmsp); 50 | #define times times_ 51 | ftime(&tb); 52 | return tb.time*CLK_TCK + (long)tb.millitm*CLK_TCK/1000; 53 | } 54 | 55 | #endif 56 | 57 | -------------------------------------------------------------------------------- /std/posix/times.h: -------------------------------------------------------------------------------- 1 | /* 2 | * sys/times.h: POSIX times() 3 | */ 4 | /* $Id: times.h,v 1.2 1992/04/25 08:22:14 sjg Exp $ */ 5 | 6 | #if ! _TIMES_H 7 | #define _TIMES_H 1 8 | 9 | #include /* defines CLK_TCK */ 10 | 11 | #if __STDC__ 12 | #define ARGS(args) args 13 | #else 14 | #define ARGS(args) () 15 | #endif 16 | 17 | struct tms { 18 | clock_t tms_utime, tms_stime; 19 | clock_t tms_cutime, tms_cstime; 20 | }; 21 | 22 | #if _V7 23 | #define times times_ 24 | #endif 25 | 26 | clock_t times ARGS((struct tms *tmsp)); 27 | 28 | #endif 29 | 30 | -------------------------------------------------------------------------------- /std/posix/unistd.c: -------------------------------------------------------------------------------- 1 | /* misc. POSIX emulation */ 2 | 3 | #ifndef lint 4 | static char *RCSid = "$Id: unistd.c,v 1.2 1992/04/25 08:22:14 sjg Exp $"; 5 | #endif 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #if _V7 || _BSD 13 | 14 | char * 15 | getcwd(buf, len) 16 | char *buf; 17 | size_t len; 18 | { 19 | char cwd [1024]; 20 | extern char *getwd(); 21 | if (getwd(cwd) == NULL) 22 | return NULL; 23 | if (strlen(cwd)+1 >= len) { 24 | errno = ERANGE; 25 | return NULL; 26 | } 27 | return strcpy(buf, cwd); 28 | } 29 | 30 | #endif 31 | 32 | #if _V7 33 | 34 | long 35 | ulimit(cmd, limit) 36 | int cmd; 37 | long limit; 38 | { 39 | return 0; 40 | } 41 | 42 | #endif 43 | 44 | -------------------------------------------------------------------------------- /std/posix/unistd.h: -------------------------------------------------------------------------------- 1 | /* unistd.h: misc. P1003.1 definitions */ 2 | /* Based on a version by Terrence W. Holm */ 3 | /* $Id: unistd.h,v 1.2 1992/04/25 08:22:14 sjg Exp $ */ 4 | 5 | #if ! _UNISTD_H 6 | #define _UNISTD_H 1 7 | 8 | #include 9 | 10 | /* doesn't really belong here, but the library function need it */ 11 | /* todo: use _ARGS, _void, _const */ 12 | #if __STDC__ 13 | #define ARGS(args) args 14 | #define void void 15 | #define const const 16 | #else 17 | #define ARGS(args) () 18 | #define void char 19 | #define const 20 | #endif 21 | 22 | #include /* POSIX IO functions */ 23 | 24 | /* for access(2) */ 25 | 26 | #define R_OK 4 27 | #define W_OK 2 28 | #define X_OK 1 29 | #define F_OK 0 30 | 31 | /* for lockf(2) */ 32 | 33 | #define F_ULOCK 0 34 | #define F_LOCK 1 35 | #define F_TLOCK 2 36 | #define F_TEST 3 37 | 38 | /* for lseek(2) */ 39 | 40 | #define SEEK_SET 0 41 | #define SEEK_CUR 1 42 | #define SEEK_END 2 43 | 44 | #define IN_PATH "/usr/include" 45 | 46 | char *getcwd ARGS ((char *buf, size_t len)); 47 | 48 | #endif 49 | 50 | -------------------------------------------------------------------------------- /std/posix/wait.h: -------------------------------------------------------------------------------- 1 | /* 2 | * POSIX 3 | */ 4 | /* $Id: wait.h,v 1.2 1992/04/25 08:22:14 sjg Exp $ */ 5 | #if __STDC__ 6 | #define ARGS(args) args 7 | #else 8 | #define ARGS(args) () 9 | #endif 10 | 11 | #ifdef HAVE_SYS_STDTYPES 12 | # include 13 | #else 14 | # ifndef _PID_T 15 | # define _PID_T 16 | typedef int pid_t; /* belong in sys/types.h */ 17 | # endif 18 | #endif 19 | 20 | #ifdef sun 21 | # include "/./usr/include/sys/wait.h" 22 | #else 23 | 24 | #define WAIT_T int 25 | 26 | /* waitpid options */ 27 | #define WNOHANG 1 /* don't hang in wait */ 28 | #define WUNTRACED 2 /* tell about stopped, untraced children */ 29 | 30 | #define WSTOPPED 0x7F /* process is stopped */ 31 | 32 | #define WIFSTOPPED(x) (((x)&0xFF) == 0x7F) 33 | #define WIFSIGNALED(x) (((x)&0xFF) != 0x7F && ((x)&0x7F) != 0) 34 | #define WIFEXITED(x) (((x)&0xFF) != 0x7F && ((x)&0x7F) == 0) 35 | #define WIFCORED(x) (!!((x)&0x80)) /* non-standard */ 36 | #define WEXITSTATUS(x) ((x)>>8&0xFF) 37 | #define WTERMSIG(x) ((x)&0x7F) 38 | #define WSTOPSIG(x) ((x)>>8&0xFF) 39 | 40 | pid_t wait ARGS((int *statp)); 41 | #if _BSD 42 | pid_t wait3 ARGS((int *statp, int options, void *)); 43 | /* todo: does not emulate pid argument */ 44 | #define waitpid(pid, sp, opts) wait3(sp, opts, (void*)NULL) 45 | #else 46 | pid_t waitpid ARGS((pid_t pid, int *statp, int options)); 47 | #endif 48 | 49 | #endif /* sparc */ 50 | -------------------------------------------------------------------------------- /std/stdc/ChangeLog: -------------------------------------------------------------------------------- 1 | Thu May 7 20:36:40 1992 Simon J. Gerraty (sjg@zen) 2 | 3 | * fprintf.c: avoid use of #if __STDC__ some compilers don't handle it. 4 | 5 | * vprintf.c: avoid side effects from putc() macro! 6 | 7 | Sat Apr 25 14:52:01 1992 Simon J. Gerraty (sjg@zen) 8 | 9 | * Added RCS keys to sources. 10 | 11 | Mon Nov 25 13:19:01 1991 Simon J. Gerraty (sjg at zen) 12 | 13 | * Added all source modules to Makefile, but most remain commented 14 | out as they are untested. 15 | 16 | -------------------------------------------------------------------------------- /std/stdc/Makefile: -------------------------------------------------------------------------------- 1 | # Standard C (ANSI) compatabilaty 2 | # $Id: Makefile,v 1.3 1992/05/03 08:30:08 sjg Exp $ 3 | 4 | # edit this makefile such that only the functions that 5 | # your systems doesn't have are provided. 6 | 7 | SHELL = /bin/sh 8 | MAKE = make 9 | 10 | #CONFIG = -D_SYSV 11 | CONFIG = -D_BSD 12 | 13 | LN = ln 14 | RANLIB = ranlib # For BSD systems 15 | #RANLIB = echo Updated 16 | 17 | LIB = ../libstdc.a 18 | INCL = ../h 19 | 20 | CFLAGS = $(CCOPTS) -I$(INCL) $(CONFIG) 21 | 22 | MISC = Makefile #stdio.h_std 23 | HDRS = limits.h stddef.h stdlib.h string.h time.h #stdarg.h 24 | SYSHDRS = types.h 25 | 26 | SRCS = strstr.c memmove.c stdio.c clock.c fprintf.c memchr.c \ 27 | memcmp.c memcpy.c memset.c setvbuf.c sprintf.c \ 28 | stdio.c strcat.c strchr.c strcmp.c strcpy.c strcspn.c \ 29 | strerror.c strlen.c strncat.c strncmp.c strncpy.c \ 30 | strpbrk.c strrchr.c strspn.c strtok.c vprintf.c 31 | 32 | # only add to this list the modules that you _need_ 33 | # some of these are untested! 34 | OBJS = $(LIB)(strstr.o) \ 35 | $(LIB)(memmove.o) \ 36 | $(LIB)(clock.o) \ 37 | # $(LIB)(vprintf.o) \ 38 | # $(LIB)(fprintf.o) \ 39 | # $(LIB)(sprintf.o) \ 40 | # $(LIB)(strtok.o) \ 41 | # $(LIB)(memchr.o) \ 42 | # $(LIB)(memcmp.o) \ 43 | # $(LIB)(memcpy.o) \ 44 | # $(LIB)(memset.o) \ 45 | # $(LIB)(setvbuf.o) \ 46 | # $(LIB)(strcat.o) \ 47 | # $(LIB)(strchr.o) \ 48 | # $(LIB)(strcmp.o) \ 49 | # $(LIB)(strcpy.o) \ 50 | # $(LIB)(strcspn.o) \ 51 | # $(LIB)(strerror.o) \ 52 | # $(LIB)(strlen.o) \ 53 | # $(LIB)(strncat.o) \ 54 | # $(LIB)(strncmp.o) \ 55 | # $(LIB)(strncpy.o) \ 56 | # $(LIB)(strpbrk.o) \ 57 | # $(LIB)(strrchr.o) \ 58 | # $(LIB)(strspn.o) \ 59 | # $(LIB)(stdio.o) 60 | # 61 | 62 | 63 | 64 | all: $(LIB) 65 | 66 | link: $(HDRS) #stdio.h 67 | [ -d $(INCL) ] || mkdir $(INCL) 68 | [ -d $(INCL)/sys ] || mkdir $(INCL)/sys 69 | ($(SHELL) ../mklinks $(INCL) $(HDRS)) 70 | ($(SHELL) ../mklinks $(INCL)/sys $(SYSHDRS)) 71 | # ($(SHELL) ../mklinks $(INCL) stdio.h) 72 | 73 | $(LIB): $(OBJS) 74 | # if you make doesn't know how to put objects in libraries 75 | # then simply make all the .o's and use the following line 76 | # ar r $@ $? 77 | $(RANLIB) $@ 78 | 79 | stdio.h: stdio.h_std stdio.sed /usr/include/stdio.h 80 | sed -f stdio.sed stdio.hacked 81 | sed stdio.h -e '/%%%/ r stdio.hacked' 82 | rm stdio.hacked 83 | 84 | clean: 85 | -rm -f *.o *.out stdio.hacked 86 | 87 | clobber: clean 88 | -rm -f $(LIB) stdio.h 89 | 90 | string.h: stddef.h 91 | 92 | stdlib.h: stddef.h 93 | 94 | stdio.h: stddef.h 95 | 96 | time.h: stddef.h 97 | 98 | stdio.o: stdio.h 99 | 100 | setvbuf.o: stdlib.h stdio.h 101 | 102 | fprintf.o: stdarg.h stdio.h 103 | 104 | sprintf.o: stdarg.h stdio.h 105 | 106 | vprintf.o: stdarg.h stdio.h 107 | 108 | strstr.o: string.h 109 | 110 | -------------------------------------------------------------------------------- /std/stdc/clock.c: -------------------------------------------------------------------------------- 1 | /* clock() */ 2 | 3 | #include 4 | 5 | #if _BSD 6 | 7 | #include 8 | #include 9 | 10 | clock_t 11 | clock() 12 | { 13 | struct timeval tv; 14 | struct rusage ru; 15 | 16 | getrusage(RUSAGE_SELF, &ru); 17 | tv.tv_sec = ru.ru_utime.tv_sec + ru.ru_stime.tv_sec; 18 | tv.tv_usec = ru.ru_utime.tv_usec + ru.ru_stime.tv_usec; 19 | return tv.tv_sec*CLK_TCK + (long)tv.tv_usec*CLK_TCK/1000000; 20 | } 21 | 22 | #endif 23 | 24 | #if _V7 || _SYSV 25 | 26 | #include 27 | 28 | clock_t 29 | clock() 30 | { 31 | struct tms tms; 32 | 33 | (void) times(&tms); 34 | return tms.tms_utime + tms.tms_stime; 35 | } 36 | 37 | #endif 38 | 39 | #if _ST 40 | 41 | #include 42 | 43 | clock_t 44 | clock() 45 | { 46 | long save; 47 | clock_t c; 48 | 49 | /* access the ST's 200 HZ system clock in protected memory */ 50 | save = Super(0L); 51 | c = *((long *)0x04BA); 52 | (void)Super(save); 53 | return c; 54 | } 55 | 56 | #endif 57 | 58 | -------------------------------------------------------------------------------- /std/stdc/fprintf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * printf and fprintf 3 | */ 4 | 5 | /* $Id: fprintf.c,v 1.3 1992/05/12 09:30:58 sjg Exp $ */ 6 | 7 | #ifdef __STDC__ 8 | #include 9 | #else 10 | #include 11 | #endif 12 | #include 13 | 14 | #if _V7 || _BSD 15 | 16 | /* printf to stdout */ 17 | int 18 | #ifdef __STDC__ 19 | printf(const char *fmt, ...) { 20 | #else 21 | printf(va_alist) va_dcl 22 | { 23 | char *fmt; 24 | #endif 25 | va_list va; 26 | 27 | #ifdef __STDC__ 28 | va_start(va, fmt); 29 | #else 30 | va_start(va); 31 | fmt = va_arg(va, char *); 32 | #endif 33 | vfprintf(stdout, fmt, va); 34 | va_end(va); 35 | return 0; 36 | } 37 | 38 | int 39 | #ifdef __STDC__ 40 | fprintf(FILE *f, const char *fmt, ...) { 41 | #else 42 | fprintf(va_alist) va_dcl 43 | { 44 | FILE *f; 45 | char *fmt; 46 | #endif 47 | va_list va; 48 | 49 | #ifdef __STDC__ 50 | va_start(va, fmt); 51 | #else 52 | va_start(va); 53 | f = va_arg(va, FILE *); 54 | fmt = va_arg(va, char *); 55 | #endif 56 | vfprintf(f, fmt, va); 57 | va_end(va); 58 | return 0; 59 | } 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /std/stdc/limits.h: -------------------------------------------------------------------------------- 1 | /* Implementation-defined limits */ 2 | 3 | #if __STDC__ 4 | #define Signed signed 5 | #else 6 | #define Signed 7 | #endif 8 | 9 | #define CHAR_BIT 8 10 | 11 | #define _S_MIN(type) (-(Signed type)((unsigned type) ~0 >> 1) - 1) 12 | #define _S_MAX(type) ((Signed type)((unsigned type) ~0 >> 1)) 13 | 14 | #define UCHAR_MIN ((unsigned char) 0) 15 | #define UCHAR_MAX ((unsigned char) ~0) 16 | #define SCHAR_MIN _S_MIN(char) 17 | #define SCHAR_MAX _S_MAX(char) 18 | 19 | /* some PCC compilers don't like the "elegant" definition of _UCHAR */ 20 | /* let the poor user provide -D_UCHAR=0 or 1 */ 21 | #ifndef _UCHAR 22 | #define _UCHAR ((char) ~0 == (unsigned char) ~0) 23 | #endif 24 | #define CHAR_MIN (_UCHAR ? UCHAR_MIN : SCHAR_MIN) 25 | #define CHAR_MAX (_UCHAR ? UCHAR_MAX : SCHAR_MAX) 26 | 27 | #define USHRT_MAX ((unsigned short) ~0) 28 | #define SHRT_MIN _S_MIN(short) 29 | #define SHRT_MAX _S_MAX(short) 30 | 31 | #define UINT_MAX ((unsigned int) ~0) 32 | #define INT_MIN _S_MIN(int) 33 | #define INT_MAX _S_MAX(int) 34 | 35 | #define ULONG_MAX ((unsigned long) ~0) 36 | #define LONG_MIN _S_MIN(long) 37 | #define LONG_MAX _S_MAX(long) 38 | 39 | -------------------------------------------------------------------------------- /std/stdc/memchr.c: -------------------------------------------------------------------------------- 1 | /* $Id: memchr.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */ 2 | 3 | #include 4 | 5 | void * 6 | memchr(ap, c, n) 7 | const void *ap; 8 | register int c; 9 | register size_t n; 10 | { 11 | register char *p = ap; 12 | 13 | if (n++ > 0) 14 | while (--n > 0) 15 | if (*p++ == c) 16 | return --p; 17 | return NULL; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /std/stdc/memcmp.c: -------------------------------------------------------------------------------- 1 | /* $Id: memcmp.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */ 2 | 3 | #include 4 | 5 | int 6 | memcmp(dap, sap, n) 7 | const void *dap; 8 | const void *sap; 9 | register size_t n; 10 | { 11 | register const unsigned char *dp = (unsigned char const *) dap; 12 | register const unsigned char *sp = (unsigned char const *) sap; 13 | 14 | if (n++ > 0) 15 | while (--n > 0) 16 | if (*dp++ != *sp++) 17 | return *--dp - *--sp; /* (int)? */ 18 | return 0; 19 | } 20 | 21 | -------------------------------------------------------------------------------- /std/stdc/memcpy.c: -------------------------------------------------------------------------------- 1 | /* $Id: memcpy.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */ 2 | 3 | #include 4 | 5 | void * 6 | memcpy(dap, sap, n) 7 | void *dap; 8 | const void *sap; 9 | register size_t n; 10 | { 11 | register char *dp = dap, *sp = (void*) sap; 12 | 13 | if (n++ > 0) 14 | while (--n > 0) 15 | *dp++ = *sp++; 16 | return dap; 17 | } 18 | 19 | -------------------------------------------------------------------------------- /std/stdc/memmove.c: -------------------------------------------------------------------------------- 1 | /* $Id: memmove.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */ 2 | 3 | #include "stdh.h" 4 | 5 | void * 6 | memmove(dap, sap, n) 7 | void *dap; 8 | const void *sap; 9 | register size_t n; 10 | { 11 | register char *dp = dap, *sp = (void*) sap; 12 | 13 | if (n <= 0) 14 | ; 15 | else if (dp < sp) 16 | do *dp++ = *sp++; while (--n > 0); 17 | else if (dp > sp) { 18 | dp += n; 19 | sp += n; 20 | do *--dp = *--sp; while (--n > 0); 21 | } 22 | return dap; 23 | } 24 | 25 | 26 | -------------------------------------------------------------------------------- /std/stdc/memset.c: -------------------------------------------------------------------------------- 1 | /* $Id: memset.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */ 2 | 3 | #include 4 | 5 | void * 6 | memset(ap, c, n) 7 | void *ap; 8 | register int c; 9 | register size_t n; 10 | { 11 | register char *p = ap; 12 | 13 | if (n++ > 0) 14 | while (--n > 0) 15 | *p++ = c; 16 | return ap; 17 | } 18 | 19 | -------------------------------------------------------------------------------- /std/stdc/setvbuf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * PD ksh needs an ANSI-compatible setvbuf. 3 | * if (buf == NULL) it must also allocate a buffer 4 | * and arrange for fclose to deallocate it. 5 | * the reason for doing setvbuf(f, (char *)NULL, _IOFBF, BUFSIZ) 6 | * in the shell is to avoid 4/8K buffers on BSD like systems. 7 | */ 8 | 9 | /* $Id: setvbuf.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */ 10 | 11 | #include 12 | #include 13 | 14 | #if _BSD || _SYSV 15 | int 16 | setvbuf(f, buf, type, size) 17 | register FILE *f; 18 | char *buf; 19 | int type; 20 | size_t size; 21 | { 22 | if ((f->_flag&_IOMYBUF) && f->_base != NULL) 23 | free(f->_base); 24 | f->_flag &= ~(_IOMYBUF|_IONBF|_IOFBF|_IOLBF); 25 | switch (type) { 26 | case _IONBF: 27 | size = 0; 28 | buf = NULL; 29 | break; 30 | case _IOLBF: 31 | case _IOFBF: 32 | if (size == 0) 33 | size = BUFSIZ; 34 | #if _V7 35 | else if (size != BUFSIZ) 36 | return -1; 37 | #endif 38 | if (buf == NULL) { 39 | buf = malloc(size); 40 | if (buf == NULL) 41 | return -1; 42 | f->_flag |= _IOMYBUF; 43 | } 44 | break; 45 | default: 46 | return -1; 47 | } 48 | f->_flag |= type; 49 | f->_base = f->_ptr = buf; 50 | f->_cnt = 0; 51 | #if _BSD 52 | f->_bufsiz = size; 53 | #endif 54 | #if _SYSV 55 | _bufend(f) = buf + size; 56 | #endif 57 | return 0; 58 | } 59 | #endif 60 | 61 | -------------------------------------------------------------------------------- /std/stdc/sprintf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * sprintf and vsprintf 3 | */ 4 | 5 | /* $Id: sprintf.c,v 1.3 1992/05/12 09:31:01 sjg Exp $ */ 6 | 7 | #ifdef __STDC__ 8 | #include 9 | #else 10 | #include 11 | #endif 12 | #include 13 | 14 | #if _V7 || _BSD 15 | 16 | int 17 | #ifdef __STDC__ 18 | sprintf(char *s, const char *fmt, ...) { 19 | #else 20 | sprintf(va_alist) va_dcl 21 | { 22 | char *s; 23 | char *fmt; 24 | #endif 25 | register va_list va; 26 | int n; 27 | 28 | #ifdef __STDC__ 29 | va_start(va, fmt); 30 | #else 31 | va_start(va); 32 | s = va_arg(va, char *); 33 | fmt = va_arg(va, char *); 34 | #endif 35 | n = vsprintf(s, fmt, va); 36 | va_end(va); 37 | return n; 38 | } 39 | 40 | int 41 | #ifdef __STDC__ 42 | vsprintf(char *s, const char *fmt, va_list va) { 43 | #else 44 | vsprintf(s, fmt, va) 45 | char *s; 46 | char *fmt; 47 | va_list va; 48 | { 49 | #endif 50 | int n; 51 | static FILE siob; 52 | 53 | siob._flag = _IOWRT; 54 | siob._base = siob._ptr = s; 55 | siob._cnt = BUFSIZ; 56 | siob._file = -1; 57 | 58 | n = vfprintf(&siob, fmt, va); 59 | *siob._ptr = 0; 60 | return n; 61 | } 62 | 63 | #endif 64 | 65 | -------------------------------------------------------------------------------- /std/stdc/stdarg.h: -------------------------------------------------------------------------------- 1 | /* $Id: stdarg.h,v 1.2 1992/04/25 08:19:26 sjg Exp $ */ 2 | /* DON'T USE THIS IF YOUR COMPILER HAS ITS OWN!!! */ 3 | 4 | #ifndef _STDARG_H 5 | #define _STDARG_H 6 | 7 | typedef char *va_list; 8 | 9 | /* Amount of space required in an argument list for an arg of type TYPE. 10 | TYPE may alternatively be an expression whose type is used. */ 11 | 12 | #define __va_rounded_size(TYPE) \ 13 | (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) 14 | 15 | #define va_start(AP, LASTARG) \ 16 | (AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG))) 17 | 18 | void va_end (va_list); /* Defined in gnulib */ 19 | #define va_end(AP) 20 | 21 | #define va_arg(AP, TYPE) \ 22 | (AP += __va_rounded_size (TYPE), \ 23 | *((TYPE *) (AP - __va_rounded_size (TYPE)))) 24 | 25 | #endif /* _STDARG_H */ 26 | -------------------------------------------------------------------------------- /std/stdc/stddef.h: -------------------------------------------------------------------------------- 1 | /* ANSI common definitions */ 2 | 3 | /* $Id: stddef.h,v 1.2 1992/04/25 08:19:26 sjg Exp $ */ 4 | 5 | #ifndef NULL 6 | #if __STDC__ 7 | #define NULL (void*)0 8 | #else 9 | #define NULL 0 10 | #endif 11 | #endif 12 | 13 | #ifndef _STDDEF_H 14 | #define _STDDEF_H 15 | 16 | /* doesn't really belong here, but the library function need it */ 17 | #ifndef ARGS 18 | # ifdef __STDC__ 19 | # define ARGS(args) args 20 | # else 21 | # define ARGS(args) () 22 | # ifdef VOID 23 | # define void VOID 24 | # endif 25 | # define const 26 | # define volatile 27 | # endif 28 | #endif 29 | 30 | #ifdef HAVE_SYS_STDTYPES 31 | # include 32 | #else 33 | typedef unsigned size_t; /* may need long */ 34 | typedef int ptrdiff_t; 35 | #endif /* HAVE_SYS_STDTYPES */ 36 | #define offsetof(type,id) ((size_t)&((type*)NULL)->id) 37 | 38 | extern int errno; /* really belongs in */ 39 | 40 | #endif 41 | 42 | -------------------------------------------------------------------------------- /std/stdc/stdio.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Emulation of misc. ANSI C stdio functions 3 | */ 4 | 5 | /* $Id: stdio.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */ 6 | 7 | #include 8 | 9 | #ifndef __STDC__ 10 | #define const 11 | #define volatile 12 | #endif 13 | 14 | #if 1 15 | int 16 | remove(name) 17 | const char *name; 18 | { 19 | return unlink(name); 20 | } 21 | #endif 22 | 23 | #if _V7 24 | int 25 | rename(oname, nname) 26 | const char *oname, *nname; 27 | { 28 | return link(oname, nname) == 0 && unlink(oname) == 0 ? 0 : -1; 29 | } 30 | #endif 31 | 32 | -------------------------------------------------------------------------------- /std/stdc/stdio.h_std: -------------------------------------------------------------------------------- 1 | /* 2 | * ANSI stream IO 3 | * 4 | * Heavily dependent on /usr/include/stdio.h being AT&T derived. 5 | * todo: needs L_* constants. 6 | */ 7 | 8 | /* $Id: stdio.h_std,v 1.1 1992/05/02 13:29:18 sjg Exp $ */ 9 | 10 | #if ! _STDIO_H 11 | #define _STDIO_H 1 12 | 13 | #include 14 | 15 | /* system stdio.h goes here ... %%% */ 16 | /* ... end system stdio.h */ 17 | #line 15 "stdio.h" 18 | 19 | #ifndef _IOFBF 20 | #define _IOFBF 00000 21 | #endif 22 | #ifndef _IOLBF 23 | #define _IOLBF 00000 /* same as _IOFBF */ 24 | #endif 25 | 26 | #define SEEK_SET 0 27 | #define SEEK_CUR 1 28 | #define SEEK_END 2 29 | 30 | #if _SYSV 31 | #define _EXTERN extern 32 | #else 33 | #define _EXTERN 34 | #endif 35 | 36 | _EXTERN int remove ARGS((const char *name)); 37 | _EXTERN int rename ARGS((const char *oname, const char *nname)); 38 | _EXTERN FILE *tmpfile ARGS((void)); 39 | _EXTERN char *tmpnam ARGS((char *s)); 40 | 41 | _EXTERN FILE *fopen ARGS((const char *name, const char *mode)); 42 | _EXTERN FILE *freopen ARGS((const char *name, const char *mode, FILE *f)); 43 | _EXTERN FILE *fdopen ARGS((int fd, const char *mode)); 44 | _EXTERN int fflush ARGS((FILE *f)); 45 | _EXTERN int fclose ARGS((FILE *f)); 46 | _EXTERN void setbuf ARGS((FILE *f, char *buf)); 47 | _EXTERN int setvbuf ARGS((FILE *f, char *buf, int flags, size_t len)); 48 | 49 | _EXTERN int fseek ARGS((FILE *f, long off, int how)); 50 | _EXTERN long ftell ARGS((FILE *f)); 51 | _EXTERN void rewind ARGS((FILE *f)); 52 | 53 | _EXTERN int printf ARGS((const char *fmt, ...)); 54 | _EXTERN int fprintf ARGS((FILE *f, const char *fmt, ...)); 55 | _EXTERN int sprintf ARGS((char *s, const char *fmt, ...)); 56 | /* we do not include to prevent conflicts */ 57 | _EXTERN int vprintf ARGS((const char *fmt, Void *va)); 58 | _EXTERN int vfprintf ARGS((FILE *f, const char *fmt, Void *va)); 59 | _EXTERN int vsprintf ARGS((char *s, const char *fmt, Void *va)); 60 | _EXTERN int scanf ARGS((const char *fmt, ...)); 61 | _EXTERN int fscanf ARGS((FILE *f, const char *fmt, ...)); 62 | _EXTERN int sscanf ARGS((const char *s, const char *fmt, ...)); 63 | 64 | _EXTERN size_t fread ARGS((void *ptr, size_t size, size_t n, FILE *f)); 65 | _EXTERN size_t frwrite ARGS((const void *ptr, size_t size, size_t n, FILE *f)); 66 | _EXTERN int fgetc ARGS((FILE *f)); 67 | _EXTERN int fputc ARGS((int c, FILE *f)); 68 | _EXTERN char *fgets ARGS((char *s, int len, FILE *f)); 69 | _EXTERN int fputs ARGS((const char *s, FILE *f)); 70 | _EXTERN char *gets ARGS((char *s)); 71 | _EXTERN int puts ARGS((const char *s)); 72 | 73 | #endif 74 | 75 | -------------------------------------------------------------------------------- /std/stdc/stdio.sed: -------------------------------------------------------------------------------- 1 | /^#[ ]*include/d 2 | /^#[ ]*define[ ]*NULL/d 3 | /remove[ ]*([ ]*)/d 4 | /rename[ ]*([ ]*)/d 5 | /tmpfile[ ]*([ ]*)/d 6 | /tmpnam[ ]*([ ]*)/d 7 | /fopen[ ]*([ ]*)/d 8 | /freopen[ ]*([ ]*)/d 9 | /fdopen[ ]*([ ]*)/d 10 | /fflush[ ]*([ ]*)/d 11 | /fclose[ ]*([ ]*)/d 12 | /setbuf[ ]*([ ]*)/d 13 | /setvbuf[ ]*([ ]*)/d 14 | /fseek[ ]*([ ]*)/d 15 | /ftell[ ]*([ ]*)/d 16 | /rewind[ ]*([ ]*)/d 17 | /printf[ ]*([ ]*)/d 18 | /fprintf[ ]*([ ]*)/d 19 | /sprintf[ ]*([ ]*)/d 20 | /vprintf[ ]*([ ]*)/d 21 | /vfprintf[ ]*([ ]*)/d 22 | /vsprintf[ ]*([ ]*)/d 23 | /scanf[ ]*([ ]*)/d 24 | /fscanf[ ]*([ ]*)/d 25 | /sscanf[ ]*([ ]*)/d 26 | /fread[ ]*([ ]*)/d 27 | /frwrite[ ]*([ ]*)/d 28 | /fgetc[ ]*([ ]*)/d 29 | /fputc[ ]*([ ]*)/d 30 | /fgets[ ]*([ ]*)/d 31 | /fputs[ ]*([ ]*)/d 32 | /gets[ ]*([ ]*)/d 33 | /puts[ ]*([ ]*)/d 34 | -------------------------------------------------------------------------------- /std/stdc/stdlib.h: -------------------------------------------------------------------------------- 1 | /* ANSI utility functions */ 2 | 3 | /* $Id: stdlib.h,v 1.2 1992/04/25 08:19:26 sjg Exp $ */ 4 | 5 | #if ! _STDLIB_H 6 | #define _STDLIB_H 1 7 | 8 | #include 9 | 10 | double atof ARGS((const char *s)); 11 | int atoi ARGS((const char *s)); 12 | long atol ARGS((const char *s)); 13 | double strtod ARGS((const char *s, char **)); 14 | long strtol ARGS((const char *s, char **, int base)); 15 | unsigned long strtoul ARGS((const char *s, char **, int base)); 16 | int rand ARGS((void)); 17 | void srand ARGS((unsigned int seed)); 18 | void *malloc ARGS((size_t size)); 19 | void *realloc ARGS((void *ptr, size_t size)); 20 | void *calloc ARGS((size_t n, size_t size)); 21 | void free ARGS((void *ptr)); 22 | void abort ARGS((void)); 23 | int atexit ARGS((void (*func)(void))); 24 | void exit ARGS((int status)); 25 | char *getenv ARGS((const char *name)); 26 | int system ARGS((const char *cmd)); 27 | void *bsearch ARGS ((const void *key, const void *base, size_t n, size_t size, 28 | int (*compar)(const void *, const void *))); 29 | void *qsort ARGS ((const void *base, size_t n, size_t size, 30 | int (*compar)(const void *, const void *))); 31 | #define abs(a) ((a) < 0 : -(a) : (a)) 32 | 33 | #endif 34 | 35 | -------------------------------------------------------------------------------- /std/stdc/strcat.c: -------------------------------------------------------------------------------- 1 | #include 2 | /* $Id: strcat.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */ 3 | 4 | /* 5 | * strcat - append string src to dst 6 | */ 7 | char * /* dst */ 8 | strcat(dst, src) 9 | char *dst; 10 | const char *src; 11 | { 12 | register char *dscan; 13 | register const char *sscan; 14 | 15 | for (dscan = dst; *dscan != '\0'; dscan++) 16 | continue; 17 | sscan = src; 18 | while ((*dscan++ = *sscan++) != '\0') 19 | continue; 20 | return(dst); 21 | } 22 | -------------------------------------------------------------------------------- /std/stdc/strchr.c: -------------------------------------------------------------------------------- 1 | #include 2 | /* $Id: strchr.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */ 3 | 4 | /* 5 | * strchr - find first occurrence of a character in a string 6 | */ 7 | 8 | char * /* found char, or NULL if none */ 9 | strchr(s, charwanted) 10 | const char *s; 11 | register char charwanted; 12 | { 13 | register const char *scan; 14 | 15 | /* 16 | * The odd placement of the two tests is so NUL is findable. 17 | */ 18 | for (scan = s; *scan != charwanted;) /* ++ moved down for opt. */ 19 | if (*scan++ == '\0') 20 | return(NULL); 21 | return(scan); 22 | } 23 | -------------------------------------------------------------------------------- /std/stdc/strcmp.c: -------------------------------------------------------------------------------- 1 | #include 2 | /* $Id: strcmp.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */ 3 | 4 | /* Modified by Eric Gisin */ 5 | 6 | /* 7 | * strcmp - compare string s1 to s2 8 | */ 9 | 10 | int /* <0 for <, 0 for ==, >0 for > */ 11 | strcmp(s1, s2) 12 | const char *s1; 13 | const char *s2; 14 | { 15 | register const char *scan1; 16 | register const char *scan2; 17 | #if 0 /* some machines prefer int to char */ 18 | register int c1, c2; 19 | #else 20 | register char c1, c2; 21 | #endif 22 | 23 | scan1 = s1; 24 | scan2 = s2; 25 | while ((c1 = *scan1++) == (c2 = *scan2++) && c1 != 0) 26 | ; 27 | 28 | /* 29 | * The following case analysis is necessary so that characters 30 | * which look negative collate low against normal characters but 31 | * high against the end-of-string NUL. 32 | */ 33 | if (c1 == '\0' && c2 == '\0') 34 | return(0); 35 | else if (c1 == '\0') 36 | return(-1); 37 | else if (c2 == '\0') 38 | return(1); 39 | else 40 | return(c1 - c2); 41 | } 42 | -------------------------------------------------------------------------------- /std/stdc/strcpy.c: -------------------------------------------------------------------------------- 1 | #include 2 | /* $Id: strcpy.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */ 3 | 4 | /* 5 | * strcpy - copy string src to dst 6 | */ 7 | char * /* dst */ 8 | strcpy(dst, src) 9 | char *dst; 10 | const char *src; 11 | { 12 | register char *dscan; 13 | register const char *sscan; 14 | 15 | dscan = dst; 16 | sscan = src; 17 | while ((*dscan++ = *sscan++) != '\0') 18 | continue; 19 | return(dst); 20 | } 21 | -------------------------------------------------------------------------------- /std/stdc/strcspn.c: -------------------------------------------------------------------------------- 1 | #include 2 | /* $Id: strcspn.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */ 3 | 4 | /* 5 | * strcspn - find length of initial segment of s consisting entirely 6 | * of characters not from reject 7 | */ 8 | 9 | size_t 10 | strcspn(s, reject) 11 | const char *s; 12 | const char *reject; 13 | { 14 | register const char *scan; 15 | register const char *rscan; 16 | register size_t count; 17 | 18 | count = 0; 19 | for (scan = s; *scan != '\0'; scan++) { 20 | for (rscan = reject; *rscan != '\0';) /* ++ moved down. */ 21 | if (*scan == *rscan++) 22 | return(count); 23 | count++; 24 | } 25 | return(count); 26 | } 27 | -------------------------------------------------------------------------------- /std/stdc/strerror.c: -------------------------------------------------------------------------------- 1 | #include 2 | /* $Id: strerror.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */ 3 | 4 | /* 5 | * strerror - map error number to descriptive string 6 | * 7 | * This version is obviously somewhat Unix-specific. 8 | */ 9 | char * 10 | strerror(errno) 11 | int errno; 12 | { 13 | extern int sys_nerr; 14 | extern char *sys_errlist[]; 15 | 16 | if (errno > 0 && errno < sys_nerr) 17 | return(sys_errlist[errno]); 18 | else 19 | return("unknown error"); 20 | } 21 | -------------------------------------------------------------------------------- /std/stdc/string.h: -------------------------------------------------------------------------------- 1 | /* ANSI string handling (missing wide char stuff) */ 2 | /* $Id: string.h,v 1.2 1992/04/25 08:19:26 sjg Exp $ */ 3 | 4 | #if ! _STRING_H 5 | #define _STRING_H 1 6 | 7 | #include /* define NULL and size_t */ 8 | 9 | #ifndef __GNUC__ 10 | void *memcpy ARGS((void *s1, const void *s2, size_t)); 11 | int memcmp ARGS((const void *s1, const void *s2, size_t)); 12 | size_t strlen ARGS((const char *s)); 13 | #endif 14 | void *memmove ARGS((void *s1, const void *s2, size_t)); 15 | void *memchr ARGS((const void *s, int c, size_t)); 16 | void *memset ARGS((void *s, int c, size_t)); 17 | char *strcpy ARGS((char *s1, const char *s2)); 18 | char *strncpy ARGS((char *s1, const char *s2, size_t)); 19 | char *strcat ARGS((char *s1, const char *s2)); 20 | char *strncat ARGS((char *s1, const char *s2, size_t)); 21 | int strcmp ARGS((const char *s1, const char *s2)); 22 | int strncmp ARGS((const char *s1, const char *s2, size_t)); 23 | char *strchr ARGS((const char *s1, int c)); 24 | char *strrchr ARGS((const char *s1, int c)); 25 | size_t strspn ARGS((const char *s1, const char *s2)); 26 | size_t strcspn ARGS((const char *s1, const char *s2)); 27 | char *strpbrk ARGS((const char *s1, const char *s2)); 28 | char *strstr ARGS((const char *s1, const char *s2)); 29 | char *strtok ARGS((char *s1, const char *s2)); 30 | char *strerror ARGS((int errno)); 31 | 32 | #endif /* _STRING_H */ 33 | 34 | -------------------------------------------------------------------------------- /std/stdc/strlen.c: -------------------------------------------------------------------------------- 1 | #include 2 | /* $Id: strlen.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */ 3 | 4 | /* 5 | * strlen - length of string (not including NUL) 6 | */ 7 | size_t 8 | strlen(s) 9 | const char *s; 10 | { 11 | register const char *scan; 12 | register size_t count; 13 | 14 | count = 0; 15 | scan = s; 16 | while (*scan++ != '\0') 17 | count++; 18 | return(count); 19 | } 20 | -------------------------------------------------------------------------------- /std/stdc/strncat.c: -------------------------------------------------------------------------------- 1 | #include 2 | /* $Id: strncat.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */ 3 | 4 | /* 5 | * strncat - append at most n characters of string src to dst 6 | */ 7 | char * /* dst */ 8 | strncat(dst, src, n) 9 | char *dst; 10 | const char *src; 11 | size_t n; 12 | { 13 | register char *dscan; 14 | register const char *sscan; 15 | register size_t count; 16 | 17 | for (dscan = dst; *dscan != '\0'; dscan++) 18 | continue; 19 | sscan = src; 20 | count = n; 21 | while (*sscan != '\0' && --count >= 0) 22 | *dscan++ = *sscan++; 23 | *dscan++ = '\0'; 24 | return(dst); 25 | } 26 | -------------------------------------------------------------------------------- /std/stdc/strncmp.c: -------------------------------------------------------------------------------- 1 | #include 2 | /* $Id: strncmp.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */ 3 | 4 | /* 5 | * strncmp - compare at most n characters of string s1 to s2 6 | */ 7 | 8 | int /* <0 for <, 0 for ==, >0 for > */ 9 | strncmp(s1, s2, n) 10 | const char *s1; 11 | const char *s2; 12 | size_t n; 13 | { 14 | register const char *scan1; 15 | register const char *scan2; 16 | register size_t count; 17 | 18 | scan1 = s1; 19 | scan2 = s2; 20 | count = n; 21 | while (--count >= 0 && *scan1 != '\0' && *scan1 == *scan2) { 22 | scan1++; 23 | scan2++; 24 | } 25 | if (count < 0) 26 | return(0); 27 | 28 | /* 29 | * The following case analysis is necessary so that characters 30 | * which look negative collate low against normal characters but 31 | * high against the end-of-string NUL. 32 | */ 33 | if (*scan1 == '\0' && *scan2 == '\0') 34 | return(0); 35 | else if (*scan1 == '\0') 36 | return(-1); 37 | else if (*scan2 == '\0') 38 | return(1); 39 | else 40 | return(*scan1 - *scan2); 41 | } 42 | -------------------------------------------------------------------------------- /std/stdc/strncpy.c: -------------------------------------------------------------------------------- 1 | #include 2 | /* $Id: strncpy.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */ 3 | 4 | /* 5 | * strncpy - copy at most n characters of string src to dst 6 | */ 7 | char * /* dst */ 8 | strncpy(dst, src, n) 9 | char *dst; 10 | const char *src; 11 | size_t n; 12 | { 13 | register char *dscan; 14 | register const char *sscan; 15 | register size_t count; 16 | 17 | dscan = dst; 18 | sscan = src; 19 | count = n; 20 | while (--count >= 0 && (*dscan++ = *sscan++) != '\0') 21 | continue; 22 | while (--count >= 0) 23 | *dscan++ = '\0'; 24 | return(dst); 25 | } 26 | -------------------------------------------------------------------------------- /std/stdc/strpbrk.c: -------------------------------------------------------------------------------- 1 | #include 2 | /* $Id: strpbrk.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */ 3 | 4 | /* 5 | * strpbrk - find first occurrence of any char from breakat in s 6 | */ 7 | 8 | char * /* found char, or NULL if none */ 9 | strpbrk(s, breakat) 10 | const char *s; 11 | const char *breakat; 12 | { 13 | register const char *sscan; 14 | register const char *bscan; 15 | 16 | for (sscan = s; *sscan != '\0'; sscan++) { 17 | for (bscan = breakat; *bscan != '\0';) /* ++ moved down. */ 18 | if (*sscan == *bscan++) 19 | return(sscan); 20 | } 21 | return(NULL); 22 | } 23 | -------------------------------------------------------------------------------- /std/stdc/strrchr.c: -------------------------------------------------------------------------------- 1 | #include 2 | /* $Id: strrchr.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */ 3 | 4 | /* 5 | * strrchr - find last occurrence of a character in a string 6 | */ 7 | 8 | char * /* found char, or NULL if none */ 9 | strrchr(s, charwanted) 10 | const char *s; 11 | register char charwanted; 12 | { 13 | register const char *scan; 14 | register const char *place; 15 | 16 | place = NULL; 17 | for (scan = s; *scan != '\0'; scan++) 18 | if (*scan == charwanted) 19 | place = scan; 20 | if (charwanted == '\0') 21 | return(scan); 22 | return(place); 23 | } 24 | -------------------------------------------------------------------------------- /std/stdc/strspn.c: -------------------------------------------------------------------------------- 1 | #include 2 | /* $Id: strspn.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */ 3 | 4 | /* 5 | * strspn - find length of initial segment of s consisting entirely 6 | * of characters from accept 7 | */ 8 | 9 | size_t 10 | strspn(s, accept) 11 | const char *s; 12 | const char *accept; 13 | { 14 | register const char *sscan; 15 | register const char *ascan; 16 | register size_t count; 17 | 18 | count = 0; 19 | for (sscan = s; *sscan != '\0'; sscan++) { 20 | for (ascan = accept; *ascan != '\0'; ascan++) 21 | if (*sscan == *ascan) 22 | break; 23 | if (*ascan == '\0') 24 | return(count); 25 | count++; 26 | } 27 | return(count); 28 | } 29 | -------------------------------------------------------------------------------- /std/stdc/strstr.c: -------------------------------------------------------------------------------- 1 | #ifndef lint 2 | static char *RCSid = "$Id: strstr.c,v 1.2 1992/04/25 00:58:50 sjg Exp $"; 3 | #endif 4 | 5 | #include "stdh.h" 6 | 7 | /* 8 | * strstr - find first occurrence of wanted in s 9 | */ 10 | 11 | char * /* found string, or NULL if none */ 12 | strstr(s, wanted) 13 | const char *s; 14 | const char *wanted; 15 | { 16 | register const char *scan; 17 | register size_t len; 18 | register char firstc; 19 | 20 | /* 21 | * The odd placement of the two tests is so "" is findable. 22 | * Also, we inline the first char for speed. 23 | * The ++ on scan has been moved down for optimization. 24 | */ 25 | firstc = *wanted; 26 | len = strlen(wanted); 27 | for (scan = s; *scan != firstc || strncmp(scan, wanted, len) != 0; ) 28 | if (*scan++ == '\0') 29 | return(NULL); 30 | return(scan); 31 | } 32 | -------------------------------------------------------------------------------- /std/stdc/strtok.c: -------------------------------------------------------------------------------- 1 | #include 2 | /* $Id: strtok.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */ 3 | 4 | /* 5 | * Get next token from string s (NULL on 2nd, 3rd, etc. calls), 6 | * where tokens are nonempty strings separated by runs of 7 | * chars from delim. Writes NULs into s to end tokens. delim need not 8 | * remain constant from call to call. 9 | */ 10 | 11 | static char *scanpoint = NULL; 12 | 13 | char * /* NULL if no token left */ 14 | strtok(s, delim) 15 | char *s; 16 | register const char *delim; 17 | { 18 | register char *scan; 19 | char *tok; 20 | register const char *dscan; 21 | 22 | if (s == NULL && scanpoint == NULL) 23 | return(NULL); 24 | if (s != NULL) 25 | scan = s; 26 | else 27 | scan = scanpoint; 28 | 29 | /* 30 | * Scan leading delimiters. 31 | */ 32 | for (; *scan != '\0'; scan++) { 33 | for (dscan = delim; *dscan != '\0'; dscan++) 34 | if (*scan == *dscan) 35 | break; 36 | if (*dscan == '\0') 37 | break; 38 | } 39 | if (*scan == '\0') { 40 | scanpoint = NULL; 41 | return(NULL); 42 | } 43 | 44 | tok = scan; 45 | 46 | /* 47 | * Scan token. 48 | */ 49 | for (; *scan != '\0'; scan++) { 50 | for (dscan = delim; *dscan != '\0';) /* ++ moved down. */ 51 | if (*scan == *dscan++) { 52 | scanpoint = scan+1; 53 | *scan = '\0'; 54 | return(tok); 55 | } 56 | } 57 | 58 | /* 59 | * Reached end of string. 60 | */ 61 | scanpoint = NULL; 62 | return(tok); 63 | } 64 | -------------------------------------------------------------------------------- /std/stdc/time.h: -------------------------------------------------------------------------------- 1 | /* time, time/date conversion */ 2 | /* $Id: time.h,v 1.2 1992/04/25 08:19:26 sjg Exp $ */ 3 | 4 | #if ! _TIME_H 5 | #define _TIME_H 1 6 | 7 | #include /* need size_t */ 8 | 9 | #ifndef HAVE_SYS_STDTYPES 10 | #ifndef _TIME_T 11 | typedef long time_t; 12 | #endif 13 | typedef long clock_t; /* seconds/CLK_TCK */ 14 | #endif 15 | 16 | #if _V7 || _SYSV 17 | #define CLK_TCK 60 /* todo: get from */ 18 | #endif 19 | 20 | #if _BSD 21 | #define CLK_TCK 100 22 | #endif 23 | 24 | #if _ST 25 | #define CLK_TCK 200 /* ST system clock */ 26 | #endif 27 | 28 | struct tm { 29 | int tm_sec, tm_min, tm_hour; 30 | int tm_mday, tm_mon, tm_year, tm_wday, tm_yday; 31 | int tm_isdst; 32 | long tm_gmtoff; /* BSD */ 33 | char *tm_zone; /* BSD */ 34 | }; 35 | 36 | clock_t clock ARGS((void)); 37 | time_t time ARGS((time_t *tp)); 38 | #define difftime(t1, t2) (double)((t2)-(t1)) 39 | time_t mktime ARGS((struct tm *tmp)); 40 | char *asctime ARGS((const struct tm *tmp)); 41 | char *ctime ARGS((const time_t *tp)); 42 | struct tm *gmtime ARGS((const time_t *tp)); 43 | struct tm *localtime ARGS((const time_t *tp)); 44 | size_t strftime ARGS((char *buf, size_t len, const char *fmt, const struct tm *tmp)); 45 | 46 | #endif 47 | 48 | -------------------------------------------------------------------------------- /std/stdc/types.h: -------------------------------------------------------------------------------- 1 | /* work around multiple typedefs in stddef.h and sys/types.h */ 2 | /* $Id: types.h,v 1.2 1992/04/25 08:19:26 sjg Exp $ */ 3 | 4 | #include /* defines size_t and ptrdiff_t */ 5 | #include /* defines time_t and clock_t */ 6 | 7 | /* "inhibit" the typedefs in sys/types.h */ 8 | #define size_t _size_t 9 | #define time_t _time_t 10 | #define clock_t _clock_t 11 | //#include "/./usr/include/sys/types.h" 12 | #undef size_t 13 | #undef time_t 14 | #undef clock_t 15 | 16 | -------------------------------------------------------------------------------- /std/stdc/vprintf.c: -------------------------------------------------------------------------------- 1 | #ifndef lint 2 | static char *RCSid = "$Id: vprintf.c,v 1.3 1992/05/12 09:31:03 sjg Exp $"; 3 | #endif 4 | #ifdef __STDC__ 5 | #include 6 | #else 7 | #include 8 | #endif 9 | #include 10 | 11 | #define BUF 40 /* buffer for int -> string conversion */ 12 | 13 | int 14 | #ifdef __STDC__ 15 | vprintf(const char *fmt, va_list va) { 16 | #else 17 | vprintf(fmt, va) char *fmt; va_list va; { 18 | #endif 19 | return vfprintf(stdout, fmt, va); 20 | } 21 | 22 | int 23 | #ifdef __STDC__ 24 | vfprintf(register FILE *f, register const char *fmt, register va_list va) { 25 | #else 26 | vfprintf(f, fmt, va) register FILE *f; register char *fmt; register va_list va; { 27 | #endif 28 | register int c; 29 | int pos = 0; /* todo: implement */ 30 | 31 | while ((c = *fmt++)) 32 | if (c == '%') { 33 | long n; 34 | register unsigned long u; 35 | char buf [BUF+1]; 36 | register char *p = buf + BUF; 37 | register enum { 38 | FF_ALT = 0x01, /* #, alternate format */ 39 | FF_SHORT = 0x02, /* h, short arg */ 40 | FF_LONG = 0x04, /* l, long arg */ 41 | FF_ZERO = 0x08, /* 0, zero fill */ 42 | FF_LEFT = 0x10, /* -, left adjust */ 43 | FF_PREC = 0x20, /* .*, precision */ 44 | FF_NEG = 0x40, /* signed arg */ 45 | FF_PUTS = 0x80, /* fputs(p, f) */ 46 | FF_DEFAULT = 0 47 | } flags = FF_DEFAULT; 48 | int sign = '-'; /* sign: [ +-] */ 49 | int width = 0, prec = 0; /* width, precision */ 50 | 51 | *p = 0; 52 | 53 | /* scan flag characters */ 54 | for (c = *fmt++; ; c = *fmt++) switch (c) { 55 | case '0': 56 | flags |= FF_ZERO; 57 | break; 58 | 59 | case '#': /* alternate format */ 60 | flags |= FF_ALT; 61 | break; 62 | 63 | case ' ': /* blank sign */ 64 | sign = ' '; 65 | break; 66 | case '+': /* +/- sign */ 67 | sign = '+'; 68 | break; 69 | 70 | case '-': /* left just. */ 71 | flags |= FF_LEFT; 72 | break; 73 | 74 | default: 75 | goto Frogs; 76 | } 77 | Frogs: 78 | 79 | /* scan width */ 80 | if (c == '*') { /* width from arg list */ 81 | width = va_arg(va, int); 82 | c = *fmt++; 83 | } else 84 | while ('0' <= c && c <= '9') { 85 | width = width*10 + (c-'0'); 86 | c = *fmt++; 87 | } 88 | 89 | if (c == '.') { /* scan precision */ 90 | flags |= FF_PREC; 91 | c = *fmt++; 92 | if (c == '*') { /* precision from arg list */ 93 | prec = va_arg(va, int); 94 | c = *fmt++; 95 | } else 96 | while ('0' <= c && c <= '9') { 97 | prec = prec*10 + (c-'0'); 98 | c = *fmt++; 99 | } 100 | } 101 | 102 | /* length modifiers */ 103 | if (c == 'h') { 104 | flags |= FF_SHORT; 105 | c = *fmt++; 106 | } else if (c == 'l') { 107 | flags |= FF_LONG; 108 | c = *fmt++; 109 | } 110 | 111 | /* do conversion */ 112 | switch (c) { 113 | case '%': /* %% -> % */ 114 | putc(c, f); 115 | pos ++; 116 | break; 117 | 118 | case 'p': /* pointer */ 119 | *--p = '}'; 120 | u = (unsigned long) va_arg(va, void*); 121 | do { 122 | *--p = "0123456789ABCDEF"[u%16]; 123 | u /= 16; 124 | } while (u != 0); 125 | *--p = '{'; 126 | flags |= FF_PUTS; 127 | break; 128 | 129 | case 'n': /* save position */ 130 | *va_arg(va, int*) = pos; 131 | break; 132 | 133 | case 'c': /* character */ 134 | u = (flags&FF_SHORT) ? va_arg(va, unsigned short) 135 | : (flags&&FF_LONG) ? va_arg(va, unsigned long) 136 | : va_arg(va, unsigned int); 137 | *--p = u; 138 | flags |= FF_PUTS; 139 | break; 140 | 141 | case 's': /* string */ 142 | if ((p = va_arg(va, char *)) == NULL) 143 | p = ""; 144 | if ((flags&FF_PREC) && strlen(p) > prec) { 145 | pos += prec; 146 | while (--prec >= 0) 147 | { 148 | c = *p++; 149 | putc(c, f); 150 | } 151 | break; 152 | } 153 | flags |= FF_PUTS; 154 | break; 155 | 156 | case 'i': case 'd': case 'u': /* decimal */ 157 | if (c != 'u') { /* signed */ 158 | n = (flags&FF_SHORT) ? va_arg(va, short) 159 | : (flags&&FF_LONG) ? va_arg(va, long) 160 | : va_arg(va, int); 161 | if (n < 0) 162 | flags |= FF_NEG; 163 | u = (n < 0) ? -n : n; 164 | } else 165 | u = (flags&FF_SHORT) ? va_arg(va, unsigned short) 166 | : (flags&&FF_LONG) ? va_arg(va, unsigned long) 167 | : va_arg(va, unsigned int); 168 | do { 169 | *--p = '0' + u%10; 170 | u /= 10; 171 | } while (u != 0); 172 | prec -= buf+BUF - p; 173 | while (--prec >= 0) 174 | *--p = '0'; 175 | if (flags&FF_NEG) 176 | *--p = '-'; 177 | else 178 | if (sign != '-') 179 | *--p = (sign == '+') ? '+' : ' '; 180 | flags |= FF_PUTS; 181 | break; 182 | 183 | case 'x': case 'X': /* hex, Hex */ 184 | u = (flags&FF_SHORT) ? va_arg(va, unsigned short) 185 | : (flags&&FF_LONG) ? va_arg(va, unsigned long) 186 | : va_arg(va, unsigned int); 187 | do { 188 | *--p = "0123456789ABCDEF"[u%16]; 189 | u /= 16; 190 | } while (u != 0); 191 | prec -= buf+BUF - p; 192 | while (--prec >= 0) 193 | *--p = '0'; 194 | if (flags&&FF_ALT) 195 | *--p = 'x', *--p = '0'; 196 | flags |= FF_PUTS; 197 | break; 198 | 199 | case 'o': /* octal */ 200 | u = (flags&FF_SHORT) ? va_arg(va, unsigned short) 201 | : (flags&&FF_LONG) ? va_arg(va, unsigned long) 202 | : va_arg(va, unsigned int); 203 | do { 204 | *--p = '0' + u%8; 205 | u /= 8; 206 | } while (u != 0); 207 | prec -= buf+BUF - p; 208 | while (--prec >= 0) 209 | *--p = '0'; 210 | if (flags&&FF_ALT && *p != '0') 211 | *--p = '0'; 212 | flags |= FF_PUTS; 213 | break; 214 | 215 | default: /* todo: error */ 216 | putc('%', f); 217 | putc(c, f); 218 | pos += 2; 219 | break; 220 | } 221 | 222 | /* copy adjusted string "p" to output */ 223 | if (flags&FF_PUTS) { 224 | int len = strlen(p); 225 | int pad = width - len; 226 | if (!(flags&FF_LEFT)) 227 | while (--pad >= 0) 228 | putc((flags&FF_ZERO) ? '0' : ' ', f); 229 | while (c = *p++) 230 | putc(c, f); 231 | if ((flags&FF_LEFT)) 232 | while (--pad >= 0) 233 | putc(' ', f); 234 | pos += (len < width) ? width : len; 235 | } 236 | } else { /* ordinary character */ 237 | putc(c, f); 238 | pos ++; 239 | } 240 | return pos; 241 | } 242 | 243 | --------------------------------------------------------------------------------