From e5888a1ffdae813d7575f5fb02275c6bb07e5199 Mon Sep 17 00:00:00 2001 From: Taru Karttunen Date: Wed, 30 Mar 2011 15:46:40 +0300 Subject: Import sources from 2011-03-30 iso image --- sys/src/ape/cmd/make/dosys.c | 287 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 287 insertions(+) create mode 100755 sys/src/ape/cmd/make/dosys.c (limited to 'sys/src/ape/cmd/make/dosys.c') diff --git a/sys/src/ape/cmd/make/dosys.c b/sys/src/ape/cmd/make/dosys.c new file mode 100755 index 000000000..7d28eaa4d --- /dev/null +++ b/sys/src/ape/cmd/make/dosys.c @@ -0,0 +1,287 @@ +#include "defs.h" +#include +#include +#include +#include + +static int metas(char *); +static int waitproc(int *); +static int doshell(char *, int); +static int doexec(char *); + +int +dosys(char *comstring, int nohalt, int nowait, char *prefix) +{ +int status; +struct process *procp; + +/* make sure there is room in the process stack */ +if(nproc >= MAXPROC) + waitstack(MAXPROC-1); + +/* make sure fewer than proclimit processes are running */ +while(proclive >= proclimit) + { + enbint(SIG_IGN); + waitproc(&status); + enbint(intrupt); + } + +if(prefix) + { + fputs(prefix, stdout); + fputs(comstring, stdout); + } + +procp = procstack + nproc; +procp->pid = (forceshell || metas(comstring) ) ? + doshell(comstring,nohalt) : doexec(comstring); +if(procp->pid == -1) + fatal("fork failed"); +procstack[nproc].nohalt = nohalt; +procstack[nproc].nowait = nowait; +procstack[nproc].done = NO; +++proclive; +++nproc; + +if(nowait) + { + printf(" &%d\n", procp->pid); + fflush(stdout); + return 0; + } +if(prefix) + { + putchar('\n'); + fflush(stdout); + } +return waitstack(nproc-1); +} + +static int +metas(char *s) /* Are there are any Shell meta-characters? */ +{ +char c; + +while( (funny[c = *s++] & META) == 0 ) + ; +return( c ); +} + +static void +doclose(void) /* Close open directory files before exec'ing */ +{ +struct dirhd *od; + +for (od = firstod; od; od = od->nxtdirhd) + if(od->dirfc) + closedir(od->dirfc); +} + +/* wait till none of the processes in the stack starting at k is live */ +int +waitstack(int k) +{ +int npending, status, totstatus; +int i; + +totstatus = 0; +npending = 0; +for(i=k ; i 1) + printf("waitstack(%d)\n", k); + +while(npending>0 && proclive>0) + { + if(waitproc(&status) >= k) + --npending; + totstatus |= status; + } + +if(nproc > k) + nproc = k; +enbint(intrupt); +return totstatus; +} + +static int +waitproc(int *statp) +{ +pid_t pid; +int status; +int i; +struct process *procp; +char junk[50]; +static int inwait = NO; + +if(inwait) /* avoid infinite recursions on errors */ + return MAXPROC; +inwait = YES; + +pid = wait(&status); +if(dbgflag > 1) + fprintf(stderr, "process %d done, status = %d\n", pid, status); +if(pid == -1) + { + if(errno == ECHILD) /* multiple deaths, no problem */ + { + if(proclive) + { + for(i=0, procp=procstack; idone = YES; + proclive = nproc = 0; + } + return MAXPROC; + } + fatal("bad wait code"); + } +for(i=0, procp=procstack; ipid == pid) + { + --proclive; + procp->done = YES; + + if(status) + { + if(procp->nowait) + printf("%d: ", pid); + if( WEXITSTATUS(status) ) + printf("*** Error code %d", WEXITSTATUS(status) ); + else printf("*** Termination code %d", WTERMSIG(status)); + + printf(procp->nohalt ? "(ignored)\n" : "\n"); + fflush(stdout); + if(!keepgoing && !procp->nohalt) + fatal(CHNULL); + } + *statp = status; + inwait = NO; + return i; + } + +sprintf(junk, "spurious return from process %d", pid); +fatal(junk); +/*NOTREACHED*/ +} + +static int +doshell(char *comstring, int nohalt) +{ +pid_t pid; + +if((pid = fork()) == 0) + { + enbint(SIG_DFL); + doclose(); + + execl(SHELLCOM, "sh", (nohalt ? "-c" : "-ce"), comstring, NULL); + fatal("Couldn't load Shell"); + } + +return pid; +} + +static int +doexec(char *str) +{ +char *t, *tend; +char **argv; +char **p; +int nargs; +pid_t pid; + +while( *str==' ' || *str=='\t' ) + ++str; +if( *str == '\0' ) + return(-1); /* no command */ + +nargs = 1; +for(t = str ; *t ; ) + { + ++nargs; + while(*t!=' ' && *t!='\t' && *t!='\0') + ++t; + if(*t) /* replace first white space with \0, skip rest */ + for( *t++ = '\0' ; *t==' ' || *t=='\t' ; ++t) + ; + } + +/* now allocate args array, copy pointer to start of each string, + then terminate array with a null +*/ +p = argv = (char **) ckalloc(nargs*sizeof(char *)); +tend = t; +for(t = str ; t