pdp11v/usr/src/cmd/sh/main.c
/* @(#)main.c 1.2 */
/* 3.0 SID # 1.3 */
#
/*
* UNIX shell
*
* S. R. Bourne
* Bell Telephone Laboratories
*
*/
#include "defs.h"
#include "sym.h"
#include "timeout.h"
#include <sys/types.h>
#include <sys/stat.h>
#include "dup.h"
LOCAL BOOL beenhere = FALSE;
CHAR tmpout[20] = "/tmp/sh-";
FILEBLK stdfile;
FILE standin = &stdfile;
#ifdef pdp11
#include <execargs.h>
#endif
PROC VOID exfile();
main(c, v, e)
INT c;
STRING v[];
STRING e[];
{
REG INT rflag=ttyflg;
INT rsflag=1; /* local restricted flag */
STRING sim;
/* initialise storage allocation */
stdsigs();
setbrk(BRKINCR);
addblok((POS)0);
/* set names from userenv */
/* 'rsflag' is non-zero if SHELL variable is
set in environment and contains an'r' in
the simple file part of the value. */
rsflag=getenv();
/* a shell is also restricted if argv(0) has
an 'r' in its simple name
*/
#ifndef RES /* restricted shell code */
IF c>0 ANDF any('r', sim=(STRING) simple(*v)) THEN rflag=0 FI
#endif
/* look for options */
/* dolc is $# */
dolc=options(c,v);
IF dolc < 2 THEN flags |= stdflg;
BEGIN REG CHAR *flagc = flagadr;
WHILE *flagc DO flagc++ OD
*flagc = STDFLG;
END
FI
IF (flags&stdflg)==0
THEN dolc--;
FI
dolv=v+c-dolc; dolc--;
/* return here for shell file execution */
/* but not for parenthesis subshells */
setjmp(subshell);
/* number of positional parameters */
assnum(&dolladr, dolc); /* $# */
cmdadr=dolv[0]; /* cmdadr is $0 */
/* set pidname '$$' */
assnum(&pidadr, getpid());
/* set up temp file names */
settmp();
/* default internal field separators - $IFS */
dfault(&ifsnod, sptbnl);
IF (beenhere++)==FALSE
THEN /* ? profile */
IF *(sim=(STRING) simple(cmdadr)) == '-'
THEN /* system profile */
#ifndef RES
IF (input=pathopen(nullstr, sysprofile)) >=0
THEN exfile(rflag); /* file exists */
FI
#endif
IF (input=pathopen(nullstr, profile)) >=0
THEN exfile(rflag); flags &= ~ttyflg;
FI
FI
IF rsflag==0 ORF rflag==0 THEN flags |= rshflg FI
/* open input file if specified */
IF comdiv
THEN estabf(comdiv); input = -1;
ELSE input=((flags&stdflg) ? 0 : chkopen(cmdadr));
comdiv--;
FI
#ifdef pdp11
ELSE *execargs=(STRING) dolv; /* for `ps' cmd */
#endif
FI
exfile(0);
done();
}
LOCAL VOID exfile(prof)
BOOL prof;
{
L_INT mailtime = 0; /* Must not be a register variable */
REG INT userid;
struct stat statb;
/* move input */
IF input>0
THEN Ldup(input,INIO);
input=INIO;
FI
/* move output to safe place */
IF output==2
THEN Ldup(dup(2),OTIO);
output=OTIO;
FI
userid=geteuid();
/* decide whether interactive */
IF (flags&intflg)
ORF ((flags&oneflg)==0
ANDF isatty(output)
ANDF isatty(input))
THEN dfault(&ps1nod, (userid?stdprompt:supprompt));
dfault(&ps2nod, readmsg);
flags |= ttyflg|prompt; ignsig(KILL);
ELSE flags |= prof; flags &= ~prompt;
FI
IF setjmp(errshell) ANDF prof
THEN close(input); return;
FI
/* error return here */
loopcnt=breakcnt=peekc=0; iopend=0;
IF input>=0 THEN initf(input) FI
/* command loop */
LOOP tdystak(0);
stakchk(); /* may reduce sbrk */
exitset();
IF (flags&prompt) ANDF standin->fstak==0 ANDF !eof
THEN IF mailnod.namval
THEN IF stat(mailnod.namval,&statb)>=0
THEN IF statb.st_size
ANDF mailtime
ANDF statb.st_mtime != mailtime
THEN prs(mailmsg)
FI
mailtime=statb.st_mtime;
ELIF mailtime==0
THEN mailtime=1
FI
FI
prs(ps1nod.namval); alarm(TIMEOUT); flags |= waiting;
FI
trapnote=0; peekc=readc();
IF eof
THEN return;
FI
alarm(0); flags &= ~waiting;
execute(cmd(NL,MTFLG),0,eflag);
eof |= (flags&oneflg);
POOL
}
chkpr(eor)
char eor;
{
IF (flags&prompt) ANDF standin->fstak==0 ANDF eor==NL
THEN prs(ps2nod.namval);
FI
}
settmp()
{
itos(getpid()); serial=0;
tmpnam=movstr(numbuf,&tmpout[TMPNAM]);
}
Ldup(fa, fb)
REG INT fa, fb;
{
#ifdef RES
dup(fa|DUPFLG, fb);
close(fa);
ioctl(fb, FIOCLEX, 0);
#else /* TS lacks two-arg dup, ioctl */
IF fa >= 0
THEN close(fb);
fcntl(fa,0,fb); /* normal dup */
close(fa);
fcntl(fb,2,1) /* autoclose for fb */
FI
#endif
}