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
This commit is contained in:
Giacomo Tesio 2016-12-11 01:19:51 +01:00
parent f52a185030
commit c6de6b66e9
18 changed files with 480 additions and 315 deletions

View File

@ -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");
}

View File

@ -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);

View File

@ -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*);

View File

@ -36,6 +36,7 @@
"root",
"rtc",
"sd",
"self",
"shr",
"srv",
"ssl",

View File

@ -32,6 +32,7 @@
"proc",
"root",
"sd",
"self",
"shr",
"srv",
"uart"

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -1,3 +1,20 @@
/*
* This file is part of Jehanne.
*
* Copyright (C) 2015-2016 Giacomo Tesio <giacomo@tesio.it>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#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;

387
sys/src/kern/port/devself.c Normal file
View File

@ -0,0 +1,387 @@
/*
* This file is part of Jehanne.
*
* Copyright (C) 2016 Giacomo Tesio <giacomo@tesio.it>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#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,
};

View File

@ -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",

View File

@ -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)
{

View File

@ -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;
}

View File

@ -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;
}

37
sys/src/lib/c/9sys/pipe.c Normal file
View File

@ -0,0 +1,37 @@
/*
* This file is part of Jehanne.
*
* Copyright (C) 2015-2017 Giacomo Tesio <giacomo@tesio.it>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <u.h>
#include <libc.h>
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;
}

View File

@ -18,21 +18,6 @@
#include <u.h>
#include <libc.h>
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;

View File

@ -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",

View File

@ -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"