kernel: add devskel for pc and pc64
This commit is contained in:
parent
df92301d8f
commit
f4840cdba5
4 changed files with 274 additions and 0 deletions
35
sys/man/3/skel
Normal file
35
sys/man/3/skel
Normal file
|
@ -0,0 +1,35 @@
|
|||
.TH SKEL 3
|
||||
.SH NAME
|
||||
skel \- skeleton builder
|
||||
.SH SYNOPSIS
|
||||
.B bind #z/\fIskel\fR
|
||||
.I dir
|
||||
.PP
|
||||
.B bind #zd/\fIskel\fR
|
||||
.I dir
|
||||
.PP
|
||||
.B bind #ze/
|
||||
.I dir
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
This device serves a single child directory with a single empty child
|
||||
file. The name of these files is determined by the first walk away
|
||||
from the root. After which, the hierarchy for that attached session
|
||||
becomes stable. The
|
||||
.B d
|
||||
attach option causes the child file to be an empty directory. The
|
||||
.B e
|
||||
attach option presents a completly empty root directory.
|
||||
.SH EXAMPLES
|
||||
Skeleton files can be used for constructing arbitrary bind targets.
|
||||
.EX
|
||||
.IP
|
||||
bind -b '#zd/newroot' /
|
||||
bind '#zd/bin' /newroot
|
||||
bind '#z/walk' /newroot/bin
|
||||
bind /bin/walk /newroot/bin/walk
|
||||
bind /newroot /
|
||||
walk /
|
||||
.EE
|
||||
.SH SOURCE
|
||||
.B /sys/src/9/port/devskel.c
|
|
@ -18,6 +18,7 @@ dev
|
|||
kprof
|
||||
fs
|
||||
dtracy
|
||||
skel
|
||||
|
||||
ether netif
|
||||
bridge netif log
|
||||
|
|
|
@ -41,6 +41,7 @@ dev
|
|||
segment
|
||||
vmx
|
||||
dtracy
|
||||
skel
|
||||
|
||||
link
|
||||
# devpccard pci
|
||||
|
|
237
sys/src/9/port/devskel.c
Normal file
237
sys/src/9/port/devskel.c
Normal file
|
@ -0,0 +1,237 @@
|
|||
#include "u.h"
|
||||
#include "../port/lib.h"
|
||||
#include "mem.h"
|
||||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
#include "netif.h"
|
||||
|
||||
typedef struct Skel Skel;
|
||||
struct Skel {
|
||||
int ref;
|
||||
QLock lk;
|
||||
char name[KNAMELEN];
|
||||
char mode;
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
QLock lk;
|
||||
ulong path;
|
||||
} skelalloc;
|
||||
|
||||
enum{
|
||||
Qroot,
|
||||
Qdir,
|
||||
Qskel,
|
||||
};
|
||||
|
||||
static Chan*
|
||||
skelattach(char *spec)
|
||||
{
|
||||
Chan *c;
|
||||
Skel *f;
|
||||
uvlong path;
|
||||
|
||||
c = devattach('z', spec);
|
||||
|
||||
f = smalloc(sizeof *f);
|
||||
if(spec != nil && spec[0] != '\0' && strchr("de", spec[0]) != nil)
|
||||
f->mode = spec[0];
|
||||
else
|
||||
f->mode = 'f';
|
||||
|
||||
f->ref = 1;
|
||||
|
||||
qlock(&skelalloc.lk);
|
||||
path = skelalloc.path++;
|
||||
qunlock(&skelalloc.lk);
|
||||
|
||||
mkqid(&c->qid, NETQID(path, Qroot), 0, QTDIR);
|
||||
c->aux = f;
|
||||
return c;
|
||||
}
|
||||
|
||||
static int
|
||||
step(Chan *c, Dir *dp, int direction)
|
||||
{
|
||||
Skel *f;
|
||||
Qid qid;
|
||||
ulong perm;
|
||||
uvlong path;
|
||||
char *name;
|
||||
|
||||
perm = 0555|DMDIR;
|
||||
path = NETTYPE(c->qid.path);
|
||||
f = c->aux;
|
||||
name = f->name;
|
||||
|
||||
path += direction;
|
||||
if(!f->name[0] && path != Qroot)
|
||||
return -1;
|
||||
|
||||
switch(path){
|
||||
case Qroot:
|
||||
mkqid(&qid, Qroot, 0, QTDIR);
|
||||
name = "#z";
|
||||
break;
|
||||
case Qdir:
|
||||
mkqid(&qid, Qdir, 0, QTDIR);
|
||||
break;
|
||||
case Qskel:
|
||||
switch(f->mode){
|
||||
case 'd':
|
||||
mkqid(&qid, Qskel, 0, QTDIR);
|
||||
break;
|
||||
case 'f':
|
||||
default:
|
||||
mkqid(&qid, Qskel, 0, QTFILE);
|
||||
perm = 0666;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
qid.path = NETQID(NETID(c->qid.path), qid.path);
|
||||
devdir(c, qid, name, 0, eve, perm, dp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
skelgen(Chan *c, char *name, Dirtab *, int, int s, Dir *dp)
|
||||
{
|
||||
Skel *f;
|
||||
|
||||
f = c->aux;
|
||||
//First walk away from root
|
||||
if(name && !f->name[0] && f->mode != 'e' && NETTYPE(c->qid.path) == Qroot)
|
||||
utfecpy(f->name, &f->name[sizeof f->name-1], name);
|
||||
|
||||
if(s != DEVDOTDOT)
|
||||
s++;
|
||||
|
||||
return step(c, dp, s);
|
||||
}
|
||||
|
||||
static Walkqid*
|
||||
skelwalk(Chan *c, Chan *nc, char **name, int nname)
|
||||
{
|
||||
Walkqid *wq;
|
||||
Skel *f;
|
||||
|
||||
f = c->aux;
|
||||
qlock(&f->lk);
|
||||
if(waserror()){
|
||||
qunlock(&f->lk);
|
||||
nexterror();
|
||||
}
|
||||
|
||||
wq = devwalk(c, nc, name, nname, nil, 0, skelgen);
|
||||
if(wq != nil && wq->clone != nil && wq->clone != c){
|
||||
if(f->ref <= 0)
|
||||
panic("devskel ref");
|
||||
f->ref++;
|
||||
}
|
||||
qunlock(&f->lk);
|
||||
poperror();
|
||||
return wq;
|
||||
}
|
||||
|
||||
static Chan*
|
||||
skelopen(Chan *c, int omode)
|
||||
{
|
||||
if(!(c->qid.type & QTDIR))
|
||||
error(Eperm);
|
||||
if(omode != OREAD)
|
||||
error(Ebadarg);
|
||||
|
||||
c->mode = omode;
|
||||
c->flag |= COPEN;
|
||||
c->offset = 0;
|
||||
return c;
|
||||
}
|
||||
|
||||
static void
|
||||
skelclose(Chan *c)
|
||||
{
|
||||
Skel *f;
|
||||
|
||||
f = c->aux;
|
||||
qlock(&f->lk);
|
||||
f->ref--;
|
||||
if(f->ref == 0){
|
||||
qunlock(&f->lk);
|
||||
free(f);
|
||||
} else
|
||||
qunlock(&f->lk);
|
||||
}
|
||||
|
||||
static long
|
||||
skelread(Chan *c, void *va, long n, vlong)
|
||||
{
|
||||
Skel *f;
|
||||
long nout;
|
||||
|
||||
if(!(c->qid.type & QTDIR))
|
||||
error(Eperm);
|
||||
|
||||
f = c->aux;
|
||||
qlock(&f->lk);
|
||||
if(waserror()){
|
||||
qunlock(&f->lk);
|
||||
nexterror();
|
||||
}
|
||||
nout = devdirread(c, va, n, nil, 0, skelgen);
|
||||
qunlock(&f->lk);
|
||||
poperror();
|
||||
return nout;
|
||||
}
|
||||
|
||||
static long
|
||||
skelwrite(Chan *, void *, long, vlong)
|
||||
{
|
||||
error(Eperm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
skelstat(Chan *c, uchar *db, int n)
|
||||
{
|
||||
Skel *f;
|
||||
Dir dir;
|
||||
|
||||
f = c->aux;
|
||||
qlock(&f->lk);
|
||||
step(c, &dir, 0);
|
||||
qunlock(&f->lk);
|
||||
|
||||
n = convD2M(&dir, db, n);
|
||||
if(n < BIT16SZ)
|
||||
error(Eshortstat);
|
||||
return n;
|
||||
}
|
||||
|
||||
Dev skeldevtab = {
|
||||
'z',
|
||||
"skel",
|
||||
|
||||
devreset,
|
||||
devinit,
|
||||
devshutdown,
|
||||
skelattach,
|
||||
skelwalk,
|
||||
skelstat,
|
||||
skelopen,
|
||||
devcreate,
|
||||
skelclose,
|
||||
skelread,
|
||||
devbread,
|
||||
skelwrite,
|
||||
devbwrite,
|
||||
devremove,
|
||||
devwstat,
|
||||
};
|
Loading…
Reference in a new issue