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:
parent
f52a185030
commit
c6de6b66e9
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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*);
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
"root",
|
||||
"rtc",
|
||||
"sd",
|
||||
"self",
|
||||
"shr",
|
||||
"srv",
|
||||
"ssl",
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
"proc",
|
||||
"root",
|
||||
"sd",
|
||||
"self",
|
||||
"shr",
|
||||
"srv",
|
||||
"uart"
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
};
|
|
@ -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",
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue