13e12c5d1SDavid du Colombier /*
23e12c5d1SDavid du Colombier * Unix versions of system-specific functions
33e12c5d1SDavid du Colombier * By convention, exported routines herein have names beginning with an
43e12c5d1SDavid du Colombier * upper case letter.
53e12c5d1SDavid du Colombier */
63e12c5d1SDavid du Colombier #include "rc.h"
71936bb65SDavid du Colombier #include "io.h"
83e12c5d1SDavid du Colombier #include "exec.h"
93e12c5d1SDavid du Colombier #include <errno.h>
101936bb65SDavid du Colombier
11bad30d5dSDavid du Colombier char *Rcmain = "/usr/lib/rcmain";
12bad30d5dSDavid du Colombier char *Fdprefix = "/dev/fd/";
131936bb65SDavid du Colombier
141936bb65SDavid du Colombier void execfinit(void);
151936bb65SDavid du Colombier
163e12c5d1SDavid du Colombier struct builtin Builtin[] = {
173e12c5d1SDavid du Colombier "cd", execcd,
183e12c5d1SDavid du Colombier "whatis", execwhatis,
193e12c5d1SDavid du Colombier "eval", execeval,
203e12c5d1SDavid du Colombier "exec", execexec, /* but with popword first */
213e12c5d1SDavid du Colombier "exit", execexit,
223e12c5d1SDavid du Colombier "shift", execshift,
233e12c5d1SDavid du Colombier "wait", execwait,
243e12c5d1SDavid du Colombier "umask", execumask,
253e12c5d1SDavid du Colombier ".", execdot,
263e12c5d1SDavid du Colombier "finit", execfinit,
273e12c5d1SDavid du Colombier "flag", execflag,
283e12c5d1SDavid du Colombier 0
293e12c5d1SDavid du Colombier };
303e12c5d1SDavid du Colombier #define SEP '\1'
313e12c5d1SDavid du Colombier char **environp;
32dc5a79c1SDavid du Colombier
33dc5a79c1SDavid du Colombier struct word*
enval(s)34dc5a79c1SDavid du Colombier enval(s)
353e12c5d1SDavid du Colombier register char *s;
363e12c5d1SDavid du Colombier {
37dc5a79c1SDavid du Colombier char *t, c;
38dc5a79c1SDavid du Colombier struct word *v;
393e12c5d1SDavid du Colombier for(t = s;*t && *t!=SEP;t++);
403e12c5d1SDavid du Colombier c=*t;
413e12c5d1SDavid du Colombier *t='\0';
423e12c5d1SDavid du Colombier v = newword(s, c=='\0'?(struct word *)0:enval(t+1));
433e12c5d1SDavid du Colombier *t = c;
443e12c5d1SDavid du Colombier return v;
453e12c5d1SDavid du Colombier }
461936bb65SDavid du Colombier
471936bb65SDavid du Colombier void
Vinit(void)481936bb65SDavid du Colombier Vinit(void)
491936bb65SDavid du Colombier {
503e12c5d1SDavid du Colombier extern char **environ;
51dc5a79c1SDavid du Colombier char *s;
52dc5a79c1SDavid du Colombier char **env = environ;
533e12c5d1SDavid du Colombier environp = env;
543e12c5d1SDavid du Colombier for(;*env;env++){
553e12c5d1SDavid du Colombier for(s=*env;*s && *s!='(' && *s!='=';s++);
563e12c5d1SDavid du Colombier switch(*s){
573e12c5d1SDavid du Colombier case '\0':
583e12c5d1SDavid du Colombier pfmt(err, "environment %q?\n", *env);
593e12c5d1SDavid du Colombier break;
603e12c5d1SDavid du Colombier case '=':
613e12c5d1SDavid du Colombier *s='\0';
623e12c5d1SDavid du Colombier setvar(*env, enval(s+1));
633e12c5d1SDavid du Colombier *s='=';
643e12c5d1SDavid du Colombier break;
653e12c5d1SDavid du Colombier case '(': /* ignore functions for now */
663e12c5d1SDavid du Colombier break;
673e12c5d1SDavid du Colombier }
683e12c5d1SDavid du Colombier }
693e12c5d1SDavid du Colombier }
701936bb65SDavid du Colombier
713e12c5d1SDavid du Colombier char **envp;
721936bb65SDavid du Colombier
731936bb65SDavid du Colombier void
Xrdfn(void)741936bb65SDavid du Colombier Xrdfn(void)
751936bb65SDavid du Colombier {
76dc5a79c1SDavid du Colombier char *s;
77dc5a79c1SDavid du Colombier int len;
783e12c5d1SDavid du Colombier for(;*envp;envp++){
793e12c5d1SDavid du Colombier for(s=*envp;*s && *s!='(' && *s!='=';s++);
803e12c5d1SDavid du Colombier switch(*s){
813e12c5d1SDavid du Colombier case '\0':
823e12c5d1SDavid du Colombier pfmt(err, "environment %q?\n", *envp);
833e12c5d1SDavid du Colombier break;
843e12c5d1SDavid du Colombier case '=': /* ignore variables */
853e12c5d1SDavid du Colombier break;
863e12c5d1SDavid du Colombier case '(': /* Bourne again */
873e12c5d1SDavid du Colombier s=*envp+3;
883e12c5d1SDavid du Colombier envp++;
893e12c5d1SDavid du Colombier len = strlen(s);
903e12c5d1SDavid du Colombier s[len]='\n';
913e12c5d1SDavid du Colombier execcmds(opencore(s, len+1));
923e12c5d1SDavid du Colombier s[len]='\0';
933e12c5d1SDavid du Colombier return;
943e12c5d1SDavid du Colombier }
953e12c5d1SDavid du Colombier }
963e12c5d1SDavid du Colombier Xreturn();
973e12c5d1SDavid du Colombier }
981936bb65SDavid du Colombier
993e12c5d1SDavid du Colombier union code rdfns[4];
1001936bb65SDavid du Colombier
1011936bb65SDavid du Colombier void
execfinit(void)1021936bb65SDavid du Colombier execfinit(void)
1031936bb65SDavid du Colombier {
1043e12c5d1SDavid du Colombier static int first = 1;
1053e12c5d1SDavid du Colombier if(first){
1063e12c5d1SDavid du Colombier rdfns[0].i = 1;
1073e12c5d1SDavid du Colombier rdfns[1].f = Xrdfn;
1083e12c5d1SDavid du Colombier rdfns[2].f = Xjump;
1093e12c5d1SDavid du Colombier rdfns[3].i = 1;
1103e12c5d1SDavid du Colombier first = 0;
1113e12c5d1SDavid du Colombier }
1123e12c5d1SDavid du Colombier Xpopm();
1133e12c5d1SDavid du Colombier envp = environp;
1143e12c5d1SDavid du Colombier start(rdfns, 1, runq->local);
1153e12c5d1SDavid du Colombier }
1161936bb65SDavid du Colombier
1171936bb65SDavid du Colombier int
cmpenv(const void * aa,const void * ab)1181936bb65SDavid du Colombier cmpenv(const void *aa, const void *ab)
1193e12c5d1SDavid du Colombier {
1201936bb65SDavid du Colombier char **a = aa, **b = ab;
1211936bb65SDavid du Colombier
1223e12c5d1SDavid du Colombier return strcmp(*a, *b);
1233e12c5d1SDavid du Colombier }
124dc5a79c1SDavid du Colombier
1251936bb65SDavid du Colombier char **
mkenv(void)1261936bb65SDavid du Colombier mkenv(void)
127dc5a79c1SDavid du Colombier {
128dc5a79c1SDavid du Colombier char **env, **ep, *p, *q;
129dc5a79c1SDavid du Colombier struct var **h, *v;
130dc5a79c1SDavid du Colombier struct word *a;
131dc5a79c1SDavid du Colombier int nvar = 0, nchr = 0, sep;
1321936bb65SDavid du Colombier
1333e12c5d1SDavid du Colombier /*
1341936bb65SDavid du Colombier * Slightly kludgy loops look at locals then globals.
1351936bb65SDavid du Colombier * locals no longer exist - geoff
1363e12c5d1SDavid du Colombier */
1371936bb65SDavid du Colombier for(h = gvar-1; h != &gvar[NVAR]; h++)
1381936bb65SDavid du Colombier for(v = h >= gvar? *h: runq->local; v ;v = v->next){
1393e12c5d1SDavid du Colombier if((v==vlook(v->name)) && v->val){
1403e12c5d1SDavid du Colombier nvar++;
1413e12c5d1SDavid du Colombier nchr+=strlen(v->name)+1;
1423e12c5d1SDavid du Colombier for(a = v->val;a;a = a->next)
1433e12c5d1SDavid du Colombier nchr+=strlen(a->word)+1;
1443e12c5d1SDavid du Colombier }
1453e12c5d1SDavid du Colombier if(v->fn){
1463e12c5d1SDavid du Colombier nvar++;
1473e12c5d1SDavid du Colombier nchr+=strlen(v->name)+strlen(v->fn[v->pc-1].s)+8;
1483e12c5d1SDavid du Colombier }
1493e12c5d1SDavid du Colombier }
1503e12c5d1SDavid du Colombier env = (char **)emalloc((nvar+1)*sizeof(char *)+nchr);
1513e12c5d1SDavid du Colombier ep = env;
1523e12c5d1SDavid du Colombier p = (char *)&env[nvar+1];
1531936bb65SDavid du Colombier for(h = gvar-1; h != &gvar[NVAR]; h++)
1541936bb65SDavid du Colombier for(v = h >= gvar? *h: runq->local;v;v = v->next){
1553e12c5d1SDavid du Colombier if((v==vlook(v->name)) && v->val){
1563e12c5d1SDavid du Colombier *ep++=p;
1573e12c5d1SDavid du Colombier q = v->name;
1583e12c5d1SDavid du Colombier while(*q) *p++=*q++;
1593e12c5d1SDavid du Colombier sep='=';
1603e12c5d1SDavid du Colombier for(a = v->val;a;a = a->next){
1613e12c5d1SDavid du Colombier *p++=sep;
1623e12c5d1SDavid du Colombier sep = SEP;
1633e12c5d1SDavid du Colombier q = a->word;
1643e12c5d1SDavid du Colombier while(*q) *p++=*q++;
1653e12c5d1SDavid du Colombier }
1663e12c5d1SDavid du Colombier *p++='\0';
1673e12c5d1SDavid du Colombier }
1683e12c5d1SDavid du Colombier if(v->fn){
1693e12c5d1SDavid du Colombier *ep++=p;
1703e12c5d1SDavid du Colombier *p++='#'; *p++='('; *p++=')'; /* to fool Bourne */
1713e12c5d1SDavid du Colombier *p++='f'; *p++='n'; *p++=' ';
1723e12c5d1SDavid du Colombier q = v->name;
1733e12c5d1SDavid du Colombier while(*q) *p++=*q++;
1743e12c5d1SDavid du Colombier *p++=' ';
1753e12c5d1SDavid du Colombier q = v->fn[v->pc-1].s;
1763e12c5d1SDavid du Colombier while(*q) *p++=*q++;
1773e12c5d1SDavid du Colombier *p++='\0';
1783e12c5d1SDavid du Colombier }
1793e12c5d1SDavid du Colombier }
1803e12c5d1SDavid du Colombier *ep = 0;
1811936bb65SDavid du Colombier qsort((void *)env, nvar, sizeof ep[0], cmpenv);
1823e12c5d1SDavid du Colombier return env;
1833e12c5d1SDavid du Colombier }
1843e12c5d1SDavid du Colombier char *sigmsg[] = {
1853e12c5d1SDavid du Colombier /* 0 normal */ 0,
1863e12c5d1SDavid du Colombier /* 1 SIGHUP */ "Hangup",
1873e12c5d1SDavid du Colombier /* 2 SIGINT */ 0,
1883e12c5d1SDavid du Colombier /* 3 SIGQUIT */ "Quit",
1893e12c5d1SDavid du Colombier /* 4 SIGILL */ "Illegal instruction",
1903e12c5d1SDavid du Colombier /* 5 SIGTRAP */ "Trace/BPT trap",
1913e12c5d1SDavid du Colombier /* 6 SIGIOT */ "abort",
1923e12c5d1SDavid du Colombier /* 7 SIGEMT */ "EMT trap",
1933e12c5d1SDavid du Colombier /* 8 SIGFPE */ "Floating exception",
1943e12c5d1SDavid du Colombier /* 9 SIGKILL */ "Killed",
1953e12c5d1SDavid du Colombier /* 10 SIGBUS */ "Bus error",
1963e12c5d1SDavid du Colombier /* 11 SIGSEGV */ "Memory fault",
1973e12c5d1SDavid du Colombier /* 12 SIGSYS */ "Bad system call",
1983e12c5d1SDavid du Colombier /* 13 SIGPIPE */ 0,
1993e12c5d1SDavid du Colombier /* 14 SIGALRM */ "Alarm call",
2003e12c5d1SDavid du Colombier /* 15 SIGTERM */ "Terminated",
2013e12c5d1SDavid du Colombier /* 16 unused */ "signal 16",
2023e12c5d1SDavid du Colombier /* 17 SIGSTOP */ "Process stopped",
2033e12c5d1SDavid du Colombier /* 18 unused */ "signal 18",
2043e12c5d1SDavid du Colombier /* 19 SIGCONT */ "Process continued",
2053e12c5d1SDavid du Colombier /* 20 SIGCHLD */ "Child death",
2063e12c5d1SDavid du Colombier };
2071936bb65SDavid du Colombier
2081936bb65SDavid du Colombier void
Waitfor(int pid,int persist)2091936bb65SDavid du Colombier Waitfor(int pid, int persist)
2101936bb65SDavid du Colombier {
211dc5a79c1SDavid du Colombier int wpid, sig;
212dc5a79c1SDavid du Colombier struct thread *p;
2133e12c5d1SDavid du Colombier int wstat;
2143e12c5d1SDavid du Colombier char wstatstr[12];
2151936bb65SDavid du Colombier
2163e12c5d1SDavid du Colombier for(;;){
2173e12c5d1SDavid du Colombier errno = 0;
2183e12c5d1SDavid du Colombier wpid = wait(&wstat);
219dc5a79c1SDavid du Colombier if(errno==EINTR && persist)
220dc5a79c1SDavid du Colombier continue;
221dc5a79c1SDavid du Colombier if(wpid==-1)
222dc5a79c1SDavid du Colombier break;
2233e12c5d1SDavid du Colombier sig = wstat&0177;
2243e12c5d1SDavid du Colombier if(sig==0177){
2253e12c5d1SDavid du Colombier pfmt(err, "trace: ");
2263e12c5d1SDavid du Colombier sig = (wstat>>8)&0177;
2273e12c5d1SDavid du Colombier }
2283e12c5d1SDavid du Colombier if(sig>(sizeof sigmsg/sizeof sigmsg[0]) || sigmsg[sig]){
229dc5a79c1SDavid du Colombier if(pid!=wpid)
230dc5a79c1SDavid du Colombier pfmt(err, "%d: ", wpid);
2313e12c5d1SDavid du Colombier if(sig<=(sizeof sigmsg/sizeof sigmsg[0]))
2323e12c5d1SDavid du Colombier pfmt(err, "%s", sigmsg[sig]);
2333e12c5d1SDavid du Colombier else if(sig==0177) pfmt(err, "stopped by ptrace");
2343e12c5d1SDavid du Colombier else pfmt(err, "signal %d", sig);
2353e12c5d1SDavid du Colombier if(wstat&0200)pfmt(err, " -- core dumped");
2363e12c5d1SDavid du Colombier pfmt(err, "\n");
2373e12c5d1SDavid du Colombier }
2383e12c5d1SDavid du Colombier wstat = sig?sig+1000:(wstat>>8)&0xFF;
2393e12c5d1SDavid du Colombier if(wpid==pid){
240dc5a79c1SDavid du Colombier inttoascii(wstatstr, wstat);
2413e12c5d1SDavid du Colombier setstatus(wstatstr);
2423e12c5d1SDavid du Colombier break;
2433e12c5d1SDavid du Colombier }
2443e12c5d1SDavid du Colombier else{
2453e12c5d1SDavid du Colombier for(p = runq->ret;p;p = p->ret)
2463e12c5d1SDavid du Colombier if(p->pid==wpid){
2473e12c5d1SDavid du Colombier p->pid=-1;
248dc5a79c1SDavid du Colombier inttoascii(p->status, wstat);
2493e12c5d1SDavid du Colombier break;
2503e12c5d1SDavid du Colombier }
2513e12c5d1SDavid du Colombier }
2523e12c5d1SDavid du Colombier }
2533e12c5d1SDavid du Colombier }
254dc5a79c1SDavid du Colombier
2551936bb65SDavid du Colombier char **
mkargv(a)2561936bb65SDavid du Colombier mkargv(a)
2573e12c5d1SDavid du Colombier register struct word *a;
2583e12c5d1SDavid du Colombier {
2593e12c5d1SDavid du Colombier char **argv = (char **)emalloc((count(a)+2)*sizeof(char *));
260dc5a79c1SDavid du Colombier char **argp = argv+1; /* leave one at front for runcoms */
2611936bb65SDavid du Colombier
2621936bb65SDavid du Colombier for(;a;a = a->next)
2631936bb65SDavid du Colombier *argp++=a->word;
2643e12c5d1SDavid du Colombier *argp = 0;
2653e12c5d1SDavid du Colombier return argv;
2663e12c5d1SDavid du Colombier }
2671936bb65SDavid du Colombier
2681936bb65SDavid du Colombier void
Updenv(void)2691936bb65SDavid du Colombier Updenv(void)
2701936bb65SDavid du Colombier {
2711936bb65SDavid du Colombier }
2721936bb65SDavid du Colombier
2731936bb65SDavid du Colombier void
Execute(struct word * args,struct word * path)2741936bb65SDavid du Colombier Execute(struct word *args, struct word *path)
2753e12c5d1SDavid du Colombier {
276dc5a79c1SDavid du Colombier char *msg="not found";
277dc5a79c1SDavid du Colombier int txtbusy = 0;
2783e12c5d1SDavid du Colombier char **env = mkenv();
2793e12c5d1SDavid du Colombier char **argv = mkargv(args);
2803e12c5d1SDavid du Colombier char file[512];
2811936bb65SDavid du Colombier
2823e12c5d1SDavid du Colombier for(;path;path = path->next){
2833e12c5d1SDavid du Colombier strcpy(file, path->word);
284dc5a79c1SDavid du Colombier if(file[0])
285dc5a79c1SDavid du Colombier strcat(file, "/");
2863e12c5d1SDavid du Colombier strcat(file, argv[1]);
2873e12c5d1SDavid du Colombier ReExec:
2883e12c5d1SDavid du Colombier execve(file, argv+1, env);
2893e12c5d1SDavid du Colombier switch(errno){
2903e12c5d1SDavid du Colombier case ENOEXEC:
2913e12c5d1SDavid du Colombier pfmt(err, "%s: Bourne again\n", argv[1]);
2923e12c5d1SDavid du Colombier argv[0]="sh";
2933e12c5d1SDavid du Colombier argv[1] = strdup(file);
2943e12c5d1SDavid du Colombier execve("/bin/sh", argv, env);
2953e12c5d1SDavid du Colombier goto Bad;
2963e12c5d1SDavid du Colombier case ETXTBSY:
2973e12c5d1SDavid du Colombier if(++txtbusy!=5){
2983e12c5d1SDavid du Colombier sleep(txtbusy);
2993e12c5d1SDavid du Colombier goto ReExec;
3003e12c5d1SDavid du Colombier }
3013e12c5d1SDavid du Colombier msg="text busy"; goto Bad;
302dc5a79c1SDavid du Colombier case EACCES:
303dc5a79c1SDavid du Colombier msg="no access";
304dc5a79c1SDavid du Colombier break;
305dc5a79c1SDavid du Colombier case ENOMEM:
306dc5a79c1SDavid du Colombier msg="not enough memory"; goto Bad;
307dc5a79c1SDavid du Colombier case E2BIG:
308dc5a79c1SDavid du Colombier msg="too big"; goto Bad;
3093e12c5d1SDavid du Colombier }
3103e12c5d1SDavid du Colombier }
3113e12c5d1SDavid du Colombier Bad:
3123e12c5d1SDavid du Colombier pfmt(err, "%s: %s\n", argv[1], msg);
3133e12c5d1SDavid du Colombier efree((char *)env);
3143e12c5d1SDavid du Colombier efree((char *)argv);
3153e12c5d1SDavid du Colombier }
3161936bb65SDavid du Colombier
3173e12c5d1SDavid du Colombier #define NDIR 14 /* should get this from param.h */
3181936bb65SDavid du Colombier
Globsize(p)3193e12c5d1SDavid du Colombier Globsize(p)
3203e12c5d1SDavid du Colombier register char *p;
3213e12c5d1SDavid du Colombier {
3223e12c5d1SDavid du Colombier int isglob = 0, globlen = NDIR+1;
3233e12c5d1SDavid du Colombier for(;*p;p++){
3243e12c5d1SDavid du Colombier if(*p==GLOB){
3253e12c5d1SDavid du Colombier p++;
326dc5a79c1SDavid du Colombier if(*p!=GLOB)
327dc5a79c1SDavid du Colombier isglob++;
3283e12c5d1SDavid du Colombier globlen+=*p=='*'?NDIR:1;
3293e12c5d1SDavid du Colombier }
3303e12c5d1SDavid du Colombier else
3313e12c5d1SDavid du Colombier globlen++;
3323e12c5d1SDavid du Colombier }
3333e12c5d1SDavid du Colombier return isglob?globlen:0;
3343e12c5d1SDavid du Colombier }
3351936bb65SDavid du Colombier
3363e12c5d1SDavid du Colombier #include <sys/types.h>
3371936bb65SDavid du Colombier #include <dirent.h>
3381936bb65SDavid du Colombier
3393e12c5d1SDavid du Colombier #define NDIRLIST 50
3401936bb65SDavid du Colombier
3413e12c5d1SDavid du Colombier DIR *dirlist[NDIRLIST];
3421936bb65SDavid du Colombier
Opendir(name)3433e12c5d1SDavid du Colombier Opendir(name)
3443e12c5d1SDavid du Colombier char *name;
3453e12c5d1SDavid du Colombier {
346dc5a79c1SDavid du Colombier DIR **dp;
3473e12c5d1SDavid du Colombier for(dp = dirlist;dp!=&dirlist[NDIRLIST];dp++)
3483e12c5d1SDavid du Colombier if(*dp==0){
3493e12c5d1SDavid du Colombier *dp = opendir(name);
3503e12c5d1SDavid du Colombier return *dp?dp-dirlist:-1;
3513e12c5d1SDavid du Colombier }
3523e12c5d1SDavid du Colombier return -1;
3533e12c5d1SDavid du Colombier }
3541936bb65SDavid du Colombier
3551936bb65SDavid du Colombier int
Readdir(int f,char * p,int onlydirs)3561936bb65SDavid du Colombier Readdir(int f, char *p, int onlydirs)
3573e12c5d1SDavid du Colombier {
3581936bb65SDavid du Colombier struct dirent *dp = readdir(dirlist[f]);
3591936bb65SDavid du Colombier
360dc5a79c1SDavid du Colombier if(dp==0)
361dc5a79c1SDavid du Colombier return 0;
3623e12c5d1SDavid du Colombier strcpy(p, dp->d_name);
3633e12c5d1SDavid du Colombier return 1;
3643e12c5d1SDavid du Colombier }
3651936bb65SDavid du Colombier
3661936bb65SDavid du Colombier void
Closedir(int f)3671936bb65SDavid du Colombier Closedir(int f)
3681936bb65SDavid du Colombier {
3693e12c5d1SDavid du Colombier closedir(dirlist[f]);
3703e12c5d1SDavid du Colombier dirlist[f] = 0;
3713e12c5d1SDavid du Colombier }
3721936bb65SDavid du Colombier
3733e12c5d1SDavid du Colombier char *Signame[] = {
3743e12c5d1SDavid du Colombier "sigexit", "sighup", "sigint", "sigquit",
3753e12c5d1SDavid du Colombier "sigill", "sigtrap", "sigiot", "sigemt",
3763e12c5d1SDavid du Colombier "sigfpe", "sigkill", "sigbus", "sigsegv",
3773e12c5d1SDavid du Colombier "sigsys", "sigpipe", "sigalrm", "sigterm",
3783e12c5d1SDavid du Colombier "sig16", "sigstop", "sigtstp", "sigcont",
3793e12c5d1SDavid du Colombier "sigchld", "sigttin", "sigttou", "sigtint",
3803e12c5d1SDavid du Colombier "sigxcpu", "sigxfsz", "sig26", "sig27",
3813e12c5d1SDavid du Colombier "sig28", "sig29", "sig30", "sig31",
3823e12c5d1SDavid du Colombier 0,
3833e12c5d1SDavid du Colombier };
384dc5a79c1SDavid du Colombier
3851936bb65SDavid du Colombier void
gettrap(int sig)3861936bb65SDavid du Colombier gettrap(int sig)
387dc5a79c1SDavid du Colombier {
3883e12c5d1SDavid du Colombier signal(sig, gettrap);
3893e12c5d1SDavid du Colombier trap[sig]++;
3903e12c5d1SDavid du Colombier ntrap++;
3913e12c5d1SDavid du Colombier if(ntrap>=NSIG){
3923e12c5d1SDavid du Colombier pfmt(err, "rc: Too many traps (trap %d), dumping core\n", sig);
3931936bb65SDavid du Colombier signal(SIGABRT, (void (*)())0);
3941936bb65SDavid du Colombier kill(getpid(), SIGABRT);
3953e12c5d1SDavid du Colombier }
3963e12c5d1SDavid du Colombier }
3971936bb65SDavid du Colombier
3981936bb65SDavid du Colombier void
Trapinit(void)3991936bb65SDavid du Colombier Trapinit(void)
4001936bb65SDavid du Colombier {
401dc5a79c1SDavid du Colombier int i;
4021936bb65SDavid du Colombier void (*sig)();
4031936bb65SDavid du Colombier
4043e12c5d1SDavid du Colombier if(1 || flag['d']){ /* wrong!!! */
4053e12c5d1SDavid du Colombier sig = signal(SIGINT, gettrap);
406dc5a79c1SDavid du Colombier if(sig==SIG_IGN)
407dc5a79c1SDavid du Colombier signal(SIGINT, SIG_IGN);
4083e12c5d1SDavid du Colombier }
4093e12c5d1SDavid du Colombier else{
4103e12c5d1SDavid du Colombier for(i = 1;i<=NSIG;i++) if(i!=SIGCHLD){
4113e12c5d1SDavid du Colombier sig = signal(i, gettrap);
412dc5a79c1SDavid du Colombier if(sig==SIG_IGN)
413dc5a79c1SDavid du Colombier signal(i, SIG_IGN);
4143e12c5d1SDavid du Colombier }
4153e12c5d1SDavid du Colombier }
4163e12c5d1SDavid du Colombier }
4171936bb65SDavid du Colombier
Unlink(name)4183e12c5d1SDavid du Colombier Unlink(name)
4193e12c5d1SDavid du Colombier char *name;
4203e12c5d1SDavid du Colombier {
4213e12c5d1SDavid du Colombier return unlink(name);
4223e12c5d1SDavid du Colombier }
Write(fd,buf,cnt)4233e12c5d1SDavid du Colombier Write(fd, buf, cnt)
4241936bb65SDavid du Colombier char *buf;
4253e12c5d1SDavid du Colombier {
4263e12c5d1SDavid du Colombier return write(fd, buf, cnt);
4273e12c5d1SDavid du Colombier }
Read(fd,buf,cnt)4283e12c5d1SDavid du Colombier Read(fd, buf, cnt)
4291936bb65SDavid du Colombier char *buf;
4303e12c5d1SDavid du Colombier {
4313e12c5d1SDavid du Colombier return read(fd, buf, cnt);
4323e12c5d1SDavid du Colombier }
Executable(file)4333e12c5d1SDavid du Colombier Executable(file)
4343e12c5d1SDavid du Colombier char *file;
4353e12c5d1SDavid du Colombier {
4363e12c5d1SDavid du Colombier return(access(file, 01)==0);
4373e12c5d1SDavid du Colombier }
Creat(file)4383e12c5d1SDavid du Colombier Creat(file)
4393e12c5d1SDavid du Colombier char *file;
4403e12c5d1SDavid du Colombier {
4413e12c5d1SDavid du Colombier return creat(file, 0666);
4423e12c5d1SDavid du Colombier }
Dup(a,b)4433e12c5d1SDavid du Colombier Dup(a, b){
4443e12c5d1SDavid du Colombier return dup2(a, b);
4453e12c5d1SDavid du Colombier }
Dup1(a)4463e12c5d1SDavid du Colombier Dup1(a){
4473e12c5d1SDavid du Colombier return dup(a);
4483e12c5d1SDavid du Colombier }
4493e12c5d1SDavid du Colombier /*
4503e12c5d1SDavid du Colombier * Wrong: should go through components of a|b|c and return the maximum.
4513e12c5d1SDavid du Colombier */
4521936bb65SDavid du Colombier void
Exit(char * stat)4531936bb65SDavid du Colombier Exit(char *stat)
4543e12c5d1SDavid du Colombier {
455dc5a79c1SDavid du Colombier int n = 0;
4561936bb65SDavid du Colombier
4573e12c5d1SDavid du Colombier while(*stat){
4583e12c5d1SDavid du Colombier if(*stat!='|'){
459dc5a79c1SDavid du Colombier if(*stat<'0' || '9'<*stat)
460dc5a79c1SDavid du Colombier exit(1);
4613e12c5d1SDavid du Colombier else n = n*10+*stat-'0';
4623e12c5d1SDavid du Colombier }
4633e12c5d1SDavid du Colombier stat++;
4643e12c5d1SDavid du Colombier }
4653e12c5d1SDavid du Colombier exit(n);
4663e12c5d1SDavid du Colombier }
Eintr()4673e12c5d1SDavid du Colombier Eintr(){
4683e12c5d1SDavid du Colombier return errno==EINTR;
4693e12c5d1SDavid du Colombier }
4701936bb65SDavid du Colombier
4711936bb65SDavid du Colombier void
Noerror()4721936bb65SDavid du Colombier Noerror()
4731936bb65SDavid du Colombier {
4743e12c5d1SDavid du Colombier errno = 0;
4753e12c5d1SDavid du Colombier }
Isatty(fd)4763e12c5d1SDavid du Colombier Isatty(fd){
4773e12c5d1SDavid du Colombier return isatty(fd);
4783e12c5d1SDavid du Colombier }
4791936bb65SDavid du Colombier
4801936bb65SDavid du Colombier void
Abort()4811936bb65SDavid du Colombier Abort()
4821936bb65SDavid du Colombier {
4833e12c5d1SDavid du Colombier abort();
4843e12c5d1SDavid du Colombier }
4851936bb65SDavid du Colombier
486*c6df1444SDavid du Colombier int
octal(char * s)487*c6df1444SDavid du Colombier octal(char *s)
488*c6df1444SDavid du Colombier {
489*c6df1444SDavid du Colombier int n = 0;
490*c6df1444SDavid du Colombier while(*s==' ' || *s=='\t' || *s=='\n') s++;
491*c6df1444SDavid du Colombier while('0'<=*s && *s<='7') n = n*8+*s++-'0';
492*c6df1444SDavid du Colombier return n;
493*c6df1444SDavid du Colombier }
494*c6df1444SDavid du Colombier
4951936bb65SDavid du Colombier void
execumask(void)4961936bb65SDavid du Colombier execumask(void) /* wrong -- should fork before writing */
4971936bb65SDavid du Colombier {
498dc5a79c1SDavid du Colombier int m;
4993e12c5d1SDavid du Colombier struct io out[1];
5003e12c5d1SDavid du Colombier switch(count(runq->argv->words)){
5013e12c5d1SDavid du Colombier default:
5023e12c5d1SDavid du Colombier pfmt(err, "Usage: umask [umask]\n");
5033e12c5d1SDavid du Colombier setstatus("umask usage");
5043e12c5d1SDavid du Colombier poplist();
5053e12c5d1SDavid du Colombier return;
506dc5a79c1SDavid du Colombier case 2:
507dc5a79c1SDavid du Colombier umask(octal(runq->argv->words->next->word));
508dc5a79c1SDavid du Colombier break;
5093e12c5d1SDavid du Colombier case 1:
5103e12c5d1SDavid du Colombier umask(m = umask(0));
5113e12c5d1SDavid du Colombier out->fd = mapfd(1);
5123e12c5d1SDavid du Colombier out->bufp = out->buf;
5133e12c5d1SDavid du Colombier out->ebuf=&out->buf[NBUF];
5143e12c5d1SDavid du Colombier out->strp = 0;
5153e12c5d1SDavid du Colombier pfmt(out, "%o\n", m);
5163e12c5d1SDavid du Colombier break;
5173e12c5d1SDavid du Colombier }
5183e12c5d1SDavid du Colombier setstatus("");
5193e12c5d1SDavid du Colombier poplist();
5203e12c5d1SDavid du Colombier }
5211936bb65SDavid du Colombier
5221936bb65SDavid du Colombier void
Memcpy(a,b,n)5233e12c5d1SDavid du Colombier Memcpy(a, b, n)
5241936bb65SDavid du Colombier char *a, *b;
5253e12c5d1SDavid du Colombier {
5263e12c5d1SDavid du Colombier memmove(a, b, n);
5273e12c5d1SDavid du Colombier }
528dc5a79c1SDavid du Colombier
529dc5a79c1SDavid du Colombier void*
Malloc(unsigned long n)5301936bb65SDavid du Colombier Malloc(unsigned long n)
531dc5a79c1SDavid du Colombier {
5323e12c5d1SDavid du Colombier return (void *)malloc(n);
5333e12c5d1SDavid du Colombier }
5341936bb65SDavid du Colombier
5351936bb65SDavid du Colombier void
errstr(char * buf,int len)5361936bb65SDavid du Colombier errstr(char *buf, int len)
5371936bb65SDavid du Colombier {
5381936bb65SDavid du Colombier strncpy(buf, strerror(errno), len);
5391936bb65SDavid du Colombier }
5401936bb65SDavid du Colombier
5411936bb65SDavid du Colombier int
needsrcquote(int c)5421936bb65SDavid du Colombier needsrcquote(int c)
5431936bb65SDavid du Colombier {
5441936bb65SDavid du Colombier if(c <= ' ')
5451936bb65SDavid du Colombier return 1;
5461936bb65SDavid du Colombier if(strchr("`^#*[]=|\\?${}()'<>&;", c))
5471936bb65SDavid du Colombier return 1;
5481936bb65SDavid du Colombier return 0;
5491936bb65SDavid du Colombier }
550bad30d5dSDavid du Colombier
551bad30d5dSDavid du Colombier int
rfork(int bits)552bad30d5dSDavid du Colombier rfork(int bits)
553bad30d5dSDavid du Colombier {
554bad30d5dSDavid du Colombier return fork();
555bad30d5dSDavid du Colombier }
556bad30d5dSDavid du Colombier
557*c6df1444SDavid du Colombier void
unixclsexec(int fd)558*c6df1444SDavid du Colombier unixclsexec(int fd)
559*c6df1444SDavid du Colombier {
560*c6df1444SDavid du Colombier fcntl(fd, F_SETFD, FD_CLOEXEC);
561*c6df1444SDavid du Colombier }
562*c6df1444SDavid du Colombier
563bad30d5dSDavid du Colombier int *waitpids;
564bad30d5dSDavid du Colombier int nwaitpids;
565bad30d5dSDavid du Colombier
566bad30d5dSDavid du Colombier void
addwaitpid(int pid)567bad30d5dSDavid du Colombier addwaitpid(int pid)
568bad30d5dSDavid du Colombier {
569bad30d5dSDavid du Colombier waitpids = realloc(waitpids, (nwaitpids+1)*sizeof waitpids[0]);
570bad30d5dSDavid du Colombier if(waitpids == 0)
571bad30d5dSDavid du Colombier panic("Can't realloc %d waitpids", nwaitpids+1);
572bad30d5dSDavid du Colombier waitpids[nwaitpids++] = pid;
573bad30d5dSDavid du Colombier }
574bad30d5dSDavid du Colombier
575bad30d5dSDavid du Colombier void
delwaitpid(int pid)576bad30d5dSDavid du Colombier delwaitpid(int pid)
577bad30d5dSDavid du Colombier {
578bad30d5dSDavid du Colombier int r, w;
579bad30d5dSDavid du Colombier
580bad30d5dSDavid du Colombier for(r=w=0; r<nwaitpids; r++)
581bad30d5dSDavid du Colombier if(waitpids[r] != pid)
582bad30d5dSDavid du Colombier waitpids[w++] = waitpids[r];
583bad30d5dSDavid du Colombier nwaitpids = w;
584bad30d5dSDavid du Colombier }
585bad30d5dSDavid du Colombier
586bad30d5dSDavid du Colombier void
clearwaitpids(void)587bad30d5dSDavid du Colombier clearwaitpids(void)
588bad30d5dSDavid du Colombier {
589bad30d5dSDavid du Colombier nwaitpids = 0;
590bad30d5dSDavid du Colombier }
591bad30d5dSDavid du Colombier
592bad30d5dSDavid du Colombier int
havewaitpid(int pid)593bad30d5dSDavid du Colombier havewaitpid(int pid)
594bad30d5dSDavid du Colombier {
595bad30d5dSDavid du Colombier int i;
596bad30d5dSDavid du Colombier
597bad30d5dSDavid du Colombier for(i=0; i<nwaitpids; i++)
598bad30d5dSDavid du Colombier if(waitpids[i] == pid)
599bad30d5dSDavid du Colombier return 1;
600bad30d5dSDavid du Colombier return 0;
601bad30d5dSDavid du Colombier }
602