diff --git a/qa/kern/wdir.rc b/qa/kern/wdir.rc new file mode 100644 index 0000000..a3c4719 --- /dev/null +++ b/qa/kern/wdir.rc @@ -0,0 +1,33 @@ +#!/cmd/rc + +rm -fr /tmp/abcdefghijklmnopqrstuvwxyz/ + +dir=/tmp/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyz + +mkdir -p $dir +cd $dir + +cwd=`{pwd} + +if ( ! ~ $dir $cwd ) { + echo FAIL: '''pwd''' returned $cwd instead of '$dir' + exit FAIL +} + +cwd=`{cat '#0/wdir'} +if ( ! ~ $dir $cwd ) { + echo FAIL: '''cat #0/wdir''' returned $cwd instead of '$dir' + exit FAIL +} + +ppath=/proc/$pid/wdir + +cwd=`{cat $ppath} +if ( ! ~ $dir $cwd ) { + echo FAIL: cat $ppath returned $cwd instead of '$dir' + exit FAIL +} + +rm -fr /tmp/abcdefghijklmnopqrstuvwxyz/ +echo PASS +exit PASS diff --git a/qa/lib/c/asmscall.c b/qa/lib/c/asmscall.c index 01e8d28..7ba2297 100644 --- a/qa/lib/c/asmscall.c +++ b/qa/lib/c/asmscall.c @@ -20,41 +20,6 @@ int verbose = 1; -#define asm_nsec() ({ \ - register long __ret asm ("rax"); \ - __asm__ __volatile__ ( \ - "syscall" \ - : "=r" (__ret) \ - : "0"(19) \ - : "cc", "rcx", "r11", "memory" \ - ); \ - __ret; }) - -#define asm_mount(/* int */ fd, /* int */ afd, /* char* */ old, /* int */ flag, /* char* */ aname, /* int */ mdev) ({ \ - register long r10 asm("r10") = flag; \ - register long r8 asm("r8") = (uintptr_t)aname; \ - register long r9 asm("r9") = mdev; \ - register int __ret asm ("eax"); \ - __asm__ __volatile__ ( \ - "syscall" \ - : "=r" (__ret) \ - : "0"(16), "D"(fd), "S"(afd), "d"(old), "r"(r10), "r"(r8), "r"(r9) \ - : "cc", "rcx", "r11", "memory" \ - ); \ - __ret; }) - -/* -long -asm_nsec(void) -{ - register int *p1 asm ("r0"); - register int *p2 asm ("r1"); - register int *result asm ("r0"); - asm ("sysint" : "=r" (result) : "0" (p1), "r" (p2)); - return result ; -} -*/ - void main(void) { @@ -62,9 +27,9 @@ main(void) uint64_t start, end; char *msg; - start = asm_nsec(); + start = sys_nsec(); sleep(1); - end = asm_nsec(); + end = sys_nsec(); if (end <= start) ret = 1; @@ -80,7 +45,7 @@ main(void) int fd; fd = open("#|", ORDWR); - asm_mount(fd, -1, "/tmp", MREPL, "", 'M'); + sys_mount(fd, -1, "/tmp", MREPL, "", 'M'); print("PASS\n"); exits("PASS"); diff --git a/sys/include/libc.h b/sys/include/libc.h index b1d5283..81c72b8 100644 --- a/sys/include/libc.h +++ b/sys/include/libc.h @@ -370,6 +370,7 @@ extern int atoi(const char*); extern int32_t atol(const char*); extern int64_t atoll(const char*); extern double charstod(int(*)(void*), void*); +extern int chdir(const char *dirname); extern char* cleanname(char*); extern int decrypt(void*, void*, int); extern int encrypt(void*, void*, int); @@ -387,7 +388,7 @@ extern char* getenv(const char*); extern int getfields(char*, char**, int, int, const char*); extern int gettokens(char *, char **, int, const char *); extern char* getuser(void); -extern char* getwd(char*, int); +extern long getwd(char*, int); extern int iounit(int); extern int32_t labs(int32_t); extern double ldexp(double, int); diff --git a/sys/src/cmd/acme/aux/win/main.c b/sys/src/cmd/acme/aux/win/main.c index 21b1783..7530034 100644 --- a/sys/src/cmd/acme/aux/win/main.c +++ b/sys/src/cmd/acme/aux/win/main.c @@ -71,7 +71,7 @@ threadmain(int argc, char *argv[]) name = av[0]; } - if(getwd(buf, sizeof buf) == 0) + if(getwd(buf, sizeof buf) <= 0) dir = "/"; else dir = buf; @@ -301,7 +301,7 @@ fsloop(void* _) break; } } -} +} void sendit(char *s) @@ -358,7 +358,7 @@ execevent(Window *w, Event *e, int (*command)(Window*, char*)) n = winread(w, e->q0, e->q1, s); s[n] = '\0'; needfree = 1; - }else + }else if(na){ t = emalloc(strlen(s)+1+na+2); sprint(t, "%s %s", s, ea->b); @@ -448,7 +448,7 @@ mainctl(void *v) write(w->data, e->b, e->nb); pendingS += e->nr; break; - + case 'E': /* write to tag or body; body happens due to sendit */ delta = e->q1-e->q0; if(e->c2=='I'){ @@ -463,7 +463,7 @@ mainctl(void *v) fprint(2, "win msg: %C %C %d %d %d %d %q\n", e->c1, e->c2, e->q0, e->q1, e->flag, e->nb, e->b); break; - + case 'F': /* generated by our actions (specifically case 'S' above) */ delta = e->q1-e->q0; if(e->c2=='D'){ @@ -540,7 +540,7 @@ mainctl(void *v) break; } break; - + case 'M': /* mouse */ delta = e->q1-e->q0; switch(e->c2){ @@ -548,14 +548,14 @@ mainctl(void *v) case 'X': execevent(w, e, command); break; - + case 'l': /* reflect all searches back to acme */ case 'L': if(e->flag & 2) recvp(w->cevent); winwriteevent(w, e); break; - + case 'I': endpt += delta; if(e->q0 < hostpt) @@ -574,7 +574,7 @@ mainctl(void *v) case 'd': /* modify away; we don't care */ case 'i': break; - + default: goto Unknown; } diff --git a/sys/src/cmd/cpu.c b/sys/src/cmd/cpu.c index 6c2bf45..bca24de 100644 --- a/sys/src/cmd/cpu.c +++ b/sys/src/cmd/cpu.c @@ -231,7 +231,7 @@ main(int argc, char **argv) /* Tell the remote side the command to execute and where our working directory is */ if(cflag) writestr(data, cmd, "command", 0); - if(getwd(dat, sizeof(dat)) == 0) + if(getwd(dat, sizeof(dat)) <= 0) writestr(data, "NO", "dir", 0); else writestr(data, dat, "dir", 0); diff --git a/sys/src/cmd/pwd.c b/sys/src/cmd/pwd.c index b862250..15f33b8 100644 --- a/sys/src/cmd/pwd.c +++ b/sys/src/cmd/pwd.c @@ -1,10 +1,19 @@ /* - * This file is part of the UCB release of Plan 9. It is subject to the license - * terms in the LICENSE file found in the top-level directory of this - * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No - * part of the UCB release of Plan 9, including this file, may be copied, - * modified, propagated, or distributed except according to the terms contained - * in the LICENSE file. + * This file is part of Jehanne. + * + * Copyright (C) 2016 Giacomo Tesio + * + * Jehanne is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * Jehanne is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Jehanne. If not, see . */ #include @@ -16,13 +25,23 @@ void main(int argc, char *argv[]) { - char pathname[512]; + long len; + char path[512]; + char *ppath = path; - //USED(argc, argv); - if(getwd(pathname, sizeof(pathname)) == 0) { - fprint(2, "pwd: %r\n"); - exits("getwd"); + len = getwd(ppath, sizeof(path)); + if(len == 0) + goto Error; + if(len < 0){ + len = ~len; + ppath = malloc(len*sizeof(char)); + if(getwd(ppath, len*sizeof(char)) <= 0) + goto Error; } - print("%s\n", pathname); + print("%s\n", ppath); exits(0); + +Error: + fprint(2, "pwd: %r\n"); + exits("getwd"); } diff --git a/sys/src/cmd/rio/rio.c b/sys/src/cmd/rio/rio.c index c395694..b7313ed 100644 --- a/sys/src/cmd/rio/rio.c +++ b/sys/src/cmd/rio/rio.c @@ -157,7 +157,7 @@ threadmain(int argc, char *argv[]) usage(); }ARGEND - if(getwd(buf, sizeof buf) == nil) + if(getwd(buf, sizeof buf) <= 0) startdir = estrdup("."); else startdir = estrdup(buf); @@ -324,7 +324,7 @@ shutdown(void * _, char *msg) { int i; static Lock shutdownlk; - + killprocs(); for(i=0; oknotes[i]; i++) if(strncmp(oknotes[i], msg, strlen(oknotes[i])) == 0){ @@ -344,7 +344,7 @@ killprocs(void) for(i=0; inotefd >= 0) - write(window[i]->notefd, "hangup", 6); + write(window[i]->notefd, "hangup", 6); } void @@ -418,7 +418,7 @@ int whichcorner(Rectangle r, Point p) { int i, j; - + i = portion(p.x, r.min.x, r.max.x); j = portion(p.y, r.min.y, r.max.y); return 3*j+i; @@ -995,7 +995,7 @@ bandsize(Window *w) drawborder(r, 1); or = r; startp = p; - + while(mouse->buttons==but){ p = onscreen(mouse->xy); r = whichrect(w->screenr, p, which); diff --git a/sys/src/cmd/tar.c b/sys/src/cmd/tar.c index b1614d0..bb41b62 100644 --- a/sys/src/cmd/tar.c +++ b/sys/src/cmd/tar.c @@ -1366,7 +1366,7 @@ main(int argc, char *argv[]) ret = extract(argv); break; case Replace: - if (getwd(origdir, sizeof origdir) == nil) + if (getwd(origdir, sizeof origdir) <= 0) strcpy(origdir, "/tmp"); ret = replace(argv); break; diff --git a/sys/src/kern/port/devdup.c b/sys/src/kern/port/devdup.c index 82f2720..566ed0c 100644 --- a/sys/src/kern/port/devdup.c +++ b/sys/src/kern/port/devdup.c @@ -64,9 +64,9 @@ dupopen(Chan *c, unsigned long omode) int fd, twicefd; if(c->qid.type & QTDIR){ - if(omode != 0) + if(omode != OREAD) error(Eisdir); - c->mode = 0; + c->mode = OREAD; c->flag |= COPEN; c->offset = 0; return c; diff --git a/sys/src/kern/port/devproc.c b/sys/src/kern/port/devproc.c index e6e64a9..53b86c7 100644 --- a/sys/src/kern/port/devproc.c +++ b/sys/src/kern/port/devproc.c @@ -25,6 +25,12 @@ #include #include "ureg.h" +extern long write_working_dir(Proc* p, void *va, long n, int64_t off); +extern long read_working_dir(Proc* p, void *va, long n, int64_t off); + +/* We can have up to 32 files in proc/n sice we dedicate 5 bits in Qid + * to it (see QSHIFT) + */ enum { Qdir, @@ -47,6 +53,7 @@ enum Qwait, Qprofile, Qsyscall, + Qwdir, }; enum @@ -76,23 +83,25 @@ enum{ }; #define STATSIZE (2*KNAMELEN+NUMSIZE+9*NUMSIZE + 1) -/* - * Status, fd, and ns are left fully readable (0444) because of their use in debugging, - * particularly on shared servers. - * Arguably, ns and fd shouldn't be readable; if you'd prefer, change them to 0000 +/* In Plan 9 status, fd, and ns were left fully readable (0444) + * because of their use in debugging, particularly on shared servers. + * + * In Jehanne the process owner and the host owner can read + * status and fd, but not others (0440). + * TODO: allow per process stats and permissions. */ Dirtab procdir[] = { "args", {Qargs}, 0, 0660, "ctl", {Qctl}, 0, 0000, - "fd", {Qfd}, 0, 0444, + "fd", {Qfd}, 0, 0440, "fpregs", {Qfpregs}, 0, 0000, "kregs", {Qkregs}, sizeof(Ureg), 0400, "mem", {Qmem}, 0, 0000, "note", {Qnote}, 0, 0000, "noteid", {Qnoteid}, 0, 0664, "notepg", {Qnotepg}, 0, 0000, - "ns", {Qns}, 0, 0444, + "ns", {Qns}, 0, 0440, "proc", {Qproc}, 0, 0400, "regs", {Qregs}, sizeof(Ureg), 0000, "segment", {Qsegment}, 0, 0444, @@ -100,6 +109,7 @@ Dirtab procdir[] = "text", {Qtext}, 0, 0000, "wait", {Qwait}, 0, 0400, "syscall", {Qsyscall}, 0, 0400, + "wdir", {Qwdir}, 0, 0640, }; static @@ -124,7 +134,7 @@ Cmdtab proccmd[] = { /* * Qids are, in path: - * 4 bits of file type (qids above) + * 5 bits of file type (qids above) * 23 bits of process slot number + 1 * in vers, * 32 bits of pid, for consistency checking @@ -232,6 +242,14 @@ procgen(Chan *c, char *name, Dirtab *tab, int _1, int s, Dir *dp) len = p->nwait; /* incorrect size, but >0 means there's something to read */ break; } + switch(QID(tab->qid)){ + case Qwdir: + /* file length might be relevant to the caller to + * malloc enough space in the buffer + */ + len = 1 + strlen(p->dot->path->s); + break; + } mkqid(&qid, path|tab->qid.path, c->qid.vers, QTFILE); devdir(c, qid, tab->name, len, p->user, perm, dp); @@ -424,6 +442,17 @@ procopen(Chan *c, unsigned long omode) c->pgrpid.vers = p->noteid; break; + case Qwdir: + if(p == up) /* self write is always allowed */ + break; + if(omode > ORDWR) + error(Eperm); + if(strcmp(up->user, p->user) != 0 /* process owner can read/write */ + || !iseve() /* host owner can read */ + || (omode&OWRITE) != 0) + error(Eperm); + break; + default: poperror(); qunlock(&p->debug); @@ -1058,6 +1087,10 @@ procread(Chan *c, void *va, long n, int64_t off) r = procfds(p, va, n, offset); psdecref(p); return r; + case Qwdir: + r = read_working_dir(p, va, n, off); + psdecref(p); + return r; } error(Egreg); return 0; /* not reached */ @@ -1213,6 +1246,9 @@ procwrite(Chan *c, void *va, long n, int64_t off) if(p->noteid != id) error(Ebadarg); break; + case Qwdir: + n = write_working_dir(p, va, n, off); + break; default: poperror(); qunlock(&p->debug); diff --git a/sys/src/kern/port/devsegment.c b/sys/src/kern/port/devsegment.c index 6ec55fc..1d53aef 100644 --- a/sys/src/kern/port/devsegment.c +++ b/sys/src/kern/port/devsegment.c @@ -215,7 +215,7 @@ segmentopen(Chan *c, int omode) switch(TYPE(c)){ case Qtopdir: case Qsegdir: - if(omode != 0) + if(omode != OREAD) error(Eisdir); break; case Qctl: diff --git a/sys/src/kern/port/devself.c b/sys/src/kern/port/devself.c index 275f6ce..522d2f9 100644 --- a/sys/src/kern/port/devself.c +++ b/sys/src/kern/port/devself.c @@ -37,6 +37,7 @@ typedef enum SelfNodes Qppid, Qsegments, Qpipes, + Qwdir, } SelfNodes; typedef enum SegmentsCmd @@ -65,9 +66,49 @@ static Dirtab selfdir[]={ "ppid", {Qppid}, 0, 0, "segments", {Qsegments}, 0, 0644, "pipes", {Qpipes}, 0, 0, + "wdir", {Qwdir}, 0, 0644, }; +static int +selfgen(Chan *c, char *name, Dirtab *tab, int ntab, int i, Dir *dp) +{ + long length; + if(tab == 0) + return -1; + if(i == DEVDOTDOT){ + if(QID(c->qid) != Qdir) + panic("selfwalk %llux", c->qid.path); + devdir(c, selfdir[0].qid, "#0", 0, up->user, selfdir[0].perm, dp); + return 1; + } + + if(name){ + for(i=1; i= ntab) + return -1; + tab += i; + } + if(tab->qid.path == Qwdir) { + /* file length might be relevant to the caller to + * malloc enough space in the buffer + */ + length = 1 + strlen(up->dot->path->s); + } else { + length = tab->length; + } + devdir(c, tab->qid, tab->name, length, up->user, tab->perm, dp); + return 1; +} + static Chan* selfattach(Chan *c, Chan *ac, char *spec, int flags) { @@ -77,23 +118,80 @@ selfattach(Chan *c, Chan *ac, char *spec, int flags) static Walkqid* selfwalk(Chan *c, Chan *nc, char **name, int nname) { - return devwalk(c, nc, name, nname, selfdir, nelem(selfdir), devgen); + return devwalk(c, nc, name, nname, selfdir, nelem(selfdir), selfgen); } static long selfstat(Chan *c, uint8_t *dp, long n) { - return devstat(c, dp, n, selfdir, nelem(selfdir), devgen); + return devstat(c, dp, n, selfdir, nelem(selfdir), selfgen); } static Chan* selfopen(Chan *c, unsigned long omode) { c->aux = nil; - c = devopen(c, omode, selfdir, nelem(selfdir), devgen); + c = devopen(c, omode, selfdir, nelem(selfdir), selfgen); return c; } +long +read_working_dir(Proc* p, void *va, long n, int64_t off) +{ + int i, j; + char *path; + Chan *dot; + + dot = up->dot; + path = dot->path->s; + i = 1 + strlen(path); + if(va == nil){ + /* the user is actually asking for the space */ + if(off != 0 && off != ~0) { + /* #0/wdir does not allow offset in read */ + error("offset reading wdir size"); + } + errorl("not enough space in buffer", ~i); + } + if(off > i) + return 0; + j = i - off; + if(n < j) + j = n; + memmove(va, path, j); + + return j; +} + + +long +write_working_dir(Proc* p, void *va, long n, int64_t off) +{ + Chan *c, *dot; + char *path, *epath; + + dot = p->dot; + path = va; + epath = vmemchr(path, 0, n); + + if(n <= 0) + error(Ebadarg); + if(off != 0 && off != ~0) + error("offset writing wdir"); + if(epath-path>=n) + error("no terminal zero writing wdir"); + + c = namec(path, Atodir, 0, 0); + if(CASV(&p->dot, dot, c)){ + cclose(dot); + } else { + cclose(c); + error("race writing wdir"); + } + + return 0; +} + static long selfread(Chan *c, void *va, long n, int64_t off) { @@ -104,6 +202,8 @@ selfread(Chan *c, void *va, long n, int64_t off) offset = off; switch(QID(c->qid)){ + case Qdir: + return devdirread(c, va, n, selfdir, nelem(selfdir), selfgen); case Qsegments: rlock(&up->seglock); j = 0; @@ -127,6 +227,8 @@ selfread(Chan *c, void *va, long n, int64_t off) exhausted("segments"); memmove(va, &statbuf[offset], n); return n; + case Qwdir: + return read_working_dir(up, va, n, off); default: error(Egreg); } @@ -271,10 +373,10 @@ selfwrite(Chan *c, void *va, long n, int64_t off) default: error(Egreg); case Qsegments: - n = procsegctl(up, va, n); - break; + return procsegctl(up, va, n); + case Qwdir: + return write_working_dir(up, va, n, off); } - return n; } static int diff --git a/sys/src/kern/port/devshr.c b/sys/src/kern/port/devshr.c index 28e3e6d..a5950bf 100644 --- a/sys/src/kern/port/devshr.c +++ b/sys/src/kern/port/devshr.c @@ -1,21 +1,3 @@ -/* - * This file is part of Jehanne. - * - * Copyright (C) 2015-2016 Giacomo Tesio - * - * Jehanne is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 2 of the License. - * - * Jehanne is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Jehanne. If not, see . - */ - /* This device has been ported from 9front. */ #include "u.h" diff --git a/sys/src/kern/port/fault.c b/sys/src/kern/port/fault.c index 842d162..37c764b 100644 --- a/sys/src/kern/port/fault.c +++ b/sys/src/kern/port/fault.c @@ -6,13 +6,6 @@ #include "fns.h" #include "../port/error.h" -//char *faulttypes[] = { - //[FT_WRITE] "write", - //[FT_READ] "read", - //[FT_EXEC] "exec" -//}; - - int fault(uintptr_t addr, uintptr_t pc, int ftype) { @@ -70,132 +63,6 @@ fault(uintptr_t addr, uintptr_t pc, int ftype) return -1; } -//int -//fixfault(Segment *s, uintptr_t addr, int ftype, int dommuput) -//{ - //int type; - //Pte **p, *etp; - //uintptr_t soff; - //uintmem mmuphys; - //Page **pg, *old, *new; - //Page *(*fn)(Segment*, uintptr_t); - //uintptr_t pgsize; - //Pages *pages; - - //pages = s->pages; /* TO DO: segwalk */ - //pgsize = 1<lg2pgsize; - //addr &= ~(pgsize-1); - //soff = addr-s->pages->base; - - //p = &pages->map[soff/pages->ptemapmem]; - //if(*p == nil) - //*p = ptealloc(); - - //etp = *p; - //pg = &etp->pages[(soff&(pages->ptemapmem-1))>>pages->lg2pgsize]; - - //if(pg < etp->first) - //etp->first = pg; - //if(pg > etp->last) - //etp->last = pg; - - //type = s->type&SG_TYPE; - //if(*pg == nil){ - //switch(type){ - //case SG_BSS: /* Zero fill on demand */ - //case SG_SHARED: - //case SG_STACK: - //new = newpage(1, s->pages->lg2pgsize, &s->lk); - //if(new == nil) - //return -1; - //*pg = new; - //break; - - //case SG_LOAD: - //case SG_TEXT: /* demand load */ - //case SG_DATA: - //if(!loadimagepage(s->image, s, pg, addr)) - //return -1; - //break; - - //case SG_PHYSICAL: - //fn = s->pseg->pgalloc; - //if(fn != nil) - //*pg = (*fn)(s, addr); - //else { - //new = smalloc(sizeof(Page)); - //new->pa = s->pseg->pa+(addr-s->pages->base); - //new->r.ref = 1; - //new->lg2size = s->pseg->lg2pgsize; - //if(new->lg2size == 0) - //new->lg2size = PGSHFT; /* TO DO */ - //*pg = new; - //} - //break; - //default: - //panic("fault on demand"); - //break; - //} - //} - //mmuphys = 0; - //switch(type) { - //default: - //panic("fault"); - //break; - - //case SG_TEXT: - //DBG("text pg %#p: %#p -> %#P %d\n", pg, addr, (*pg)->pa, (*pg)->r.ref); - //mmuphys = PPN((*pg)->pa) | PTERONLY|PTEVALID; - //break; - - //case SG_BSS: - //case SG_SHARED: - //case SG_STACK: - //case SG_DATA: /* copy on write */ - //DBG("data pg %#p: %#p -> %#P %d\n", pg, addr, (*pg)->pa, (*pg)->r.ref); - ///* - //* It's only possible to copy on write if - //* we're the only user of the segment. - //*/ - //if(ftype != FT_WRITE && sys->copymode == 0 && s->r.ref == 1) { - //mmuphys = PPN((*pg)->pa)|PTERONLY|PTEVALID; - //break; - //} - - //old = *pg; - //if(old->r.ref > 1){ - ///* shared (including image pages): make private writable copy */ - //new = newpage(0, s->pages->lg2pgsize, &s->lk); - //if(new != nil) - //copypage(old, new); - //*pg = new; - //putpage(old); - //if(new == nil) - //return -1; - //DBG("data' pg %#p: %#p -> %#P %d\n", *pg, addr, old->pa, old->r.ref); - //}else if(old->r.ref <= 0) - //panic("fault: page %#p %#P ref %d <= 0", old, old->pa, old->r.ref); - //mmuphys = PPN((*pg)->pa) | PTEWRITE | PTEVALID; - //break; - - //case SG_PHYSICAL: - //mmuphys = PPN((*pg)->pa) | PTEVALID; - //if((s->pseg->attr & SG_WRITE)) - //mmuphys |= PTEWRITE; - //if((s->pseg->attr & SG_CACHED) == 0) - //mmuphys |= PTEUNCACHED; - //break; - //} - //runlock(&s->lk); - - //if(dommuput) - //mmuput(addr, mmuphys, *pg); - //if(ftype == FT_EXEC) - //peekAtExecFaults(addr); - - //return 0; -//} - /* * Called only in a system call */ @@ -225,7 +92,7 @@ void* validaddr(void* addr, long len, int write) { if(!okaddr(PTR2UINT(addr), len, write)){ - pprint("trap: invalid address %#p/%lud in sys call pc=%#P\n", addr, len, userpc(nil)); + pprint("trap: invalid address %#p/%ld in sys call pc=%#P\n", addr, len, userpc(nil)); postnote(up, 1, "sys: bad address in syscall", NDebug); error(Ebadarg); } diff --git a/sys/src/kern/port/sysfile.c b/sys/src/kern/port/sysfile.c index cc22a91..ea38c53 100644 --- a/sys/src/kern/port/sysfile.c +++ b/sys/src/kern/port/sysfile.c @@ -597,14 +597,24 @@ mountfix(Chan *c, uint8_t *op, int32_t n, int32_t maxn) } long -syspread(int fd, void *p, int32_t n, int64_t off) +syspread(int fd, void *p, long n, int64_t off) { int32_t nn; long nnn; int sequential; Chan *c; - p = validaddr(p, n, 1); + if(n >= 0) + p = validaddr(p, n, 1); + else if(p != nil) { + /* in Jehanne, a negative length can be meaningful to + * the target device/server, but with a negative length + * to read the buffer must be nil + */ + pprint("trap: invalid address %#p/%ld in sys call pc=%#P\n", p, n, userpc(nil)); + postnote(up, 1, "sys: bad address in syscall", NDebug); + error(Ebadarg); + } c = fdtochan(fd, OREAD, 1, 1); @@ -679,7 +689,7 @@ syspread(int fd, void *p, int32_t n, int64_t off) } long -syspwrite(int fd, void *p, int32_t n, int64_t off) +syspwrite(int fd, void *p, long n, int64_t off) { long r; int sequential; @@ -858,20 +868,6 @@ sysfstat(int fd, uint8_t* p, int n) return r; } -int -syschdir(char *aname) -{ - Chan *c; - - aname = validaddr(aname, 1, 0); - - c = namec(aname, Atodir, 0, 0); - cclose(up->dot); - up->dot = c; - - return 0; -} - /* white list of devices we allow mounting on. * At some point we can have build generate this if we ever * really start using it. diff --git a/sys/src/lib/auth/newns.c b/sys/src/lib/auth/newns.c index 8d7ac32..ea37b3b 100644 --- a/sys/src/lib/auth/newns.c +++ b/sys/src/lib/auth/newns.c @@ -77,7 +77,7 @@ buildns(int newns, char *user, char *file) /* make sure we managed to cd into the new name space */ if(newns && !cdroot){ path = malloc(1024); - if(path == nil || getwd(path, 1024) == 0 || chdir(path) < 0) + if(path == nil || getwd(path, 1024) <= 0 || chdir(path) < 0) chdir("/"); if(path != nil) free(path); @@ -222,7 +222,7 @@ unquote(char *s) { char *r, *w; int inquote; - + inquote = 0; for(r=w=s; *r; r++){ if(*r != '\''){ @@ -267,7 +267,7 @@ nextdollar(char *arg) { char *p; int inquote; - + inquote = 0; for(p=arg; *p; p++){ if(*p == '\'') diff --git a/sys/src/lib/c/9sys/chdir.c b/sys/src/lib/c/9sys/chdir.c new file mode 100644 index 0000000..8c7009c --- /dev/null +++ b/sys/src/lib/c/9sys/chdir.c @@ -0,0 +1,38 @@ +/* + * This file is part of Jehanne. + * + * Copyright (C) 2016 Giacomo Tesio + * + * Jehanne is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * Jehanne is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Jehanne. If not, see . + */ + +#include +#include + +int +chdir(const char *dirname) +{ + char buf[32]; + int tmp, fd; + + tmp = getpid(); + snprint(buf, sizeof(buf), "/proc/%d/wdir", tmp); + fd = open(buf, OWRITE); + if(fd < 0) + fd = open("#0/wdir", OWRITE); + if(fd < 0) + return fd; + tmp = write(fd, dirname, 1+strlen(dirname)); + close(fd); + return tmp; +} diff --git a/sys/src/lib/c/9sys/getwd.c b/sys/src/lib/c/9sys/getwd.c index 4834c1e..2b4e04b 100644 --- a/sys/src/lib/c/9sys/getwd.c +++ b/sys/src/lib/c/9sys/getwd.c @@ -1,26 +1,45 @@ /* - * This file is part of the UCB release of Plan 9. It is subject to the license - * terms in the LICENSE file found in the top-level directory of this - * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No - * part of the UCB release of Plan 9, including this file, may be copied, - * modified, propagated, or distributed except according to the terms contained - * in the LICENSE file. + * This file is part of Jehanne. + * + * Copyright (C) 2016 Giacomo Tesio + * + * Jehanne is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * Jehanne is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Jehanne. If not, see . */ #include #include -char* +/* Fills buf with the current workking directory. + * + * Returns + * - 0 on error + * - the negated length of the working directory path if nbuf is too small + * - the (positive) length of the working directory on success + */ +long getwd(char *buf, int nbuf) { - int n, fd; + long n; + int fd; - fd = open(".", OREAD); + fd = open("#0/wdir", OREAD); if(fd < 0) - return nil; - n = fd2path(fd, buf, nbuf); + return 0; + n = read(fd, nil, -1); + if(n == ~0) /* an error occurred */ + return 0; + if(nbuf >= ~n) + n = read(fd, buf, nbuf); close(fd); - if(n < 0) - return nil; - return buf; + return n; } diff --git a/sys/src/lib/c/build.json b/sys/src/lib/c/build.json index 097b7a5..6de15f9 100644 --- a/sys/src/lib/c/build.json +++ b/sys/src/lib/c/build.json @@ -38,6 +38,7 @@ "9sys/access.c", "9sys/announce.c", "9sys/awakened.c", + "9sys/chdir.c", "9sys/convD2M.c", "9sys/convM2D.c", "9sys/cputime.c", diff --git a/sys/src/sysconf.json b/sys/src/sysconf.json index 853cc64..ab80fe9 100644 --- a/sys/src/sysconf.json +++ b/sys/src/sysconf.json @@ -65,19 +65,9 @@ }, { "Args": [ - "const char*" + "int" ], "Id": 4, - "Name": "chdir", - "Ret": [ - "int" - ] - }, - { - "Args": [ - "int" - ], - "Id": 5, "Name": "close", "Ret": [ "long" @@ -89,7 +79,7 @@ "uint32_t", "uint32_t" ], - "Id": 6, + "Id": 5, "Name": "create", "Ret": [ "long" @@ -100,7 +90,7 @@ "int32_t", "int32_t" ], - "Id": 7, + "Id": 6, "Name": "dup", "Ret": [ "int32_t" @@ -111,7 +101,7 @@ "char*", "int" ], - "Id": 8, + "Id": 7, "Name": "errstr", "Ret": [ "int" @@ -122,7 +112,7 @@ "const char*", "const char**" ], - "Id": 9, + "Id": 8, "Name": "exec", "Ret": [ "uintptr_t" @@ -132,7 +122,7 @@ "Args": [ "const char*" ], - "Id": 10, + "Id": 9, "Name": "_exits", "Ret": [ "int" @@ -143,7 +133,7 @@ "int", "const char*" ], - "Id": 11, + "Id": 10, "Name": "fauth", "Ret": [ "int" @@ -155,7 +145,7 @@ "const char*", "uint32_t" ], - "Id": 12, + "Id": 11, "Name": "fd2path", "Ret": [ "int32_t" @@ -167,7 +157,7 @@ "uint8_t*", "int" ], - "Id": 13, + "Id": 12, "Name": "fstat", "Ret": [ "long" @@ -180,7 +170,7 @@ "const char*", "int" ], - "Id": 14, + "Id": 13, "Name": "fversion", "Ret": [ "int" @@ -192,7 +182,7 @@ "const uint8_t*", "uint32_t" ], - "Id": 15, + "Id": 14, "Name": "fwstat", "Ret": [ "long" @@ -207,7 +197,7 @@ "const char*", "int" ], - "Id": 16, + "Id": 15, "Name": "mount", "Ret": [ "int" @@ -217,7 +207,7 @@ "Args": [ "int" ], - "Id": 17, + "Id": 16, "Name": "noted", "Ret": [ "int" @@ -227,14 +217,14 @@ "Args": [ "const void*" ], - "Id": 18, + "Id": 17, "Name": "notify", "Ret": [ "int" ] }, { - "Id": 19, + "Id": 18, "Name": "nsec", "Ret": [ "long" @@ -245,7 +235,7 @@ "const char*", "uint32_t" ], - "Id": 20, + "Id": 19, "Name": "open", "Ret": [ "long" @@ -255,10 +245,10 @@ "Args": [ "int", "void*", - "int", + "long", "long" ], - "Id": 21, + "Id": 20, "Name": "pread", "Ret": [ "long" @@ -268,10 +258,10 @@ "Args": [ "int", "const void*", - "int", + "long", "long" ], - "Id": 22, + "Id": 21, "Name": "pwrite", "Ret": [ "long" @@ -281,7 +271,7 @@ "Args": [ "const char*" ], - "Id": 23, + "Id": 22, "Name": "remove", "Ret": [ "long" @@ -292,7 +282,7 @@ "const void*", "void*" ], - "Id": 24, + "Id": 23, "Name": "rendezvous", "Ret": [ "void*" @@ -302,7 +292,7 @@ "Args": [ "uint32_t" ], - "Id": 25, + "Id": 24, "Name": "rfork", "Ret": [ "int" @@ -314,7 +304,7 @@ "long", "int" ], - "Id": 26, + "Id": 25, "Name": "seek", "Ret": [ "long" @@ -325,7 +315,7 @@ "int*", "int" ], - "Id": 27, + "Id": 26, "Name": "semacquire", "Ret": [ "int" @@ -336,7 +326,7 @@ "int*", "int" ], - "Id": 28, + "Id": 27, "Name": "semrelease", "Ret": [ "int" @@ -347,7 +337,7 @@ "int*", "uint64_t" ], - "Id": 29, + "Id": 28, "Name": "tsemacquire", "Ret": [ "int" @@ -358,7 +348,7 @@ "const char*", "const char*" ], - "Id": 30, + "Id": 29, "Name": "unmount", "Ret": [ "int" @@ -368,7 +358,7 @@ "Args": [ "unsigned long" ], - "Id": 31, + "Id": 30, "Name": "alarm", "Ret": [ "long"