Blob


1 /*
2 * Lib9 is miscellany from the Plan 9 C library that doesn't
3 * fit into libutf or into libfmt, but is still missing from traditional
4 * Unix C libraries.
5 */
6 #ifndef _LIB9H_
7 #define _LIB9H_ 1
9 #if defined(__cplusplus)
10 extern "C" {
11 #endif
14 #include <unistd.h>
15 #include <string.h>
16 #include <stdlib.h>
17 #include <stdarg.h>
18 #include <fcntl.h>
19 #include <assert.h>
20 #include <setjmp.h>
22 #ifndef _FMTH_
23 # include <fmt.h>
24 #endif
26 #define nil ((void*)0)
27 #define nelem(x) (sizeof(x)/sizeof((x)[0]))
29 #define _NEEDUCHAR 1
30 #define _NEEDUSHORT 1
31 #define _NEEDUINT 1
32 #define _NEEDULONG 1
34 #if defined(__linux__)
35 # include <sys/types.h>
36 # if defined(__USE_MISC)
37 # undef _NEEDUSHORT
38 # undef _NEEDUINT
39 # undef _NEEDULONG
40 # endif
41 #endif
42 #if defined(__FreeBSD__)
43 # include <sys/types.h>
44 # if !defined(_POSIX_SOURCE)
45 # undef _NEEDUSHORT
46 # undef _NEEDUINT
47 # endif
48 #endif
49 #if defined(__APPLE__)
50 # include <sys/types.h>
51 # undef _NEEDUSHORT
52 # undef _NEEDUINT
53 #endif
55 typedef signed char schar;
56 typedef unsigned int u32int;
57 #ifdef _NEEDUCHAR
58 typedef unsigned char uchar;
59 #endif
60 #ifdef _NEEDUSHORT
61 typedef unsigned short ushort;
62 #endif
63 #ifdef _NEEDUINT
64 typedef unsigned int uint;
65 #endif
66 #ifdef _NEEDULONG
67 typedef unsigned long ulong;
68 #endif
69 typedef unsigned long long uvlong;
70 typedef long long vlong;
72 #define NAMELEN 28
73 #define CHDIR 0x80000000 /* mode bit for directories */
74 #define CHAPPEND 0x40000000 /* mode bit for append only files */
75 #define CHEXCL 0x20000000 /* mode bit for exclusive use files */
76 #define CHMOUNT 0x10000000 /* mode bit for mounted channel */
77 #define CHREAD 0x4 /* mode bit for read permission */
78 #define CHWRITE 0x2 /* mode bit for write permission */
79 #define CHEXEC 0x1 /* mode bit for execute permission */
81 /* rfork to create new process running fn(arg) */
83 #if defined(__FreeBSD__)
84 #undef RFFDG
85 #undef RFNOTEG
86 #undef RFPROC
87 #undef RFMEM
88 #undef RFNOWAIT
89 #undef RFCFDG
90 #endif
92 enum
93 {
94 /* RFNAMEG = (1<<0), */
95 /* RFENVG = (1<<1), */
96 RFFDG = (1<<2),
97 RFNOTEG = (1<<3),
98 RFPROC = (1<<4),
99 RFMEM = (1<<5),
100 RFNOWAIT = (1<<6),
101 /* RFCNAMEG = (1<<10), */
102 /* RFCENVG = (1<<11), */
103 RFCFDG = (1<<12),
104 /* RFREND = (1<<13), */
105 /* RFNOMNT = (1<<14) */
106 };
107 extern int ffork(int, void(*)(void*), void*);
109 /* wait for processes */
110 #define wait _p9wait
111 typedef struct Waitmsg Waitmsg;
112 struct Waitmsg
114 int pid; /* of loved one */
115 ulong time[3]; /* of loved one & descendants */
116 char *msg;
117 };
118 extern int await(char*, int);
119 extern Waitmsg* wait(void);
121 /* synchronization */
122 typedef struct Lock Lock;
123 struct Lock
125 int val;
126 };
128 extern int _tas(void*);
129 extern void lock(Lock*);
130 extern void unlock(Lock*);
131 extern int canlock(Lock*);
133 typedef struct QLp QLp;
134 struct QLp
136 int inuse;
137 QLp *next;
138 int state;
139 };
141 typedef struct QLock QLock;
142 struct QLock
144 Lock lock;
145 int locked;
146 QLp *head;
147 QLp *tail;
148 };
150 extern void qlock(QLock*);
151 extern void qunlock(QLock*);
152 extern int canqlock(QLock*);
153 extern void _qlockinit(ulong (*)(ulong, ulong));
155 typedef struct RWLock RWLock;
156 struct RWLock
158 Lock lock;
159 int readers;
160 int writer;
161 QLp *head;
162 QLp *tail;
163 };
165 extern void rlock(RWLock*);
166 extern void runlock(RWLock*);
167 extern int canrlock(RWLock*);
168 extern void wlock(RWLock*);
169 extern void wunlock(RWLock*);
170 extern int canwlock(RWLock*);
172 typedef struct Rendez Rendez;
173 struct Rendez
175 QLock *l;
176 QLp *head;
177 QLp *tail;
178 };
180 extern void rsleep(Rendez*);
181 extern int rwakeup(Rendez*);
182 extern int rwakeupall(Rendez*);
184 extern ulong rendezvous(ulong, ulong);
186 typedef struct Qid Qid;
187 typedef struct Dir Dir;
189 struct Qid
191 ulong path;
192 ulong vers;
193 };
195 struct Dir
197 char name[NAMELEN];
198 char uid[NAMELEN];
199 char gid[NAMELEN];
200 Qid qid;
201 ulong mode;
202 long atime;
203 long mtime;
204 vlong length;
205 ushort type;
206 ushort dev;
207 };
209 extern int dirstat(char*, Dir*);
210 extern int dirfstat(int, Dir*);
211 extern int dirwstat(char*, Dir*);
212 extern int dirfwstat(int, Dir*);
215 /* one of a kind */
216 extern void sysfatal(char*, ...);
217 extern int nrand(int);
218 extern long lrand(void);
219 extern void setmalloctag(void*, ulong);
220 extern void setrealloctag(void*, ulong);
221 extern void *mallocz(ulong, int);
222 extern long readn(int, void*, long);
223 extern void exits(char*);
224 extern void _exits(char*);
225 extern ulong getcallerpc(void*);
226 extern char* cleanname(char*);
228 /* string routines */
229 extern char* strecpy(char*, char*, char*);
230 extern int tokenize(char*, char**, int);
231 extern int cistrncmp(char*, char*, int);
232 extern int cistrcmp(char*, char*);
233 extern char* cistrstr(char*, char*);
234 extern int getfields(char*, char**, int, int, char*);
235 extern int gettokens(char *, char **, int, char *);
237 /* formatting helpers */
238 extern int dec64(uchar*, int, char*, int);
239 extern int enc64(char*, int, uchar*, int);
240 extern int dec32(uchar*, int, char*, int);
241 extern int enc32(char*, int, uchar*, int);
242 extern int dec16(uchar*, int, char*, int);
243 extern int enc16(char*, int, uchar*, int);
244 extern int encodefmt(Fmt*);
246 /* error string */
247 enum
249 ERRMAX = 128
250 };
251 extern void rerrstr(char*, uint);
252 extern void werrstr(char*, ...);
253 extern int errstr(char*, uint);
255 /* compiler directives on plan 9 */
256 #define USED(x) if(x){}else{}
257 #define SET(x) ((x)=0)
259 /* command line */
260 extern char *argv0;
261 extern void __fixargv0(void);
262 #define ARGBEGIN for((argv0||(argv0=(__fixargv0(),*argv))),argv++,argc--;\
263 argv[0] && argv[0][0]=='-' && argv[0][1];\
264 argc--, argv++) {\
265 char *_args, *_argt;\
266 Rune _argc;\
267 _args = &argv[0][1];\
268 if(_args[0]=='-' && _args[1]==0){\
269 argc--; argv++; break;\
270 }\
271 _argc = 0;\
272 while(*_args && (_args += chartorune(&_argc, _args)))\
273 switch(_argc)
274 #define ARGEND SET(_argt);USED(_argt);USED(_argc);USED(_args);}USED(argv);USED(argc);
275 #define ARGF() (_argt=_args, _args="",\
276 (*_argt? _argt: argv[1]? (argc--, *++argv): 0))
277 #define EARGF(x) (_argt=_args, _args="",\
278 (*_argt? _argt: argv[1]? (argc--, *++argv): ((x), abort(), (char*)0)))
280 #define ARGC() _argc
282 #define OREAD O_RDONLY
283 #define OWRITE O_WRONLY
284 #define ORDWR O_RDWR
285 #define AEXIST 0
286 #define AREAD 4
287 #define AWRITE 2
288 #define AEXEC 1
289 #define ORCLOSE 8
290 #define OCEXEC 16
292 #define dup dup2
293 #define exec execv
294 #define seek lseek
295 #define getwd getcwd
297 #if defined(__cplusplus)
299 #endif
301 #endif /* _LIB9H_ */