13e12c5d1SDavid du Colombier /*
23e12c5d1SDavid du Colombier * Plan 9 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"
73e12c5d1SDavid du Colombier #include "exec.h"
83e12c5d1SDavid du Colombier #include "io.h"
93e12c5d1SDavid du Colombier #include "fns.h"
103e12c5d1SDavid du Colombier #include "getflags.h"
11276e7d6dSDavid du Colombier
12276e7d6dSDavid du Colombier enum {
13276e7d6dSDavid du Colombier Maxenvname = 256, /* undocumented limit */
14276e7d6dSDavid du Colombier };
15276e7d6dSDavid du Colombier
163e12c5d1SDavid du Colombier char *Signame[] = {
173e12c5d1SDavid du Colombier "sigexit", "sighup", "sigint", "sigquit",
18219b2ee8SDavid du Colombier "sigalrm", "sigkill", "sigfpe", "sigterm",
19219b2ee8SDavid du Colombier 0
203e12c5d1SDavid du Colombier };
213e12c5d1SDavid du Colombier char *syssigname[] = {
223e12c5d1SDavid du Colombier "exit", /* can't happen */
233e12c5d1SDavid du Colombier "hangup",
243e12c5d1SDavid du Colombier "interrupt",
253e12c5d1SDavid du Colombier "quit", /* can't happen */
263e12c5d1SDavid du Colombier "alarm",
27219b2ee8SDavid du Colombier "kill",
283e12c5d1SDavid du Colombier "sys: fp: ",
29219b2ee8SDavid du Colombier "term",
303e12c5d1SDavid du Colombier 0
313e12c5d1SDavid du Colombier };
32bad30d5dSDavid du Colombier char *Rcmain = "/rc/lib/rcmain";
33bad30d5dSDavid du Colombier char *Fdprefix = "/fd/";
34bad30d5dSDavid du Colombier
353e12c5d1SDavid du Colombier void execfinit(void);
363e12c5d1SDavid du Colombier void execbind(void);
373e12c5d1SDavid du Colombier void execmount(void);
383e12c5d1SDavid du Colombier void execnewpgrp(void);
39bad30d5dSDavid du Colombier
403e12c5d1SDavid du Colombier builtin Builtin[] = {
413e12c5d1SDavid du Colombier "cd", execcd,
423e12c5d1SDavid du Colombier "whatis", execwhatis,
433e12c5d1SDavid du Colombier "eval", execeval,
443e12c5d1SDavid du Colombier "exec", execexec, /* but with popword first */
453e12c5d1SDavid du Colombier "exit", execexit,
463e12c5d1SDavid du Colombier "shift", execshift,
473e12c5d1SDavid du Colombier "wait", execwait,
483e12c5d1SDavid du Colombier ".", execdot,
493e12c5d1SDavid du Colombier "finit", execfinit,
503e12c5d1SDavid du Colombier "flag", execflag,
513e12c5d1SDavid du Colombier "rfork", execnewpgrp,
523e12c5d1SDavid du Colombier 0
533e12c5d1SDavid du Colombier };
54dc5a79c1SDavid du Colombier
55dc5a79c1SDavid du Colombier void
execnewpgrp(void)56dc5a79c1SDavid du Colombier execnewpgrp(void)
57dc5a79c1SDavid du Colombier {
583e12c5d1SDavid du Colombier int arg;
593e12c5d1SDavid du Colombier char *s;
603e12c5d1SDavid du Colombier switch(count(runq->argv->words)){
61dc5a79c1SDavid du Colombier case 1:
62dc5a79c1SDavid du Colombier arg = RFENVG|RFNAMEG|RFNOTEG;
63dc5a79c1SDavid du Colombier break;
643e12c5d1SDavid du Colombier case 2:
653e12c5d1SDavid du Colombier arg = 0;
663e12c5d1SDavid du Colombier for(s = runq->argv->words->next->word;*s;s++) switch(*s){
673e12c5d1SDavid du Colombier default:
683e12c5d1SDavid du Colombier goto Usage;
69dc5a79c1SDavid du Colombier case 'n':
70dc5a79c1SDavid du Colombier arg|=RFNAMEG; break;
71dc5a79c1SDavid du Colombier case 'N':
72dc5a79c1SDavid du Colombier arg|=RFCNAMEG;
73dc5a79c1SDavid du Colombier break;
74dc5a79c1SDavid du Colombier case 'm':
75dc5a79c1SDavid du Colombier arg|=RFNOMNT; break;
76dc5a79c1SDavid du Colombier case 'e':
77dc5a79c1SDavid du Colombier arg|=RFENVG; break;
78dc5a79c1SDavid du Colombier case 'E':
79dc5a79c1SDavid du Colombier arg|=RFCENVG; break;
80dc5a79c1SDavid du Colombier case 's':
81dc5a79c1SDavid du Colombier arg|=RFNOTEG; break;
82dc5a79c1SDavid du Colombier case 'f':
83dc5a79c1SDavid du Colombier arg|=RFFDG; break;
84dc5a79c1SDavid du Colombier case 'F':
85dc5a79c1SDavid du Colombier arg|=RFCFDG; break;
863e12c5d1SDavid du Colombier }
873e12c5d1SDavid du Colombier break;
883e12c5d1SDavid du Colombier default:
893e12c5d1SDavid du Colombier Usage:
907dd7cddfSDavid du Colombier pfmt(err, "Usage: %s [fnesFNEm]\n", runq->argv->words->word);
913e12c5d1SDavid du Colombier setstatus("rfork usage");
923e12c5d1SDavid du Colombier poplist();
933e12c5d1SDavid du Colombier return;
943e12c5d1SDavid du Colombier }
953e12c5d1SDavid du Colombier if(rfork(arg)==-1){
963e12c5d1SDavid du Colombier pfmt(err, "rc: %s failed\n", runq->argv->words->word);
973e12c5d1SDavid du Colombier setstatus("rfork failed");
983e12c5d1SDavid du Colombier }
993e12c5d1SDavid du Colombier else
1003e12c5d1SDavid du Colombier setstatus("");
1013e12c5d1SDavid du Colombier poplist();
1023e12c5d1SDavid du Colombier }
103dc5a79c1SDavid du Colombier
104dc5a79c1SDavid du Colombier void
Vinit(void)105dc5a79c1SDavid du Colombier Vinit(void)
106dc5a79c1SDavid du Colombier {
107276e7d6dSDavid du Colombier int dir, f, len, i, n, nent;
1083e12c5d1SDavid du Colombier char *buf, *s;
109276e7d6dSDavid du Colombier char envname[Maxenvname];
110276e7d6dSDavid du Colombier word *val;
1119a747e4fSDavid du Colombier Dir *ent;
112276e7d6dSDavid du Colombier
1139a747e4fSDavid du Colombier dir = open("/env", OREAD);
1143e12c5d1SDavid du Colombier if(dir<0){
1159a747e4fSDavid du Colombier pfmt(err, "rc: can't open /env: %r\n");
1163e12c5d1SDavid du Colombier return;
1173e12c5d1SDavid du Colombier }
1189a747e4fSDavid du Colombier ent = nil;
1199a747e4fSDavid du Colombier for(;;){
1209a747e4fSDavid du Colombier nent = dirread(dir, &ent);
1219a747e4fSDavid du Colombier if(nent <= 0)
1229a747e4fSDavid du Colombier break;
1239a747e4fSDavid du Colombier for(i = 0; i<nent; i++){
1249a747e4fSDavid du Colombier len = ent[i].length;
1259a747e4fSDavid du Colombier if(len && strncmp(ent[i].name, "fn#", 3)!=0){
12699eb86a7SDavid du Colombier snprint(envname, sizeof envname, "/env/%s", ent[i].name);
1273e12c5d1SDavid du Colombier if((f = open(envname, 0))>=0){
128276e7d6dSDavid du Colombier buf = emalloc(len+1);
129276e7d6dSDavid du Colombier n = readn(f, buf, len);
130276e7d6dSDavid du Colombier if (n <= 0)
131276e7d6dSDavid du Colombier buf[0] = '\0';
132276e7d6dSDavid du Colombier else
133276e7d6dSDavid du Colombier buf[n] = '\0';
1343e12c5d1SDavid du Colombier val = 0;
1353e12c5d1SDavid du Colombier /* Charitably add a 0 at the end if need be */
136dc5a79c1SDavid du Colombier if(buf[len-1])
137dc5a79c1SDavid du Colombier buf[len++]='\0';
1383e12c5d1SDavid du Colombier s = buf+len-1;
1393e12c5d1SDavid du Colombier for(;;){
14099eb86a7SDavid du Colombier while(s!=buf && s[-1]!='\0') --s;
1413e12c5d1SDavid du Colombier val = newword(s, val);
142dc5a79c1SDavid du Colombier if(s==buf)
143dc5a79c1SDavid du Colombier break;
1443e12c5d1SDavid du Colombier --s;
1453e12c5d1SDavid du Colombier }
1469a747e4fSDavid du Colombier setvar(ent[i].name, val);
1479a747e4fSDavid du Colombier vlook(ent[i].name)->changed = 0;
1483e12c5d1SDavid du Colombier close(f);
1493e12c5d1SDavid du Colombier efree(buf);
1503e12c5d1SDavid du Colombier }
1513e12c5d1SDavid du Colombier }
1523e12c5d1SDavid du Colombier }
1539a747e4fSDavid du Colombier free(ent);
1549a747e4fSDavid du Colombier }
1553e12c5d1SDavid du Colombier close(dir);
1563e12c5d1SDavid du Colombier }
1573e12c5d1SDavid du Colombier int envdir;
158dc5a79c1SDavid du Colombier
159dc5a79c1SDavid du Colombier void
Xrdfn(void)160dc5a79c1SDavid du Colombier Xrdfn(void)
161dc5a79c1SDavid du Colombier {
1623e12c5d1SDavid du Colombier int f, len;
163276e7d6dSDavid du Colombier Dir *e;
164276e7d6dSDavid du Colombier char envname[Maxenvname];
1659a747e4fSDavid du Colombier static Dir *ent, *allocent;
1669a747e4fSDavid du Colombier static int nent;
1679a747e4fSDavid du Colombier
1689a747e4fSDavid du Colombier for(;;){
1699a747e4fSDavid du Colombier if(nent == 0){
1709a747e4fSDavid du Colombier free(allocent);
1719a747e4fSDavid du Colombier nent = dirread(envdir, &allocent);
1729a747e4fSDavid du Colombier ent = allocent;
1739a747e4fSDavid du Colombier }
1749a747e4fSDavid du Colombier if(nent <= 0)
1759a747e4fSDavid du Colombier break;
1769a747e4fSDavid du Colombier while(nent){
1779a747e4fSDavid du Colombier e = ent++;
1789a747e4fSDavid du Colombier nent--;
1799a747e4fSDavid du Colombier len = e->length;
1809a747e4fSDavid du Colombier if(len && strncmp(e->name, "fn#", 3)==0){
18199eb86a7SDavid du Colombier snprint(envname, sizeof envname, "/env/%s", e->name);
1823e12c5d1SDavid du Colombier if((f = open(envname, 0))>=0){
1833e12c5d1SDavid du Colombier execcmds(openfd(f));
1843e12c5d1SDavid du Colombier return;
1853e12c5d1SDavid du Colombier }
1863e12c5d1SDavid du Colombier }
1873e12c5d1SDavid du Colombier }
1889a747e4fSDavid du Colombier }
1893e12c5d1SDavid du Colombier close(envdir);
1903e12c5d1SDavid du Colombier Xreturn();
1913e12c5d1SDavid du Colombier }
1923e12c5d1SDavid du Colombier union code rdfns[4];
193dc5a79c1SDavid du Colombier
194dc5a79c1SDavid du Colombier void
execfinit(void)195dc5a79c1SDavid du Colombier execfinit(void)
196dc5a79c1SDavid du Colombier {
1973e12c5d1SDavid du Colombier static int first = 1;
1983e12c5d1SDavid du Colombier if(first){
1993e12c5d1SDavid du Colombier rdfns[0].i = 1;
2003e12c5d1SDavid du Colombier rdfns[1].f = Xrdfn;
2013e12c5d1SDavid du Colombier rdfns[2].f = Xjump;
2023e12c5d1SDavid du Colombier rdfns[3].i = 1;
2033e12c5d1SDavid du Colombier first = 0;
2043e12c5d1SDavid du Colombier }
2053e12c5d1SDavid du Colombier Xpopm();
2069a747e4fSDavid du Colombier envdir = open("/env", 0);
2073e12c5d1SDavid du Colombier if(envdir<0){
2089a747e4fSDavid du Colombier pfmt(err, "rc: can't open /env: %r\n");
2093e12c5d1SDavid du Colombier return;
2103e12c5d1SDavid du Colombier }
2113e12c5d1SDavid du Colombier start(rdfns, 1, runq->local);
2123e12c5d1SDavid du Colombier }
213dc5a79c1SDavid du Colombier
214dc5a79c1SDavid du Colombier int
Waitfor(int pid,int)215dc5a79c1SDavid du Colombier Waitfor(int pid, int)
216dc5a79c1SDavid du Colombier {
2173e12c5d1SDavid du Colombier thread *p;
2189a747e4fSDavid du Colombier Waitmsg *w;
2199a747e4fSDavid du Colombier char errbuf[ERRMAX];
2209a747e4fSDavid du Colombier
221d3907fe5SDavid du Colombier if(pid >= 0 && !havewaitpid(pid))
222d3907fe5SDavid du Colombier return 0;
223d3907fe5SDavid du Colombier
2249a747e4fSDavid du Colombier while((w = wait()) != nil){
225d3907fe5SDavid du Colombier delwaitpid(w->pid);
2269a747e4fSDavid du Colombier if(w->pid==pid){
2279a747e4fSDavid du Colombier setstatus(w->msg);
2289a747e4fSDavid du Colombier free(w);
229219b2ee8SDavid du Colombier return 0;
2303e12c5d1SDavid du Colombier }
2313e12c5d1SDavid du Colombier for(p = runq->ret;p;p = p->ret)
2329a747e4fSDavid du Colombier if(p->pid==w->pid){
2333e12c5d1SDavid du Colombier p->pid=-1;
2349a747e4fSDavid du Colombier strcpy(p->status, w->msg);
2353e12c5d1SDavid du Colombier }
2369a747e4fSDavid du Colombier free(w);
2373e12c5d1SDavid du Colombier }
2389a747e4fSDavid du Colombier
2399a747e4fSDavid du Colombier errstr(errbuf, sizeof errbuf);
24099eb86a7SDavid du Colombier if(strcmp(errbuf, "interrupted")==0) return -1;
2413e12c5d1SDavid du Colombier return 0;
2423e12c5d1SDavid du Colombier }
243dc5a79c1SDavid du Colombier
244276e7d6dSDavid du Colombier char **
mkargv(word * a)245276e7d6dSDavid du Colombier mkargv(word *a)
2463e12c5d1SDavid du Colombier {
2473e12c5d1SDavid du Colombier char **argv = (char **)emalloc((count(a)+2)*sizeof(char *));
2483e12c5d1SDavid du Colombier char **argp = argv+1; /* leave one at front for runcoms */
24999eb86a7SDavid du Colombier for(;a;a = a->next) *argp++=a->word;
2503e12c5d1SDavid du Colombier *argp = 0;
2513e12c5d1SDavid du Colombier return argv;
2523e12c5d1SDavid du Colombier }
253dc5a79c1SDavid du Colombier
254dc5a79c1SDavid du Colombier void
addenv(var * v)255dc5a79c1SDavid du Colombier addenv(var *v)
2563e12c5d1SDavid du Colombier {
257276e7d6dSDavid du Colombier char envname[Maxenvname];
2583e12c5d1SDavid du Colombier word *w;
2593e12c5d1SDavid du Colombier int f;
2603e12c5d1SDavid du Colombier io *fd;
2613e12c5d1SDavid du Colombier if(v->changed){
2623e12c5d1SDavid du Colombier v->changed = 0;
2639a747e4fSDavid du Colombier snprint(envname, sizeof envname, "/env/%s", v->name);
2643e12c5d1SDavid du Colombier if((f = Creat(envname))<0)
2659a747e4fSDavid du Colombier pfmt(err, "rc: can't open %s: %r\n", envname);
2663e12c5d1SDavid du Colombier else{
2673e12c5d1SDavid du Colombier for(w = v->val;w;w = w->next)
26899eb86a7SDavid du Colombier write(f, w->word, strlen(w->word)+1L);
2693e12c5d1SDavid du Colombier close(f);
2703e12c5d1SDavid du Colombier }
2713e12c5d1SDavid du Colombier }
2723e12c5d1SDavid du Colombier if(v->fnchanged){
2733e12c5d1SDavid du Colombier v->fnchanged = 0;
2749a747e4fSDavid du Colombier snprint(envname, sizeof envname, "/env/fn#%s", v->name);
2753e12c5d1SDavid du Colombier if((f = Creat(envname))<0)
2769a747e4fSDavid du Colombier pfmt(err, "rc: can't open %s: %r\n", envname);
2773e12c5d1SDavid du Colombier else{
2783e12c5d1SDavid du Colombier if(v->fn){
2793e12c5d1SDavid du Colombier fd = openfd(f);
280fed0fa9eSDavid du Colombier pfmt(fd, "fn %q %s\n", v->name, v->fn[v->pc-1].s);
2813e12c5d1SDavid du Colombier closeio(fd);
2823e12c5d1SDavid du Colombier }
2833e12c5d1SDavid du Colombier close(f);
2843e12c5d1SDavid du Colombier }
2853e12c5d1SDavid du Colombier }
2863e12c5d1SDavid du Colombier }
287dc5a79c1SDavid du Colombier
288dc5a79c1SDavid du Colombier void
updenvlocal(var * v)289dc5a79c1SDavid du Colombier updenvlocal(var *v)
2903e12c5d1SDavid du Colombier {
2913e12c5d1SDavid du Colombier if(v){
2923e12c5d1SDavid du Colombier updenvlocal(v->next);
2933e12c5d1SDavid du Colombier addenv(v);
2943e12c5d1SDavid du Colombier }
2953e12c5d1SDavid du Colombier }
296dc5a79c1SDavid du Colombier
297dc5a79c1SDavid du Colombier void
Updenv(void)298dc5a79c1SDavid du Colombier Updenv(void)
299dc5a79c1SDavid du Colombier {
3003e12c5d1SDavid du Colombier var *v, **h;
3013e12c5d1SDavid du Colombier for(h = gvar;h!=&gvar[NVAR];h++)
3023e12c5d1SDavid du Colombier for(v=*h;v;v = v->next)
3033e12c5d1SDavid du Colombier addenv(v);
304dc5a79c1SDavid du Colombier if(runq)
305dc5a79c1SDavid du Colombier updenvlocal(runq->local);
3063e12c5d1SDavid du Colombier }
307dc5a79c1SDavid du Colombier
3085acbe002SDavid du Colombier /* not used on plan 9 */
309dc5a79c1SDavid du Colombier int
ForkExecute(char * file,char ** argv,int sin,int sout,int serr)310dc5a79c1SDavid du Colombier ForkExecute(char *file, char **argv, int sin, int sout, int serr)
311dc5a79c1SDavid du Colombier {
312dc5a79c1SDavid du Colombier int pid;
313dc5a79c1SDavid du Colombier
314dc5a79c1SDavid du Colombier if(access(file, 1) != 0)
315dc5a79c1SDavid du Colombier return -1;
316dc5a79c1SDavid du Colombier switch(pid = fork()){
317dc5a79c1SDavid du Colombier case -1:
318dc5a79c1SDavid du Colombier return -1;
319dc5a79c1SDavid du Colombier case 0:
320dc5a79c1SDavid du Colombier if(sin >= 0)
321dc5a79c1SDavid du Colombier dup(sin, 0);
322dc5a79c1SDavid du Colombier else
323dc5a79c1SDavid du Colombier close(0);
324dc5a79c1SDavid du Colombier if(sout >= 0)
325dc5a79c1SDavid du Colombier dup(sout, 1);
326dc5a79c1SDavid du Colombier else
327dc5a79c1SDavid du Colombier close(1);
328dc5a79c1SDavid du Colombier if(serr >= 0)
329dc5a79c1SDavid du Colombier dup(serr, 2);
330dc5a79c1SDavid du Colombier else
331dc5a79c1SDavid du Colombier close(2);
332dc5a79c1SDavid du Colombier exec(file, argv);
333dc5a79c1SDavid du Colombier exits(file);
334dc5a79c1SDavid du Colombier }
335dc5a79c1SDavid du Colombier return pid;
336dc5a79c1SDavid du Colombier }
337dc5a79c1SDavid du Colombier
338dc5a79c1SDavid du Colombier void
Execute(word * args,word * path)339dc5a79c1SDavid du Colombier Execute(word *args, word *path)
3403e12c5d1SDavid du Colombier {
3413e12c5d1SDavid du Colombier char **argv = mkargv(args);
3425acbe002SDavid du Colombier char file[1024], errstr[1024];
343219b2ee8SDavid du Colombier int nc;
3445acbe002SDavid du Colombier
3453e12c5d1SDavid du Colombier Updenv();
3465acbe002SDavid du Colombier errstr[0] = '\0';
3473e12c5d1SDavid du Colombier for(;path;path = path->next){
348219b2ee8SDavid du Colombier nc = strlen(path->word);
349276e7d6dSDavid du Colombier if(nc < sizeof file - 1){ /* 1 for / */
3503e12c5d1SDavid du Colombier strcpy(file, path->word);
351219b2ee8SDavid du Colombier if(file[0]){
352219b2ee8SDavid du Colombier strcat(file, "/");
353219b2ee8SDavid du Colombier nc++;
354219b2ee8SDavid du Colombier }
355276e7d6dSDavid du Colombier if(nc + strlen(argv[1]) < sizeof file){
3563e12c5d1SDavid du Colombier strcat(file, argv[1]);
3573e12c5d1SDavid du Colombier exec(file, argv+1);
3585acbe002SDavid du Colombier rerrstr(errstr, sizeof errstr);
3595acbe002SDavid du Colombier /*
360d9cef801SDavid du Colombier * if file exists and is executable, exec should
361d9cef801SDavid du Colombier * have worked, unless it's a directory or an
362d9cef801SDavid du Colombier * executable for another architecture. in
363d9cef801SDavid du Colombier * particular, if it failed due to lack of
364d9cef801SDavid du Colombier * swap/vm (e.g., arg. list too long) or other
365d9cef801SDavid du Colombier * allocation failure, stop searching and print
366d9cef801SDavid du Colombier * the reason for failure.
3675acbe002SDavid du Colombier */
368d9cef801SDavid du Colombier if (strstr(errstr, " allocat") != nil ||
369d9cef801SDavid du Colombier strstr(errstr, " full") != nil)
3705acbe002SDavid du Colombier break;
3713e12c5d1SDavid du Colombier }
37299eb86a7SDavid du Colombier else werrstr("command name too long");
373219b2ee8SDavid du Colombier }
374219b2ee8SDavid du Colombier }
3755acbe002SDavid du Colombier pfmt(err, "%s: %s\n", argv[1], errstr);
3763e12c5d1SDavid du Colombier efree((char *)argv);
3773e12c5d1SDavid du Colombier }
37899eb86a7SDavid du Colombier #define NDIR 256 /* shoud be a better way */
379dc5a79c1SDavid du Colombier
380dc5a79c1SDavid du Colombier int
Globsize(char * p)381dc5a79c1SDavid du Colombier Globsize(char *p)
3823e12c5d1SDavid du Colombier {
38373e742d7SDavid du Colombier int isglob = 0, globlen = NDIR+1;
3843e12c5d1SDavid du Colombier for(;*p;p++){
3853e12c5d1SDavid du Colombier if(*p==GLOB){
3863e12c5d1SDavid du Colombier p++;
387dc5a79c1SDavid du Colombier if(*p!=GLOB)
388dc5a79c1SDavid du Colombier isglob++;
3899a747e4fSDavid du Colombier globlen+=*p=='*'?NDIR:1;
3903e12c5d1SDavid du Colombier }
3913e12c5d1SDavid du Colombier else
3923e12c5d1SDavid du Colombier globlen++;
3933e12c5d1SDavid du Colombier }
3943e12c5d1SDavid du Colombier return isglob?globlen:0;
3953e12c5d1SDavid du Colombier }
3963e12c5d1SDavid du Colombier #define NFD 50
397276e7d6dSDavid du Colombier
3983e12c5d1SDavid du Colombier struct{
3999a747e4fSDavid du Colombier Dir *dbuf;
4009a747e4fSDavid du Colombier int i;
4013e12c5d1SDavid du Colombier int n;
4023e12c5d1SDavid du Colombier }dir[NFD];
403dc5a79c1SDavid du Colombier
404dc5a79c1SDavid du Colombier int
Opendir(char * name)405dc5a79c1SDavid du Colombier Opendir(char *name)
4063e12c5d1SDavid du Colombier {
4079a747e4fSDavid du Colombier Dir *db;
4083e12c5d1SDavid du Colombier int f;
4093e12c5d1SDavid du Colombier f = open(name, 0);
4103e12c5d1SDavid du Colombier if(f==-1)
4113e12c5d1SDavid du Colombier return f;
4129a747e4fSDavid du Colombier db = dirfstat(f);
4139a747e4fSDavid du Colombier if(db!=nil && (db->mode&DMDIR)){
4149a747e4fSDavid du Colombier if(f<NFD){
4159a747e4fSDavid du Colombier dir[f].i = 0;
4169a747e4fSDavid du Colombier dir[f].n = 0;
4173e12c5d1SDavid du Colombier }
4189a747e4fSDavid du Colombier free(db);
4193e12c5d1SDavid du Colombier return f;
4203e12c5d1SDavid du Colombier }
4219a747e4fSDavid du Colombier free(db);
4223e12c5d1SDavid du Colombier close(f);
4233e12c5d1SDavid du Colombier return -1;
4243e12c5d1SDavid du Colombier }
4256b6b9ac8SDavid du Colombier
4266b6b9ac8SDavid du Colombier static int
trimdirs(Dir * d,int nd)4276b6b9ac8SDavid du Colombier trimdirs(Dir *d, int nd)
4286b6b9ac8SDavid du Colombier {
4296b6b9ac8SDavid du Colombier int r, w;
4306b6b9ac8SDavid du Colombier
4316b6b9ac8SDavid du Colombier for(r=w=0; r<nd; r++)
4326b6b9ac8SDavid du Colombier if(d[r].mode&DMDIR)
4336b6b9ac8SDavid du Colombier d[w++] = d[r];
4346b6b9ac8SDavid du Colombier return w;
4356b6b9ac8SDavid du Colombier }
4366b6b9ac8SDavid du Colombier
4376b6b9ac8SDavid du Colombier /*
4386b6b9ac8SDavid du Colombier * onlydirs is advisory -- it means you only
4396b6b9ac8SDavid du Colombier * need to return the directories. it's okay to
4406b6b9ac8SDavid du Colombier * return files too (e.g., on unix where you can't
4416b6b9ac8SDavid du Colombier * tell during the readdir), but that just makes
4426b6b9ac8SDavid du Colombier * the globber work harder.
4436b6b9ac8SDavid du Colombier */
444dc5a79c1SDavid du Colombier int
Readdir(int f,void * p,int onlydirs)445276e7d6dSDavid du Colombier Readdir(int f, void *p, int onlydirs)
4463e12c5d1SDavid du Colombier {
4473e12c5d1SDavid du Colombier int n;
448dc5a79c1SDavid du Colombier
4499a747e4fSDavid du Colombier if(f<0 || f>=NFD)
4503e12c5d1SDavid du Colombier return 0;
4516b6b9ac8SDavid du Colombier Again:
4529a747e4fSDavid du Colombier if(dir[f].i==dir[f].n){ /* read */
4539a747e4fSDavid du Colombier free(dir[f].dbuf);
4549a747e4fSDavid du Colombier dir[f].dbuf = 0;
4559a747e4fSDavid du Colombier n = dirread(f, &dir[f].dbuf);
4566b6b9ac8SDavid du Colombier if(n>0){
4576b6b9ac8SDavid du Colombier if(onlydirs){
4586b6b9ac8SDavid du Colombier n = trimdirs(dir[f].dbuf, n);
4596b6b9ac8SDavid du Colombier if(n == 0)
4606b6b9ac8SDavid du Colombier goto Again;
4616b6b9ac8SDavid du Colombier }
4629a747e4fSDavid du Colombier dir[f].n = n;
4636b6b9ac8SDavid du Colombier }else
4643e12c5d1SDavid du Colombier dir[f].n = 0;
4659a747e4fSDavid du Colombier dir[f].i = 0;
4663e12c5d1SDavid du Colombier }
4679a747e4fSDavid du Colombier if(dir[f].i == dir[f].n)
4683e12c5d1SDavid du Colombier return 0;
4699a747e4fSDavid du Colombier strcpy(p, dir[f].dbuf[dir[f].i].name);
4709a747e4fSDavid du Colombier dir[f].i++;
4713e12c5d1SDavid du Colombier return 1;
4723e12c5d1SDavid du Colombier }
473dc5a79c1SDavid du Colombier
474dc5a79c1SDavid du Colombier void
Closedir(int f)475dc5a79c1SDavid du Colombier Closedir(int f)
476dc5a79c1SDavid du Colombier {
4779a747e4fSDavid du Colombier if(f>=0 && f<NFD){
4789a747e4fSDavid du Colombier free(dir[f].dbuf);
4799a747e4fSDavid du Colombier dir[f].i = 0;
4809a747e4fSDavid du Colombier dir[f].n = 0;
4819a747e4fSDavid du Colombier dir[f].dbuf = 0;
4823e12c5d1SDavid du Colombier }
4833e12c5d1SDavid du Colombier close(f);
4843e12c5d1SDavid du Colombier }
4853e12c5d1SDavid du Colombier int interrupted = 0;
4863e12c5d1SDavid du Colombier void
notifyf(void *,char * s)4877dd7cddfSDavid du Colombier notifyf(void*, char *s)
4883e12c5d1SDavid du Colombier {
4893e12c5d1SDavid du Colombier int i;
49099eb86a7SDavid du Colombier for(i = 0;syssigname[i];i++) if(strncmp(s, syssigname[i], strlen(syssigname[i]))==0){
49199eb86a7SDavid du Colombier if(strncmp(s, "sys: ", 5)!=0) interrupted = 1;
4923e12c5d1SDavid du Colombier goto Out;
4933e12c5d1SDavid du Colombier }
4943e12c5d1SDavid du Colombier pfmt(err, "rc: note: %s\n", s);
4953e12c5d1SDavid du Colombier noted(NDFLT);
4963e12c5d1SDavid du Colombier return;
4973e12c5d1SDavid du Colombier Out:
498219b2ee8SDavid du Colombier if(strcmp(s, "interrupt")!=0 || trap[i]==0){
4993e12c5d1SDavid du Colombier trap[i]++;
5003e12c5d1SDavid du Colombier ntrap++;
501219b2ee8SDavid du Colombier }
5023e12c5d1SDavid du Colombier if(ntrap>=32){ /* rc is probably in a trap loop */
5033e12c5d1SDavid du Colombier pfmt(err, "rc: Too many traps (trap %s), aborting\n", s);
5043e12c5d1SDavid du Colombier abort();
5053e12c5d1SDavid du Colombier }
5063e12c5d1SDavid du Colombier noted(NCONT);
5073e12c5d1SDavid du Colombier }
508dc5a79c1SDavid du Colombier
509dc5a79c1SDavid du Colombier void
Trapinit(void)510dc5a79c1SDavid du Colombier Trapinit(void)
511dc5a79c1SDavid du Colombier {
5123e12c5d1SDavid du Colombier notify(notifyf);
5133e12c5d1SDavid du Colombier }
514dc5a79c1SDavid du Colombier
515dc5a79c1SDavid du Colombier void
Unlink(char * name)516dc5a79c1SDavid du Colombier Unlink(char *name)
5173e12c5d1SDavid du Colombier {
5183e12c5d1SDavid du Colombier remove(name);
5193e12c5d1SDavid du Colombier }
520dc5a79c1SDavid du Colombier
521dc5a79c1SDavid du Colombier long
Write(int fd,void * buf,long cnt)522276e7d6dSDavid du Colombier Write(int fd, void *buf, long cnt)
5233e12c5d1SDavid du Colombier {
524276e7d6dSDavid du Colombier return write(fd, buf, cnt);
5253e12c5d1SDavid du Colombier }
526dc5a79c1SDavid du Colombier
527dc5a79c1SDavid du Colombier long
Read(int fd,void * buf,long cnt)528276e7d6dSDavid du Colombier Read(int fd, void *buf, long cnt)
5293e12c5d1SDavid du Colombier {
5303e12c5d1SDavid du Colombier return read(fd, buf, cnt);
5313e12c5d1SDavid du Colombier }
532dc5a79c1SDavid du Colombier
533dc5a79c1SDavid du Colombier long
Seek(int fd,long cnt,long whence)534dc5a79c1SDavid du Colombier Seek(int fd, long cnt, long whence)
5353e12c5d1SDavid du Colombier {
5363e12c5d1SDavid du Colombier return seek(fd, cnt, whence);
5373e12c5d1SDavid du Colombier }
538dc5a79c1SDavid du Colombier
539dc5a79c1SDavid du Colombier int
Executable(char * file)540dc5a79c1SDavid du Colombier Executable(char *file)
5413e12c5d1SDavid du Colombier {
5429a747e4fSDavid du Colombier Dir *statbuf;
5439a747e4fSDavid du Colombier int ret;
5443e12c5d1SDavid du Colombier
5459a747e4fSDavid du Colombier statbuf = dirstat(file);
546dc5a79c1SDavid du Colombier if(statbuf == nil)
547dc5a79c1SDavid du Colombier return 0;
54899eb86a7SDavid du Colombier ret = ((statbuf->mode&0111)!=0 && (statbuf->mode&DMDIR)==0);
5499a747e4fSDavid du Colombier free(statbuf);
5509a747e4fSDavid du Colombier return ret;
5513e12c5d1SDavid du Colombier }
552dc5a79c1SDavid du Colombier
553dc5a79c1SDavid du Colombier int
Creat(char * file)554dc5a79c1SDavid du Colombier Creat(char *file)
5553e12c5d1SDavid du Colombier {
55699eb86a7SDavid du Colombier return create(file, 1, 0666L);
5573e12c5d1SDavid du Colombier }
558dc5a79c1SDavid du Colombier
559dc5a79c1SDavid du Colombier int
Dup(int a,int b)560dc5a79c1SDavid du Colombier Dup(int a, int b)
561dc5a79c1SDavid du Colombier {
5623e12c5d1SDavid du Colombier return dup(a, b);
5633e12c5d1SDavid du Colombier }
564dc5a79c1SDavid du Colombier
565dc5a79c1SDavid du Colombier int
Dup1(int)566dc5a79c1SDavid du Colombier Dup1(int)
567dc5a79c1SDavid du Colombier {
5683e12c5d1SDavid du Colombier return -1;
5693e12c5d1SDavid du Colombier }
570dc5a79c1SDavid du Colombier
571dc5a79c1SDavid du Colombier void
Exit(char * stat)572dc5a79c1SDavid du Colombier Exit(char *stat)
5733e12c5d1SDavid du Colombier {
5743e12c5d1SDavid du Colombier Updenv();
5753e12c5d1SDavid du Colombier setstatus(stat);
5763e12c5d1SDavid du Colombier exits(truestatus()?"":getstatus());
5773e12c5d1SDavid du Colombier }
578dc5a79c1SDavid du Colombier
579dc5a79c1SDavid du Colombier int
Eintr(void)580dc5a79c1SDavid du Colombier Eintr(void)
581dc5a79c1SDavid du Colombier {
5823e12c5d1SDavid du Colombier return interrupted;
5833e12c5d1SDavid du Colombier }
584dc5a79c1SDavid du Colombier
585dc5a79c1SDavid du Colombier void
Noerror(void)586dc5a79c1SDavid du Colombier Noerror(void)
587dc5a79c1SDavid du Colombier {
5883e12c5d1SDavid du Colombier interrupted = 0;
5893e12c5d1SDavid du Colombier }
590dc5a79c1SDavid du Colombier
591dc5a79c1SDavid du Colombier int
Isatty(int fd)592dc5a79c1SDavid du Colombier Isatty(int fd)
593dc5a79c1SDavid du Colombier {
5944f281771SDavid du Colombier char buf[64];
5953e12c5d1SDavid du Colombier
5964f281771SDavid du Colombier if(fd2path(fd, buf, sizeof buf) != 0)
597dc5a79c1SDavid du Colombier return 0;
5984f281771SDavid du Colombier
5993806af99SDavid du Colombier /* might be #c/cons during boot - fixed 22 april 2005, remove this later */
6003806af99SDavid du Colombier if(strcmp(buf, "#c/cons") == 0)
6013806af99SDavid du Colombier return 1;
6023806af99SDavid du Colombier
6034f281771SDavid du Colombier /* might be /mnt/term/dev/cons */
6044f281771SDavid du Colombier return strlen(buf) >= 9 && strcmp(buf+strlen(buf)-9, "/dev/cons") == 0;
6053e12c5d1SDavid du Colombier }
606dc5a79c1SDavid du Colombier
607dc5a79c1SDavid du Colombier void
Abort(void)608dc5a79c1SDavid du Colombier Abort(void)
609dc5a79c1SDavid du Colombier {
6103e12c5d1SDavid du Colombier pfmt(err, "aborting\n");
6113e12c5d1SDavid du Colombier flush(err);
6123e12c5d1SDavid du Colombier Exit("aborting");
6133e12c5d1SDavid du Colombier }
614dc5a79c1SDavid du Colombier
615dc5a79c1SDavid du Colombier void
Memcpy(void * a,void * b,long n)616276e7d6dSDavid du Colombier Memcpy(void *a, void *b, long n)
6173e12c5d1SDavid du Colombier {
618276e7d6dSDavid du Colombier memmove(a, b, n);
6193e12c5d1SDavid du Colombier }
620dc5a79c1SDavid du Colombier
621dc5a79c1SDavid du Colombier void*
Malloc(ulong n)622dc5a79c1SDavid du Colombier Malloc(ulong n)
623dc5a79c1SDavid du Colombier {
624*4e3613abSDavid du Colombier return mallocz(n, 1);
6253e12c5d1SDavid du Colombier }
626d3907fe5SDavid du Colombier
627d3907fe5SDavid du Colombier int *waitpids;
628d3907fe5SDavid du Colombier int nwaitpids;
629d3907fe5SDavid du Colombier
630d3907fe5SDavid du Colombier void
addwaitpid(int pid)631d3907fe5SDavid du Colombier addwaitpid(int pid)
632d3907fe5SDavid du Colombier {
633d3907fe5SDavid du Colombier waitpids = realloc(waitpids, (nwaitpids+1)*sizeof waitpids[0]);
634d3907fe5SDavid du Colombier if(waitpids == 0)
635d3907fe5SDavid du Colombier panic("Can't realloc %d waitpids", nwaitpids+1);
636d3907fe5SDavid du Colombier waitpids[nwaitpids++] = pid;
637d3907fe5SDavid du Colombier }
638d3907fe5SDavid du Colombier
639d3907fe5SDavid du Colombier void
delwaitpid(int pid)640d3907fe5SDavid du Colombier delwaitpid(int pid)
641d3907fe5SDavid du Colombier {
642d3907fe5SDavid du Colombier int r, w;
643d3907fe5SDavid du Colombier
644d3907fe5SDavid du Colombier for(r=w=0; r<nwaitpids; r++)
645d3907fe5SDavid du Colombier if(waitpids[r] != pid)
646d3907fe5SDavid du Colombier waitpids[w++] = waitpids[r];
647d3907fe5SDavid du Colombier nwaitpids = w;
648d3907fe5SDavid du Colombier }
649d3907fe5SDavid du Colombier
650d3907fe5SDavid du Colombier void
clearwaitpids(void)651d3907fe5SDavid du Colombier clearwaitpids(void)
652d3907fe5SDavid du Colombier {
653d3907fe5SDavid du Colombier nwaitpids = 0;
654d3907fe5SDavid du Colombier }
655d3907fe5SDavid du Colombier
656d3907fe5SDavid du Colombier int
havewaitpid(int pid)657d3907fe5SDavid du Colombier havewaitpid(int pid)
658d3907fe5SDavid du Colombier {
659d3907fe5SDavid du Colombier int i;
660d3907fe5SDavid du Colombier
661d3907fe5SDavid du Colombier for(i=0; i<nwaitpids; i++)
662d3907fe5SDavid du Colombier if(waitpids[i] == pid)
663d3907fe5SDavid du Colombier return 1;
664d3907fe5SDavid du Colombier return 0;
665d3907fe5SDavid du Colombier }
666f07722aaSDavid du Colombier
667f07722aaSDavid du Colombier /* avoid loading any floating-point library code */
668f07722aaSDavid du Colombier int
_efgfmt(Fmt *)669f07722aaSDavid du Colombier _efgfmt(Fmt *)
670f07722aaSDavid du Colombier {
671f07722aaSDavid du Colombier return -1;
672f07722aaSDavid du Colombier }
673