v16i078: MSDOS Shell (sh) Implementation 1.6.4, Patch01/02
Ian Stewartson
istewart at datlog.co.uk
Thu Jan 17 06:50:36 AEST 1991
Submitted-by: istewart at datlog.co.uk (Ian Stewartson)
Posting-number: Volume 16, Issue 78
Archive-name: ms_sh-1.6/patch01
Patch-To: ms_sh-1.6: Volume 12, Issue 19-26
1.6.4 of the MSDOS Shell. Unfortunately, I'm tied up with real work
at the moment, so this is likely to be the last upgrade for a couple
of months.
It fixes one or two bugs and provides some new feature from the
Korn/POSIX shell (see release notes).
Regards,
Ian Stewartson
Data Logic
-------
#!/bin/sh
# This is a shell archive (shar 3.46)
# made 12/24/1990 18:01 UTC by istewart at dlvax2
# Source directory /usr/proj1/ssd/istewart/src/shell
#
# existing files will NOT be overwritten unless -c is specified
#
# This is part 1 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 63614 -rw-r--r-- Patch1.6.4
#
if test -r _shar_seq_.tmp; then
echo 'Must unpack archives in sequence!'
echo Please unpack part `cat _shar_seq_.tmp` next
exit 1
fi
# ============= Patch1.6.4 ==============
if test -f 'Patch1.6.4' -a X"$1" != X"-c"; then
echo 'x - skipping Patch1.6.4 (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting Patch1.6.4 (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'Patch1.6.4' &&
Index: Notes1.6
*** ../sh16.3/Notes1.6 Fri Aug 17 21:29:59 1990
--- Notes1.6 Tue Nov 6 20:47:31 1990
***************
*** 1,4 ****
! Version 1.6.3 Release Notes:
X
X Note: Release 1.6.1 did occur to comp.ibm.pc.binaries. However, the
X transmission was corrupt and by the time I was notified (the moderator having
--- 1,4 ----
! Version 1.6.4 Release Notes:
X
X Note: Release 1.6.1 did occur to comp.ibm.pc.binaries. However, the
X transmission was corrupt and by the time I was notified (the moderator having
***************
*** 41,47 ****
X The code has been fixed to cope with DOS 4.
X 21. A bug in the processing of functions has been fixed which caused
X the shell to crash or hang has been fixed.
!
X The following enhancements have been made:
X
X 1. /dev/tty and /dev/null are mapped to /dev/con and /dev/nul internally
--- 41,48 ----
X The code has been fixed to cope with DOS 4.
X 21. A bug in the processing of functions has been fixed which caused
X the shell to crash or hang has been fixed.
! 22. A bug in the function code that caused case functions to hang
! has been fixed.
X The following enhancements have been made:
X
X 1. /dev/tty and /dev/null are mapped to /dev/con and /dev/nul internally
***************
*** 78,83 ****
--- 79,87 ----
X 20. The POSIX variable substitution command ${#name} to give the
X string length has been implemented.
X 21. The POSIX I/O option <> has been implemented.
+ 22. The POSIX I/O options ${#*%} and ~ have been implemented.
+ 23. The builtin command command has been implemented.
+ 24. The source for stdargv.c has been modified to work under OS/2
X
X The following enhancements/bugs remain outstanding:
X
***************
*** 93,98 ****
--- 97,108 ----
X processing of escape characters. The shell uses the 8-bit to
X mark escaped characters (Release 1.7).
X
+ 3. Interrupting a disk swap at the wrong time may cause the shell to
+ hang. I've tried disabling Control-Break during disk read/writes
+ but this only causes the shell to hang on re-load every time in
+ some environments. In the next release, I'm going to put in some
+ checks and issue re-read/writes when necessary.
+
X Thanks are due to
X
X Greg Yachuk
***************
*** 101,106 ****
--- 111,117 ----
X John B Thiel
X Harry McGavran
X Bill Davidsen
+ Richard J Reiner
X
X for their comments, fixes, tolerance etc in testing release 1.6
X
Index: lib/stdargv.c
*** ../sh16.3/lib/stdargv.c Fri Mar 2 11:34:58 1990
--- lib/stdargv.c Tue Nov 6 20:52:05 1990
***************
*** 18,25 ****
X * This function replaces the standard MS-DOS command
X * line processing function (_setargv in stdargv.obj).
X *
! * CALLING SEQUENCE: The following calling sequences are used:
X *
X * void _setargv ();
X *
X * ERROR MESSAGES: Out of memory
--- 18,27 ----
X * This function replaces the standard MS-DOS command
X * line processing function (_setargv in stdargv.obj).
X *
! * Support for OS2 added. Compile with -DOS2
X *
+ * CALLING SEQUENCE: The following calling sequences are used:
+ *
X * void _setargv ();
X *
X * ERROR MESSAGES: Out of memory
***************
*** 32,45 ****
X #include <stdio.h> /* Standard I/O delarations */
X #include <stdlib.h> /* Standard library functions */
X #include <errno.h> /* Error number declarations */
X #include <dos.h> /* DOS functions declarations */
X #include <bios.h> /* BIOS functions declarations */
X #include <ctype.h> /* Character type declarations */
X #include <string.h> /* String library functions */
X #include <limits.h> /* String library functions */
X #include <fcntl.h> /* File Control Declarations */
- #include <io.h> /* Input/Output Declarations */
X #include <dirent.h> /* Direction I/O functions */
X
X /*
X * DATA DEFINITIONS:
--- 34,51 ----
X #include <stdio.h> /* Standard I/O delarations */
X #include <stdlib.h> /* Standard library functions */
X #include <errno.h> /* Error number declarations */
+ #ifdef OS2
+ #include <os2.h> /* OS2 functions declarations */
+ #else
X #include <dos.h> /* DOS functions declarations */
X #include <bios.h> /* BIOS functions declarations */
+ #endif
X #include <ctype.h> /* Character type declarations */
X #include <string.h> /* String library functions */
X #include <limits.h> /* String library functions */
X #include <fcntl.h> /* File Control Declarations */
X #include <dirent.h> /* Direction I/O functions */
+ #include <unistd.h>
X
X /*
X * DATA DEFINITIONS:
***************
*** 65,76 ****
--- 71,90 ----
X static void ex_fatal (int, char *, char *); /* Fatal error processing*/
X static char *ex_environment (char *); /* Process environment */
X static char *_ex_multi_drive (char *); /* Check for multidrive */
+ static int N_floppy_disks (void);
X static char *ex_nomem = "%s: %s\n";
X
X extern char far *_pgmptr; /* Program name */
X extern char **__argv; /* Current argument address */
X extern int __argc; /* Current argument count */
X
+ #ifdef OS2
+ static void _dos_setdrive (unsigned int, unsigned int *);
+ static void _dos_getdrive (unsigned int *);
+ extern ushort _aenvseg; /* Environment seg */
+ extern ushort _acmdln; /* Command line offset */
+ #endif
+
X /*
X * MODULE ABSTRACT: _setargv
X *
***************
*** 79,92 ****
X
X void _setargv ()
X {
X /* Set up pointer to command line */
X char far *argvp = (char far *)((((long)_psp) << 16) + 0x081L);
X unsigned int envs = *(int far *)((((long)_psp) << 16) + 0x02cL);
X char far *s; /* Temporary string pointer */
! #ifndef M_I86LM
X char buf[MAX_LINE]; /* Temporary space */
X char *cp;
! #endif
X
X /* Command line can be null or 0x0d terminated - convert to null */
X
--- 93,131 ----
X
X void _setargv ()
X {
+ #ifdef OS2
+ char far *argvp = (char far *)((((long)_aenvseg) << 16));
+ ushort off = _acmdln;
+
+ while (--off)
+ {
+ if (argvp[off - 1] == 0)
+ break;
+ }
+
+ /* Add program name */
+
+ _pgmptr = &argvp[off];
+
+ if (argvp[_acmdln] == 0)
+ ex_add_arg (ex_tounix (_pgmptr)); /* Add the program name */
+
+ else
+ {
+ argvp += _acmdln;
+ ex_add_arg (ex_tounix (argvp)); /* Add the program name */
+ argvp += strlen (argvp) + 1;
+ exp_line (argvp);
+ }
+ #else
X /* Set up pointer to command line */
X char far *argvp = (char far *)((((long)_psp) << 16) + 0x081L);
X unsigned int envs = *(int far *)((((long)_psp) << 16) + 0x02cL);
X char far *s; /* Temporary string pointer */
! # ifndef M_I86LM
X char buf[MAX_LINE]; /* Temporary space */
X char *cp;
! # endif
X
X /* Command line can be null or 0x0d terminated - convert to null */
X
***************
*** 123,129 ****
X
X _pgmptr = s;
X
! #ifndef M_I86LM
X cp = buf;
X while (*(cp++) = *(s++));
X
--- 162,168 ----
X
X _pgmptr = s;
X
! # ifndef M_I86LM
X cp = buf;
X while (*(cp++) = *(s++));
X
***************
*** 134,142 ****
X while (*(cp++) = *(s++));
X
X exp_line (buf);
! #else
X ex_add_arg (ex_tounix (s)); /* Add the program name */
X exp_line (argvp);
X #endif
X
X ex_add_arg ((char *)NULL);
--- 173,182 ----
X while (*(cp++) = *(s++));
X
X exp_line (buf);
! # else
X ex_add_arg (ex_tounix (s)); /* Add the program name */
X exp_line (argvp);
+ # endif
X #endif
X
X ex_add_arg ((char *)NULL);
***************
*** 262,268 ****
X
X /* Check to see if the second diskette drive is really there */
X
! if (((_bios_equiplist () & 0x00c0) == 0x0000) && (s_drive == 2))
X continue;
X
X /* If the drive exists and is in our list - process it */
--- 302,308 ----
X
X /* Check to see if the second diskette drive is really there */
X
! if ((N_floppy_disks () < 2) && (s_drive == 2))
X continue;
X
X /* If the drive exists and is in our list - process it */
***************
*** 619,623 ****
--- 659,703 ----
X }
X
X return (*prefix && (*(prefix + 1) == ':')) ? prefix + 1 : (char *)NULL;
+ }
+
+ /* Some OS/2 functions to emulate the DOS functions */
+
+ #ifdef OS2
+ static void _dos_getdrive (cdp)
+ unsigned int *cdp;
+ {
+ USHORT cdr;
+ ULONG ndr;
+
+ DosQCurDisk((PUSHORT)&cdr, (PULONG) &ndr);
+ *cdp = (unsigned int)cdr;
+ }
+
+ static void _dos_setdrive (cdr, ndp)
+ unsigned int cdr;
+ unsigned int *ndp;
+ {
+ USHORT dummy;
+ ULONG ndr;
+
+ DosQCurDisk((PUSHORT)&dummy, (PULONG) &ndr);
+ *ndp = (unsigned int)ndr;
+
+ DosSelectDisk ((USHORT)cdr);
+ }
+ #endif
+
+ /* Return the number of floppy disks */
+
+ static int N_floppy_disks ()
+ {
+ #ifdef OS2
+ BYTE nflop = 1;
+ DosDevConfig (&nflop, 2, 0);
+ return nflop;
+ #else
+ return ((_bios_equiplist () & 0x00c0) >> 6) + 1;
+ #endif
X }
X #endif
Index: sh.1
Prereq: 1.11
*** ../sh16.3/sh.1 Fri Aug 17 21:31:41 1990
--- sh.1 Tue Nov 6 20:11:17 1990
***************
*** 14,22 ****
X .\" 2. The sources (or parts thereof) or objects generated from the sources
X .\" (or parts of sources) cannot be sold under any circumstances.
X .\"
! .\" $Header: C:/SRC/SHELL/RCS/sh.1 1.11 90/08/14 23:17:25 Ian_Stewartson Exp $
X .\"
X .\" $Log: sh.1 $
X .\" Revision 1.11 90/08/14 23:17:25 Ian_Stewartson
X .\" Add IO read/write open
X .\"
--- 14,26 ----
X .\" 2. The sources (or parts thereof) or objects generated from the sources
X .\" (or parts of sources) cannot be sold under any circumstances.
X .\"
! .\" $Header: D:/SRC/SHELL/RCS/sh.1 1.12 90/11/06 20:08:46 Ian_Stewartson Exp $
X .\"
X .\" $Log: sh.1 $
+ .\" Revision 1.12 90/11/06 20:08:46 Ian_Stewartson
+ .\" Add POSIX options {#%*} and ~
+ .\" Add builtin command
+ .\"
X .\" Revision 1.11 90/08/14 23:17:25 Ian_Stewartson
X .\" Add IO read/write open
X .\"
***************
*** 163,172 ****
X .SS Comments
X A word beginning with \fB#\fR causes that word and all the following
X characters up to a new-line to be ignored.
X .SS Command Substitution
! The standard output from a command enclosed in a pair of grave accents
! (\fB\(ga\(ga\fR) may be used as part or all of a word; trailing new-lines
! are removed.
X .SS Parameter Substitution
X The character \fB$\fR is used to introduce substitutable \fIparameters\fR.
X There are two types of parameters, positional and keyword. If \fIparameter\fR
--- 167,179 ----
X .SS Comments
X A word beginning with \fB#\fR causes that word and all the following
X characters up to a new-line to be ignored.
+ .SS Tilde Substitution
+ Each word is checked to see if it begins with an unquoted\fB~\fR. If it is,
+ the \fB~\fR is replaced by the value of the \fBHOME\fR parameter.
X .SS Command Substitution
! The standard output from a command enclosed in parenthesis preceded by a
! dollar sign (\fB$()\fR), or in a pair of grave accents (\fB\(ga\(ga\fR) may
! be used as part or all of a word; trailing new-lines are removed.
X .SS Parameter Substitution
X The character \fB$\fR is used to introduce substitutable \fIparameters\fR.
X There are two types of parameters, positional and keyword. If \fIparameter\fR
***************
*** 184,196 ****
X .PD 0
X .TP
X \fB${\fIparameter\fB}\fR
! The value, if any, of the parameter is substituted. The braces are required
! only when \fIparameter\fR is followed by a letter, digit, or underscore that
! is not to be interpreted as part of its name. If \fIparameter\fR is
! \fB*\fR or \fB@\fR, all the positional parameters, starting with \fB$1\fR,
! are substituted (separated by spaces). Parameter \fB$0\fR is set from argument
! zero when the shell is invoked.
X .TP
X \fB${\fIparameter\fB:-\fIword\fB}\fR
X If \fIparameter\fR is set and is non-null, substitute its value; otherwise
X substitute \fIword\fR.
--- 191,208 ----
X .PD 0
X .TP
X \fB${\fIparameter\fB}\fR
! The value, if any, of the \fIparameter\fR is substituted. The braces are
! required only when \fIparameter\fR is followed by a letter, digit, or
! underscore that is not to be interpreted as part of its name. If
! \fIparameter\fR is \fB*\fR or \fB@\fR, all the positional parameters, starting
! with \fB$1\fR, are substituted (separated by spaces). Parameter \fB$0\fR is
! set from argument zero when the shell is invoked.
X .TP
+ \fB${#\fIparameter\fB}\fR
+ If \fIparameter\fR is \fB*\fR or \fB@\fR, the number of positional parameters
+ is substituted. Otherwise, the length of the value of the \fIparameter\fR is
+ substituted.
+ .TP
X \fB${\fIparameter\fB:-\fIword\fB}\fR
X If \fIparameter\fR is set and is non-null, substitute its value; otherwise
X substitute \fIword\fR.
***************
*** 208,213 ****
--- 220,242 ----
X \fB${\fIparameter\fB:+\fIword\fB}\fR
X If \fIparameter\fR is set and is non-null, substitute \fIword\fR; otherwise
X substitute nothing.
+ .TP
+ \fB${\fIparameter\fB#\fIpattern\fB}\fR
+ \fB${\fIparameter\fB##\fIpattern\fB}\fR
+ If the Shell \fIpattern\fR matches the beginning of the value of
+ \fIparameter\fR, then the value of this substitution is the value of the
+ \fIparameter\fR with the matched portion deleted; otherwise the value of
+ this \fIparameter\fR is substituted. In the first form the smallest matching
+ \fIpattern\fR is deleted and in the latter form the largest matching
+ \fIpattern\fR is deleted.
+ .TP
+ \fB${\fIparameter\fB%\fIpattern\fB}\fR
+ \fB${\fIparameter\fB%%\fIpattern\fB}\fR
+ If the Shell \fIpattern\fR matches the end of the value of \fIparameter\fR,
+ then the value of this substitution is the value of the \fIparameter\fR with
+ the matched portion deleted; otherwise the value of this \fIparameter\fR is
+ substituted. In the first form the smallest matching \fIpattern\fR is deleted
+ and in the latter form the largest matching \fIpattern\fR is deleted.
X .PD
X .PP
X In the above, \fIword\fR is not evaluated unless it is to be used as the
***************
*** 830,835 ****
--- 859,886 ----
X Exit from the enclosing \fBfor\fR or \fBwhile\fR loop, if any. If \fIn\fR is
X specified, break \fIn\fR levels.
X .TP
+ \fBbuiltin\fR \*(OK \fIargs\fR ... \*(CK
+ Force the selection of the \fBbuiltin\fR version of a command. The builtin
+ shell command selected by the first \fIargs\fR value is executed with the
+ parameters defined by the remaining \fIargs\fRs. If no arguments are given,
+ a list of all \fIbuiltin\fR commands is printed.
+ .sp
+ If the first argument is one of the following, the processing of the
+ builtin command in the following arguments are changed as indicated:
+ .RS
+ .TP
+ \fB-a\fR
+ Set the following builtin commands to use builtin version in preference to
+ any function or external versions.
+ .TP
+ \fB-d\fR
+ Set the following builtin commands to use the function or external version
+ in preference to the builtin version.
+ .TP
+ \fB-s\fR
+ Display the current status of the following builtin commands.
+ .RE
+ .TP
X \fBcontinue\fR \*(OK \fIn\fR \*(CK
X Resume the next iteration of the enclosing \fBfor\fR or \fBwhile\fR loop. If
X \fIn\fR is specified, resume at the \fIn\fR-th enclosing loop.
***************
*** 986,992 ****
X \fBmsdos\fR \*(OK \fIname\fR ... \*(CK
X The given \fIname\fRs are marked \fImsdos\fR format and if the \fB-m\fR flag
X is set, the values of the these \fIname\fRs are exported to child processes
! with any slashes in the value replaced by backslashes.
X .TP
X \fBpwd\fR
X Print the current working directory.
--- 1037,1044 ----
X \fBmsdos\fR \*(OK \fIname\fR ... \*(CK
X The given \fIname\fRs are marked \fImsdos\fR format and if the \fB-m\fR flag
X is set, the values of the these \fIname\fRs are exported to child processes
! with any slashes in the value replaced by backslashes. If no arguments are
! given, a list of all \fImsdos\fR names is printed.
X .TP
X \fBpwd\fR
X Print the current working directory.
Index: shell/sh.h
Prereq: 1.21
*** ../sh16.3/shell/sh.h Fri Aug 17 21:33:20 1990
--- shell/sh.h Tue Nov 6 19:18:37 1990
***************
*** 13,21 ****
X * 2. The sources (or parts thereof) or objects generated from the sources
X * (or parts of sources) cannot be sold under any circumstances.
X *
! * $Header: C:/SRC/SHELL/RCS/sh.h 1.21 90/08/14 23:54:44 MS_user Exp $
X *
X * $Log: sh.h $
X * Revision 1.21 90/08/14 23:54:44 MS_user
X * Add addition value to env structure
X * Add some new publics
--- 13,27 ----
X * 2. The sources (or parts thereof) or objects generated from the sources
X * (or parts of sources) cannot be sold under any circumstances.
X *
! * $Header: D:/SRC/SHELL/RCS/sh.h 1.23 90/09/19 15:29:54 Ian_Stewartson Exp $
X *
X * $Log: sh.h $
+ * Revision 1.23 90/09/19 15:29:54 Ian_Stewartson
+ * Allow builtin commands to selected/de-selected
+ *
+ * Revision 1.22 90/08/24 21:53:13 Ian_Stewartson
+ * Add support for POSIX macro command {x#y} and {x%y}
+ *
X * Revision 1.21 90/08/14 23:54:44 MS_user
X * Add addition value to env structure
X * Add some new publics
***************
*** 85,91 ****
X *
X */
X
! #define PATCHLEVEL 7
X #define LINE_MAX 1000 /* Command line length */
X #define HISTORY_MAX 100 /* History array length */
X /* Space for full file name */
--- 91,97 ----
X *
X */
X
! #define PATCHLEVEL 8
X #define LINE_MAX 1000 /* Command line length */
X #define HISTORY_MAX 100 /* History array length */
X /* Space for full file name */
***************
*** 168,179 ****
X struct builtin {
X char *command;
X int (*fn)(C_Op *);
X };
X
X /*
! * actions determining the environment of a process
X */
X
X #define FEXEC 0x0001 /* execute without forking */
X
X /* MSDOS Memory Control Block chain structure */
--- 174,193 ----
X struct builtin {
X char *command;
X int (*fn)(C_Op *);
+ int mode;
X };
X
X /*
! * Valid values of mode
X */
X
+ #define BLT_ALWAYS 0x0001 /* Always use builtin version */
+ #define BLT_CURRENT 0x0002 /* Currently use builtin version */
+
+ /*
+ * actions determining the environment of a process
+ */
+
X #define FEXEC 0x0001 /* execute without forking */
X
X /* MSDOS Memory Control Block chain structure */
***************
*** 376,384 ****
X /* depth */
X
X /*
! * Variable list
X */
X
X typedef struct var {
X char *value; /* Value */
X char *name; /* Name */
--- 390,407 ----
X /* depth */
X
X /*
! * Mode values for new gmatch
X */
X
+ #define GM_ALL 0 /* Match full string */
+ #define GM_SHORTEST 1 /* Shortest prefix/suffix */
+ #define GM_LONGEST 2 /* Longest prefix/suffix */
+
+ /*
+ /*
+ * Variable list
+ */
+
X typedef struct var {
X char *value; /* Value */
X char *name; /* Name */
***************
*** 531,537 ****
X extern void s_vstatus (Var_List *, int);
X extern bool isassign (char *);
X extern bool assign (char *, int);
! extern bool gmatch (char *, char *, bool);
X extern char *getcell (unsigned int);
X extern void freecell (char *);
X extern void freearea (int);
--- 554,561 ----
X extern void s_vstatus (Var_List *, int);
X extern bool isassign (char *);
X extern bool assign (char *, int);
! extern bool gmatch (char *, char *, bool, char **, int);
! extern bool gmatch_suffix (char *, char *, bool, char **, int);
X extern char *getcell (unsigned int);
X extern void freecell (char *);
X extern void freearea (int);
***************
*** 574,580 ****
X extern void put_prompt (char *);
X extern bool eqname (char *, char *);
X extern bool any (char, char *);
! extern int (*inbuilt (char *))();
X extern char *path_append (char *, char *, char *);
X extern void unset (char *, bool);
X extern int S_open (bool, char *, int, ...);
--- 598,604 ----
X extern void put_prompt (char *);
X extern bool eqname (char *, char *);
X extern bool any (char, char *);
! extern int (*inbuilt (char *, bool *))();
X extern char *path_append (char *, char *, char *);
X extern void unset (char *, bool);
X extern int S_open (bool, char *, int, ...);
Index: shell/sh0.asm
Prereq: 1.10
*** ../sh16.3/shell/sh0.asm Fri Aug 17 21:33:41 1990
--- shell/sh0.asm Tue Nov 6 19:19:30 1990
***************
*** 16,22 ****
X ; 2. The sources (or parts thereof) or objects generated from the sources
X ; (or parts of sources) cannot be sold under any circumstances.
X ;
! ; $Header: C:/SRC/SHELL/RCS/sh0.asm 1.10 90/05/31 17:46:31 MS_user Exp $
X ;
X ; $Log: sh0.asm $
X ; Revision 1.10 90/05/31 17:46:31 MS_user
--- 16,22 ----
X ; 2. The sources (or parts thereof) or objects generated from the sources
X ; (or parts of sources) cannot be sold under any circumstances.
X ;
! ; $Header: D:/SRC/SHELL/RCS/sh0.asm 1.10 90/05/31 17:46:31 MS_user Exp $
X ;
X ; $Log: sh0.asm $
X ; Revision 1.10 90/05/31 17:46:31 MS_user
Index: shell/sh1.c
Prereq: 1.17
*** ../sh16.3/shell/sh1.c Fri Aug 17 21:32:33 1990
--- shell/sh1.c Tue Nov 6 19:20:30 1990
***************
*** 13,77 ****
X * 2. The sources (or parts thereof) or objects generated from the sources
X * (or parts of sources) cannot be sold under any circumstances.
X *
! * $Header: C:/SRC/SHELL/RCS/sh1.c 1.17 90/08/14 23:32:53 MS_user Exp $
X *
X * $Log: sh1.c $
X * Revision 1.17 90/08/14 23:32:53 MS_user
X * Fix memory bugs - Add malloc checking functions for debug
X * Make Convert_Backslashes public
! *
X * Revision 1.16 90/05/31 09:48:06 MS_user
X * Implement partial write when swapping to disk
X * Add some signal lockouts to prevent corruption
! *
X * Revision 1.15 90/05/15 21:08:59 MS_user
X * Restore original directory on exit
! *
X * Revision 1.14 90/04/25 22:33:28 MS_user
X * Fix rsh check for PATH
! *
X * Revision 1.13 90/04/25 09:18:12 MS_user
X * Change version message processing
! *
X * Revision 1.12 90/04/04 11:32:12 MS_user
X * Change MAILPATH to use a semi-colon and not a colon for DOS
! *
X * Revision 1.11 90/04/03 17:58:35 MS_user
X * Stop shell exit from lowest level CLI
! *
X * Revision 1.10 90/03/27 20:24:49 MS_user
X * Fix problem with Interrupts not restoring std??? and clearing extended file
! *
X * Revision 1.9 90/03/26 20:56:13 MS_user
X * Change I/O restore so that "exec >filename" works
! *
X * Revision 1.8 90/03/26 04:30:14 MS_user
X * Remove original Interrupt 24 save address
! *
X * Revision 1.7 90/03/12 20:16:22 MS_user
X * Save program name for Initialisation file processing
! *
X * Revision 1.6 90/03/09 16:05:33 MS_user
X * Add build file name function and change the profile check to use it
! *
X * Revision 1.5 90/03/06 16:49:14 MS_user
X * Add disable history option
! *
X * Revision 1.4 90/03/06 15:09:27 MS_user
X * Add Unix PATH variable conversion
! *
X * Revision 1.3 90/03/05 13:47:45 MS_user
X * Get /etc/profile and profile order rigth
X * Use $HOME/profile and not profile
X * Check cursor position before outputing prompt
X * Move some of processing in main to sub-routines
! *
X * Revision 1.2 90/02/14 04:46:20 MS_user
X * Add Interrupt 24 processing
! *
X * Revision 1.1 90/01/25 13:40:39 MS_user
X * Initial revision
! *
X */
X
X #include <sys/types.h>
--- 13,83 ----
X * 2. The sources (or parts thereof) or objects generated from the sources
X * (or parts of sources) cannot be sold under any circumstances.
X *
! * $Header: D:/SRC/SHELL/RCS/sh1.c 1.19 90/11/06 19:13:39 Ian_Stewartson Exp $
X *
X * $Log: sh1.c $
+ * Revision 1.19 90/11/06 19:13:39 Ian_Stewartson
+ * Add deletion of swap file on interrupt
+ *
+ * Revision 1.18 90/08/24 21:54:05 Ian_Stewartson
+ * Add support for POSIX macro command {x#y} and {x%y}
+ *
X * Revision 1.17 90/08/14 23:32:53 MS_user
X * Fix memory bugs - Add malloc checking functions for debug
X * Make Convert_Backslashes public
! *
X * Revision 1.16 90/05/31 09:48:06 MS_user
X * Implement partial write when swapping to disk
X * Add some signal lockouts to prevent corruption
! *
X * Revision 1.15 90/05/15 21:08:59 MS_user
X * Restore original directory on exit
! *
X * Revision 1.14 90/04/25 22:33:28 MS_user
X * Fix rsh check for PATH
! *
X * Revision 1.13 90/04/25 09:18:12 MS_user
X * Change version message processing
! *
X * Revision 1.12 90/04/04 11:32:12 MS_user
X * Change MAILPATH to use a semi-colon and not a colon for DOS
! *
X * Revision 1.11 90/04/03 17:58:35 MS_user
X * Stop shell exit from lowest level CLI
! *
X * Revision 1.10 90/03/27 20:24:49 MS_user
X * Fix problem with Interrupts not restoring std??? and clearing extended file
! *
X * Revision 1.9 90/03/26 20:56:13 MS_user
X * Change I/O restore so that "exec >filename" works
! *
X * Revision 1.8 90/03/26 04:30:14 MS_user
X * Remove original Interrupt 24 save address
! *
X * Revision 1.7 90/03/12 20:16:22 MS_user
X * Save program name for Initialisation file processing
! *
X * Revision 1.6 90/03/09 16:05:33 MS_user
X * Add build file name function and change the profile check to use it
! *
X * Revision 1.5 90/03/06 16:49:14 MS_user
X * Add disable history option
! *
X * Revision 1.4 90/03/06 15:09:27 MS_user
X * Add Unix PATH variable conversion
! *
X * Revision 1.3 90/03/05 13:47:45 MS_user
X * Get /etc/profile and profile order rigth
X * Use $HOME/profile and not profile
X * Check cursor position before outputing prompt
X * Move some of processing in main to sub-routines
! *
X * Revision 1.2 90/02/14 04:46:20 MS_user
X * Add Interrupt 24 processing
! *
X * Revision 1.1 90/01/25 13:40:39 MS_user
X * Initial revision
! *
X */
X
X #include <sys/types.h>
***************
*** 528,534 ****
X
X Clear_Swap_File ();
X
! /* If this is a command only - restore the directory because DOS doesn't
X * and the user might expect it
X */
X
--- 534,540 ----
X
X Clear_Swap_File ();
X
! /* If this is a command only - restore the directory because DOS doesn't
X * and the user might expect it
X */
X
***************
*** 713,720 ****
X signal (SIGINT, onintr);
X SW_intr = 1;
X
! /* Are we talking to the user? Yes - check in parser */
X
X if (talking)
X {
X if (inparse)
--- 719,731 ----
X signal (SIGINT, onintr);
X SW_intr = 1;
X
! /* Zap the swap file, just in case it got corrupted */
X
+ S_close (SW_fp, TRUE);
+ Clear_Swap_File ();
+
+ /* Are we talking to the user? Yes - check in parser */
+
X if (talking)
X {
X if (inparse)
***************
*** 775,782 ****
--- 786,800 ----
X register int i;
X {
X if (i == SIGINT) /* Need this because swapper sets it */
+ {
X SW_intr = 0;
X
+ /* Zap the swap file, just in case it got corrupted */
+
+ S_close (SW_fp, TRUE);
+ Clear_Swap_File ();
+ }
+
X trapset = i;
X signal (i, sig);
X }
***************
*** 1185,1298 ****
X }
X
X /*
! * Match a pattern as in sh(1).
X */
X
! bool gmatch (s, p, IgnoreCase)
! register char *s, *p;
X bool IgnoreCase;
X {
! register int sc, pc;
X
! if ((s == (char *)NULL) || (p == (char *)NULL))
X return FALSE;
X
! while ((pc = *(p++) & CMASK) != '\0')
X {
! sc = *(s++) & QMASK;
X
! switch (pc)
X {
X case '[': /* Class expression */
! if ((p = cclass (p, sc, IgnoreCase)) == (char *)NULL)
X return FALSE;
X
X break;
X
X case '?': /* Match any character */
! if (sc == 0)
X return FALSE;
X
X break;
X
X case '*': /* Match as many as possible */
! s--;
X do
X {
! if (!*p || gmatch (s, p, IgnoreCase))
! return TRUE;
X
! } while (*(s++));
X
! return FALSE;
X
X default:
X if (IgnoreCase)
X {
! sc = tolower (sc);
! pc = tolower ((pc & ~QUOTE));
X }
X
! if (sc != (pc & ~QUOTE))
X return FALSE;
X }
X }
X
! return (*s == 0) ? TRUE : FALSE;
! }
X
X /*
X * Process a class expression - []
X */
X
! static char *cclass (p, sub, IgnoreCase)
! register char *p;
! register int sub;
X bool IgnoreCase;
X {
! register int c, d, not, found;
X
X /* Exclusive or inclusive class */
X
! if ((not = *p == NOT) != 0)
! p++;
X
X found = not;
X
X do
X {
! if (!*p)
X return (char *)NULL;
X
X /* Get the next character in class, converting to lower case if necessary */
X
! c = IgnoreCase ? tolower ((*p & CMASK)) : (*p & CMASK);
X
X /* If this is a range, get the end of range character */
X
! if ((*(p + 1) == '-') && (*(p + 2) != ']'))
X {
! d = IgnoreCase ? tolower ((*(p + 2) & CMASK)) : (*(p + 2) & CMASK);
! p++;
X }
X
X else
! d = c;
X
X /* Is the current character in the class? */
X
! if ((c <= sub) && (sub <= d))
X found = !not;
X
! } while (*(++p) != ']');
X
! return found ? p + 1 : (char *)NULL;
X }
X
X /*
! * Get a string in a malloced area
X */
X
X char *getcell (nbytes)
X unsigned int nbytes;
X {
--- 1203,1381 ----
X }
X
X /*
! * Match a pattern as in sh(1). Enhancement to handle prefix processing
! *
! * IgnoreCase - ignore case on comparisions.
! * end - end of match in 'string'.
! * mode - mode for match processing - see GM_ flags in sh.h
X */
X
! bool gmatch (string, pattern, IgnoreCase, end, mode)
! register char *string, *pattern;
X bool IgnoreCase;
+ char **end;
+ int mode;
X {
! register int string_c, pattern_c;
! char *save_end;
X
! if ((string == (char *)NULL) || (pattern == (char *)NULL))
X return FALSE;
X
! while ((pattern_c = *(pattern++) & CMASK) != '\0')
X {
! string_c = *(string++) & QMASK;
X
! switch (pattern_c)
X {
X case '[': /* Class expression */
! if ((pattern = cclass (pattern, string_c, IgnoreCase)) == (char *)NULL)
X return FALSE;
X
X break;
X
X case '?': /* Match any character */
! if (string_c == 0)
X return FALSE;
X
X break;
X
X case '*': /* Match as many as possible */
! --string;
! save_end = (char *)NULL;
!
X do
X {
! if (!*pattern ||
! gmatch (string, pattern, IgnoreCase, end, mode))
! {
! if (mode == GM_LONGEST)
! save_end = *end;
X
! else
! return TRUE;
! }
X
! } while (*(string++));
X
+ if (end != (char **)NULL)
+ *end = save_end;
+
+ return (save_end == (char *)NULL) ? FALSE : TRUE;
+
X default:
X if (IgnoreCase)
X {
! string_c = tolower (string_c);
! pattern_c = tolower ((pattern_c & ~QUOTE));
X }
X
! if (string_c != (pattern_c & ~QUOTE))
X return FALSE;
X }
X }
X
! if (end != (char **)NULL)
! {
! *end = string;
! return TRUE;
! }
X
+ return (*string == 0) ? TRUE : FALSE;
+ }
+
X /*
X * Process a class expression - []
X */
X
! static char *cclass (pattern, string_c, IgnoreCase)
! register char *pattern;
! register int string_c;
X bool IgnoreCase;
X {
! register int llimit_c, ulimit_c, not, found;
X
X /* Exclusive or inclusive class */
X
! if ((not = *pattern == NOT) != 0)
! pattern++;
X
X found = not;
X
X do
X {
! if (!*pattern)
X return (char *)NULL;
X
X /* Get the next character in class, converting to lower case if necessary */
X
! llimit_c = IgnoreCase ? tolower ((*pattern & CMASK))
! : (*pattern & CMASK);
X
X /* If this is a range, get the end of range character */
X
! if ((*(pattern + 1) == '-') && (*(pattern + 2) != ']'))
X {
! ulimit_c = IgnoreCase ? tolower ((*(pattern + 2) & CMASK))
! : (*(pattern + 2) & CMASK);
! pattern++;
X }
X
X else
! ulimit_c = llimit_c;
X
X /* Is the current character in the class? */
X
! if ((llimit_c <= string_c) && (string_c <= ulimit_c))
X found = !not;
X
! } while (*(++pattern) != ']');
X
! return found ? pattern + 1 : (char *)NULL;
X }
X
X /*
! * Suffix processing - find the longest/shortest suffix.
X */
X
+ bool gmatch_suffix (string, pattern, IgnoreCase, start, mode)
+ register char *string, *pattern;
+ bool IgnoreCase;
+ char **start;
+ int mode;
+ {
+ char *save_start = (char *)NULL;
+
+ /* Scan the string, looking for a match to the end */
+
+ while (*string)
+ {
+ if (gmatch (string, pattern, IgnoreCase, (char **)NULL, GM_ALL))
+ {
+
+ /* If longest, stop here */
+
+ if (mode == GM_LONGEST)
+ {
+ *start = string;
+ return TRUE;
+ }
+
+ /* Save the start of the shortest string so far and continue */
+
+ save_start = string;
+ }
+
+ ++string;
+ }
+
+ return ((*start = save_start) == (char *)NULL) ? FALSE : TRUE;
+ }
+
+ /*
+ * Get a string in a malloced area
+ */
+
X char *getcell (nbytes)
X unsigned int nbytes;
X {
***************
*** 1323,1329 ****
X print_warn ("Malloc access to bad segment\n");
X return (char *)NULL;
X }
!
X np->magic1 = MAGIC1;
X np->len = nbytes;
X rp = (char *)(np + 1);
--- 1406,1412 ----
X print_warn ("Malloc access to bad segment\n");
X return (char *)NULL;
X }
!
X np->magic1 = MAGIC1;
X np->len = nbytes;
X rp = (char *)(np + 1);
***************
*** 1362,1370 ****
X /* Disable signals */
X
X save_signal = signal (SIGINT, SIG_IGN);
-
- /* Find the string in the chain */
X
X if (s != (char *)NULL)
X {
X while (cp != (s_region *)NULL)
--- 1445,1453 ----
X /* Disable signals */
X
X save_signal = signal (SIGINT, SIG_IGN);
X
+ /* Find the string in the chain */
+
X if (s != (char *)NULL)
X {
X while (cp != (s_region *)NULL)
***************
*** 2012,2018 ****
X str1++;
X str2++;
X }
!
X return rtn;
X }
X
--- 2095,2101 ----
X str1++;
X str2++;
X }
!
X return rtn;
X }
X
***************
*** 2064,2074 ****
X
X while (--len >= 0)
X {
! if ((*(str1++) = *(str2++)) == 0)
X {
X while (--len >= 0)
X *(str1++) = 0;
!
X break;
X }
X }
--- 2147,2157 ----
X
X while (--len >= 0)
X {
! if ((*(str1++) = *(str2++)) == 0)
X {
X while (--len >= 0)
X *(str1++) = 0;
!
X break;
X }
X }
Index: shell/sh3.c
Prereq: 1.24
*** ../sh16.3/shell/sh3.c Fri Aug 17 21:34:34 1990
--- shell/sh3.c Tue Nov 6 19:21:26 1990
***************
*** 13,21 ****
X * 2. The sources (or parts thereof) or objects generated from the sources
X * (or parts of sources) cannot be sold under any circumstances.
X *
! * $Header: C:/SRC/SHELL/RCS/sh3.c 1.24 90/08/16 10:28:47 Ian_Stewartson Exp $
X *
X * $Log: sh3.c $
X * Revision 1.24 90/08/16 10:28:47 Ian_Stewartson
X * Find setting of switch character for DOS4 for batch files
X *
--- 13,32 ----
X * 2. The sources (or parts thereof) or objects generated from the sources
X * (or parts of sources) cannot be sold under any circumstances.
X *
! * $Header: C:/SRC/SHELL/RCS/sh3.c 1.27 90/09/19 15:30:31 Ian_Stewartson Exp $
X *
X * $Log: sh3.c $
+ * Revision 1.27 90/09/19 15:30:31 Ian_Stewartson
+ * Allow builtin commands to selected/de-selected
+ *
+ * Revision 1.26 90/09/11 20:06:11 Ian_Stewartson
+ * Add support for buitlin command, including the alway builtin functions
+ * Change search order to match POSIX
+ *
+ * Revision 1.25 90/08/24 21:55:00 Ian_Stewartson
+ * Change processing order (function, external, internal) to conform to
+ * POSIX. Update to gmatch for macro command changes
+ *
X * Revision 1.24 90/08/16 10:28:47 Ian_Stewartson
X * Find setting of switch character for DOS4 for batch files
X *
***************
*** 144,149 ****
--- 155,161 ----
X static char *AE2big = "arg/env list too big";
X static char *EMS_emsg = "Warning: EMS Error (%x)\n";
X static char *XMS_emsg = "Warning: XMS Error (%x)\n";
+ static char *EF_msg = "%s: %s\n";
X /* Extended Command line processing file name */
X static char *Extend_file = (char *)NULL;
X static char *Swap_File = (char *)NULL; /* Swap file */
***************
*** 475,481 ****
--- 487,495 ----
X void (*sig_int)();
X char **owp = wp;
X bool spawn = FALSE;
+ bool builtin = FALSE;
X Fun_Ops *fop;
+ int i;
X
X if (t->type == TCOM)
X {
***************
*** 510,522 ****
X /* Check for built in commands */
X
X else if (cp != (char *)NULL)
! shcom = inbuilt (cp);
X }
X
X /* Unix fork simulation? */
X
X t->words = wp;
! if (shcom == NULL && (act & FEXEC) == 0)
X {
X spawn = TRUE;
X
--- 524,536 ----
X /* Check for built in commands */
X
X else if (cp != (char *)NULL)
! shcom = inbuilt (cp, &builtin);
X }
X
X /* Unix fork simulation? */
X
X t->words = wp;
! if ((act & FEXEC) == 0)
X {
X spawn = TRUE;
X
***************
*** 534,540 ****
X
X while (((cp = *owp++) != (char *)NULL) && assign (cp, COPYV))
X {
! if (shcom == NULL)
X s_vstatus (lookup (cp, TRUE), EXPORT);
X }
X
--- 548,554 ----
X
X while (((cp = *owp++) != (char *)NULL) && assign (cp, COPYV))
X {
! if (shcom == (int (*)())NULL)
X s_vstatus (lookup (cp, TRUE), EXPORT);
X }
X
***************
*** 565,572 ****
X }
X }
X
- if (shcom)
- return restore_std (setstatus ((*shcom)(t)), TRUE);
X
X /* All fids above 10 are autoclosed in the exec file because we have used
X * the O_NOINHERIT flag. Note I patched open.obj to pass this flag to the
--- 579,584 ----
***************
*** 598,604 ****
X * in some processing for return.
X */
X
! if ((fop = Fun_Search (wp[0])) != (Fun_Ops *)NULL)
X {
X char **s_dolv = dolv;
X int s_dolc = dolc;
--- 610,616 ----
X * in some processing for return.
X */
X
! if (!builtin && (fop = Fun_Search (wp[0])) != (Fun_Ops *)NULL)
X {
X char **s_dolv = dolv;
X int s_dolc = dolc;
***************
*** 651,659 ****
X
X /* Ok - execute the program */
X
! return restore_std (rexecve (wp[0], wp, makenv (), spawn), TRUE);
! }
X
X /*
X * Restore Local Environment
X */
--- 663,685 ----
X
X /* Ok - execute the program */
X
! if (!builtin)
! rv = rexecve (wp[0], wp, makenv (), spawn);
X
+ /* If we didn't find it, check for internal command */
+
+ if (builtin || ((rv == -1) && (errno == ENOENT)))
+ {
+ if (shcom != (int (*)())NULL)
+ rv = setstatus ((*shcom)(t));
+
+ else
+ print_warn (EF_msg, wp[0], "not found");
+ }
+
+ return restore_std (rv, TRUE);
+ }
+
X /*
X * Restore Local Environment
X */
***************
*** 835,841 ****
X
X for (wp = t1->words; *wp != (char *)NULL;)
SHAR_EOF
true || echo 'restore of Patch1.6.4 failed'
fi
echo 'End of part 1'
echo 'File Patch1.6.4 is continued in part 2'
echo 2 > _shar_seq_.tmp
exit 0
exit 0 # Just in case...
--
Kent Landfield INTERNET: kent at sparky.IMD.Sterling.COM
Sterling Software, IMD UUCP: uunet!sparky!kent
Phone: (402) 291-8300 FAX: (402) 291-4362
Please send comp.sources.misc-related mail to kent at uunet.uu.net.
More information about the Comp.sources.misc
mailing list