xref: /plan9/sys/include/libc.h (revision 51f48f69b4c3e5c9d9f7955d28612ef2d4048ccc)
1 #pragma	lib	"libc.a"
2 #pragma	src	"/sys/src/libc"
3 
4 #define	nelem(x)	(sizeof(x)/sizeof((x)[0]))
5 #define	offsetof(s, m)	(ulong)(&(((s*)0)->m))
6 #define	assert(x)	if(x){}else _assert("x")
7 
8 /*
9  * mem routines
10  */
11 extern	void*	memccpy(void*, void*, int, ulong);
12 extern	void*	memset(void*, int, ulong);
13 extern	int	memcmp(void*, void*, ulong);
14 extern	void*	memcpy(void*, void*, ulong);
15 extern	void*	memmove(void*, void*, ulong);
16 extern	void*	memchr(void*, int, ulong);
17 
18 /*
19  * string routines
20  */
21 extern	char*	strcat(char*, char*);
22 extern	char*	strchr(char*, int);
23 extern	int	strcmp(char*, char*);
24 extern	char*	strcpy(char*, char*);
25 extern	char*	strecpy(char*, char*, char*);
26 extern	char*	strdup(char*);
27 extern	char*	strncat(char*, char*, long);
28 extern	char*	strncpy(char*, char*, long);
29 extern	int	strncmp(char*, char*, long);
30 extern	char*	strpbrk(char*, char*);
31 extern	char*	strrchr(char*, int);
32 extern	char*	strtok(char*, char*);
33 extern	long	strlen(char*);
34 extern	long	strspn(char*, char*);
35 extern	long	strcspn(char*, char*);
36 extern	char*	strstr(char*, char*);
37 extern	int	cistrncmp(char*, char*, int);
38 extern	int	cistrcmp(char*, char*);
39 extern	char*	cistrstr(char*, char*);
40 extern	int	tokenize(char*, char**, int);
41 
42 enum
43 {
44 	UTFmax		= 4,		/* maximum bytes per rune */
45 	Runesync	= 0x80,		/* cannot represent part of a UTF sequence (<) */
46 	Runeself	= 0x80,		/* rune and UTF sequences are the same (<) */
47 	Runeerror	= 0xFFFD,	/* decoding error in UTF */
48 	Runemax		= 0x10FFFF,	/* 21-bit rune */
49 	Runemask	= 0x1FFFFF,	/* bits used by runes (see grep) */
50 };
51 
52 /*
53  * rune routines
54  */
55 extern	int	runetochar(char*, Rune*);
56 extern	int	chartorune(Rune*, char*);
57 extern	int	runelen(long);
58 extern	int	runenlen(Rune*, int);
59 extern	int	fullrune(char*, int);
60 extern	int	utflen(char*);
61 extern	int	utfnlen(char*, long);
62 extern	char*	utfrune(char*, long);
63 extern	char*	utfrrune(char*, long);
64 extern	char*	utfutf(char*, char*);
65 extern	char*	utfecpy(char*, char*, char*);
66 
67 extern	Rune*	runestrcat(Rune*, Rune*);
68 extern	Rune*	runestrchr(Rune*, Rune);
69 extern	int	runestrcmp(Rune*, Rune*);
70 extern	Rune*	runestrcpy(Rune*, Rune*);
71 extern	Rune*	runestrncpy(Rune*, Rune*, long);
72 extern	Rune*	runestrecpy(Rune*, Rune*, Rune*);
73 extern	Rune*	runestrdup(Rune*);
74 extern	Rune*	runestrncat(Rune*, Rune*, long);
75 extern	int	runestrncmp(Rune*, Rune*, long);
76 extern	Rune*	runestrrchr(Rune*, Rune);
77 extern	long	runestrlen(Rune*);
78 extern	Rune*	runestrstr(Rune*, Rune*);
79 
80 extern	Rune	tolowerrune(Rune);
81 extern	Rune	totitlerune(Rune);
82 extern	Rune	toupperrune(Rune);
83 extern	Rune	tobaserune(Rune);
84 extern	int	isalpharune(Rune);
85 extern	int	isbaserune(Rune);
86 extern	int	isdigitrune(Rune);
87 extern	int	islowerrune(Rune);
88 extern	int	isspacerune(Rune);
89 extern	int	istitlerune(Rune);
90 extern	int	isupperrune(Rune);
91 
92 /*
93  * malloc
94  */
95 extern	void*	malloc(ulong);
96 extern	void*	mallocz(ulong, int);
97 extern	void	free(void*);
98 extern	ulong	msize(void*);
99 extern	void*	mallocalign(ulong, ulong, long, ulong);
100 extern	void*	calloc(ulong, ulong);
101 extern	void*	realloc(void*, ulong);
102 extern	void	setmalloctag(void*, ulong);
103 extern	void	setrealloctag(void*, ulong);
104 extern	ulong	getmalloctag(void*);
105 extern	ulong	getrealloctag(void*);
106 extern	void*	malloctopoolblock(void*);
107 
108 /*
109  * print routines
110  */
111 typedef struct Fmt	Fmt;
112 struct Fmt{
113 	uchar	runes;			/* output buffer is runes or chars? */
114 	void	*start;			/* of buffer */
115 	void	*to;			/* current place in the buffer */
116 	void	*stop;			/* end of the buffer; overwritten if flush fails */
117 	int	(*flush)(Fmt *);	/* called when to == stop */
118 	void	*farg;			/* to make flush a closure */
119 	int	nfmt;			/* num chars formatted so far */
120 	va_list	args;			/* args passed to dofmt */
121 	int	r;			/* % format Rune */
122 	int	width;
123 	int	prec;
124 	ulong	flags;
125 };
126 
127 enum{
128 	FmtWidth	= 1,
129 	FmtLeft		= FmtWidth << 1,
130 	FmtPrec		= FmtLeft << 1,
131 	FmtSharp	= FmtPrec << 1,
132 	FmtSpace	= FmtSharp << 1,
133 	FmtSign		= FmtSpace << 1,
134 	FmtZero		= FmtSign << 1,
135 	FmtUnsigned	= FmtZero << 1,
136 	FmtShort	= FmtUnsigned << 1,
137 	FmtLong		= FmtShort << 1,
138 	FmtVLong	= FmtLong << 1,
139 	FmtComma	= FmtVLong << 1,
140 	FmtByte		= FmtComma << 1,
141 
142 	FmtFlag		= FmtByte << 1
143 };
144 
145 extern	int	print(char*, ...);
146 extern	char*	seprint(char*, char*, char*, ...);
147 extern	char*	vseprint(char*, char*, char*, va_list);
148 extern	int	snprint(char*, int, char*, ...);
149 extern	int	vsnprint(char*, int, char*, va_list);
150 extern	char*	smprint(char*, ...);
151 extern	char*	vsmprint(char*, va_list);
152 extern	int	sprint(char*, char*, ...);
153 extern	int	fprint(int, char*, ...);
154 extern	int	vfprint(int, char*, va_list);
155 
156 extern	int	runesprint(Rune*, char*, ...);
157 extern	int	runesnprint(Rune*, int, char*, ...);
158 extern	int	runevsnprint(Rune*, int, char*, va_list);
159 extern	Rune*	runeseprint(Rune*, Rune*, char*, ...);
160 extern	Rune*	runevseprint(Rune*, Rune*, char*, va_list);
161 extern	Rune*	runesmprint(char*, ...);
162 extern	Rune*	runevsmprint(char*, va_list);
163 
164 extern	int	fmtfdinit(Fmt*, int, char*, int);
165 extern	int	fmtfdflush(Fmt*);
166 extern	int	fmtstrinit(Fmt*);
167 extern	char*	fmtstrflush(Fmt*);
168 extern	int	runefmtstrinit(Fmt*);
169 extern	Rune*	runefmtstrflush(Fmt*);
170 
171 #pragma	varargck	argpos	fmtprint	2
172 #pragma	varargck	argpos	fprint		2
173 #pragma	varargck	argpos	print		1
174 #pragma	varargck	argpos	runeseprint	3
175 #pragma	varargck	argpos	runesmprint	1
176 #pragma	varargck	argpos	runesnprint	3
177 #pragma	varargck	argpos	runesprint	2
178 #pragma	varargck	argpos	seprint		3
179 #pragma	varargck	argpos	smprint		1
180 #pragma	varargck	argpos	snprint		3
181 #pragma	varargck	argpos	sprint		2
182 
183 #pragma	varargck	type	"lld"	vlong
184 #pragma	varargck	type	"llo"	vlong
185 #pragma	varargck	type	"llx"	vlong
186 #pragma	varargck	type	"llb"	vlong
187 #pragma	varargck	type	"lld"	uvlong
188 #pragma	varargck	type	"llo"	uvlong
189 #pragma	varargck	type	"llx"	uvlong
190 #pragma	varargck	type	"llb"	uvlong
191 #pragma	varargck	type	"ld"	long
192 #pragma	varargck	type	"lo"	long
193 #pragma	varargck	type	"lx"	long
194 #pragma	varargck	type	"lb"	long
195 #pragma	varargck	type	"ld"	ulong
196 #pragma	varargck	type	"lo"	ulong
197 #pragma	varargck	type	"lx"	ulong
198 #pragma	varargck	type	"lb"	ulong
199 #pragma	varargck	type	"d"	int
200 #pragma	varargck	type	"o"	int
201 #pragma	varargck	type	"x"	int
202 #pragma	varargck	type	"c"	int
203 #pragma	varargck	type	"C"	int
204 #pragma	varargck	type	"b"	int
205 #pragma	varargck	type	"d"	uint
206 #pragma	varargck	type	"x"	uint
207 #pragma	varargck	type	"c"	uint
208 #pragma	varargck	type	"C"	uint
209 #pragma	varargck	type	"b"	uint
210 #pragma	varargck	type	"f"	double
211 #pragma	varargck	type	"e"	double
212 #pragma	varargck	type	"g"	double
213 #pragma	varargck	type	"s"	char*
214 #pragma	varargck	type	"q"	char*
215 #pragma	varargck	type	"S"	Rune*
216 #pragma	varargck	type	"Q"	Rune*
217 #pragma	varargck	type	"r"	void
218 #pragma	varargck	type	"%"	void
219 #pragma	varargck	type	"n"	int*
220 #pragma	varargck	type	"p"	uintptr
221 #pragma	varargck	type	"p"	void*
222 #pragma	varargck	flag	','
223 #pragma	varargck	flag	' '
224 #pragma	varargck	flag	'h'
225 #pragma varargck	type	"<"	void*
226 #pragma varargck	type	"["	void*
227 #pragma varargck	type	"H"	void*
228 #pragma varargck	type	"lH"	void*
229 
230 extern	int	fmtinstall(int, int (*)(Fmt*));
231 extern	int	dofmt(Fmt*, char*);
232 extern	int	dorfmt(Fmt*, Rune*);
233 extern	int	fmtprint(Fmt*, char*, ...);
234 extern	int	fmtvprint(Fmt*, char*, va_list);
235 extern	int	fmtrune(Fmt*, int);
236 extern	int	fmtstrcpy(Fmt*, char*);
237 extern	int	fmtrunestrcpy(Fmt*, Rune*);
238 /*
239  * error string for %r
240  * supplied on per os basis, not part of fmt library
241  */
242 extern	int	errfmt(Fmt *f);
243 
244 /*
245  * quoted strings
246  */
247 extern	char	*unquotestrdup(char*);
248 extern	Rune	*unquoterunestrdup(Rune*);
249 extern	char	*quotestrdup(char*);
250 extern	Rune	*quoterunestrdup(Rune*);
251 extern	int	quotestrfmt(Fmt*);
252 extern	int	quoterunestrfmt(Fmt*);
253 extern	void	quotefmtinstall(void);
254 extern	int	(*doquote)(int);
255 extern	int	needsrcquote(int);
256 
257 /*
258  * random number
259  */
260 extern	void	srand(long);
261 extern	int	rand(void);
262 extern	int	nrand(int);
263 extern	long	lrand(void);
264 extern	long	lnrand(long);
265 extern	double	frand(void);
266 extern	ulong	truerand(void);			/* uses /dev/random */
267 extern	ulong	ntruerand(ulong);		/* uses /dev/random */
268 
269 /*
270  * math
271  */
272 extern	ulong	getfcr(void);
273 extern	void	setfsr(ulong);
274 extern	ulong	getfsr(void);
275 extern	void	setfcr(ulong);
276 extern	double	NaN(void);
277 extern	double	Inf(int);
278 extern	int	isNaN(double);
279 extern	int	isInf(double, int);
280 extern	ulong	umuldiv(ulong, ulong, ulong);
281 extern	long	muldiv(long, long, long);
282 
283 extern	double	pow(double, double);
284 extern	double	atan2(double, double);
285 extern	double	fabs(double);
286 extern	double	atan(double);
287 extern	double	log(double);
288 extern	double	log10(double);
289 extern	double	exp(double);
290 extern	double	floor(double);
291 extern	double	ceil(double);
292 extern	double	hypot(double, double);
293 extern	double	sin(double);
294 extern	double	cos(double);
295 extern	double	tan(double);
296 extern	double	asin(double);
297 extern	double	acos(double);
298 extern	double	sinh(double);
299 extern	double	cosh(double);
300 extern	double	tanh(double);
301 extern	double	sqrt(double);
302 extern	double	fmod(double, double);
303 
304 #define	HUGE	3.4028234e38
305 #define	PIO2	1.570796326794896619231e0
306 #define	PI	(PIO2+PIO2)
307 
308 /*
309  * Time-of-day
310  */
311 
312 typedef
313 struct Tm
314 {
315 	int	sec;
316 	int	min;
317 	int	hour;
318 	int	mday;
319 	int	mon;
320 	int	year;
321 	int	wday;
322 	int	yday;
323 	char	zone[4];
324 	int	tzoff;
325 } Tm;
326 
327 extern	Tm*	gmtime(long);
328 extern	Tm*	localtime(long);
329 extern	char*	asctime(Tm*);
330 extern	char*	ctime(long);
331 extern	double	cputime(void);
332 extern	long	times(long*);
333 extern	long	tm2sec(Tm*);
334 extern	vlong	nsec(void);
335 
336 extern	void	cycles(uvlong*);	/* 64-bit value of the cycle counter if there is one, 0 if there isn't */
337 
338 /*
339  * one-of-a-kind
340  */
341 enum
342 {
343 	PNPROC		= 1,
344 	PNGROUP		= 2,
345 };
346 
347 extern	void	_assert(char*);
348 extern	int	abs(int);
349 extern	int	atexit(void(*)(void));
350 extern	void	atexitdont(void(*)(void));
351 extern	int	atnotify(int(*)(void*, char*), int);
352 extern	double	atof(char*);
353 extern	int	atoi(char*);
354 extern	long	atol(char*);
355 extern	vlong	atoll(char*);
356 extern	double	charstod(int(*)(void*), void*);
357 extern	char*	cleanname(char*);
358 extern	int	decrypt(void*, void*, int);
359 extern	int	encrypt(void*, void*, int);
360 extern	int	dec64(uchar*, int, char*, int);
361 extern	int	enc64(char*, int, uchar*, int);
362 extern	int	dec32(uchar*, int, char*, int);
363 extern	int	enc32(char*, int, uchar*, int);
364 extern	int	dec16(uchar*, int, char*, int);
365 extern	int	enc16(char*, int, uchar*, int);
366 extern	int	encodefmt(Fmt*);
367 extern	void	exits(char*);
368 extern	double	frexp(double, int*);
369 extern	uintptr	getcallerpc(void*);
370 extern	char*	getenv(char*);
371 extern	int	getfields(char*, char**, int, int, char*);
372 extern	int	gettokens(char *, char **, int, char *);
373 extern	char*	getuser(void);
374 extern	char*	getwd(char*, int);
375 extern	int	iounit(int);
376 extern	long	labs(long);
377 extern	double	ldexp(double, int);
378 extern	void	longjmp(jmp_buf, int);
379 extern	char*	mktemp(char*);
380 extern	double	modf(double, double*);
381 extern	int	netcrypt(void*, void*);
382 extern	void	notejmp(void*, jmp_buf, int);
383 extern	void	perror(char*);
384 extern	int	postnote(int, int, char *);
385 extern	double	pow10(int);
386 extern	int	putenv(char*, char*);
387 extern	void	qsort(void*, long, long, int (*)(void*, void*));
388 extern	int	setjmp(jmp_buf);
389 extern	double	strtod(char*, char**);
390 extern	long	strtol(char*, char**, int);
391 extern	ulong	strtoul(char*, char**, int);
392 extern	vlong	strtoll(char*, char**, int);
393 extern	uvlong	strtoull(char*, char**, int);
394 extern	void	sysfatal(char*, ...);
395 #pragma	varargck	argpos	sysfatal	1
396 extern	void	syslog(int, char*, char*, ...);
397 #pragma	varargck	argpos	syslog	3
398 extern	long	time(long*);
399 extern	int	tolower(int);
400 extern	int	toupper(int);
401 
402 /*
403  *  profiling
404  */
405 enum {
406 	Profoff,		/* No profiling */
407 	Profuser,		/* Measure user time only (default) */
408 	Profkernel,		/* Measure user + kernel time */
409 	Proftime,		/* Measure total time */
410 	Profsample,		/* Use clock interrupt to sample (default when there is no cycle counter) */
411 }; /* what */
412 extern	void	prof(void (*fn)(void*), void *arg, int entries, int what);
413 
414 /*
415  * atomic
416  */
417 long	ainc(long*);
418 long	adec(long*);
419 int	cas32(u32int*, u32int, u32int);
420 int	casp(void**, void*, void*);
421 int	casl(ulong*, ulong, ulong);
422 
423 /*
424  *  synchronization
425  */
426 typedef
427 struct Lock {
428 	long	key;
429 	long	sem;
430 } Lock;
431 
432 extern int	_tas(int*);
433 
434 extern	void	lock(Lock*);
435 extern	void	unlock(Lock*);
436 extern	int	canlock(Lock*);
437 
438 typedef struct QLp QLp;
439 struct QLp
440 {
441 	int	inuse;
442 	QLp	*next;
443 	char	state;
444 };
445 
446 typedef
447 struct QLock
448 {
449 	Lock	lock;
450 	int	locked;
451 	QLp	*head;
452 	QLp 	*tail;
453 } QLock;
454 
455 extern	void	qlock(QLock*);
456 extern	void	qunlock(QLock*);
457 extern	int	canqlock(QLock*);
458 extern	void	_qlockinit(void* (*)(void*, void*));	/* called only by the thread library */
459 
460 typedef
461 struct RWLock
462 {
463 	Lock	lock;
464 	int	readers;	/* number of readers */
465 	int	writer;		/* number of writers */
466 	QLp	*head;		/* list of waiting processes */
467 	QLp	*tail;
468 } RWLock;
469 
470 extern	void	rlock(RWLock*);
471 extern	void	runlock(RWLock*);
472 extern	int	canrlock(RWLock*);
473 extern	void	wlock(RWLock*);
474 extern	void	wunlock(RWLock*);
475 extern	int	canwlock(RWLock*);
476 
477 typedef
478 struct Rendez
479 {
480 	QLock	*l;
481 	QLp	*head;
482 	QLp	*tail;
483 } Rendez;
484 
485 extern	void	rsleep(Rendez*);	/* unlocks r->l, sleeps, locks r->l again */
486 extern	int	rwakeup(Rendez*);
487 extern	int	rwakeupall(Rendez*);
488 extern	void**	privalloc(void);
489 extern	void	privfree(void**);
490 
491 /*
492  *  network dialing
493  */
494 #define NETPATHLEN 40
495 extern	int	accept(int, char*);
496 extern	int	announce(char*, char*);
497 extern	int	dial(char*, char*, char*, int*);
498 extern	void	setnetmtpt(char*, int, char*);
499 extern	int	hangup(int);
500 extern	int	listen(char*, char*);
501 extern	char*	netmkaddr(char*, char*, char*);
502 extern	int	reject(int, char*, char*);
503 
504 /*
505  *  encryption
506  */
507 extern	int	pushssl(int, char*, char*, char*, int*);
508 extern	int	pushtls(int, char*, char*, int, char*, char*);
509 
510 /*
511  *  network services
512  */
513 typedef struct NetConnInfo NetConnInfo;
514 struct NetConnInfo
515 {
516 	char	*dir;		/* connection directory */
517 	char	*root;		/* network root */
518 	char	*spec;		/* binding spec */
519 	char	*lsys;		/* local system */
520 	char	*lserv;		/* local service */
521 	char	*rsys;		/* remote system */
522 	char	*rserv;		/* remote service */
523 	char	*laddr;		/* local address */
524 	char	*raddr;		/* remote address */
525 };
526 extern	NetConnInfo*	getnetconninfo(char*, int);
527 extern	void		freenetconninfo(NetConnInfo*);
528 
529 /*
530  * system calls
531  *
532  */
533 #define	STATMAX	65535U	/* max length of machine-independent stat structure */
534 #define	DIRMAX	(sizeof(Dir)+STATMAX)	/* max length of Dir structure */
535 #define	ERRMAX	128	/* max length of error string */
536 
537 #define	MORDER	0x0003	/* mask for bits defining order of mounting */
538 #define	MREPL	0x0000	/* mount replaces object */
539 #define	MBEFORE	0x0001	/* mount goes before others in union directory */
540 #define	MAFTER	0x0002	/* mount goes after others in union directory */
541 #define	MCREATE	0x0004	/* permit creation in mounted directory */
542 #define	MCACHE	0x0010	/* cache some data */
543 #define	MMASK	0x0017	/* all bits on */
544 
545 #define	OREAD	0	/* open for read */
546 #define	OWRITE	1	/* write */
547 #define	ORDWR	2	/* read and write */
548 #define	OEXEC	3	/* execute, == read but check execute permission */
549 #define	OTRUNC	16	/* or'ed in (except for exec), truncate file first */
550 #define	OCEXEC	32	/* or'ed in, close on exec */
551 #define	ORCLOSE	64	/* or'ed in, remove on close */
552 #define	OEXCL	0x1000	/* or'ed in, exclusive use (create only) */
553 // #define	OBEHIND	0x2000	/* use write behind for writes [for 9n] */
554 
555 #define	AEXIST	0	/* accessible: exists */
556 #define	AEXEC	1	/* execute access */
557 #define	AWRITE	2	/* write access */
558 #define	AREAD	4	/* read access */
559 
560 /* Segattch */
561 #define	SG_RONLY	0040	/* read only */
562 #define	SG_CEXEC	0100	/* detach on exec */
563 
564 #define	NCONT	0	/* continue after note */
565 #define	NDFLT	1	/* terminate after note */
566 #define	NSAVE	2	/* clear note but hold state */
567 #define	NRSTR	3	/* restore saved state */
568 
569 /* bits in Qid.type */
570 #define QTDIR		0x80		/* type bit for directories */
571 #define QTAPPEND	0x40		/* type bit for append only files */
572 #define QTEXCL		0x20		/* type bit for exclusive use files */
573 #define QTMOUNT		0x10		/* type bit for mounted channel */
574 #define QTAUTH		0x08		/* type bit for authentication file */
575 #define QTTMP		0x04		/* type bit for not-backed-up file */
576 #define QTFILE		0x00		/* plain file */
577 
578 /* bits in Dir.mode */
579 #define DMDIR		0x80000000	/* mode bit for directories */
580 #define DMAPPEND	0x40000000	/* mode bit for append only files */
581 #define DMEXCL		0x20000000	/* mode bit for exclusive use files */
582 #define DMMOUNT		0x10000000	/* mode bit for mounted channel */
583 #define DMAUTH		0x08000000	/* mode bit for authentication file */
584 #define DMTMP		0x04000000	/* mode bit for non-backed-up files */
585 #define DMREAD		0x4		/* mode bit for read permission */
586 #define DMWRITE		0x2		/* mode bit for write permission */
587 #define DMEXEC		0x1		/* mode bit for execute permission */
588 
589 /* rfork */
590 enum
591 {
592 	RFNAMEG		= (1<<0),
593 	RFENVG		= (1<<1),
594 	RFFDG		= (1<<2),
595 	RFNOTEG		= (1<<3),
596 	RFPROC		= (1<<4),
597 	RFMEM		= (1<<5),
598 	RFNOWAIT	= (1<<6),
599 	RFCNAMEG	= (1<<10),
600 	RFCENVG		= (1<<11),
601 	RFCFDG		= (1<<12),
602 	RFREND		= (1<<13),
603 	RFNOMNT		= (1<<14)
604 };
605 
606 typedef
607 struct Qid
608 {
609 	uvlong	path;
610 	ulong	vers;
611 	uchar	type;
612 } Qid;
613 
614 typedef
615 struct Dir {
616 	/* system-modified data */
617 	ushort	type;	/* server type */
618 	uint	dev;	/* server subtype */
619 	/* file data */
620 	Qid	qid;	/* unique id from server */
621 	ulong	mode;	/* permissions */
622 	ulong	atime;	/* last read time */
623 	ulong	mtime;	/* last write time */
624 	vlong	length;	/* file length */
625 	char	*name;	/* last element of path */
626 	char	*uid;	/* owner name */
627 	char	*gid;	/* group name */
628 	char	*muid;	/* last modifier name */
629 } Dir;
630 
631 /* keep /sys/src/ape/lib/ap/plan9/sys9.h in sync with this -rsc */
632 typedef
633 struct Waitmsg
634 {
635 	int	pid;		/* of loved one */
636 	ulong	time[3];	/* of loved one & descendants */
637 	char	*msg;
638 } Waitmsg;
639 
640 typedef
641 struct IOchunk
642 {
643 	void	*addr;
644 	ulong	len;
645 } IOchunk;
646 
647 extern	void	_exits(char*);
648 
649 extern	void	abort(void);
650 extern	int	access(char*, int);
651 extern	long	alarm(ulong);
652 extern	int	await(char*, int);
653 extern	int	bind(char*, char*, int);
654 extern	int	brk(void*);
655 extern	int	chdir(char*);
656 extern	int	close(int);
657 extern	int	create(char*, int, ulong);
658 extern	int	dup(int, int);
659 extern	int	errstr(char*, uint);
660 extern	int	exec(char*, char*[]);
661 extern	int	execl(char*, ...);
662 extern	int	fork(void);
663 extern	int	rfork(int);
664 extern	int	fauth(int, char*);
665 extern	int	fstat(int, uchar*, int);
666 extern	int	fwstat(int, uchar*, int);
667 extern	int	fversion(int, int, char*, int);
668 extern	int	mount(int, int, char*, int, char*);
669 extern	int	unmount(char*, char*);
670 extern	int	noted(int);
671 extern	int	notify(void(*)(void*, char*));
672 extern	int	open(char*, int);
673 extern	int	fd2path(int, char*, int);
674 // extern	int	fdflush(int);
675 extern	int	pipe(int*);
676 extern	long	pread(int, void*, long, vlong);
677 extern	long	preadv(int, IOchunk*, int, vlong);
678 extern	long	pwrite(int, void*, long, vlong);
679 extern	long	pwritev(int, IOchunk*, int, vlong);
680 extern	long	read(int, void*, long);
681 extern	long	readn(int, void*, long);
682 extern	long	readv(int, IOchunk*, int);
683 extern	int	remove(char*);
684 extern	void*	sbrk(ulong);
685 extern	long	oseek(int, long, int);
686 extern	vlong	seek(int, vlong, int);
687 extern	void*	segattach(int, char*, void*, ulong);
688 extern	void*	segbrk(void*, void*);
689 extern	int	segdetach(void*);
690 extern	int	segflush(void*, ulong);
691 extern	int	segfree(void*, ulong);
692 extern	int	semacquire(long*, int);
693 extern	long	semrelease(long*, long);
694 extern	int	sleep(long);
695 extern	int	stat(char*, uchar*, int);
696 extern	int	tsemacquire(long*, ulong);
697 extern	Waitmsg*	wait(void);
698 extern	int	waitpid(void);
699 extern	long	write(int, void*, long);
700 extern	long	writev(int, IOchunk*, int);
701 extern	int	wstat(char*, uchar*, int);
702 extern	void*	rendezvous(void*, void*);
703 
704 extern	Dir*	dirstat(char*);
705 extern	Dir*	dirfstat(int);
706 extern	int	dirwstat(char*, Dir*);
707 extern	int	dirfwstat(int, Dir*);
708 extern	long	dirread(int, Dir**);
709 extern	void	nulldir(Dir*);
710 extern	long	dirreadall(int, Dir**);
711 extern	int	getpid(void);
712 extern	int	getppid(void);
713 extern	void	rerrstr(char*, uint);
714 extern	char*	sysname(void);
715 extern	void	werrstr(char*, ...);
716 #pragma	varargck	argpos	werrstr	1
717 
718 extern char *argv0;
719 #define	ARGBEGIN	for((argv0||(argv0=*argv)),argv++,argc--;\
720 			    argv[0] && argv[0][0]=='-' && argv[0][1];\
721 			    argc--, argv++) {\
722 				char *_args, *_argt;\
723 				Rune _argc;\
724 				_args = &argv[0][1];\
725 				if(_args[0]=='-' && _args[1]==0){\
726 					argc--; argv++; break;\
727 				}\
728 				_argc = 0;\
729 				while(*_args && (_args += chartorune(&_argc, _args)))\
730 				switch(_argc)
731 #define	ARGEND		SET(_argt);USED(_argt,_argc,_args);}USED(argv, argc);
732 #define	ARGF()		(_argt=_args, _args="",\
733 				(*_argt? _argt: argv[1]? (argc--, *++argv): 0))
734 #define	EARGF(x)	(_argt=_args, _args="",\
735 				(*_argt? _argt: argv[1]? (argc--, *++argv): ((x), abort(), (char*)0)))
736 
737 #define	ARGC()		_argc
738 
739 /* this is used by sbrk and brk,  it's a really bad idea to redefine it */
740 extern	char	end[];
741