libixp

git clone git://oldgit.suckless.org/libixp/
Log | Files | Refs | LICENSE

ixp.h (20325B)


      1 /* Copyright ©2006-2010 Kris Maglione <maglione.k at Gmail>
      2  * See LICENSE file for license details.
      3  */
      4 
      5 #include <stdarg.h>
      6 #include <stdint.h>
      7 #include <sys/types.h>
      8 #include <sys/select.h>
      9 
     10 /**
     11  * Macro: IXP_API
     12  * Macro: IXP_NEEDAPI
     13  * Macro: IXP_MAXAPI
     14  * Macro: IXP_ASSERT_VERSION
     15  *
     16  * IXP_API contains the current libixp API revision number.
     17  *
     18  * IXP_NEEDAPI, if defined before ixp.h is included, directs the
     19  * header to present an older version of the libixp API. This allows
     20  * code written for older versions of libixp to compile against
     21  * newer versions without modification. It does not, however, ensure
     22  * that it will link against a different version of libixp than the
     23  * ixp.h header belongs to.
     24  *
     25  * IXP_MAXAPI, if defined before ixp.h is included, prevents code
     26  * from compiling with a newer version of libixp than specified.
     27  *
     28  * When inserted into any function, IXP_ASSERT_VERSION ensures that
     29  * the resulting object will fail to link link against any version
     30  * of libixp with a different API version than it was compiled
     31  * against.
     32  */
     33 #define IXP_API 135
     34 #define _IXP_ASSERT_VERSION ixp_version_ ## 135 ## _required
     35 
     36 #ifndef IXP_NEEDAPI
     37 #define IXP_NEEDAPI IXP_API
     38 #endif
     39 
     40 #ifndef IXP_MAXAPI
     41 #define IXP_MAXAPI IXP_API
     42 #endif
     43 
     44 #define IXP_ASSERT_VERSION do _IXP_ASSERT_VERSION = 0; while(0)
     45 extern int _IXP_ASSERT_VERSION;
     46 
     47 /* Gunk */
     48 #if IXP_API < IXP_NEEDAPI
     49 #  error A newer version of libixp is needed for this compilation.
     50 #endif
     51 #if IXP_API > IXP_MAXAPI
     52 #  warning This version of libixp has a newer API than this compilation requests.
     53 #endif
     54 
     55 #if IXP_NEEDAPI < 127
     56 # undef	uchar
     57 # undef	ushort
     58 # undef	ulong
     59 # undef	vlong
     60 # undef	uvlong
     61 # define	uchar		_ixpuchar
     62 # define	ushort	_ixpushort
     63 # define	ulong	_ixpulong
     64 # define	vlong	_ixpvlong
     65 # define	uvlong	_ixpuvlong
     66 
     67 typedef unsigned char	uchar;
     68 typedef uint16_t	ushort;
     69 typedef uint32_t	ulong;
     70 typedef uint64_t	uvlong;
     71 
     72 typedef int64_t		vlong;
     73 
     74 # define respond ixp_respond
     75 # define serve_9pcon ixp_serve9pconn
     76 #endif
     77 
     78 #undef	uint
     79 #define	uint		_ixpuint
     80 typedef unsigned int	uint;
     81 
     82 #ifdef KENC
     83 #  define STRUCT(x) struct {x};
     84 #  define UNION(x) union {x};
     85 #elif defined(__GNUC__)
     86 #  define STRUCT(x) __extension__ struct {x};
     87 #  define UNION(x) __extension__ union {x};
     88 #endif
     89 /* End Gunk */
     90 
     91 #define IXP_VERSION	"9P2000"
     92 #define IXP_NOTAG	((uint16_t)~0)	/* Dummy tag */
     93 #define IXP_NOFID	(~0U)
     94 
     95 enum {
     96 	IXP_MAX_VERSION = 32,
     97 	IXP_MAX_MSG = 8192,
     98 	IXP_MAX_ERROR = 128,
     99 	IXP_MAX_CACHE = 32,
    100 	IXP_MAX_FLEN = 128,
    101 	IXP_MAX_ULEN = 32,
    102 	IXP_MAX_WELEM = 16,
    103 };
    104 
    105 /* 9P message types */
    106 enum IxpFType {
    107 	P9_TVersion = 100,
    108 	P9_RVersion,
    109 	P9_TAuth = 102,
    110 	P9_RAuth,
    111 	P9_TAttach = 104,
    112 	P9_RAttach,
    113 	P9_TError = 106, /* illegal */
    114 	P9_RError,
    115 	P9_TFlush = 108,
    116 	P9_RFlush,
    117 	P9_TWalk = 110,
    118 	P9_RWalk,
    119 	P9_TOpen = 112,
    120 	P9_ROpen,
    121 	P9_TCreate = 114,
    122 	P9_RCreate,
    123 	P9_TRead = 116,
    124 	P9_RRead,
    125 	P9_TWrite = 118,
    126 	P9_RWrite,
    127 	P9_TClunk = 120,
    128 	P9_RClunk,
    129 	P9_TRemove = 122,
    130 	P9_RRemove,
    131 	P9_TStat = 124,
    132 	P9_RStat,
    133 	P9_TWStat = 126,
    134 	P9_RWStat,
    135 };
    136 
    137 /* from libc.h in p9p */
    138 enum IxpOMode {
    139 	P9_OREAD	= 0,	/* open for read */
    140 	P9_OWRITE	= 1,	/* write */
    141 	P9_ORDWR	= 2,	/* read and write */
    142 	P9_OEXEC	= 3,	/* execute, == read but check execute permission */
    143 	P9_OTRUNC	= 16,	/* or'ed in (except for exec), truncate file first */
    144 	P9_OCEXEC	= 32,	/* or'ed in, close on exec */
    145 	P9_ORCLOSE	= 64,	/* or'ed in, remove on close */
    146 	P9_ODIRECT	= 128,	/* or'ed in, direct access */
    147 	P9_ONONBLOCK	= 256,	/* or'ed in, non-blocking call */
    148 	P9_OEXCL	= 0x1000,	/* or'ed in, exclusive use (create only) */
    149 	P9_OLOCK	= 0x2000,	/* or'ed in, lock after opening */
    150 	P9_OAPPEND	= 0x4000	/* or'ed in, append only */
    151 };
    152 
    153 /* bits in IxpQid.type */
    154 enum IxpQType {
    155 	P9_QTDIR	= 0x80,	/* type bit for directories */
    156 	P9_QTAPPEND	= 0x40,	/* type bit for append only files */
    157 	P9_QTEXCL	= 0x20,	/* type bit for exclusive use files */
    158 	P9_QTMOUNT	= 0x10,	/* type bit for mounted channel */
    159 	P9_QTAUTH	= 0x08,	/* type bit for authentication file */
    160 	P9_QTTMP	= 0x04,	/* type bit for non-backed-up file */
    161 	P9_QTSYMLINK	= 0x02,	/* type bit for symbolic link */
    162 	P9_QTFILE	= 0x00	/* type bits for plain file */
    163 };
    164 
    165 /* bits in IxpStat.mode */
    166 enum IxpDMode {
    167 	P9_DMEXEC	= 0x1,		/* mode bit for execute permission */
    168 	P9_DMWRITE	= 0x2,		/* mode bit for write permission */
    169 	P9_DMREAD	= 0x4,		/* mode bit for read permission */
    170 
    171 #define P9_DMDIR	0x80000000	/* mode bit for directories */
    172 #define P9_DMAPPEND	0x40000000	/* mode bit for append only files */
    173 #define P9_DMEXCL	0x20000000	/* mode bit for exclusive use files */
    174 #define P9_DMMOUNT	0x10000000	/* mode bit for mounted channel */
    175 #define P9_DMAUTH	0x08000000	/* mode bit for authentication file */
    176 #define P9_DMTMP	0x04000000	/* mode bit for non-backed-up file */
    177 #define P9_DMSYMLINK	0x02000000	/* mode bit for symbolic link (Unix, 9P2000.u) */
    178 #define P9_DMDEVICE	0x00800000	/* mode bit for device file (Unix, 9P2000.u) */
    179 #define P9_DMNAMEDPIPE	0x00200000	/* mode bit for named pipe (Unix, 9P2000.u) */
    180 #define P9_DMSOCKET	0x00100000	/* mode bit for socket (Unix, 9P2000.u) */
    181 #define P9_DMSETUID	0x00080000	/* mode bit for setuid (Unix, 9P2000.u) */
    182 #define P9_DMSETGID	0x00040000	/* mode bit for setgid (Unix, 9P2000.u) */
    183 };
    184 
    185 #ifdef IXP_NO_P9_
    186 #  define TVersion P9_TVersion
    187 #  define RVersion P9_RVersion
    188 #  define TAuth P9_TAuth
    189 #  define RAuth P9_RAuth
    190 #  define TAttach P9_TAttach
    191 #  define RAttach P9_RAttach
    192 #  define TError P9_TError
    193 #  define RError P9_RError
    194 #  define TFlush P9_TFlush
    195 #  define RFlush P9_RFlush
    196 #  define TWalk P9_TWalk
    197 #  define RWalk P9_RWalk
    198 #  define TOpen P9_TOpen
    199 #  define ROpen P9_ROpen
    200 #  define TCreate P9_TCreate
    201 #  define RCreate P9_RCreate
    202 #  define TRead P9_TRead
    203 #  define RRead P9_RRead
    204 #  define TWrite P9_TWrite
    205 #  define RWrite P9_RWrite
    206 #  define TClunk P9_TClunk
    207 #  define RClunk P9_RClunk
    208 #  define TRemove P9_TRemove
    209 #  define RRemove P9_RRemove
    210 #  define TStat P9_TStat
    211 #  define RStat P9_RStat
    212 #  define TWStat P9_TWStat
    213 #  define RWStat P9_RWStat
    214 #
    215 #  define OREAD P9_OREAD
    216 #  define OWRITE P9_OWRITE
    217 #  define ORDWR P9_ORDWR
    218 #  define OEXEC P9_OEXEC
    219 #  define OTRUNC P9_OTRUNC
    220 #  define OCEXEC P9_OCEXEC
    221 #  define ORCLOSE P9_ORCLOSE
    222 #  define ODIRECT P9_ODIRECT
    223 #  define ONONBLOCK P9_ONONBLOCK
    224 #  define OEXCL P9_OEXCL
    225 #  define OLOCK P9_OLOCK
    226 #  define OAPPEND P9_OAPPEND
    227 #
    228 #  define QTDIR P9_QTDIR
    229 #  define QTAPPEND P9_QTAPPEND
    230 #  define QTEXCL P9_QTEXCL
    231 #  define QTMOUNT P9_QTMOUNT
    232 #  define QTAUTH P9_QTAUTH
    233 #  define QTTMP P9_QTTMP
    234 #  define QTSYMLINK P9_QTSYMLINK
    235 #  define QTFILE P9_QTFILE
    236 #  define DMDIR P9_DMDIR
    237 #  define DMAPPEND P9_DMAPPEND
    238 #  define DMEXCL P9_DMEXCL
    239 #  define DMMOUNT P9_DMMOUNT
    240 #  define DMAUTH P9_DMAUTH
    241 #  define DMTMP P9_DMTMP
    242 #
    243 #  define DMSYMLINK P9_DMSYMLINK
    244 #  define DMDEVICE P9_DMDEVICE
    245 #  define DMNAMEDPIPE P9_DMNAMEDPIPE
    246 #  define DMSOCKET P9_DMSOCKET
    247 #  define DMSETUID P9_DMSETUID
    248 #  define DMSETGID P9_DMSETGID
    249 #endif
    250 
    251 typedef struct IxpMap IxpMap;
    252 typedef struct Ixp9Conn Ixp9Conn;
    253 typedef struct Ixp9Req Ixp9Req;
    254 typedef struct Ixp9Srv Ixp9Srv;
    255 typedef struct IxpCFid IxpCFid;
    256 typedef struct IxpClient IxpClient;
    257 typedef struct IxpConn IxpConn;
    258 typedef struct IxpFid IxpFid;
    259 typedef struct IxpMsg IxpMsg;
    260 typedef struct IxpQid IxpQid;
    261 typedef struct IxpRpc IxpRpc;
    262 typedef struct IxpServer IxpServer;
    263 typedef struct IxpStat IxpStat;
    264 typedef struct IxpTimer IxpTimer;
    265 
    266 typedef struct IxpMutex IxpMutex;
    267 typedef struct IxpRWLock IxpRWLock;
    268 typedef struct IxpRendez IxpRendez;
    269 typedef struct IxpThread IxpThread;
    270 
    271 /* Threading */
    272 enum {
    273 	IXP_ERRMAX = IXP_MAX_ERROR,
    274 };
    275 
    276 struct IxpMutex {
    277 	void*	aux;
    278 };
    279 
    280 struct IxpRendez {
    281 	IxpMutex*	mutex;
    282 	void*	aux;
    283 };
    284 
    285 struct IxpRWLock {
    286 	void*	aux;
    287 };
    288 
    289 enum IxpMsgMode {
    290 	MsgPack,
    291 	MsgUnpack,
    292 };
    293 struct IxpMsg {
    294 	char*	data; /* Begining of buffer. */
    295 	char*	pos;  /* Current position in buffer. */
    296 	char*	end;  /* End of message. */ 
    297 	uint	size; /* Size of buffer. */
    298 	uint	mode; /* MsgPack or MsgUnpack. */
    299 };
    300 
    301 struct IxpQid {
    302 	uint8_t		type;
    303 	uint32_t	version;
    304 	uint64_t	path;
    305 	/* Private members */
    306 	uint8_t		dir_type;
    307 };
    308 
    309 /* stat structure */
    310 struct IxpStat {
    311 	uint16_t	type;
    312 	uint32_t	dev;
    313 	IxpQid		qid;
    314 	uint32_t	mode;
    315 	uint32_t	atime;
    316 	uint32_t	mtime;
    317 	uint64_t	length;
    318 	char*	name;
    319 	char*	uid;
    320 	char*	gid;
    321 	char*	muid;
    322 };
    323 
    324 typedef struct IxpFHdr		IxpFHdr;
    325 typedef struct IxpFError	IxpFError;
    326 typedef struct IxpFROpen	IxpFRAttach;
    327 typedef struct IxpFRAuth	IxpFRAuth;
    328 typedef struct IxpFROpen	IxpFRCreate;
    329 typedef struct IxpFROpen	IxpFROpen;
    330 typedef struct IxpFIO		IxpFRRead;
    331 typedef struct IxpFRStat	IxpFRStat;
    332 typedef struct IxpFVersion	IxpFRVersion;
    333 typedef struct IxpFRWalk	IxpFRWalk;
    334 typedef struct IxpFAttach	IxpFTAttach;
    335 typedef struct IxpFAttach	IxpFTAuth;
    336 typedef struct IxpFTCreate	IxpFTCreate;
    337 typedef struct IxpFTFlush	IxpFTFlush;
    338 typedef struct IxpFTCreate	IxpFTOpen;
    339 typedef struct IxpFIO		IxpFTRead;
    340 typedef struct IxpFVersion	IxpFTVersion;
    341 typedef struct IxpFTWalk	IxpFTWalk;
    342 typedef struct IxpFIO		IxpFTWrite;
    343 typedef struct IxpFTWStat	IxpFTWStat;
    344 typedef struct IxpFAttach	IxpFAttach;
    345 typedef struct IxpFIO		IxpFIO;
    346 typedef struct IxpFVersion	IxpFVersion;
    347 
    348 struct IxpFHdr {
    349 	uint8_t		type;
    350 	uint16_t	tag;
    351 	uint32_t	fid;
    352 };
    353 struct IxpFVersion {
    354 	IxpFHdr		hdr;
    355 	uint32_t	msize;
    356 	char*		version;
    357 };
    358 struct IxpFTFlush {
    359 	IxpFHdr		hdr;
    360 	uint16_t	oldtag;
    361 };
    362 struct IxpFError {
    363 	IxpFHdr		hdr;
    364 	char*		ename;
    365 };
    366 struct IxpFROpen {
    367 	IxpFHdr		hdr;
    368 	IxpQid		qid; /* +Rattach */
    369 	uint32_t	iounit;
    370 };
    371 struct IxpFRAuth {
    372 	IxpFHdr		hdr;
    373 	IxpQid		aqid;
    374 };
    375 struct IxpFAttach {
    376 	IxpFHdr		hdr;
    377 	uint32_t	afid;
    378 	char*		uname;
    379 	char*		aname;
    380 };
    381 struct IxpFTCreate {
    382 	IxpFHdr		hdr;
    383 	uint32_t	perm;
    384 	char*		name;
    385 	uint8_t		mode; /* +Topen */
    386 };
    387 struct IxpFTWalk {
    388 	IxpFHdr	hdr;
    389 	uint32_t	newfid;
    390 	uint16_t	nwname;
    391 	char*		wname[IXP_MAX_WELEM];
    392 };
    393 struct IxpFRWalk {
    394 	IxpFHdr		hdr;
    395 	uint16_t	nwqid;
    396 	IxpQid		wqid[IXP_MAX_WELEM];
    397 };
    398 struct IxpFIO {
    399 	IxpFHdr		hdr;
    400 	uint64_t	offset; /* Tread, Twrite */
    401 	uint32_t	count; /* Tread, Twrite, Rread */
    402 	char*		data; /* Twrite, Rread */
    403 };
    404 struct IxpFRStat {
    405 	IxpFHdr		hdr;
    406 	uint16_t	nstat;
    407 	uint8_t*	stat;
    408 };
    409 struct IxpFTWStat {
    410 	IxpFHdr		hdr;
    411 	IxpStat		stat;
    412 };
    413 
    414 #if IXP_NEEDAPI <= 89
    415 /* from fcall(3) in plan9port */
    416 typedef struct IxpFcall IxpFcall; /* Deprecated */
    417 struct IxpFcall {		  /* Deprecated */
    418 	uint8_t type;
    419 	uint16_t tag;
    420 	uint32_t fid;
    421 
    422 	UNION (
    423 		STRUCT ( /* Tversion, Rversion */
    424 			uint32_t	msize;
    425 			char	*version;
    426 		)
    427 		STRUCT ( /* Tflush */
    428 			uint16_t	oldtag;
    429 		)
    430 		STRUCT ( /* Rerror */
    431 			char	*ename;
    432 		)
    433 		STRUCT ( /* Ropen, Rcreate */
    434 			IxpQid	qid; /* +Rattach */
    435 			uint32_t	iounit;
    436 		)
    437 		STRUCT ( /* Rauth */
    438 			IxpQid	aqid;
    439 		)
    440 		STRUCT ( /* Tauth, Tattach */
    441 			uint32_t	afid;
    442 			char	*uname;
    443 			char	*aname;
    444 		)
    445 		STRUCT ( /* Tcreate */
    446 			uint32_t	perm;
    447 			char	*name;
    448 			uint8_t	mode; /* +Topen */
    449 		)
    450 		STRUCT ( /* Twalk */
    451 			uint32_t	newfid;
    452 			uint16_t	nwname;
    453 			char	*wname[IXP_MAX_WELEM];
    454 		)
    455 		STRUCT ( /* Rwalk */
    456 			uint16_t	nwqid;
    457 			IxpQid	wqid[IXP_MAX_WELEM];
    458 		)
    459 		STRUCT (
    460 			uint64_t	offset; /* Tread, Twrite */
    461 			uint32_t	count; /* Tread, Twrite, Rread */
    462 			char	*data; /* Twrite, Rread */
    463 		)
    464 		STRUCT ( /* Rstat */
    465 			uint16_t	nstat;
    466 			char	*stat;
    467 		)
    468 		STRUCT ( /* Twstat */
    469 			IxpStat	st;
    470 		)
    471 	)
    472 };
    473 #else
    474 /**
    475  * Type: IxpFcall
    476  * Type: IxpFType
    477  * Type: IxpFAttach
    478  * Type: IxpFError
    479  * Type: IxpFHdr
    480  * Type: IxpFIO
    481  * Type: IxpFRAuth
    482  * Type: IxpFROpen
    483  * Type: IxpFRStat
    484  * Type: IxpFRWalk
    485  * Type: IxpFTCreate
    486  * Type: IxpFTFlush
    487  * Type: IxpFTWStat
    488  * Type: IxpFTWalk
    489  * Type: IxpFVersion
    490  *
    491  * The IxpFcall structure represents a 9P protocol message. The
    492  * P<hdr> element is common to all Fcall types, and may be used to
    493  * determine the type and tag of the message. The IxpFcall type is
    494  * used heavily in server applications, where it both presents a
    495  * request to handler functions and returns a response to the
    496  * client.
    497  *
    498  * Each member of the IxpFcall structure represents a certain
    499  * message type, which can be discerned from the P<hdr.type> field.
    500  * This value corresponds to one of the IxpFType constants. Types
    501  * with significant overlap use the same structures, thus TRead and
    502  * RWrite are both represented by IxpFIO and can be accessed via the
    503  * P<io> member as well as P<tread> and P<rwrite> respectively.
    504  *
    505  * See also:
    506  *	T<Ixp9Srv>, T<Ixp9Req>
    507  */
    508 typedef union IxpFcall	IxpFcall;
    509 union IxpFcall {
    510 	IxpFHdr		hdr;
    511 	IxpFVersion	version;
    512 	IxpFVersion	tversion;
    513 	IxpFVersion	rversion;
    514 	IxpFTFlush	tflush;
    515 	IxpFROpen	ropen;
    516 	IxpFROpen	rcreate;
    517 	IxpFROpen	rattach;
    518 	IxpFError	error;
    519 	IxpFRAuth	rauth;
    520 	IxpFAttach	tattach;
    521 	IxpFAttach	tauth;
    522 	IxpFTCreate	tcreate;
    523 	IxpFTCreate	topen;
    524 	IxpFTWalk	twalk;
    525 	IxpFRWalk	rwalk;
    526 	IxpFTWStat	twstat;
    527 	IxpFRStat	rstat;
    528 	IxpFIO		twrite;
    529 	IxpFIO		rwrite;
    530 	IxpFIO		tread;
    531 	IxpFIO		rread;
    532 	IxpFIO		io;
    533 };
    534 #endif
    535 
    536 #ifdef IXP_P9_STRUCTS
    537 typedef IxpFcall	Fcall;
    538 typedef IxpFid		Fid;
    539 typedef IxpQid		Qid;
    540 typedef IxpStat		Stat;
    541 #endif
    542 
    543 struct IxpConn {
    544 	IxpServer*	srv;
    545 	void*		aux;	/* Arbitrary pointer, to be used by handlers. */
    546 	int		fd;	/* The file descriptor of the connection. */
    547 	void		(*read)(IxpConn *);
    548 	void		(*close)(IxpConn *);
    549 	char		closed;	/* Non-zero when P<fd> has been closed. */
    550 
    551 	/* Private members */
    552 	IxpConn		*next;
    553 };
    554 
    555 struct IxpServer {
    556 	IxpConn*	conn;
    557 	IxpMutex	lk;
    558 	IxpTimer*	timer;
    559 	void		(*preselect)(IxpServer*);
    560 	void*		aux;
    561 	int		running;
    562 	int		maxfd;
    563 	fd_set		rd;
    564 };
    565 
    566 struct IxpRpc {
    567 	IxpClient*	mux;
    568 	IxpRpc*		next;
    569 	IxpRpc*		prev;
    570 	IxpRendez	r;
    571 	uint		tag;
    572 	IxpFcall*	p;
    573 	int		waiting;
    574 	int		async;
    575 };
    576 
    577 struct IxpClient {
    578 	int	fd;
    579 	uint	msize;
    580 	uint	lastfid;
    581 
    582 	/* Private members */
    583 	uint		nwait;
    584 	uint		mwait;
    585 	uint		freetag;
    586 	IxpCFid*	freefid;
    587 	IxpMsg		rmsg;
    588 	IxpMsg		wmsg;
    589 	IxpMutex	lk;
    590 	IxpMutex	rlock;
    591 	IxpMutex	wlock;
    592 	IxpRendez	tagrend;
    593 	IxpRpc**	wait;
    594 	IxpRpc*		muxer;
    595 	IxpRpc		sleep;
    596 	int		mintag;
    597 	int		maxtag;
    598 };
    599 
    600 struct IxpCFid {
    601 	uint32_t	fid;
    602 	IxpQid		qid;
    603 	uint8_t		mode;
    604 	uint		open;
    605 	uint		iounit;
    606 	uint32_t	offset;
    607 	IxpClient*	client;
    608 
    609 	/* Private members */
    610 	IxpCFid*	next;
    611 	IxpMutex	iolock;
    612 };
    613 
    614 /**
    615  * Type: IxpFid
    616  *
    617  * Represents an open file for a 9P connection. The same
    618  * structure persists as long as the file remains open, and is
    619  * installed in the T<Ixp9Req> structure for any request Fcall
    620  * which references it. Handlers may use the P<aux> member to
    621  * store any data which must persist for the life of the open
    622  * file.
    623  *
    624  * See also:
    625  *	T<Ixp9Req>, T<IxpQid>, T<IxpOMode>
    626  */
    627 struct IxpFid {
    628 	char*		uid;	/* The uid of the file opener. */
    629 	void*		aux;    /* Arbitrary pointer, to be used by handlers. */
    630 	uint32_t		fid;    /* The ID number of the fid. */
    631 	IxpQid		qid;    /* The filesystem-unique QID of the file. */
    632 	signed char	omode;  /* The open mode of the file. */
    633 	uint		iounit; /* The maximum size of any IO request. */
    634 
    635 	/* Private members */
    636 	Ixp9Conn*	conn;
    637 	IxpMap*		map;
    638 };
    639 
    640 struct Ixp9Req {
    641 	Ixp9Srv*	srv;
    642 	IxpFid*		fid;    /* Fid structure corresponding to IxpFHdr.fid */
    643 	IxpFid*		newfid; /* Corresponds to IxpFTWStat.newfid */
    644 	Ixp9Req*	oldreq; /* For TFlush requests, the original request. */
    645 	IxpFcall	ifcall; /* The incoming request fcall. */
    646 	IxpFcall	ofcall; /* The response fcall, to be filled by handler. */
    647 	void*		aux;    /* Arbitrary pointer, to be used by handlers. */
    648 
    649 	/* Private members */
    650 	Ixp9Conn *conn;
    651 };
    652 
    653 struct Ixp9Srv {
    654 	void* aux;
    655 	void (*attach)(Ixp9Req*);
    656 	void (*clunk)(Ixp9Req*);
    657 	void (*create)(Ixp9Req*);
    658 	void (*flush)(Ixp9Req*);
    659 	void (*open)(Ixp9Req*);
    660 	void (*read)(Ixp9Req*);
    661 	void (*remove)(Ixp9Req*);
    662 	void (*stat)(Ixp9Req*);
    663 	void (*walk)(Ixp9Req*);
    664 	void (*write)(Ixp9Req*);
    665 	void (*wstat)(Ixp9Req*);
    666 	void (*freefid)(IxpFid*);
    667 };
    668 
    669 /**
    670  * Type: IxpThread
    671  * Type: IxpMutex
    672  * Type: IxpRWLock
    673  * Type: IxpRendez
    674  * Variable: ixp_thread
    675  *
    676  * The IxpThread structure is used to adapt libixp to any of the
    677  * myriad threading systems it may be used with. Before any
    678  * other of libixp's functions is called, ixp_thread may be set
    679  * to a structure filled with implementations of various locking
    680  * primitives, along with primitive IO functions which may
    681  * perform context switches until data is available.
    682  *
    683  * The names of the functions should be fairly self-explanitory.
    684  * Read/write locks should allow multiple readers and a single
    685  * writer of a shared resource, but should not allow new readers
    686  * while a writer is waitng for a lock. Mutexes should allow
    687  * only one accessor at a time. Rendezvous points are similar to
    688  * pthread condition types. P<errbuf> should return a
    689  * thread-local buffer or the size IXP_ERRMAX.
    690  *
    691  * See also:
    692  *	F<ixp_pthread_init>, F<ixp_taskinit>, F<ixp_rubyinit>
    693  */
    694 struct IxpThread {
    695 	/* Read/write lock */
    696 	int	(*initrwlock)(IxpRWLock*);
    697 	void	(*rlock)(IxpRWLock*);
    698 	int	(*canrlock)(IxpRWLock*);
    699 	void	(*runlock)(IxpRWLock*);
    700 	void	(*wlock)(IxpRWLock*);
    701 	int	(*canwlock)(IxpRWLock*);
    702 	void	(*wunlock)(IxpRWLock*);
    703 	void	(*rwdestroy)(IxpRWLock*);
    704 	/* Mutex */
    705 	int	(*initmutex)(IxpMutex*);
    706 	void	(*lock)(IxpMutex*);
    707 	int	(*canlock)(IxpMutex*);
    708 	void	(*unlock)(IxpMutex*);
    709 	void	(*mdestroy)(IxpMutex*);
    710 	/* Rendezvous point */
    711 	int	(*initrendez)(IxpRendez*);
    712 	void	(*sleep)(IxpRendez*);
    713 	int	(*wake)(IxpRendez*);
    714 	int	(*wakeall)(IxpRendez*);
    715 	void	(*rdestroy)(IxpRendez*);
    716 	/* Other */
    717 	char*	(*errbuf)(void);
    718 	ssize_t	(*read)(int, void*, size_t);
    719 	ssize_t	(*write)(int, const void*, size_t);
    720 	int	(*select)(int, fd_set*, fd_set*, fd_set*, struct timeval*);
    721 };
    722 
    723 extern IxpThread*	ixp_thread;
    724 extern int	(*ixp_vsnprint)(char *buf, int nbuf, const char *fmt, va_list);
    725 extern char*	(*ixp_vsmprint)(const char *fmt, va_list);
    726 extern void	(*ixp_printfcall)(IxpFcall*);
    727 
    728 /* thread_*.c */
    729 int ixp_taskinit(void);
    730 int ixp_rubyinit(void);
    731 int ixp_pthread_init(void);
    732 
    733 #ifdef VARARGCK
    734 #  pragma varargck	argpos	ixp_print	2
    735 #  pragma varargck	argpos	ixp_werrstr	1
    736 #  pragma varargck	argpos	ixp_eprint	1
    737 #endif
    738 
    739 /* client.c */
    740 int	ixp_close(IxpCFid*);
    741 long	ixp_pread(IxpCFid*, void*, long, int64_t);
    742 int	ixp_print(IxpCFid*, const char*, ...);
    743 long	ixp_pwrite(IxpCFid*, const void*, long, int64_t);
    744 long	ixp_read(IxpCFid*, void*, long);
    745 int	ixp_remove(IxpClient*, const char*);
    746 void	ixp_unmount(IxpClient*);
    747 int	ixp_vprint(IxpCFid*, const char*, va_list);
    748 long	ixp_write(IxpCFid*, const void*, long);
    749 IxpCFid*	ixp_create(IxpClient*, const char*, uint perm, uint8_t mode);
    750 IxpStat*	ixp_fstat(IxpCFid*);
    751 IxpClient*	ixp_mount(const char*);
    752 IxpClient*	ixp_mountfd(int);
    753 IxpClient*	ixp_nsmount(const char*);
    754 IxpCFid*	ixp_open(IxpClient*, const char*, uint8_t);
    755 IxpStat*	ixp_stat(IxpClient*, const char*);
    756 
    757 /* convert.c */
    758 void ixp_pu8(IxpMsg*, uint8_t*);
    759 void ixp_pu16(IxpMsg*, uint16_t*);
    760 void ixp_pu32(IxpMsg*, uint32_t*);
    761 void ixp_pu64(IxpMsg*, uint64_t*);
    762 void ixp_pdata(IxpMsg*, char**, uint);
    763 void ixp_pstring(IxpMsg*, char**);
    764 void ixp_pstrings(IxpMsg*, uint16_t*, char**, uint);
    765 void ixp_pqid(IxpMsg*, IxpQid*);
    766 void ixp_pqids(IxpMsg*, uint16_t*, IxpQid*, uint);
    767 void ixp_pstat(IxpMsg*, IxpStat*);
    768 void ixp_pfcall(IxpMsg*, IxpFcall*);
    769 
    770 /* error.h */
    771 char*	ixp_errbuf(void);
    772 void	ixp_errstr(char*, int);
    773 void	ixp_rerrstr(char*, int);
    774 void	ixp_werrstr(const char*, ...);
    775 
    776 /* request.c */
    777 void ixp_respond(Ixp9Req*, const char *err);
    778 void ixp_serve9conn(IxpConn*);
    779 
    780 /* message.c */
    781 uint16_t	ixp_sizeof_stat(IxpStat*);
    782 IxpMsg	ixp_message(char*, uint len, uint mode);
    783 void	ixp_freestat(IxpStat*);
    784 void	ixp_freefcall(IxpFcall*);
    785 uint	ixp_msg2fcall(IxpMsg*, IxpFcall*);
    786 uint	ixp_fcall2msg(IxpMsg*, IxpFcall*);
    787 
    788 /* server.c */
    789 IxpConn* ixp_listen(IxpServer*, int, void*,
    790 		void (*read)(IxpConn*),
    791 		void (*close)(IxpConn*));
    792 void	ixp_hangup(IxpConn*);
    793 int	ixp_serverloop(IxpServer*);
    794 void	ixp_server_close(IxpServer*);
    795 
    796 /* socket.c */
    797 int ixp_dial(const char*);
    798 int ixp_announce(const char*);
    799 
    800 /* transport.c */
    801 uint ixp_sendmsg(int, IxpMsg*);
    802 uint ixp_recvmsg(int, IxpMsg*);
    803 
    804 /* timer.c */
    805 long	ixp_msec(void);
    806 long	ixp_settimer(IxpServer*, long, void (*)(long, void*), void*);
    807 int	ixp_unsettimer(IxpServer*, long);
    808 
    809 /* util.c */
    810 void	ixp_cleanname(char*);
    811 void*	ixp_emalloc(uint);
    812 void*	ixp_emallocz(uint);
    813 void	ixp_eprint(const char*, ...);
    814 void*	ixp_erealloc(void*, uint);
    815 char*	ixp_estrdup(const char*);
    816 char*	ixp_namespace(void);
    817 char*	ixp_smprint(const char*, ...);
    818 uint	ixp_strlcat(char*, const char*, uint);
    819 uint	ixp_tokenize(char**, uint len, char*, char);
    820