|  | /* | 
|  | Derived from Inferno include/kern.h and | 
|  | Plan 9 from User Space include/libc.h | 
|  |  | 
|  | http://code.google.com/p/inferno-os/source/browse/include/kern.h | 
|  | http://code.swtch.com/plan9port/src/tip/include/libc.h | 
|  |  | 
|  | Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved. | 
|  | Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).  All rights reserved. | 
|  | Portions Copyright © 2001-2007 Russ Cox.  All rights reserved. | 
|  | Portions Copyright © 2009 The Go Authors.  All rights reserved. | 
|  |  | 
|  | Permission is hereby granted, free of charge, to any person obtaining a copy | 
|  | of this software and associated documentation files (the "Software"), to deal | 
|  | in the Software without restriction, including without limitation the rights | 
|  | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | 
|  | copies of the Software, and to permit persons to whom the Software is | 
|  | furnished to do so, subject to the following conditions: | 
|  |  | 
|  | The above copyright notice and this permission notice shall be included in | 
|  | all copies or substantial portions of the Software. | 
|  |  | 
|  | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | 
|  | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | 
|  | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE | 
|  | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | 
|  | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | 
|  | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | 
|  | THE SOFTWARE. | 
|  | */ | 
|  |  | 
|  | /* | 
|  | * Lib9 is miscellany from the Plan 9 C library that doesn't | 
|  | * fit into libutf or into libfmt, but is still missing from traditional | 
|  | * Unix C libraries. | 
|  | */ | 
|  | #ifndef _LIBC_H_ | 
|  | #define _LIBC_H_ 1 | 
|  | #if defined(__cplusplus) | 
|  | extern "C" { | 
|  | #endif | 
|  |  | 
|  | #include <utf.h> | 
|  | #include <fmt.h> | 
|  |  | 
|  | /* | 
|  | * Begin trimmed down usual libc.h | 
|  | */ | 
|  |  | 
|  | #ifndef nil | 
|  | #define	nil	((void*)0) | 
|  | #endif | 
|  | #define	nelem(x)	(sizeof(x)/sizeof((x)[0])) | 
|  |  | 
|  | #ifndef offsetof | 
|  | #define offsetof(s, m)	(ulong)(&(((s*)0)->m)) | 
|  | #endif | 
|  |  | 
|  | extern	char*	strecpy(char*, char*, char*); | 
|  | extern  int tokenize(char*, char**, int); | 
|  |  | 
|  | extern  double  p9cputime(void); | 
|  | #ifndef NOPLAN9DEFINES | 
|  | #define cputime     p9cputime | 
|  | #endif | 
|  | /* | 
|  | * one-of-a-kind | 
|  | */ | 
|  | enum | 
|  | { | 
|  | PNPROC		= 1, | 
|  | PNGROUP		= 2 | 
|  | }; | 
|  | int isInf(double, int); | 
|  |  | 
|  | extern	int	p9atoi(char*); | 
|  | extern	long	p9atol(char*); | 
|  | extern	vlong	p9atoll(char*); | 
|  | extern	double	fmtcharstod(int(*)(void*), void*); | 
|  | extern	char*	cleanname(char*); | 
|  | extern	int	exitcode(char*); | 
|  | extern	void	exits(char*); | 
|  | extern	double	frexp(double, int*); | 
|  | extern	char*	p9getenv(char*); | 
|  | extern	int	p9putenv(char*, char*); | 
|  | extern	int	getfields(char*, char**, int, int, char*); | 
|  | extern	int	gettokens(char *, char **, int, char *); | 
|  | extern	char*	p9getwd(char*, int); | 
|  | extern	void	p9longjmp(p9jmp_buf, int); | 
|  | extern	void	p9notejmp(void*, p9jmp_buf, int); | 
|  | extern	void	perror(const char*); | 
|  | extern	int	postnote(int, int, char *); | 
|  | extern	double	p9pow10(int); | 
|  | extern	char*	p9ctime(long); | 
|  | #define p9setjmp(b)	sigsetjmp((void*)(b), 1) | 
|  |  | 
|  | extern	void	sysfatal(char*, ...); | 
|  |  | 
|  | #ifndef NOPLAN9DEFINES | 
|  | #define atoi		p9atoi | 
|  | #define atol		p9atol | 
|  | #define atoll		p9atoll | 
|  | #define getenv		p9getenv | 
|  | #define	getwd		p9getwd | 
|  | #define	longjmp		p9longjmp | 
|  | #undef  setjmp | 
|  | #define setjmp		p9setjmp | 
|  | #define putenv		p9putenv | 
|  | #define notejmp		p9notejmp | 
|  | #define jmp_buf		p9jmp_buf | 
|  | #define pow10		p9pow10 | 
|  | #undef  strtod | 
|  | #define strtod		fmtstrtod | 
|  | #define charstod	fmtcharstod | 
|  | #define ctime	p9ctime | 
|  | #endif | 
|  |  | 
|  | /* | 
|  | * system calls | 
|  | * | 
|  | */ | 
|  | #define	STATMAX	65535U	/* max length of machine-independent stat structure */ | 
|  | #define	DIRMAX	(sizeof(Dir)+STATMAX)	/* max length of Dir structure */ | 
|  | #define	ERRMAX	128	/* max length of error string */ | 
|  |  | 
|  | #define	MORDER	0x0003	/* mask for bits defining order of mounting */ | 
|  | #define	MREPL	0x0000	/* mount replaces object */ | 
|  | #define	MBEFORE	0x0001	/* mount goes before others in union directory */ | 
|  | #define	MAFTER	0x0002	/* mount goes after others in union directory */ | 
|  | #define	MCREATE	0x0004	/* permit creation in mounted directory */ | 
|  | #define	MCACHE	0x0010	/* cache some data */ | 
|  | #define	MMASK	0x0017	/* all bits on */ | 
|  |  | 
|  | #define	OREAD	0	/* open for read */ | 
|  | #define	OWRITE	1	/* write */ | 
|  | #define	ORDWR	2	/* read and write */ | 
|  | #define	OEXEC	3	/* execute, == read but check execute permission */ | 
|  | #define	OTRUNC	16	/* or'ed in (except for exec), truncate file first */ | 
|  | #define	ORCLOSE	64	/* or'ed in, remove on close */ | 
|  | #define	ODIRECT	128	/* or'ed in, direct access */ | 
|  | #define	OEXCL	0x1000	/* or'ed in, exclusive use (create only) */ | 
|  | #define	OAPPEND	0x4000	/* or'ed in, append only */ | 
|  |  | 
|  | #define	AEXIST	0	/* accessible: exists */ | 
|  | #define	AEXEC	1	/* execute access */ | 
|  | #define	AWRITE	2	/* write access */ | 
|  | #define	AREAD	4	/* read access */ | 
|  |  | 
|  | /* Segattch */ | 
|  | #define	SG_RONLY	0040	/* read only */ | 
|  | #define	SG_CEXEC	0100	/* detach on exec */ | 
|  |  | 
|  | #define	NCONT	0	/* continue after note */ | 
|  | #define	NDFLT	1	/* terminate after note */ | 
|  | #define	NSAVE	2	/* clear note but hold state */ | 
|  | #define	NRSTR	3	/* restore saved state */ | 
|  |  | 
|  | /* bits in Qid.type */ | 
|  | #define QTDIR		0x80		/* type bit for directories */ | 
|  | #define QTAPPEND	0x40		/* type bit for append only files */ | 
|  | #define QTEXCL		0x20		/* type bit for exclusive use files */ | 
|  | #define QTMOUNT		0x10		/* type bit for mounted channel */ | 
|  | #define QTAUTH		0x08		/* type bit for authentication file */ | 
|  | #define QTTMP		0x04		/* type bit for non-backed-up file */ | 
|  | #define QTSYMLINK	0x02		/* type bit for symbolic link */ | 
|  | #define QTFILE		0x00		/* type bits for plain file */ | 
|  |  | 
|  | /* bits in Dir.mode */ | 
|  | #define DMDIR		0x80000000	/* mode bit for directories */ | 
|  | #define DMAPPEND	0x40000000	/* mode bit for append only files */ | 
|  | #define DMEXCL		0x20000000	/* mode bit for exclusive use files */ | 
|  | #define DMMOUNT		0x10000000	/* mode bit for mounted channel */ | 
|  | #define DMAUTH		0x08000000	/* mode bit for authentication file */ | 
|  | #define DMTMP		0x04000000	/* mode bit for non-backed-up file */ | 
|  | #define DMSYMLINK	0x02000000	/* mode bit for symbolic link (Unix, 9P2000.u) */ | 
|  | #define DMDEVICE	0x00800000	/* mode bit for device file (Unix, 9P2000.u) */ | 
|  | #define DMNAMEDPIPE	0x00200000	/* mode bit for named pipe (Unix, 9P2000.u) */ | 
|  | #define DMSOCKET	0x00100000	/* mode bit for socket (Unix, 9P2000.u) */ | 
|  | #define DMSETUID	0x00080000	/* mode bit for setuid (Unix, 9P2000.u) */ | 
|  | #define DMSETGID	0x00040000	/* mode bit for setgid (Unix, 9P2000.u) */ | 
|  |  | 
|  | #define DMREAD		0x4		/* mode bit for read permission */ | 
|  | #define DMWRITE		0x2		/* mode bit for write permission */ | 
|  | #define DMEXEC		0x1		/* mode bit for execute permission */ | 
|  |  | 
|  | #ifdef RFMEM	/* FreeBSD, OpenBSD, NetBSD */ | 
|  | #undef RFFDG | 
|  | #undef RFNOTEG | 
|  | #undef RFPROC | 
|  | #undef RFMEM | 
|  | #undef RFNOWAIT | 
|  | #undef RFCFDG | 
|  | #undef RFNAMEG | 
|  | #undef RFENVG | 
|  | #undef RFCENVG | 
|  | #undef RFCFDG | 
|  | #undef RFCNAMEG | 
|  | #endif | 
|  |  | 
|  | enum | 
|  | { | 
|  | RFNAMEG		= (1<<0), | 
|  | RFENVG		= (1<<1), | 
|  | RFFDG		= (1<<2), | 
|  | RFNOTEG		= (1<<3), | 
|  | RFPROC		= (1<<4), | 
|  | RFMEM		= (1<<5), | 
|  | RFNOWAIT	= (1<<6), | 
|  | RFCNAMEG	= (1<<10), | 
|  | RFCENVG		= (1<<11), | 
|  | RFCFDG		= (1<<12) | 
|  | /*	RFREND		= (1<<13), */ | 
|  | /*	RFNOMNT		= (1<<14) */ | 
|  | }; | 
|  |  | 
|  | typedef | 
|  | struct Qid | 
|  | { | 
|  | uvlong	path; | 
|  | ulong	vers; | 
|  | uchar	type; | 
|  | } Qid; | 
|  |  | 
|  | typedef | 
|  | struct Dir { | 
|  | /* system-modified data */ | 
|  | ushort	type;	/* server type */ | 
|  | uint	dev;	/* server subtype */ | 
|  | /* file data */ | 
|  | Qid	qid;	/* unique id from server */ | 
|  | ulong	mode;	/* permissions */ | 
|  | ulong	atime;	/* last read time */ | 
|  | ulong	mtime;	/* last write time */ | 
|  | vlong	length;	/* file length */ | 
|  | char	*name;	/* last element of path */ | 
|  | char	*uid;	/* owner name */ | 
|  | char	*gid;	/* group name */ | 
|  | char	*muid;	/* last modifier name */ | 
|  |  | 
|  | /* 9P2000.u extensions */ | 
|  | uint	uidnum;		/* numeric uid */ | 
|  | uint	gidnum;		/* numeric gid */ | 
|  | uint	muidnum;	/* numeric muid */ | 
|  | char	*ext;		/* extended info */ | 
|  | } Dir; | 
|  |  | 
|  | typedef | 
|  | struct Waitmsg | 
|  | { | 
|  | int pid;	/* of loved one */ | 
|  | ulong time[3];	/* of loved one & descendants */ | 
|  | char	*msg; | 
|  | } Waitmsg; | 
|  |  | 
|  | extern	void	_exits(char*); | 
|  |  | 
|  | extern	void	abort(void); | 
|  | extern	long	p9alarm(ulong); | 
|  | extern	int	await(char*, int); | 
|  | extern	int	awaitfor(int, char*, int); | 
|  | extern	int	awaitnohang(char*, int); | 
|  | extern	int	p9chdir(char*); | 
|  | extern	int	close(int); | 
|  | extern	int	p9create(char*, int, ulong); | 
|  | extern	int	p9dup(int, int); | 
|  | extern	int	errstr(char*, uint); | 
|  | extern	int	p9exec(char*, char*[]); | 
|  | extern	int	p9execl(char*, ...); | 
|  | extern	int	p9rfork(int); | 
|  | extern	int	noted(int); | 
|  | extern	int	notify(void(*)(void*, char*)); | 
|  | extern	int	noteenable(char*); | 
|  | extern	int	notedisable(char*); | 
|  | extern	int	notifyon(char*); | 
|  | extern	int	notifyoff(char*); | 
|  | extern	int	p9open(char*, int); | 
|  | extern	int	fd2path(int, char*, int); | 
|  | extern	long	readn(int, void*, long); | 
|  | extern	int	remove(const char*); | 
|  | extern	vlong	p9seek(int, vlong, int); | 
|  | extern	int	p9sleep(long); | 
|  | extern	Waitmsg*	p9wait(void); | 
|  | extern	Waitmsg*	p9waitfor(int); | 
|  | extern	Waitmsg*	waitnohang(void); | 
|  | extern	int	p9waitpid(void); | 
|  | extern	ulong	rendezvous(ulong, ulong); | 
|  |  | 
|  | extern	char*	getgoos(void); | 
|  | extern	char*	getgoarch(void); | 
|  | extern	char*	getgoroot(void); | 
|  | extern	char*	getgoversion(void); | 
|  | extern	char*	getgoarm(void); | 
|  | extern	char*	getgo386(void); | 
|  | extern	char*	getgoextlinkenabled(void); | 
|  |  | 
|  | extern	char*	mktempdir(void); | 
|  | extern	void	removeall(char*); | 
|  | extern	int	runcmd(char**); | 
|  |  | 
|  | extern	void	flagcount(char*, char*, int*); | 
|  | extern	void	flagint32(char*, char*, int32*); | 
|  | extern	void	flagint64(char*, char*, int64*); | 
|  | extern	void	flagstr(char*, char*, char**); | 
|  | extern	void	flagparse(int*, char***, void (*usage)(void)); | 
|  | extern	void	flagfn0(char*, char*, void(*fn)(void)); | 
|  | extern	void	flagfn1(char*, char*, void(*fn)(char*)); | 
|  | extern	void	flagfn2(char*, char*, void(*fn)(char*, char*)); | 
|  | extern	void	flagprint(int); | 
|  |  | 
|  | #ifdef _WIN32 | 
|  |  | 
|  | #if !defined(_WIN64) && !defined(__MINGW64_VERSION_MAJOR) | 
|  | struct timespec { | 
|  | int tv_sec; | 
|  | long tv_nsec; | 
|  | }; | 
|  | #define execv(prog, argv) execv(prog, (const char* const*)(argv)) | 
|  | #define execvp(prog, argv) execvp(prog, (const char**)(argv)) | 
|  | #endif | 
|  |  | 
|  | extern int nanosleep(const struct timespec *rqtp, struct timespec *rmtp); | 
|  | extern int fork(void); | 
|  | extern int pread(int fd, void *buf, int n, int off); | 
|  | extern int pwrite(int fd, void *buf, int n, int off); | 
|  | #undef  getwd | 
|  | #define getwd(s, ns) getcwd(s, ns) | 
|  | #undef  lseek | 
|  | #define lseek(fd, n, base) _lseeki64(fd, n, base) | 
|  | #define mkdir(path, perm) mkdir(path) | 
|  | #define pipe(fd) _pipe(fd, 512, O_BINARY) | 
|  | #else | 
|  | #define O_BINARY 0 | 
|  | #endif | 
|  |  | 
|  | #ifndef NOPLAN9DEFINES | 
|  | #define alarm		p9alarm | 
|  | #define	dup		p9dup | 
|  | #define	exec		p9exec | 
|  | #define	execl	p9execl | 
|  | #define	seek		p9seek | 
|  | #define sleep		p9sleep | 
|  | #define wait		p9wait | 
|  | #define waitpid		p9waitpid | 
|  | #define rfork		p9rfork | 
|  | #define create		p9create | 
|  | #undef open | 
|  | #define open		p9open | 
|  | #define	waitfor		p9waitfor | 
|  | #endif | 
|  |  | 
|  | extern	Dir*	dirstat(char*); | 
|  | extern	Dir*	dirfstat(int); | 
|  | extern	int	dirwstat(char*, Dir*); | 
|  | extern	int	dirfwstat(int, Dir*); | 
|  | extern	void	nulldir(Dir*); | 
|  | extern	long	dirreadall(int, Dir**); | 
|  | extern	void	rerrstr(char*, uint); | 
|  | extern	char*	sysname(void); | 
|  | extern	void	werrstr(char*, ...); | 
|  | extern	char*	getns(void); | 
|  | extern	char*	get9root(void); | 
|  | extern	char*	unsharp(char*); | 
|  |  | 
|  | /* external names that we don't want to step on */ | 
|  | #ifndef NOPLAN9DEFINES | 
|  | #define main	p9main | 
|  | #endif | 
|  |  | 
|  | /* compiler directives on plan 9 */ | 
|  | #define	SET(x)	((x)=0) | 
|  | #define	USED(x)	if(x){}else{} | 
|  | #ifdef __GNUC__ | 
|  | #	if __GNUC__ >= 3 | 
|  | #		undef USED | 
|  | #		define USED(x) ((void)(x)) | 
|  | #	endif | 
|  | #endif | 
|  |  | 
|  | /* command line */ | 
|  | extern char	*argv0; | 
|  | extern void __fixargv0(void); | 
|  | #define	ARGBEGIN	for((void)(argv0?0:(argv0=(__fixargv0(),*argv))),argv++,argc--;\ | 
|  | argv[0] && argv[0][0]=='-' && argv[0][1];\ | 
|  | argc--, argv++) {\ | 
|  | char *_args, *_argt;\ | 
|  | Rune _argc;\ | 
|  | _args = &argv[0][1];\ | 
|  | if(_args[0]=='-' && _args[1]==0){\ | 
|  | argc--; argv++; break;\ | 
|  | }\ | 
|  | _argc = 0;\ | 
|  | while(*_args && (_args += chartorune(&_argc, _args)))\ | 
|  | switch(_argc) | 
|  | #define	ARGEND		SET(_argt);USED(_argt);USED(_argc);USED(_args);}USED(argv);USED(argc); | 
|  | #define	ARGF()		(_argt=_args, _args="",\ | 
|  | (*_argt? _argt: argv[1]? (argc--, *++argv): 0)) | 
|  | #define	EARGF(x)	(_argt=_args, _args="",\ | 
|  | (*_argt? _argt: argv[1]? (argc--, *++argv): ((x), abort(), (char*)0))) | 
|  |  | 
|  | #define	ARGC()		_argc | 
|  |  | 
|  | #if defined(__cplusplus) | 
|  | } | 
|  | #endif | 
|  | #endif	/* _LIB9_H_ */ |