blob: f9ad963345a577b98cfe6fb789e0ec1af1bdaebc [file] [log] [blame]
Rob Pike69b74c32008-06-12 13:26:16 -07001/*
2Derived from Inferno include/kern.h and
3Plan 9 from User Space include/libc.h
4
5http://code.google.com/p/inferno-os/source/browse/include/kern.h
6http://code.swtch.com/plan9port/src/tip/include/libc.h
7
8 Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
9 Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com). All rights reserved.
10 Portions Copyright © 2001-2007 Russ Cox. All rights reserved.
11 Portions Copyright © 2009 The Go Authors. All rights reserved.
12
13Permission is hereby granted, free of charge, to any person obtaining a copy
14of this software and associated documentation files (the "Software"), to deal
15in the Software without restriction, including without limitation the rights
16to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17copies of the Software, and to permit persons to whom the Software is
18furnished to do so, subject to the following conditions:
19
20The above copyright notice and this permission notice shall be included in
21all copies or substantial portions of the Software.
22
23THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
29THE SOFTWARE.
30*/
31
32/*
33 * Lib9 is miscellany from the Plan 9 C library that doesn't
34 * fit into libutf or into libfmt, but is still missing from traditional
35 * Unix C libraries.
36 */
37#ifndef _LIBC_H_
38#define _LIBC_H_ 1
39#if defined(__cplusplus)
40extern "C" {
41#endif
42
43#include <utf.h>
44#include <fmt.h>
45
46/*
47 * Begin trimmed down usual libc.h
48 */
49
50#ifndef nil
51#define nil ((void*)0)
52#endif
53#define nelem(x) (sizeof(x)/sizeof((x)[0]))
54
55#ifndef offsetof
56#define offsetof(s, m) (ulong)(&(((s*)0)->m))
57#endif
58
59extern char* strecpy(char*, char*, char*);
60extern int tokenize(char*, char**, int);
61
62extern double p9cputime(void);
63#ifndef NOPLAN9DEFINES
64#define cputime p9cputime
65#endif
66/*
67 * one-of-a-kind
68 */
69enum
70{
71 PNPROC = 1,
72 PNGROUP = 2
73};
74int isInf(double, int);
75
76extern int p9atoi(char*);
77extern long p9atol(char*);
78extern vlong p9atoll(char*);
79extern double fmtcharstod(int(*)(void*), void*);
80extern char* cleanname(char*);
81extern int exitcode(char*);
82extern void exits(char*);
83extern double frexp(double, int*);
84extern char* p9getenv(char*);
85extern int p9putenv(char*, char*);
86extern int getfields(char*, char**, int, int, char*);
87extern int gettokens(char *, char **, int, char *);
88extern char* getuser(void);
89extern char* p9getwd(char*, int);
90extern void p9longjmp(p9jmp_buf, int);
91extern char* mktemp(char*);
92extern int opentemp(char*);
93extern void p9notejmp(void*, p9jmp_buf, int);
94extern void perror(const char*);
95extern int postnote(int, int, char *);
96extern double p9pow10(int);
97extern char* searchpath(char*);
98#define p9setjmp(b) sigsetjmp((void*)(b), 1)
99
100extern void sysfatal(char*, ...);
101
102#ifndef NOPLAN9DEFINES
103#define atoi p9atoi
104#define atol p9atol
105#define atoll p9atoll
106#define getenv p9getenv
107#define getwd p9getwd
108#define longjmp p9longjmp
109#undef setjmp
110#define setjmp p9setjmp
111#define putenv p9putenv
112#define notejmp p9notejmp
113#define jmp_buf p9jmp_buf
114#define pow10 p9pow10
Hector Chu1d6ae532011-08-29 16:17:08 +1000115#undef strtod
Rob Pike69b74c32008-06-12 13:26:16 -0700116#define strtod fmtstrtod
117#define charstod fmtcharstod
118#endif
119
120/*
121 * system calls
122 *
123 */
124#define STATMAX 65535U /* max length of machine-independent stat structure */
125#define DIRMAX (sizeof(Dir)+STATMAX) /* max length of Dir structure */
126#define ERRMAX 128 /* max length of error string */
127
128#define MORDER 0x0003 /* mask for bits defining order of mounting */
129#define MREPL 0x0000 /* mount replaces object */
130#define MBEFORE 0x0001 /* mount goes before others in union directory */
131#define MAFTER 0x0002 /* mount goes after others in union directory */
132#define MCREATE 0x0004 /* permit creation in mounted directory */
133#define MCACHE 0x0010 /* cache some data */
134#define MMASK 0x0017 /* all bits on */
135
136#define OREAD 0 /* open for read */
137#define OWRITE 1 /* write */
138#define ORDWR 2 /* read and write */
139#define OEXEC 3 /* execute, == read but check execute permission */
140#define OTRUNC 16 /* or'ed in (except for exec), truncate file first */
Rob Pike69b74c32008-06-12 13:26:16 -0700141#define ORCLOSE 64 /* or'ed in, remove on close */
142#define ODIRECT 128 /* or'ed in, direct access */
Rob Pike69b74c32008-06-12 13:26:16 -0700143#define OEXCL 0x1000 /* or'ed in, exclusive use (create only) */
Rob Pike69b74c32008-06-12 13:26:16 -0700144#define OAPPEND 0x4000 /* or'ed in, append only */
145
146#define AEXIST 0 /* accessible: exists */
147#define AEXEC 1 /* execute access */
148#define AWRITE 2 /* write access */
149#define AREAD 4 /* read access */
150
151/* Segattch */
152#define SG_RONLY 0040 /* read only */
153#define SG_CEXEC 0100 /* detach on exec */
154
155#define NCONT 0 /* continue after note */
156#define NDFLT 1 /* terminate after note */
157#define NSAVE 2 /* clear note but hold state */
158#define NRSTR 3 /* restore saved state */
159
160/* bits in Qid.type */
161#define QTDIR 0x80 /* type bit for directories */
162#define QTAPPEND 0x40 /* type bit for append only files */
163#define QTEXCL 0x20 /* type bit for exclusive use files */
164#define QTMOUNT 0x10 /* type bit for mounted channel */
165#define QTAUTH 0x08 /* type bit for authentication file */
166#define QTTMP 0x04 /* type bit for non-backed-up file */
167#define QTSYMLINK 0x02 /* type bit for symbolic link */
168#define QTFILE 0x00 /* type bits for plain file */
169
170/* bits in Dir.mode */
171#define DMDIR 0x80000000 /* mode bit for directories */
172#define DMAPPEND 0x40000000 /* mode bit for append only files */
173#define DMEXCL 0x20000000 /* mode bit for exclusive use files */
174#define DMMOUNT 0x10000000 /* mode bit for mounted channel */
175#define DMAUTH 0x08000000 /* mode bit for authentication file */
176#define DMTMP 0x04000000 /* mode bit for non-backed-up file */
177#define DMSYMLINK 0x02000000 /* mode bit for symbolic link (Unix, 9P2000.u) */
178#define DMDEVICE 0x00800000 /* mode bit for device file (Unix, 9P2000.u) */
179#define DMNAMEDPIPE 0x00200000 /* mode bit for named pipe (Unix, 9P2000.u) */
180#define DMSOCKET 0x00100000 /* mode bit for socket (Unix, 9P2000.u) */
181#define DMSETUID 0x00080000 /* mode bit for setuid (Unix, 9P2000.u) */
182#define DMSETGID 0x00040000 /* mode bit for setgid (Unix, 9P2000.u) */
183
184#define DMREAD 0x4 /* mode bit for read permission */
185#define DMWRITE 0x2 /* mode bit for write permission */
186#define DMEXEC 0x1 /* mode bit for execute permission */
187
188#ifdef RFMEM /* FreeBSD, OpenBSD */
189#undef RFFDG
190#undef RFNOTEG
191#undef RFPROC
192#undef RFMEM
193#undef RFNOWAIT
194#undef RFCFDG
195#undef RFNAMEG
196#undef RFENVG
197#undef RFCENVG
198#undef RFCFDG
199#undef RFCNAMEG
200#endif
201
202enum
203{
204 RFNAMEG = (1<<0),
205 RFENVG = (1<<1),
206 RFFDG = (1<<2),
207 RFNOTEG = (1<<3),
208 RFPROC = (1<<4),
209 RFMEM = (1<<5),
210 RFNOWAIT = (1<<6),
211 RFCNAMEG = (1<<10),
212 RFCENVG = (1<<11),
213 RFCFDG = (1<<12)
214/* RFREND = (1<<13), */
215/* RFNOMNT = (1<<14) */
216};
217
218typedef
219struct Qid
220{
221 uvlong path;
222 ulong vers;
223 uchar type;
224} Qid;
225
226typedef
227struct Dir {
228 /* system-modified data */
229 ushort type; /* server type */
230 uint dev; /* server subtype */
231 /* file data */
232 Qid qid; /* unique id from server */
233 ulong mode; /* permissions */
234 ulong atime; /* last read time */
235 ulong mtime; /* last write time */
236 vlong length; /* file length */
237 char *name; /* last element of path */
238 char *uid; /* owner name */
239 char *gid; /* group name */
240 char *muid; /* last modifier name */
241
242 /* 9P2000.u extensions */
243 uint uidnum; /* numeric uid */
244 uint gidnum; /* numeric gid */
245 uint muidnum; /* numeric muid */
246 char *ext; /* extended info */
247} Dir;
248
249typedef
250struct Waitmsg
251{
252 int pid; /* of loved one */
253 ulong time[3]; /* of loved one & descendants */
254 char *msg;
255} Waitmsg;
256
257extern void _exits(char*);
258
259extern void abort(void);
260extern long p9alarm(ulong);
261extern int await(char*, int);
262extern int awaitfor(int, char*, int);
263extern int awaitnohang(char*, int);
264extern int p9chdir(char*);
265extern int close(int);
266extern int p9create(char*, int, ulong);
267extern int p9dup(int, int);
268extern int errstr(char*, uint);
269extern int p9exec(char*, char*[]);
270extern int p9execl(char*, ...);
271extern int p9rfork(int);
272extern int noted(int);
273extern int notify(void(*)(void*, char*));
274extern int noteenable(char*);
275extern int notedisable(char*);
276extern int notifyon(char*);
277extern int notifyoff(char*);
278extern int p9open(char*, int);
279extern int fd2path(int, char*, int);
Rob Pike69b74c32008-06-12 13:26:16 -0700280extern long readn(int, void*, long);
281extern int remove(const char*);
282extern vlong p9seek(int, vlong, int);
283extern int p9sleep(long);
284extern Waitmsg* p9wait(void);
285extern Waitmsg* p9waitfor(int);
286extern Waitmsg* waitnohang(void);
287extern int p9waitpid(void);
288extern ulong rendezvous(ulong, ulong);
289
Russ Cox38430212010-01-19 09:08:05 -0800290extern char* getgoos(void);
291extern char* getgoarch(void);
292extern char* getgoroot(void);
Dean Prichard49c42562010-02-08 11:53:27 -0800293extern char* getgoversion(void);
Russ Cox38430212010-01-19 09:08:05 -0800294
Joe Poirierbf3f7682011-02-08 15:42:52 -0500295#ifdef _WIN32
Wei Guangjingee14fbd2011-07-25 13:39:01 -0400296
297#ifndef _WIN64
Joe Poirierb57ffae2010-07-30 11:47:11 +1000298struct timespec {
299 int tv_sec;
300 long tv_nsec;
301};
Wei Guangjingee14fbd2011-07-25 13:39:01 -0400302#define execv(prog, argv) execv(prog, (const char* const*)(argv))
303#define execvp(prog, argv) execvp(prog, (const char**)(argv))
304#endif
305
Joe Poirierb57ffae2010-07-30 11:47:11 +1000306extern int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
307extern int fork(void);
Hector Chucd9d72b2009-11-30 11:53:11 -0800308extern int pread(int fd, void *buf, int n, int off);
309extern int pwrite(int fd, void *buf, int n, int off);
Hector Chuaed2c062011-09-07 15:49:56 -0400310#undef getwd
311#define getwd(s, ns) getcwd(s, ns)
Hector Chu1d6ae532011-08-29 16:17:08 +1000312#undef lseek
Hector Chucd9d72b2009-11-30 11:53:11 -0800313#define lseek(fd, n, base) _lseeki64(fd, n, base)
314#define mkdir(path, perm) mkdir(path)
315#define pipe(fd) _pipe(fd, 512, O_BINARY)
316#else
317#define O_BINARY 0
318#endif
319
Rob Pike69b74c32008-06-12 13:26:16 -0700320#ifndef NOPLAN9DEFINES
321#define alarm p9alarm
322#define dup p9dup
323#define exec p9exec
324#define execl p9execl
325#define seek p9seek
326#define sleep p9sleep
327#define wait p9wait
328#define waitpid p9waitpid
329#define rfork p9rfork
330#define create p9create
331#undef open
332#define open p9open
Rob Pike69b74c32008-06-12 13:26:16 -0700333#define waitfor p9waitfor
334#endif
335
336extern Dir* dirstat(char*);
337extern Dir* dirfstat(int);
338extern int dirwstat(char*, Dir*);
339extern int dirfwstat(int, Dir*);
340extern void nulldir(Dir*);
341extern long dirreadall(int, Dir**);
342extern void rerrstr(char*, uint);
343extern char* sysname(void);
344extern void werrstr(char*, ...);
345extern char* getns(void);
346extern char* get9root(void);
347extern char* unsharp(char*);
348
349/* external names that we don't want to step on */
350#ifndef NOPLAN9DEFINES
351#define main p9main
352#endif
353
354/* compiler directives on plan 9 */
355#define SET(x) ((x)=0)
356#define USED(x) if(x){}else{}
357#ifdef __GNUC__
358# if __GNUC__ >= 3
359# undef USED
360# define USED(x) ((void)(x))
361# endif
362#endif
363
364/* command line */
365extern char *argv0;
366extern void __fixargv0(void);
367#define ARGBEGIN for((argv0?0:(argv0=(__fixargv0(),*argv))),argv++,argc--;\
368 argv[0] && argv[0][0]=='-' && argv[0][1];\
369 argc--, argv++) {\
370 char *_args, *_argt;\
371 Rune _argc;\
372 _args = &argv[0][1];\
373 if(_args[0]=='-' && _args[1]==0){\
374 argc--; argv++; break;\
375 }\
376 _argc = 0;\
377 while(*_args && (_args += chartorune(&_argc, _args)))\
378 switch(_argc)
379#define ARGEND SET(_argt);USED(_argt);USED(_argc);USED(_args);}USED(argv);USED(argc);
380#define ARGF() (_argt=_args, _args="",\
381 (*_argt? _argt: argv[1]? (argc--, *++argv): 0))
382#define EARGF(x) (_argt=_args, _args="",\
383 (*_argt? _argt: argv[1]? (argc--, *++argv): ((x), abort(), (char*)0)))
384
385#define ARGC() _argc
386
387#if defined(__cplusplus)
388}
389#endif
390#endif /* _LIB9_H_ */