1 typedef struct Block Block; 2 typedef struct Chan Chan; 3 typedef struct Cmdbuf Cmdbuf; 4 typedef struct Cmdtab Cmdtab; 5 typedef struct Cname Cname; 6 typedef struct Dev Dev; 7 typedef struct Dirtab Dirtab; 8 typedef struct Egrp Egrp; 9 typedef struct Evalue Evalue; 10 typedef struct Fgrp Fgrp; 11 typedef struct Mount Mount; 12 typedef struct Mntcache Mntcache; 13 typedef struct Mntparam Mntparam; 14 typedef struct Mntrpc Mntrpc; 15 typedef struct Mntwalk Mntwalk; 16 typedef struct Mnt Mnt; 17 typedef struct Mhead Mhead; 18 typedef struct Osenv Osenv; 19 typedef struct Pgrp Pgrp; 20 typedef struct Proc Proc; 21 typedef struct Queue Queue; 22 typedef struct Ref Ref; 23 typedef struct Rendez Rendez; 24 typedef struct Rept Rept; 25 typedef struct Rootdata Rootdata; 26 /*typedef struct RWlock RWlock;*/ 27 typedef struct RWLock RWlock; 28 typedef struct Procs Procs; 29 typedef struct Signerkey Signerkey; 30 typedef struct Skeyset Skeyset; 31 typedef struct Uqid Uqid; 32 typedef struct Uqidtab Uqidtab; 33 typedef struct Walkqid Walkqid; 34 35 #include "lib9.h" 36 #undef CHDIR 37 #undef NAMELEN 38 #undef ERRLEN 39 40 #include "emu.h" 41 42 #pragma incomplete Queue 43 #pragma incomplete Mntrpc 44 45 #include "fcall.h" 46 47 #include "pool.h" 48 49 typedef int Devgen(Chan*, char*, Dirtab*, int, int, Dir*); 50 51 enum 52 { 53 NERR = 32, 54 KNAMELEN = 28, 55 MAXROOT = 5*KNAMELEN, /* Maximum root pathname len of devfs-* */ 56 NUMSIZE = 11, 57 PRINTSIZE = 256, 58 READSTR = 1000 /* temporary buffer size for device reads */ 59 }; 60 61 struct Ref 62 { 63 Lock lk; 64 long ref; 65 }; 66 67 struct Rendez 68 { 69 Lock l; 70 Proc* p; 71 }; 72 73 struct Rept 74 { 75 Lock l; 76 Rendez r; 77 void *o; 78 int t; 79 int (*active)(void*); 80 int (*ck)(void*, int); 81 void (*f)(void*); /* called with VM acquire()'d */ 82 }; 83 84 /* 85 * Access types in namec & channel flags 86 */ 87 enum 88 { 89 Aaccess, /* as in access, stat */ 90 Abind, /* for left-hand-side of bind */ 91 Atodir, /* as in chdir */ 92 Aopen, /* for i/o */ 93 Amount, /* to be mounted upon */ 94 Acreate, /* file is to be created */ 95 Aremove, /* will be removed by caller */ 96 97 COPEN = 0x0001, /* for i/o */ 98 CMSG = 0x0002, /* the message channel for a mount */ 99 /*rsc CCREATE = 0x0004, /* permits creation if c->mnt */ 100 CCEXEC = 0x0008, /* close on exec */ 101 CFREE = 0x0010, /* not in use */ 102 CRCLOSE = 0x0020, /* remove on close */ 103 CCACHE = 0x0080 /* client cache */ 104 }; 105 106 struct Chan 107 { 108 Lock l; 109 Ref r; 110 Chan* next; /* allocation */ 111 Chan* link; 112 vlong offset; /* in file */ 113 ushort type; 114 ulong dev; 115 ushort mode; /* read/write */ 116 ushort flag; 117 Qid qid; 118 int fid; /* for devmnt */ 119 ulong iounit; /* chunk size for i/o; 0==default */ 120 Mhead* umh; /* mount point that derived Chan; used in unionread */ 121 Chan* umc; /* channel in union; held for union read */ 122 QLock umqlock; /* serialize unionreads */ 123 int uri; /* union read index */ 124 int dri; /* devdirread index */ 125 ulong mountid; 126 Mntcache *mcp; /* Mount cache pointer */ 127 Mnt *mux; /* Mnt for clients using me for messages */ 128 void* aux; /* device specific data */ 129 Chan* mchan; /* channel to mounted server */ 130 Qid mqid; /* qid of root of mount point */ 131 Cname *name; 132 }; 133 134 struct Cname 135 { 136 Ref r; 137 int alen; /* allocated length */ 138 int len; /* strlen(s) */ 139 char *s; 140 }; 141 142 struct Dev 143 { 144 int dc; 145 char* name; 146 147 void (*init)(void); 148 Chan* (*attach)(char*); 149 Walkqid* (*walk)(Chan*, Chan*, char**, int); 150 int (*stat)(Chan*, uchar*, int); 151 Chan* (*open)(Chan*, int); 152 void (*create)(Chan*, char*, int, ulong); 153 void (*close)(Chan*); 154 long (*read)(Chan*, void*, long, vlong); 155 Block* (*bread)(Chan*, long, ulong); 156 long (*write)(Chan*, void*, long, vlong); 157 long (*bwrite)(Chan*, Block*, ulong); 158 void (*remove)(Chan*); 159 int (*wstat)(Chan*, uchar*, int); 160 }; 161 162 enum 163 { 164 BINTR = (1<<0), 165 BFREE = (1<<1), 166 BMORE = (1<<2) /* continued in next block */ 167 }; 168 169 struct Block 170 { 171 Block* next; 172 Block* list; 173 uchar* rp; /* first unconsumed byte */ 174 uchar* wp; /* first empty byte */ 175 uchar* lim; /* 1 past the end of the buffer */ 176 uchar* base; /* start of the buffer */ 177 void (*free)(Block*); 178 ulong flag; 179 }; 180 #define BLEN(s) ((s)->wp - (s)->rp) 181 #define BALLOC(s) ((s)->lim - (s)->base) 182 183 struct Dirtab 184 { 185 char name[KNAMELEN]; 186 Qid qid; 187 vlong length; 188 long perm; 189 }; 190 191 struct Walkqid 192 { 193 Chan *clone; 194 int nqid; 195 Qid qid[1]; 196 }; 197 198 enum 199 { 200 NSMAX = 1000, 201 NSLOG = 7, 202 NSCACHE = (1<<NSLOG) 203 }; 204 205 struct Mntwalk /* state for /proc/#/ns */ 206 { 207 int cddone; 208 ulong id; 209 Mhead* mh; 210 Mount* cm; 211 }; 212 213 struct Mount 214 { 215 ulong mountid; 216 Mount* next; 217 Mhead* head; 218 Mount* copy; 219 Mount* order; 220 Chan* to; /* channel replacing channel */ 221 int mflag; 222 char *spec; 223 }; 224 225 struct Mhead 226 { 227 Ref r; 228 RWlock lock; 229 Chan* from; /* channel mounted upon */ 230 Mount* mount; /* what's mounted upon it */ 231 Mhead* hash; /* Hash chain */ 232 }; 233 234 struct Mnt 235 { 236 Lock l; 237 /* references are counted using c->ref; channels on this mount point incref(c->mchan) == Mnt.c */ 238 Chan* c; /* Channel to file service */ 239 Proc* rip; /* Reader in progress */ 240 Mntrpc* queue; /* Queue of pending requests on this channel */ 241 ulong id; /* Multiplexor id for channel check */ 242 Mnt* list; /* Free list */ 243 int flags; /* cache */ 244 int msize; /* data + IOHDRSZ */ 245 char *version; /* 9P version */ 246 Queue *q; /* input queue */ 247 }; 248 249 enum 250 { 251 MNTLOG = 5, 252 MNTHASH = 1<<MNTLOG, /* Hash to walk mount table */ 253 DELTAFD= 20, /* allocation quantum for process file descriptors */ 254 MAXNFD = 4000, /* max per process file descriptors */ 255 MAXKEY = 8 /* keys for signed modules */ 256 }; 257 #define MOUNTH(p,qid) ((p)->mnthash[(qid).path&((1<<MNTLOG)-1)]) 258 259 struct Mntparam { 260 Chan* chan; 261 Chan* authchan; 262 char* spec; 263 int flags; 264 }; 265 266 struct Pgrp 267 { 268 Ref r; /* also used as a lock when mounting */ 269 ulong pgrpid; 270 RWlock ns; /* Namespace n read/one write lock */ 271 QLock nsh; 272 Mhead* mnthash[MNTHASH]; 273 int progmode; 274 Chan* dot; 275 Chan* slash; 276 int nodevs; 277 int pin; 278 }; 279 280 enum 281 { 282 Nopin = -1 283 }; 284 285 struct Fgrp 286 { 287 Lock l; 288 Ref r; 289 Chan** fd; 290 int nfd; /* number of fd slots */ 291 int maxfd; /* highest fd in use */ 292 int minfd; /* lower bound on free fd */ 293 }; 294 295 struct Evalue 296 { 297 char *var; 298 char *val; 299 int len; 300 Qid qid; 301 Evalue *next; 302 }; 303 304 struct Egrp 305 { 306 Ref r; 307 QLock l; 308 ulong path; 309 ulong vers; 310 Evalue *entries; 311 }; 312 313 struct Signerkey 314 { 315 Ref r; 316 char* owner; 317 ushort footprint; 318 ulong expires; 319 void* alg; 320 void* pk; 321 void (*pkfree)(void*); 322 }; 323 324 struct Skeyset 325 { 326 Ref r; 327 QLock l; 328 ulong flags; 329 char* devs; 330 int nkey; 331 Signerkey *keys[MAXKEY]; 332 }; 333 334 struct Uqid 335 { 336 Ref r; 337 int type; 338 int dev; 339 vlong oldpath; 340 vlong newpath; 341 Uqid* next; 342 }; 343 344 enum 345 { 346 Nqidhash = 32 347 }; 348 349 struct Uqidtab 350 { 351 QLock l; 352 Uqid* qids[Nqidhash]; 353 ulong pathgen; 354 }; 355 356 struct Osenv 357 { 358 char *syserrstr; /* last error from a system call, errbuf0 or 1 */ 359 char *errstr; /* reason we're unwinding the error stack, errbuf1 or 0 */ 360 char errbuf0[ERRMAX]; 361 char errbuf1[ERRMAX]; 362 Pgrp* pgrp; /* Ref to namespace, working dir and root */ 363 Fgrp* fgrp; /* Ref to file descriptors */ 364 Egrp* egrp; /* Environment vars */ 365 Skeyset* sigs; /* Signed module keys */ 366 Rendez* rend; /* Synchro point */ 367 Queue* waitq; /* Info about dead children */ 368 Queue* childq; /* Info about children for debuggers */ 369 void* debug; /* Debugging master */ 370 char* user; /* Inferno user name */ 371 FPU fpu; /* Floating point thread state */ 372 int uid; /* Numeric user id for host system */ 373 int gid; /* Numeric group id for host system */ 374 void *ui; /* User info for NT */ 375 }; 376 377 enum 378 { 379 Unknown = 0xdeadbabe, 380 IdleGC = 0x16, 381 Interp = 0x17, 382 BusyGC = 0x18, 383 Moribund 384 }; 385 386 struct Proc 387 { 388 int type; /* interpreter or not */ 389 char text[KNAMELEN]; 390 Proc* qnext; /* list of processes waiting on a Qlock */ 391 long pid; 392 Proc* next; /* list of created processes */ 393 Proc* prev; 394 Lock rlock; /* sync between sleep/swiproc for r */ 395 Rendez* r; /* rendezvous point slept on */ 396 Rendez sleep; /* place to sleep */ 397 int killed; /* by swiproc */ 398 int swipend; /* software interrupt pending for Prog */ 399 int syscall; /* set true under sysio for interruptable syscalls */ 400 int intwait; /* spin wait for note to turn up */ 401 int sigid; /* handle used for signal/note/exception */ 402 Lock sysio; /* note handler lock */ 403 char genbuf[128]; /* buffer used e.g. for last name element from namec */ 404 int nerr; /* error stack SP */ 405 osjmpbuf estack[NERR]; /* vector of error jump labels */ 406 char* kstack; 407 void (*func)(void*); /* saved trampoline pointer for kproc */ 408 void* arg; /* arg for invoked kproc function */ 409 void* iprog; /* work for Prog after release */ 410 void* prog; /* fake prog for slaves eg. exportfs */ 411 Osenv* env; /* effective operating system environment */ 412 Osenv defenv; /* default env for slaves with no prog */ 413 osjmpbuf privstack; /* private stack for making new kids */ 414 osjmpbuf sharestack; 415 Proc *kid; 416 void *kidsp; 417 void *os; /* host os specific data */ 418 }; 419 420 #define poperror() up->nerr-- 421 #define waserror() (up->nerr++, ossetjmp(up->estack[up->nerr-1])) 422 423 enum 424 { 425 /* kproc flags */ 426 KPDUPPG = (1<<0), 427 KPDUPFDG = (1<<1), 428 KPDUPENVG = (1<<2), 429 KPX11 = (1<<8), /* needs silly amount of stack */ 430 KPDUP = (KPDUPPG|KPDUPFDG|KPDUPENVG) 431 }; 432 433 struct Procs 434 { 435 Lock l; 436 Proc* head; 437 Proc* tail; 438 }; 439 440 struct Rootdata 441 { 442 int dotdot; 443 void *ptr; 444 int size; 445 int *sizep; 446 }; 447 448 extern Dev* devtab[]; 449 extern char *ossysname; 450 extern char *eve; 451 extern Queue* kbdq; 452 extern Queue* gkbdq; 453 extern Queue* gkscanq; 454 extern int Xsize; 455 extern int Ysize; 456 extern Pool* mainmem; 457 extern char rootdir[MAXROOT]; /* inferno root */ 458 extern Procs procs; 459 extern int sflag; 460 extern int xtblbit; 461 extern int globfs; 462 extern int greyscale; 463 extern uint qiomaxatomic; 464 465 /* 466 * floating point control and status register masks 467 */ 468 enum 469 { 470 INVAL = 0x0001, 471 ZDIV = 0x0002, 472 OVFL = 0x0004, 473 UNFL = 0x0008, 474 INEX = 0x0010, 475 RND_NR = 0x0000, 476 RND_NINF = 0x0100, 477 RND_PINF = 0x0200, 478 RND_Z = 0x0300, 479 RND_MASK = 0x0300 480 }; 481 482 struct Cmdbuf 483 { 484 char *buf; 485 char **f; 486 int nf; 487 }; 488 489 struct Cmdtab 490 { 491 int index; /* used by client to switch on result */ 492 char *cmd; /* command name */ 493 int narg; /* expected #args; 0 ==> variadic */ 494 }; 495 496 /* queue state bits, Qmsg, Qcoalesce, and Qkick can be set in qopen */ 497 enum 498 { 499 /* Queue.state */ 500 Qstarve = (1<<0), /* consumer starved */ 501 Qmsg = (1<<1), /* message stream */ 502 Qclosed = (1<<2), /* queue has been closed/hungup */ 503 Qflow = (1<<3), /* producer flow controlled */ 504 Qcoalesce = (1<<4), /* coallesce packets on read */ 505 Qkick = (1<<5), /* always call the kick routine after qwrite */ 506 }; 507 508 #define DEVDOTDOT -1 509 510 #pragma varargck type "I" uchar* 511 #pragma varargck type "E" uchar* 512 513 extern void (*mainmonitor)(int, void*, ulong); 514