/*
* 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 <mdproc.h>
#include <mddir.h>
#include <mdfloat.h>
#include <fcall.h>
#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<<NSLOG)
};
struct Mntwalk /* state for /proc/#/ns */
{
int cddone;
ulong id;
Mhead* mh;
Mount* cm;
};
struct Mount
{
ulong mountid;
Mount* next;
Mhead* head;
Mount* copy;
Mount* order;
Chan* to; /* channel replacing channel */
int mflag;
char *spec;
};
struct Mhead
{
Ref r;
RWLock lock;
Chan* from; /* channel mounted upon */
Mount* mount; /* what's mounted upon it */
Mhead* hash; /* Hash chain */
};
struct Mnt
{
Lock l;
/* references are counted using c->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<<MNTLOG, /* Hash to walk mount table */
INITNFD = 100, /* init per process file descriptors */
MAXNFD = 4096, /* max per process file descriptors */
};
#define MOUNTH(p,qid) ((p)->mnthash[(qid).path&((1<<MNTLOG)-1)])
struct Nsconf
{
int flags;
int stacksize; /* per thread */
char *rootdir;
char *name;
char *Name;
char *consname;
char *eve;
void (*addproc)(Proc*);
void (*fault)(char*);
};
enum
{
NsGraphics = (1<<0),
NsCmap7 = (1<<1),
NsNoperm = (1<<2) /* don't check permissions in devfs */
};
struct Pgrp
{
Ref r; /* also used as a lock when mounting */
int noattach;
ulong pgrpid;
RWLock ns; /* Namespace n read/one write lock */
QLock nsh;
Mhead* mnthash[MNTHASH];
int progmode;
Chan* dot;
Chan* slash;
};
struct Fgrp
{
Ref r;
Chan** fd;
int nfd; /* number of fd slots */
int maxfd; /* highest fd in use */
int minfd; /* lower bound on free fd */
};
struct Pointer
{
int x;
int y;
int b;
int modify;
Rendez r;
};
struct Osenv
{
char error[ERRMAX]; /* Last system error */
Pgrp* pgrp; /* Ref to namespace, working dir and root */
Fgrp* fgrp; /* Ref to file descriptors */
Rendez* rend; /* Synchro point */
Queue* waitq; /* Info about dead children */
Queue* childq; /* Info about children for debuggers */
void* debug; /* Debugging master */
char *user; /* Inferno user name */
FPU fpu; /* Floating point thread state */
int uid; /* Numeric user id for host system */
int gid; /* Numeric group id for host system */
void *ui; /* User info for NT */
};
enum
{
Unknown = 0xdeadbabe,
IdleGC = 0x16,
Interp = 0x17
};
struct Proc
{
int type; /* interpreter or not */
char *text;
Proc* qnext; /* list of processes waiting on a Qlock */
int pid;
Proc* next; /* list of created processes */
Proc* prev;
Rendez* r; /* rendezvous we are Sleeping on */
Rendez sleep; /* place to sleep */
int swipend; /* software interrupt pending for Prog */
int syscall; /* set true under sysio for interruptable syscalls */
int killed; /* software interrupt of Proc */
int intwait; /* spin wait for note to turn up */
Tid sigid; /* handle used for signal/note/exception */
Lock sysio; /* note handler lock */
int nerr; /* error stack SP */
char* kstack;
jmp_buf estack[32]; /* vector of error jump labels */
void (*func)(void*); /* saved trampoline pointer for kproc */
void* arg; /* arg for invoked kproc function */
void* iprog; /* work for Prog after release */
void* prog; /* fake prog for slaves eg. exportfs */
Osenv* env; /* effective operating system environment */
Osenv defenv; /* default env for slaves with no prog */
char genbuf[128]; /* buffer used e.g. for last name element from namec */
jmp_buf privstack; /* private stack for making new kids */
jmp_buf sharestack;
Proc *kid;
void *kidsp;
};
#define poperror() up->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
syntax highlighted by Code2HTML, v. 0.9.1