/* * Namespace emulation for Unix and Windows * * This header is included by device drivers and libns itself. * Programs wishing to use the emulation should be compiled * with -DUSENS. */ typedef struct Block Block; typedef struct Chan Chan; typedef struct Cname Cname; typedef struct Dev Dev; typedef struct DevConf DevConf; typedef struct Dirtab Dirtab; typedef struct Fgrp Fgrp; typedef struct Mntcache Mntcache; typedef struct Mount Mount; typedef struct Mntrpc Mntrpc; typedef struct Mntwalk Mntwalk; typedef struct Mnt Mnt; typedef struct Mhead Mhead; typedef struct Nsconf Nsconf; typedef struct Osenv Osenv; typedef struct Pgrp Pgrp; typedef struct Pointer Pointer; typedef struct Proc Proc; typedef struct Procs Procs; typedef struct Rb Rb; typedef struct Queue Queue; typedef struct Ref Ref; typedef struct Rendez Rendez; typedef struct Session Session; typedef struct Walkqid Walkqid; typedef int Devgen(Chan*, char*, Dirtab*, int, int, Dir*); #include #include #include #include #define sleep rendsleep #define wakeup rendwakeup /* * Manifest constants */ enum { MAXROOT = 128, /* Maximum root pathname len of devfs-* */ NUMSIZE = 11, MAXDEVCMD = 128, /* Maximum size for command */ KNAMELEN = 28, }; /* * Access types in namec & channel flags */ enum { Aaccess, /* as in access, stat */ Atodir, /* as in chdir */ Aopen, /* for i/o */ Amount, /* to be mounted upon */ Acreate, /* file is to be created */ Aremove, /* will be removed by caller */ Abind, /* will be bound somewhere by caller */ COPEN = 0x0001, /* for i/o */ CMSG = 0x0002, /* the message channel for a mount */ CCEXEC = 0x0008, /* close on exec */ CFREE = 0x0010, /* not in use */ CRCLOSE = 0x0020, /* remove on close */ CCACHE = 0x0080 /* client cache */ }; /* * Process creation */ enum { NSPDUP = 1 << 0, }; struct Ref { Lock l; long ref; }; struct Rendez { Lock l; Proc* p; }; struct Cname { Ref r; int alen; /* allocated length */ int len; /* strlen(s) */ char *s; }; struct Chan { Ref r; Chan* next; /* allocation */ Chan* link; vlong offset; /* in file */ ushort type; ulong dev; ushort mode; /* read/write */ ushort flag; Qid qid; int fid; /* for devmnt */ ulong iounit; /* chunk size for i/o; 0==default */ Mhead* umh; /* mount point that derived Chan */ Chan* umc; /* channel in union; held for union read */ QLock umqlock; /* serialize unionreads */ int uri; /* union read index */ int dri; /* dirread index */ ulong mountid; Mntcache *mcp; /* Mount cache pointer */ Mnt *mux; /* Mnt for clients using me for messages */ union { void* aux; Mnt* mntptr; /* for devmnt */ } u; Chan* mchan; /* channel to mounted server */ Qid mqid; /* qid of root of mount point */ Session *session; Cname *name; }; struct Dev { int dc; char* name; void (*reset)(void); void (*init)(void); Chan* (*attach)(char*); Walkqid* (*walk)(Chan*, Chan*, char**, int); int (*stat)(Chan*, uchar*, int); Chan* (*open)(Chan*, int); void (*create)(Chan*, char*, int, ulong); void (*close)(Chan*); long (*read)(Chan*, void*, long, vlong); Block* (*bread)(Chan*, long, ulong); long (*write)(Chan*, void*, long, vlong); long (*bwrite)(Chan*, Block*, ulong); void (*remove)(Chan*); int (*wstat)(Chan*, uchar*, int); void (*power)(int); /* power mgt: power(1) => on, power (0) => off */ int (*config)(int, char*, DevConf*); }; enum { BINTR = (1<<0), BFREE = (1<<1), BMORE = (1<<2) /* continued in next block */ }; struct Block { Block* next; Block* list; uchar* rp; /* first unconsumed byte */ uchar* wp; /* first empty byte */ uchar* lim; /* 1 past the end of the buffer */ uchar* base; /* start of the buffer */ void (*free)(Block*); }; #define BLEN(s) ((s)->wp - (s)->rp) #define BALLOC(s) ((s)->lim - (s)->base) struct Dirtab { char name[KNAMELEN]; Qid qid; vlong length; long perm; }; struct Walkqid { Chan *clone; int nqid; Qid qid[1]; }; enum { NSMAX = 1000, NSLOG = 7, NSCACHE = (1<ref; channels on this mount point incref(c->mchan) == Mnt.c */ Chan* c; /* Channel to file service */ Proc *rip; /* Reader in progress */ Mntrpc* queue; /* Queue of pending requests on this channel */ ulong id; /* Multiplexor id for channel check */ Mnt* list; /* Free list */ int flags; /* cache */ int msize; /* data + IOHDRSZ */ char *version; /* 9P version */ Queue *q; /* input queue */ }; enum { MNTLOG = 5, MNTHASH = 1<mnthash[(qid).path&((1<nerr-- #define waserror() (up->nerr++, setjmp(up->estack[up->nerr-1])) struct Procs { Lock l; Proc* head; Proc* tail; }; struct Rb { QLock l; Rendez producer; Rendez consumer; Rendez clock; ulong randomcount; uchar buf[4096]; uchar *ep; uchar *rp; uchar *wp; uchar next; uchar bits; uchar wakeme; uchar filled; int target; int kprocstarted; }; extern Dev* devtab[]; extern char *ossysname; extern char *eve; extern int cpuserver; extern Nsconf nsconf; extern Block* allocb(int); extern Block* bl2mem(uchar*, Block*, int); extern int blocklen(Block*); extern void cclose(Chan*); extern void chandevinit(void); extern void chandevreset(void); extern void chanfree(Chan*); extern void clearintr(void); extern Chan* cclone(Chan*); extern void closepgrp(Pgrp*); extern void closefgrp(Fgrp*); extern int cmount(Chan* volatile*, Chan*, int, char*); extern void cunmount(Chan*, Chan*); extern int decref(Ref*); extern int decrypt(void*, void*, int); extern void drawflush(void); extern Fgrp* dupfgrp(Fgrp*); extern int encrypt(void*, void*, int); extern int eqqid(Qid, Qid); extern int export(int, int); extern Chan* fdtochan(Fgrp*, int, int, int, int); extern void freeb(Block*); extern void freeblist(Block*); extern long hostownerwrite(char*, int); extern int incref(Ref*); extern int iprint(char*, ...); extern void isdir(Chan*); extern int iseve(void); extern long keyread(char*, int, long); extern long keywrite(char*, int); extern void kbdinit(void); extern void kbdputc(int); extern Block* mem2bl(uchar*, int); extern void mkqid(Qid*, vlong, ulong, int); extern int nsaddproc(char*, void (*)(void*), void*, int); extern long latin1(Rune*, int); extern void mountfree(Mount*); extern Chan* namec(char*, int, int, ulong); extern void nameok(char*); extern Chan* newchan(void); extern Fgrp* newfgrp(Fgrp*); extern Mount* newmount(Mhead*, Chan*, int, char*); extern Pgrp* newpgrp(void); extern char* nextelem(char*, char*); extern void nexterror(void); Cname* newcname(char*); extern int nrand(int n); extern void nsinit(void); extern int openmode(ulong); extern void osenter(void); extern void oserror(void); extern void osleave(void); extern void osfillproc(Proc*); extern Block* padblock(Block*, int); extern void panic(char*, ...); extern void pexit(char*, int); extern void procserve(void); extern int pullblock(Block**, int); extern Block* pullupblock(Block*, int); extern Block* pullupqueue(Queue*, int); extern void putmhead(Mhead*); extern void qadd(Queue*, Block*); extern void qaddlist(Queue*, Block*); extern Block* qbread(Queue*, int); extern long qbwrite(Queue*, Block*); extern int qcanread(Queue*); extern void qclose(Queue*); extern int qconsume(Queue*, void*, int); extern int qdiscard(Queue*, int); extern void qflush(Queue*); extern void qfree(Queue*); extern void qhangup(Queue*, char*); extern void qinit(void); extern int qlen(Queue*); extern Queue* qopen(int, int, void (*)(void*), void*); extern int qpass(Queue*, Block*); extern int qproduce(Queue*, void*, int); extern void qputback(Queue*, Block*); extern long qread(Queue*, void*, int); extern Block* qremove(Queue*); extern void qreopen(Queue*); extern int qwindow(Queue*); extern int qiwrite(Queue*, void*, int); extern int qwrite(Queue*, void*, int); extern void qsetlimit(Queue*, int); extern void qnoblock(Queue*, int); extern int readkbd(void); extern int readstr(ulong, char*, ulong, char*); extern int running(void); extern void (*screenputs)(char*, int); extern char* skipslash(char*); extern void* smalloc(ulong); extern int ticks(void); extern long unionread(Chan*, void*, long); extern void validname(char*, int); /* generic device functions */ extern void devinit(void); extern void devreset(void); extern Chan* devattach(int, char*); extern Chan* devattach(int, char*); extern Block* devbread(Chan*, long, ulong); extern long devbwrite(Chan*, Block*, ulong); extern void devcreate(Chan*, char*, int, ulong); extern void devdir(Chan*, Qid, char*, vlong, char*, long, Dir*); extern long devdirread(Chan*, char*, long, Dirtab*, int, Devgen*); extern Chan* devclone(Chan*); Devgen devgen; extern int devno(int, int); extern Chan* devopen(Chan*, int, Dirtab*, int, Devgen*); extern void devpermcheck(char*, ulong, int); extern int devstat(Chan*, uchar*, int, Dirtab*, int, Devgen*); extern Walkqid* devwalk(Chan*, Chan*, char**, int, Dirtab*, int, Devgen*); extern void devremove(Chan*); extern int devwstat(Chan*, uchar*, int); #define DEVDOTDOT -1