From c6de6b66e9dd9543ead73b8c283e58c1caf3c898 Mon Sep 17 00:00:00 2001 From: Giacomo Tesio Date: Sun, 11 Dec 2016 01:19:51 +0100 Subject: [PATCH] kernel: introduce devself Devself provides to each process access to its own structures. So far it contains four files: - pid - ppid - pipes used to implement pipe(2) - segments used to implement segattach, segdetach and segfree --- qa/kern/getpid.c | 9 +- qa/kern/getppid.c | 9 +- sys/include/libc.h | 1 + sys/src/kern/amd64/build.json | 1 + sys/src/kern/amd64/workhorse.json | 1 + sys/src/kern/port/chan.c | 9 +- sys/src/kern/port/devcons.c | 10 - sys/src/kern/port/devdup.c | 4 +- sys/src/kern/port/devproc.c | 163 ++----------- sys/src/kern/port/devself.c | 387 ++++++++++++++++++++++++++++++ sys/src/kern/port/include.json | 3 +- sys/src/kern/port/sysfile.c | 68 +----- sys/src/lib/c/9sys/getpid.c | 17 +- sys/src/lib/c/9sys/getppid.c | 19 +- sys/src/lib/c/9sys/pipe.c | 37 +++ sys/src/lib/c/9sys/segattach.c | 24 +- sys/src/lib/c/build.json | 1 + sys/src/sysconf.json | 32 +-- 18 files changed, 480 insertions(+), 315 deletions(-) create mode 100644 sys/src/kern/port/devself.c create mode 100644 sys/src/lib/c/9sys/pipe.c diff --git a/qa/kern/getpid.c b/qa/kern/getpid.c index 914bbd7..ce2f945 100644 --- a/qa/kern/getpid.c +++ b/qa/kern/getpid.c @@ -36,13 +36,8 @@ main(void) exits("FAIL"); } rfork(RFNOMNT|RFCNAMEG); - if(getpid() != -1){ - print("FAIL: rfork(RFNOMNT|RFCNAMEG)); getpid() != -1\n"); - exits("FAIL"); - } - rerrstr(err, ERRMAX); - if(strcmp("getpid: cannot open neither #c/pid nor /dev/pid", err)){ - print("FAIL: rfork(RFNOMNT|RFCNAMEG)); getpid() set errstr '%s'\n", err); + if(getpid() != pid){ + print("FAIL: rfork(RFNOMNT|RFCNAMEG)); getpid() != getmainpid()\n"); exits("FAIL"); } diff --git a/qa/kern/getppid.c b/qa/kern/getppid.c index fa2cb0a..e2b76b9 100644 --- a/qa/kern/getppid.c +++ b/qa/kern/getppid.c @@ -38,13 +38,8 @@ main(void) exits("FAIL"); } rfork(RFNOMNT|RFCNAMEG); - if(getppid() != -1){ - print("FAIL: rfork(RFNOMNT|RFCNAMEG)); getppid() != -1\n"); - exits("FAIL"); - } - rerrstr(err, ERRMAX); - if(strcmp("getppid: cannot open neither #c/ppid nor /dev/ppid", err)){ - print("FAIL: rfork(RFNOMNT|RFCNAMEG)); getppid() set errstr '%s'\n", err); + if(getppid() != ppid){ + print("FAIL: rfork(RFNOMNT|RFCNAMEG)); getppid() != getmainpid()\n"); exits("FAIL"); } exits(nil); diff --git a/sys/include/libc.h b/sys/include/libc.h index f2ce6fd..b1d5283 100644 --- a/sys/include/libc.h +++ b/sys/include/libc.h @@ -396,6 +396,7 @@ extern char* mktemp(char*); extern double modf(double, double*); extern void notejmp(void*, jmp_buf, int); extern void perror(const char*); +extern int pipe(int pipes[2]); extern int postnote(int, int, const char *); extern double pow10(int); extern int putenv(const char*, const char*); diff --git a/sys/src/kern/amd64/build.json b/sys/src/kern/amd64/build.json index 605ae8b..2e9dd6e 100644 --- a/sys/src/kern/amd64/build.json +++ b/sys/src/kern/amd64/build.json @@ -36,6 +36,7 @@ "root", "rtc", "sd", + "self", "shr", "srv", "ssl", diff --git a/sys/src/kern/amd64/workhorse.json b/sys/src/kern/amd64/workhorse.json index 1617a82..0f52255 100644 --- a/sys/src/kern/amd64/workhorse.json +++ b/sys/src/kern/amd64/workhorse.json @@ -32,6 +32,7 @@ "proc", "root", "sd", + "self", "shr", "srv", "uart" diff --git a/sys/src/kern/port/chan.c b/sys/src/kern/port/chan.c index 945e18b..bbb42d0 100644 --- a/sys/src/kern/port/chan.c +++ b/sys/src/kern/port/chan.c @@ -1291,9 +1291,10 @@ namec(char *aname, int amode, int omode, int perm) * noattach is sandboxing. * * the OK exceptions are: - * | it only gives access to pipes you create - * d this process's file descriptors - * e this process's environment + * | current process's pipes + * 0 current process's kernel infos + * d current process's file descriptors + * e current process's environment * NOTE: Plan9 also allows * c time and pid, but also cons and consctl * p control of your own processes (and unfortunately @@ -1303,7 +1304,7 @@ namec(char *aname, int amode, int omode, int perm) * Who actually need them can bind #c and #p somewhere * before rfork(RFNOMNT) */ - if(up->pgrp->noattach && utfrune("|de", r)==nil) + if(up->pgrp->noattach && utfrune("|0de", r)==nil) error(Enoattach); dev = devtabget(r, 1); //XDYNX if(dev == nil) diff --git a/sys/src/kern/port/devcons.c b/sys/src/kern/port/devcons.c index 3d49ab2..e67cf29 100644 --- a/sys/src/kern/port/devcons.c +++ b/sys/src/kern/port/devcons.c @@ -680,8 +680,6 @@ enum{ Qnull, Qosversion, Qpgrpid, - Qpid, - Qppid, Qrandom, Qreboot, Qswap, @@ -713,8 +711,6 @@ static Dirtab consdir[]={ "null", {Qnull}, 0, 0666, "osversion", {Qosversion}, 0, 0444, "pgrpid", {Qpgrpid}, NUMSIZE, 0444, - "pid", {Qpid}, NUMSIZE, 0444, - "ppid", {Qppid}, NUMSIZE, 0444, "random", {Qrandom}, 0, 0444, "reboot", {Qreboot}, 0, 0664, "swap", {Qswap}, 0, 0664, @@ -944,12 +940,6 @@ consread(Chan *c, void *buf, long n, int64_t off) case Qpgrpid: return readnum(offset, buf, n, up->pgrp->pgrpid, NUMSIZE); - case Qpid: - return readnum(offset, buf, n, up->pid, NUMSIZE); - - case Qppid: - return readnum(offset, buf, n, up->parentpid, NUMSIZE); - case Qtime: return readtime(offset, buf, n); diff --git a/sys/src/kern/port/devdup.c b/sys/src/kern/port/devdup.c index 770860d..82f2720 100644 --- a/sys/src/kern/port/devdup.c +++ b/sys/src/kern/port/devdup.c @@ -12,7 +12,7 @@ dupgen(Chan *c, char * _1, Dirtab* _2, int _3, int s, Dir *dp) { Fgrp *fgrp = up->fgrp; Chan *f; - static int perm[] = { 0400, 0200, 0600, 0 }; + static int perm[] = { 0, 0400, 0200, 0600, 0 }; int p; Qid q; @@ -31,7 +31,7 @@ dupgen(Chan *c, char * _1, Dirtab* _2, int _3, int s, Dir *dp) p = 0400; sprint(up->genbuf, "%dctl", s/2); }else{ - p = perm[f->mode&3]; + p = perm[f->mode&7]; sprint(up->genbuf, "%d", s/2); } mkqid(&q, s+1, 0, QTFILE); diff --git a/sys/src/kern/port/devproc.c b/sys/src/kern/port/devproc.c index 4aa3b7e..e6e64a9 100644 --- a/sys/src/kern/port/devproc.c +++ b/sys/src/kern/port/devproc.c @@ -1,3 +1,20 @@ +/* + * 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 . + */ #include "u.h" #include "../port/lib.h" #include "mem.h" @@ -51,11 +68,6 @@ enum CMwaitstop, CMwired, CMtrace, - - /* segments */ - CMsegattach, - CMsegdetach, - CMsegfree, }; enum{ @@ -83,7 +95,7 @@ Dirtab procdir[] = "ns", {Qns}, 0, 0444, "proc", {Qproc}, 0, 0400, "regs", {Qregs}, sizeof(Ureg), 0000, - "segment", {Qsegment}, 0, 0644, + "segment", {Qsegment}, 0, 0444, "status", {Qstatus}, STATSIZE, 0444, "text", {Qtext}, 0, 0000, "wait", {Qwait}, 0, 0400, @@ -108,9 +120,6 @@ Cmdtab proccmd[] = { CMwaitstop, "waitstop", 1, CMwired, "wired", 2, CMtrace, "trace", 0, - CMsegattach, "attach", 5, - CMsegdetach, "detach", 2, - CMsegfree, "free", 3, }; /* @@ -366,7 +375,6 @@ procopen(Chan *c, unsigned long omode) case Qsegment: if(omode != OREAD && omode != OSTAT) - if(omode != OWRITE || up->pid != pid) error(Eperm); break; @@ -1092,137 +1100,6 @@ mntscan(Mntwalk *mw, Proc *p) runlock(&pg->ns); } -static uintptr_t -segattach(Proc* p, int attr, const char* name, uintptr_t va, usize len) -{ - unsigned int sno, tmp; - ProcSegment *s; - uintptr_t pa, size; - - - if((va != 0 && va < UTZERO) || iskaddr(va)) - error("virtual address below text or in kernel"); - - vmemchr((void *)name, 0, ~0); - - for(sno = 0; sno < NSEG; sno++) - if(p->seg[sno] == nil && sno != ESEG) - break; - - if(sno == NSEG) - error("too many segments in process"); - - len = ROUNDUP(va+len, PGSZ) - ROUNDDN(va, PGSZ); - va = ROUNDDN(va, PGSZ); - - if(rawmem_find((char**)&name, &pa, &tmp, &size)){ - s = 0; - wlock(&p->seglock); - if(pa){ - if(!segment_physical(&s, attr&SegPermissionMask, attr&SegFlagMask, va, pa)) - goto SegAttachEbadarg; - } else if(size != -1){ - if(!segment_global(&s, attr&SegPermissionMask, va, (char*)name)) - goto SegAttachEbadarg; - } else { - if(!segment_virtual(&s, tmp&SegmentTypesMask, attr&SegPermissionMask&~SgExecute, attr&SegFlagMask, va, va+len)) - goto SegAttachEbadarg; - } - for(tmp = 0; tmp < NSEG; tmp++){ - if(p->seg[tmp]) - if((p->seg[tmp]->base > s->base && p->seg[tmp]->base < s->top) - || (p->seg[tmp]->top > s->base && p->seg[tmp]->top < s->top)){ - goto SegAttachEsoverlap; - } - } - up->seg[sno] = s; - wunlock(&p->seglock); - return s->base; - } - error("segment not found"); -SegAttachEbadarg: - wunlock(&p->seglock); - error(Ebadarg); -SegAttachEsoverlap: - wunlock(&p->seglock); - segment_release(&s); - error(Esoverlap); -} - -static uintptr_t -segdetach(Proc* p, uintptr_t va) -{ - if(!proc_segment_detach(p, va)) - error(Ebadarg); - - mmuflush(); - return 0; -} - -static uintptr_t -segfree(Proc* p, uintptr_t va, unsigned long len) -{ - ProcSegment *s; - uintptr_t from, to; - - from = PTR2UINT(va); - to = ROUNDDN(from + len, PGSZ); - - s = proc_segment(p, from); - if(s == nil || to < from || to > s->top) - error(Ebadarg); - - from = ROUNDUP(from, PGSZ); - if(from == to) - return 0; - - segment_free_pages(s, from, to); - mmuflush(); - return 0; -} - -static long -procsegctl(Proc *p, char *va, int n) -{ - Cmdbuf *cb; - Cmdtab *ct; - int attr; - const char *class; - uintptr_t vareq; - unsigned long len; - long result; - - cb = parsecmd(va, n); - if(waserror()){ - free(cb); - nexterror(); - } - - ct = lookupcmd(cb, proccmd, nelem(proccmd)); - switch(ct->index){ - default: - error(Ebadctl); - return -1; - case CMsegattach: - attr = strtoul(cb->f[1], 0, 0); - vareq = strtoull(cb->f[2], 0, 0); - len = strtoull(cb->f[3], 0, 0); - class = cb->f[4]; - result = segattach(p, attr, class, vareq, len); - break; - case CMsegdetach: - vareq = strtoull(cb->f[1], 0, 0); - result = segdetach(p, vareq); - break; - case CMsegfree: - vareq = strtoull(cb->f[1], 0, 0); - len = strtoull(cb->f[2], 0, 0); - result = segfree(p, vareq, len); - break; - } - poperror(); - return result; -} static long procwrite(Chan *c, void *va, long n, int64_t off) @@ -1300,10 +1177,6 @@ procwrite(Chan *c, void *va, long n, int64_t off) n = fpudevprocio(p, va, n, offset, 1); break; - case Qsegment: - n = procsegctl(p, va, n); - break; - case Qctl: procctlreq(p, va, n); break; diff --git a/sys/src/kern/port/devself.c b/sys/src/kern/port/devself.c new file mode 100644 index 0000000..275f6ce --- /dev/null +++ b/sys/src/kern/port/devself.c @@ -0,0 +1,387 @@ +/* + * 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 "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "../port/error.h" + +#define QID(q) ((((uint32_t)(q).path)&0x0000001F)>>0) +#define STATSIZE (2*KNAMELEN+NUMSIZE+9*NUMSIZE + 1) + +/* devself provides to each process access to its own structures + * (pid, ppid, segments...). + */ +typedef enum SelfNodes +{ + Qdir, + + /* Process control */ + Qpid, + Qppid, + Qsegments, + Qpipes, +} SelfNodes; + +typedef enum SegmentsCmd +{ + CMsegattach, + CMsegdetach, + CMsegfree, +} SegmentsCmd; + +static +Cmdtab proccmd[] = { + CMsegattach, "attach", 5, + CMsegdetach, "detach", 2, + CMsegfree, "free", 3, +}; + +typedef union PipeSet +{ + long merged; + int fd[2]; +} PipeSet; + +static Dirtab selfdir[]={ + ".", {Qdir, 0, QTDIR}, 0, DMDIR|0777, + "pid", {Qpid}, 0, 0, + "ppid", {Qppid}, 0, 0, + "segments", {Qsegments}, 0, 0644, + "pipes", {Qpipes}, 0, 0, +}; + + +static Chan* +selfattach(Chan *c, Chan *ac, char *spec, int flags) +{ + return devattach('0', spec); +} + +static Walkqid* +selfwalk(Chan *c, Chan *nc, char **name, int nname) +{ + return devwalk(c, nc, name, nname, selfdir, nelem(selfdir), devgen); +} + +static long +selfstat(Chan *c, uint8_t *dp, long n) +{ + return devstat(c, dp, n, selfdir, nelem(selfdir), devgen); +} + +static Chan* +selfopen(Chan *c, unsigned long omode) +{ + c->aux = nil; + c = devopen(c, omode, selfdir, nelem(selfdir), devgen); + return c; +} + +static long +selfread(Chan *c, void *va, long n, int64_t off) +{ + int64_t offset; + ProcSegment *sg; + int i, j; + char statbuf[NSEG*STATSIZE]; + + offset = off; + switch(QID(c->qid)){ + case Qsegments: + rlock(&up->seglock); + j = 0; + for(i = 0; i < NSEG; i++) { + sg = up->seg[i]; + if(sg == 0) + continue; + j += sprint(statbuf+j, "%-6s %c%c %p %p %4d\n", + segment_name(sg), + !(sg->type&SgWrite) ? 'R' : ' ', + (sg->type&SgExecute) ? 'x' : ' ', + ' ', // sg->profile ? 'P' : ' ', // here was profiling + sg->base, sg->top, sg->r.ref); + } + runlock(&up->seglock); + if(offset >= j) + return 0; + if(offset+n > j) + n = j-offset; + if(n == 0 && offset == 0) + exhausted("segments"); + memmove(va, &statbuf[offset], n); + return n; + default: + error(Egreg); + } +} + +static uintptr_t +segattach(Proc* p, int attr, const char* name, uintptr_t va, usize len) +{ + unsigned int sno, tmp; + ProcSegment *s; + uintptr_t pa, size; + + + if((va != 0 && va < UTZERO) || iskaddr(va)) + error("virtual address below text or in kernel"); + + vmemchr((void *)name, 0, ~0); + + for(sno = 0; sno < NSEG; sno++) + if(p->seg[sno] == nil && sno != ESEG) + break; + + if(sno == NSEG) + error("too many segments in process"); + + len = ROUNDUP(va+len, PGSZ) - ROUNDDN(va, PGSZ); + va = ROUNDDN(va, PGSZ); + + if(rawmem_find((char**)&name, &pa, &tmp, &size)){ + s = 0; + wlock(&p->seglock); + if(pa){ + if(!segment_physical(&s, attr&SegPermissionMask, attr&SegFlagMask, va, pa)) + goto SegAttachEbadarg; + } else if(size != -1){ + if(!segment_global(&s, attr&SegPermissionMask, va, (char*)name)) + goto SegAttachEbadarg; + } else { + if(!segment_virtual(&s, tmp&SegmentTypesMask, attr&SegPermissionMask&~SgExecute, attr&SegFlagMask, va, va+len)) + goto SegAttachEbadarg; + } + for(tmp = 0; tmp < NSEG; tmp++){ + if(p->seg[tmp]) + if((p->seg[tmp]->base > s->base && p->seg[tmp]->base < s->top) + || (p->seg[tmp]->top > s->base && p->seg[tmp]->top < s->top)){ + goto SegAttachEsoverlap; + } + } + up->seg[sno] = s; + wunlock(&p->seglock); + return s->base; + } + error("segment not found"); +SegAttachEbadarg: + wunlock(&p->seglock); + error(Ebadarg); +SegAttachEsoverlap: + wunlock(&p->seglock); + segment_release(&s); + error(Esoverlap); +} + +static uintptr_t +segdetach(Proc* p, uintptr_t va) +{ + if(!proc_segment_detach(p, va)) + error(Ebadarg); + + mmuflush(); + return 0; +} + +static uintptr_t +segfree(Proc* p, uintptr_t va, unsigned long len) +{ + ProcSegment *s; + uintptr_t from, to; + + from = PTR2UINT(va); + to = ROUNDDN(from + len, PGSZ); + + s = proc_segment(p, from); + if(s == nil || to < from || to > s->top) + error(Ebadarg); + + from = ROUNDUP(from, PGSZ); + if(from == to) + return 0; + + segment_free_pages(s, from, to); + mmuflush(); + return 0; +} + +static long +procsegctl(Proc *p, char *va, int n) +{ + Cmdbuf *cb; + Cmdtab *ct; + int attr; + const char *class; + uintptr_t vareq; + unsigned long len; + long result; + + cb = parsecmd(va, n); + if(waserror()){ + free(cb); + nexterror(); + } + + ct = lookupcmd(cb, proccmd, nelem(proccmd)); + switch(ct->index){ + default: + error(Ebadctl); + return -1; + case CMsegattach: + attr = strtoul(cb->f[1], 0, 0); + vareq = strtoull(cb->f[2], 0, 0); + len = strtoull(cb->f[3], 0, 0); + class = cb->f[4]; + result = segattach(p, attr, class, vareq, len); + break; + case CMsegdetach: + vareq = strtoull(cb->f[1], 0, 0); + result = segdetach(p, vareq); + break; + case CMsegfree: + vareq = strtoull(cb->f[1], 0, 0); + len = strtoull(cb->f[2], 0, 0); + result = segfree(p, vareq, len); + break; + } + poperror(); + return result; +} + +static long +selfwrite(Chan *c, void *va, long n, int64_t off) +{ + switch(QID(c->qid)){ + default: + error(Egreg); + case Qsegments: + n = procsegctl(up, va, n); + break; + } + return n; +} + +static int +newfd2(int fd[2], Chan *c[2]) +{ + extern int findfreefd(Fgrp *f, int start); + extern void unlockfgrp(Fgrp *f); + Fgrp *f; + + f = up->fgrp; + lock(&f->l); + fd[0] = findfreefd(f, 0); + if(fd[0] < 0){ + unlockfgrp(f); + return -1; + } + fd[1] = findfreefd(f, fd[0]+1); + if(fd[1] < 0){ + unlockfgrp(f); + return -1; + } + if(fd[1] > f->maxfd) + f->maxfd = fd[1]; + f->fd[fd[0]] = c[0]; + f->fd[fd[1]] = c[1]; + unlockfgrp(f); + + return 0; +} + +static long +newpipe(void) +{ + PipeSet pipe; + Chan *c[2]; + static char *datastr[] = {"data", "data1"}; + + c[0] = namec("#|", Atodir, 0, 0); + c[1] = nil; + pipe.fd[0] = -1; + pipe.fd[1] = -1; + + if(waserror()){ + cclose(c[0]); + if(c[1]) + cclose(c[1]); + nexterror(); + } + c[1] = cclone(c[0]); + if(walk(&c[0], datastr+0, 1, 1, nil) < 0) + error(Egreg); + if(walk(&c[1], datastr+1, 1, 1, nil) < 0) + error(Egreg); + c[0] = c[0]->dev->open(c[0], ORDWR); + c[1] = c[1]->dev->open(c[1], ORDWR); + if(newfd2(pipe.fd, c) < 0) + error(Enofd); + poperror(); + + return pipe.merged; +} + +static void +selfremove(Chan* c) +{ + long pipeset; + switch((uint32_t)c->qid.path){ + case Qsegments: + error(Eperm); + break; + case Qpid: + errorl("got pid", up->pid); + break; + case Qppid: + errorl("got parent pid", up->parentpid); + break; + case Qpipes: + pipeset = newpipe(); + errorl("got new pipes", pipeset); + break; + } +} + + +static void +selfclose(Chan *c) +{ +} + + +Dev selfdevtab = { + '0', + "self", + + devreset, + devinit, + devshutdown, + selfattach, + selfwalk, + selfstat, + selfopen, + devcreate, + selfclose, + selfread, + devbread, + selfwrite, + devbwrite, + selfremove, + devwstat, +}; diff --git a/sys/src/kern/port/include.json b/sys/src/kern/port/include.json index 5340a0b..b6b19bf 100644 --- a/sys/src/kern/port/include.json +++ b/sys/src/kern/port/include.json @@ -23,6 +23,7 @@ "../port/chan.c", "../port/debug.c", "../port/dev.c", + "../port/dev9p.c", "../port/devbridge.c", "../port/devcap.c", "../port/devcons.c", @@ -30,12 +31,12 @@ "../port/devenv.c", "../port/devfs.c", "../port/devkprof.c", - "../port/dev9p.c", "../port/devpci.c", "../port/devpipe.c", "../port/devproc.c", "../port/devroot.c", "../port/devsd.c", + "../port/devself.c", "../port/devshr.c", "../port/devsrv.c", "../port/devssl.c", diff --git a/sys/src/kern/port/sysfile.c b/sys/src/kern/port/sysfile.c index e5e45ee..cc22a91 100644 --- a/sys/src/kern/port/sysfile.c +++ b/sys/src/kern/port/sysfile.c @@ -26,7 +26,7 @@ * The sys*() routines needn't poperror() as they return directly to syscall(). */ -static void +void unlockfgrp(Fgrp *f) { int ex; @@ -74,7 +74,7 @@ growfd(Fgrp *f, int fd) /* fd is always >= 0 */ /* * this assumes that the fgrp is locked */ -static int +int findfreefd(Fgrp *f, int start) { int fd; @@ -107,32 +107,6 @@ newfd(Chan *c) return fd; } -static int -newfd2(int fd[2], Chan *c[2]) -{ - Fgrp *f; - - f = up->fgrp; - lock(&f->l); - fd[0] = findfreefd(f, 0); - if(fd[0] < 0){ - unlockfgrp(f); - return -1; - } - fd[1] = findfreefd(f, fd[0]+1); - if(fd[1] < 0){ - unlockfgrp(f); - return -1; - } - if(fd[1] > f->maxfd) - f->maxfd = fd[1]; - f->fd[fd[0]] = c[0]; - f->fd[fd[1]] = c[1]; - unlockfgrp(f); - - return 0; -} - Chan* fdtochan(int fd, unsigned long mode, int chkmnt, int iref) { @@ -205,44 +179,6 @@ sysfd2path(int fd, char* buf, int nbuf) return 0; } -int -syspipe(int* a) -{ - int fd[2]; - Chan *c[2]; - static char *datastr[] = {"data", "data1"}; - - a = validaddr(a, sizeof(fd), 1); - evenaddr(PTR2UINT(a)); - - c[0] = namec("#|", Atodir, 0, 0); - c[1] = nil; - fd[0] = -1; - fd[1] = -1; - - if(waserror()){ - cclose(c[0]); - if(c[1]) - cclose(c[1]); - nexterror(); - } - c[1] = cclone(c[0]); - if(walk(&c[0], datastr+0, 1, 1, nil) < 0) - error(Egreg); - if(walk(&c[1], datastr+1, 1, 1, nil) < 0) - error(Egreg); - c[0] = c[0]->dev->open(c[0], ORDWR); - c[1] = c[1]->dev->open(c[1], ORDWR); - if(newfd2(fd, c) < 0) - error(Enofd); - poperror(); - - a[0] = fd[0]; - a[1] = fd[1]; - - return 0; -} - int sysdup(int ofd, int nfd) { diff --git a/sys/src/lib/c/9sys/getpid.c b/sys/src/lib/c/9sys/getpid.c index ac04f65..4e113f6 100644 --- a/sys/src/lib/c/9sys/getpid.c +++ b/sys/src/lib/c/9sys/getpid.c @@ -22,20 +22,7 @@ int getpid(void) { - char buf[20]; int pid; - - pid = open("#c/pid", OREAD); - if(pid < 0){ - // probably rfork(RFNOMNT) - pid = open("/dev/pid", OREAD); - if(pid < 0){ - werrstr("getpid: cannot open neither #c/pid nor /dev/pid"); - return -1; // probably rfork(RFNOMNT|RFCNAMEG) - } - } - memset(buf, 0, sizeof(buf)); - assert(read(pid, buf, sizeof(buf)) > 0); - close(pid); - return atol(buf); + pid = (int)remove("#0/pid"); + return pid; } diff --git a/sys/src/lib/c/9sys/getppid.c b/sys/src/lib/c/9sys/getppid.c index 9bade04..d18c57e 100644 --- a/sys/src/lib/c/9sys/getppid.c +++ b/sys/src/lib/c/9sys/getppid.c @@ -22,20 +22,7 @@ int getppid(void) { - char buf[20]; - int ppid; - - ppid = open("#c/ppid", OREAD); - if(ppid < 0){ - // probably rfork(RFNOMNT) - ppid = open("/dev/ppid", OREAD); - if(ppid < 0){ - werrstr("getppid: cannot open neither #c/ppid nor /dev/ppid"); - return -1; // probably rfork(RFNOMNT|RFCNAMEG) - } - } - memset(buf, 0, sizeof(buf)); - assert(read(ppid, buf, sizeof(buf)) > 0); - close(ppid); - return atol(buf); + int pid; + pid = (int)remove("#0/ppid"); + return pid; } diff --git a/sys/src/lib/c/9sys/pipe.c b/sys/src/lib/c/9sys/pipe.c new file mode 100644 index 0000000..4e4d89e --- /dev/null +++ b/sys/src/lib/c/9sys/pipe.c @@ -0,0 +1,37 @@ +/* + * This file is part of Jehanne. + * + * Copyright (C) 2015-2017 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 + +typedef union PipeSet +{ + long merged; + int fd[2]; +} PipeSet; + +int +pipe(int pipes[2]) +{ + PipeSet pset; + pset.merged = remove("#0/pipes"); + if(pset.merged == -1) + return -1; + pipes[0] = pset.fd[0]; + pipes[1] = pset.fd[1]; + return 0; +} diff --git a/sys/src/lib/c/9sys/segattach.c b/sys/src/lib/c/9sys/segattach.c index e1f5d2e..af98ae1 100644 --- a/sys/src/lib/c/9sys/segattach.c +++ b/sys/src/lib/c/9sys/segattach.c @@ -18,21 +18,6 @@ #include #include -static int -opensegment(int pid) -{ - char file[128]; - int32_t f; - - sprint(file, "#p/%d/segment", pid); - f = open(file, OWRITE); - if(f < 0){ - sprint(file, "/proc/%d/segment", pid); - f = open(file, OWRITE); - } - return f; -} - void* segattach(int attr, const char *class, void *va, unsigned long len) { @@ -40,8 +25,7 @@ segattach(int attr, const char *class, void *va, unsigned long len) long tmp; char msg[256]; - tmp = getpid(); - fd = opensegment(tmp); + fd = open("#0/segments", OWRITE); if(fd < 0) return (void*)-1; @@ -57,8 +41,7 @@ segdetach(void *addr) int fd, tmp; char msg[256]; - tmp = getpid(); - fd = opensegment(tmp); + fd = open("#0/segments", OWRITE); if(fd < 0) return -1; @@ -74,8 +57,7 @@ segfree(void *addr, unsigned long len) int fd, tmp; char msg[256]; - tmp = getpid(); - fd = opensegment(tmp); + fd = open("#0/segments", OWRITE); if(fd < 0) return -1; diff --git a/sys/src/lib/c/build.json b/sys/src/lib/c/build.json index f68c27a..097b7a5 100644 --- a/sys/src/lib/c/build.json +++ b/sys/src/lib/c/build.json @@ -58,6 +58,7 @@ "9sys/getwd.c", "9sys/iounit.c", "9sys/nulldir.c", + "9sys/pipe.c", "9sys/postnote.c", "9sys/privalloc.c", "9sys/pushssl.c", diff --git a/sys/src/sysconf.json b/sys/src/sysconf.json index 28fa4f7..853cc64 100644 --- a/sys/src/sysconf.json +++ b/sys/src/sysconf.json @@ -251,16 +251,6 @@ "long" ] }, - { - "Args": [ - "int*" - ], - "Id": 21, - "Name": "pipe", - "Ret": [ - "int" - ] - }, { "Args": [ "int", @@ -268,7 +258,7 @@ "int", "long" ], - "Id": 22, + "Id": 21, "Name": "pread", "Ret": [ "long" @@ -281,7 +271,7 @@ "int", "long" ], - "Id": 23, + "Id": 22, "Name": "pwrite", "Ret": [ "long" @@ -291,7 +281,7 @@ "Args": [ "const char*" ], - "Id": 24, + "Id": 23, "Name": "remove", "Ret": [ "long" @@ -302,7 +292,7 @@ "const void*", "void*" ], - "Id": 25, + "Id": 24, "Name": "rendezvous", "Ret": [ "void*" @@ -312,7 +302,7 @@ "Args": [ "uint32_t" ], - "Id": 26, + "Id": 25, "Name": "rfork", "Ret": [ "int" @@ -324,7 +314,7 @@ "long", "int" ], - "Id": 27, + "Id": 26, "Name": "seek", "Ret": [ "long" @@ -335,7 +325,7 @@ "int*", "int" ], - "Id": 28, + "Id": 27, "Name": "semacquire", "Ret": [ "int" @@ -346,7 +336,7 @@ "int*", "int" ], - "Id": 29, + "Id": 28, "Name": "semrelease", "Ret": [ "int" @@ -357,7 +347,7 @@ "int*", "uint64_t" ], - "Id": 30, + "Id": 29, "Name": "tsemacquire", "Ret": [ "int" @@ -368,7 +358,7 @@ "const char*", "const char*" ], - "Id": 31, + "Id": 30, "Name": "unmount", "Ret": [ "int" @@ -378,7 +368,7 @@ "Args": [ "unsigned long" ], - "Id": 32, + "Id": 31, "Name": "alarm", "Ret": [ "long"