1 /* define _BSD_SOURCE to use ISO C, POSIX, and 4.3BSD things. */
2 #define USE_PTHREADS
3 #ifndef _DEFAULT_SOURCE
4 #define _DEFAULT_SOURCE
5 #endif
6 #ifndef _BSD_SOURCE
7 #define _BSD_SOURCE
8 #endif
9 #define _XOPEN_SOURCE 500
10 #define _LARGEFILE_SOURCE 1
11 #define _LARGEFILE64_SOURCE 1
12 #define _FILE_OFFSET_BITS 64
13 #ifdef USE_PTHREADS
14 #define _REENTRANT 1
15 #endif
16 #include <features.h>
17 #include <sys/types.h>
18 #include <stdlib.h>
19 #include <stdarg.h>
20 #define sync __os_sync
21 #include <unistd.h>
22 #undef sync
23 #include <errno.h>
24 #define __NO_STRING_INLINES
25 #include <string.h>
26 #include "math.h"
27 #include <fcntl.h>
28 #include <setjmp.h>
29 #include <float.h>
30 #include <endian.h>
31
32 #define getwd infgetwd
33
34 #ifndef EMU
35 typedef struct Proc Proc;
36 #endif
37
38 /*
39 * math module dtoa
40 * #define __LITTLE_ENDIAN /usr/include/endian.h under linux
41 */
42
43 #define nil ((void*)0)
44
45 typedef unsigned char uchar;
46 typedef signed char schar;
47 typedef unsigned int Rune;
48 typedef long long int vlong;
49 typedef unsigned long long int uvlong;
50 typedef unsigned int u32int;
51 typedef uvlong u64int;
52
53 typedef unsigned int mpdigit; /* for /sys/include/mp.h */
54 typedef unsigned short u16int;
55 typedef unsigned char u8int;
56 typedef unsigned long uintptr;
57
58 #define USED(x) if(x){}else{}
59 #define SET(x)
60
61 #undef nelem
62 #define nelem(x) (sizeof(x)/sizeof((x)[0]))
63 #undef offsetof
64 #define offsetof(s, m) (ulong)(&(((s*)0)->m))
65 #undef assert
66 #define assert(x) if(x){}else _assert("x")
67
68 /*
69 * most mem and string routines are declared by ANSI/POSIX files above
70 */
71
72 extern char* strecpy(char*, char*, char*);
73 extern char* strdup(const char*);
74 extern int cistrncmp(char*, char*, int);
75 extern int cistrcmp(char*, char*);
76 extern char* cistrstr(char*, char*);
77 extern int tokenize(char*, char**, int);
78
79 enum
80 {
81 UTFmax = 4, /* maximum bytes per rune */
82 Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */
83 Runeself = 0x80, /* rune and UTF sequences are the same (<) */
84 Runeerror = 0xFFFD, /* decoding error in UTF */
85 Runemax = 0x10FFFF, /* 21-bit rune */
86 Runemask = 0x1FFFFF, /* bits used by runes (see grep) */
87 };
88
89 /*
90 * rune routines
91 */
92 extern int runetochar(char*, Rune*);
93 extern int chartorune(Rune*, char*);
94 extern int runelen(long);
95 extern int runenlen(Rune*, int);
96 extern int fullrune(char*, int);
97 extern int utflen(char*);
98 extern int utfnlen(char*, long);
99 extern char* utfrune(char*, long);
100 extern char* utfrrune(char*, long);
101 extern char* utfutf(char*, char*);
102 extern char* utfecpy(char*, char*, char*);
103
104 extern Rune* runestrcat(Rune*, Rune*);
105 extern Rune* runestrchr(Rune*, Rune);
106 extern int runestrcmp(Rune*, Rune*);
107 extern Rune* runestrcpy(Rune*, Rune*);
108 extern Rune* runestrncpy(Rune*, Rune*, long);
109 extern Rune* runestrecpy(Rune*, Rune*, Rune*);
110 extern Rune* runestrdup(Rune*);
111 extern Rune* runestrncat(Rune*, Rune*, long);
112 extern int runestrncmp(Rune*, Rune*, long);
113 extern Rune* runestrrchr(Rune*, Rune);
114 extern long runestrlen(Rune*);
115 extern Rune* runestrstr(Rune*, Rune*);
116
117 extern Rune tolowerrune(Rune);
118 extern Rune totitlerune(Rune);
119 extern Rune toupperrune(Rune);
120 extern int isalpharune(Rune);
121 extern int islowerrune(Rune);
122 extern int isspacerune(Rune);
123 extern int istitlerune(Rune);
124 extern int isupperrune(Rune);
125
126 /*
127 * malloc
128 */
129 extern void* malloc(size_t);
130 extern void* mallocz(ulong, int);
131 extern void free(void*);
132 extern ulong msize(void*);
133 extern void* calloc(size_t, size_t);
134 extern void* realloc(void*, size_t);
135 extern void setmalloctag(void*, ulong);
136 extern void setrealloctag(void*, ulong);
137 extern ulong getmalloctag(void*);
138 extern ulong getrealloctag(void*);
139 extern void* malloctopoolblock(void*);
140
141 /*
142 * print routines
143 */
144 typedef struct Fmt Fmt;
145 struct Fmt{
146 uchar runes; /* output buffer is runes or chars? */
147 void *start; /* of buffer */
148 void *to; /* current place in the buffer */
149 void *stop; /* end of the buffer; overwritten if flush fails */
150 int (*flush)(Fmt *); /* called when to == stop */
151 void *farg; /* to make flush a closure */
152 int nfmt; /* num chars formatted so far */
153 va_list args; /* args passed to dofmt */
154 int r; /* % format Rune */
155 int width;
156 int prec;
157 ulong flags;
158 };
159
160 enum{
161 FmtWidth = 1,
162 FmtLeft = FmtWidth << 1,
163 FmtPrec = FmtLeft << 1,
164 FmtSharp = FmtPrec << 1,
165 FmtSpace = FmtSharp << 1,
166 FmtSign = FmtSpace << 1,
167 FmtZero = FmtSign << 1,
168 FmtUnsigned = FmtZero << 1,
169 FmtShort = FmtUnsigned << 1,
170 FmtLong = FmtShort << 1,
171 FmtVLong = FmtLong << 1,
172 FmtComma = FmtVLong << 1,
173 FmtByte = FmtComma << 1,
174
175 FmtFlag = FmtByte << 1
176 };
177
178 extern int print(char*, ...);
179 extern char* seprint(char*, char*, char*, ...);
180 extern char* vseprint(char*, char*, char*, va_list);
181 extern int snprint(char*, int, char*, ...);
182 extern int vsnprint(char*, int, char*, va_list);
183 extern char* smprint(char*, ...);
184 extern char* vsmprint(char*, va_list);
185 extern int sprint(char*, char*, ...);
186 extern int fprint(int, char*, ...);
187 extern int vfprint(int, char*, va_list);
188
189 extern int runesprint(Rune*, char*, ...);
190 extern int runesnprint(Rune*, int, char*, ...);
191 extern int runevsnprint(Rune*, int, char*, va_list);
192 extern Rune* runeseprint(Rune*, Rune*, char*, ...);
193 extern Rune* runevseprint(Rune*, Rune*, char*, va_list);
194 extern Rune* runesmprint(char*, ...);
195 extern Rune* runevsmprint(char*, va_list);
196
197 extern int fmtfdinit(Fmt*, int, char*, int);
198 extern int fmtfdflush(Fmt*);
199 extern int fmtstrinit(Fmt*);
200 extern char* fmtstrflush(Fmt*);
201 extern int runefmtstrinit(Fmt*);
202 extern Rune* runefmtstrflush(Fmt*);
203
204 extern int fmtinstall(int, int (*)(Fmt*));
205 extern int dofmt(Fmt*, char*);
206 extern int dorfmt(Fmt*, Rune*);
207 extern int fmtprint(Fmt*, char*, ...);
208 extern int fmtvprint(Fmt*, char*, va_list);
209 extern int fmtrune(Fmt*, int);
210 extern int fmtstrcpy(Fmt*, char*);
211 extern int fmtrunestrcpy(Fmt*, Rune*);
212 /*
213 * error string for %r
214 * supplied on per os basis, not part of fmt library
215 */
216 extern int errfmt(Fmt *f);
217
218 /*
219 * quoted strings
220 */
221 extern char *unquotestrdup(char*);
222 extern Rune *unquoterunestrdup(Rune*);
223 extern char *quotestrdup(char*);
224 extern Rune *quoterunestrdup(Rune*);
225 extern int quotestrfmt(Fmt*);
226 extern int quoterunestrfmt(Fmt*);
227 extern void quotefmtinstall(void);
228 extern int (*doquote)(int);
229
230 /*
231 * random number
232 */
233 extern ulong truerand(void);
234 extern ulong ntruerand(ulong);
235
236 /*
237 * math
238 */
239 extern int isNaN(double);
240 extern double NaN(void);
241 extern int isInf(double, int);
242
243 /*
244 * Time-of-day
245 */
246
247 typedef struct Tm Tm;
248 struct Tm {
249 int sec;
250 int min;
251 int hour;
252 int mday;
253 int mon;
254 int year;
255 int wday;
256 int yday;
257 char zone[4];
258 int tzoff;
259 };
260 extern vlong osnsec(void);
261 #define nsec osnsec
262
263 /*
264 * one-of-a-kind
265 */
266 extern void _assert(char*);
267 extern double charstod(int(*)(void*), void*);
268 extern char* cleanname(char*);
269 //extern uintptr getcallerpc(void*);
270 extern int getfields(char*, char**, int, int, char*);
271 extern char* getuser(void);
272 extern char* getwd(char*, int);
273 extern double ipow10(int);
274 #define pow10 infpow10
275 extern double pow10(int);
276 extern vlong strtoll(const char*, char**, int);
277 #define qsort infqsort
278 extern void qsort(void*, long, long, int (*)(void*, void*));
279 extern uvlong strtoull(const char*, char**, int);
280 extern void sysfatal(char*, ...);
281 extern int dec64(uchar*, int, char*, int);
282 extern int enc64(char*, int, uchar*, int);
283 extern int dec32(uchar*, int, char*, int);
284 extern int enc32(char*, int, uchar*, int);
285 extern int dec16(uchar*, int, char*, int);
286 extern int enc16(char*, int, uchar*, int);
287 extern int encodefmt(Fmt*);
288
289 /*
290 * synchronization
291 */
292 typedef
293 struct Lock {
294 int val;
295 int pid;
296 } Lock;
297
298 extern int _tas(int*);
299
300 extern void lock(Lock*);
301 extern void unlock(Lock*);
302 extern int canlock(Lock*);
303
304 typedef struct QLock QLock;
305 struct QLock
306 {
307 Lock use; /* to access Qlock structure */
308 Proc *head; /* next process waiting for object */
309 Proc *tail; /* last process waiting for object */
310 int locked; /* flag */
311 };
312
313 extern void qlock(QLock*);
314 extern void qunlock(QLock*);
315 extern int canqlock(QLock*);
316 extern void _qlockinit(ulong (*)(ulong, ulong)); /* called only by the thread library */
317
318 typedef
319 struct RWLock
320 {
321 Lock l; /* Lock modify lock */
322 QLock x; /* Mutual exclusion lock */
323 QLock k; /* Lock for waiting writers */
324 int readers; /* Count of readers in lock */
325 } RWLock;
326
327 extern int canrlock(RWLock*);
328 extern int canwlock(RWLock*);
329 extern void rlock(RWLock*);
330 extern void runlock(RWLock*);
331 extern void wlock(RWLock*);
332 extern void wunlock(RWLock*);
333
334 /*
335 * network dialing
336 */
337 #define NETPATHLEN 40
338
339 /*
340 * system calls
341 *
342 */
343 #define STATMAX 65535U /* max length of machine-independent stat structure */
344 #define DIRMAX (sizeof(Dir)+STATMAX) /* max length of Dir structure */
345 #define ERRMAX 128 /* max length of error string */
346
347 #define MORDER 0x0003 /* mask for bits defining order of mounting */
348 #define MREPL 0x0000 /* mount replaces object */
349 #define MBEFORE 0x0001 /* mount goes before others in union directory */
350 #define MAFTER 0x0002 /* mount goes after others in union directory */
351 #define MCREATE 0x0004 /* permit creation in mounted directory */
352 #define MCACHE 0x0010 /* cache some data */
353 #define MMASK 0x0017 /* all bits on */
354
355 #define OREAD 0 /* open for read */
356 #define OWRITE 1 /* write */
357 #define ORDWR 2 /* read and write */
358 #define OEXEC 3 /* execute, == read but check execute permission */
359 #define OTRUNC 16 /* or'ed in (except for exec), truncate file first */
360 #define OCEXEC 32 /* or'ed in, close on exec */
361 #define ORCLOSE 64 /* or'ed in, remove on close */
362 #define OEXCL 0x1000 /* or'ed in, exclusive use (create only) */
363
364 #define AEXIST 0 /* accessible: exists */
365 #define AEXEC 1 /* execute access */
366 #define AWRITE 2 /* write access */
367 #define AREAD 4 /* read access */
368
369 /* bits in Qid.type */
370 #define QTDIR 0x80 /* type bit for directories */
371 #define QTAPPEND 0x40 /* type bit for append only files */
372 #define QTEXCL 0x20 /* type bit for exclusive use files */
373 #define QTMOUNT 0x10 /* type bit for mounted channel */
374 #define QTAUTH 0x08 /* type bit for authentication file */
375 #define QTFILE 0x00 /* plain file */
376
377 /* bits in Dir.mode */
378 #define DMDIR 0x80000000 /* mode bit for directories */
379 #define DMAPPEND 0x40000000 /* mode bit for append only files */
380 #define DMEXCL 0x20000000 /* mode bit for exclusive use files */
381 #define DMMOUNT 0x10000000 /* mode bit for mounted channel */
382 #define DMAUTH 0x08000000 /* mode bit for authentication file */
383 #define DMREAD 0x4 /* mode bit for read permission */
384 #define DMWRITE 0x2 /* mode bit for write permission */
385 #define DMEXEC 0x1 /* mode bit for execute permission */
386
387 typedef
388 struct Qid
389 {
390 uvlong path;
391 ulong vers;
392 uchar type;
393 } Qid;
394
395 typedef
396 struct Dir {
397 /* system-modified data */
398 ushort type; /* server type */
399 uint dev; /* server subtype */
400 /* file data */
401 Qid qid; /* unique id from server */
402 ulong mode; /* permissions */
403 ulong atime; /* last read time */
404 ulong mtime; /* last write time */
405 vlong length; /* file length */
406 char *name; /* last element of path */
407 char *uid; /* owner name */
408 char *gid; /* group name */
409 char *muid; /* last modifier name */
410 } Dir;
411
412 extern Dir* dirstat(char*);
413 extern Dir* dirfstat(int);
414 extern int dirwstat(char*, Dir*);
415 extern int dirfwstat(int, Dir*);
416 extern long dirread(int, Dir**);
417 extern void nulldir(Dir*);
418 extern long dirreadall(int, Dir**);
419
420 typedef
421 struct Waitmsg
422 {
423 int pid; /* of loved one */
424 ulong time[3]; /* of loved one & descendants */
425 char *msg;
426 } Waitmsg;
427
428 extern void _exits(char*);
429
430 extern void exits(char*);
431 extern int create(char*, int, int);
432 extern int errstr(char*, uint);
433
434 extern void perror(const char*);
435 extern long readn(int, void*, long);
436 extern int remove(const char*);
437 extern void rerrstr(char*, uint);
438 extern vlong seek(int, vlong, int);
439 extern int segflush(void*, ulong);
440 extern void werrstr(char*, ...);
441
442 extern char *argv0;
443 #define ARGBEGIN for((argv0||(argv0=*argv)),argv++,argc--;\
444 argv[0] && argv[0][0]=='-' && argv[0][1];\
445 argc--, argv++) {\
446 char *_args, *_argt;\
447 Rune _argc;\
448 _args = &argv[0][1];\
449 if(_args[0]=='-' && _args[1]==0){\
450 argc--; argv++; break;\
451 }\
452 _argc = 0;\
453 while(*_args && (_args += chartorune(&_argc, _args)))\
454 switch(_argc)
455 #define ARGEND SET(_argt);USED(_argt);USED(_argc); USED(_args);}USED(argv); USED(argc);
456 #define ARGF() (_argt=_args, _args="",\
457 (*_argt? _argt: argv[1]? (argc--, *++argv): 0))
458 #define EARGF(x) (_argt=_args, _args="",\
459 (*_argt? _argt: argv[1]? (argc--, *++argv): ((x), abort(), (char*)0)))
460
461 #define ARGC() _argc
462
463 /*
464 * Extensions for Inferno to basic libc.h
465 */
466
467 #define setbinmode()
468
469 /* need the inline because the link register is not saved in a known location */
getcallerpc(void * dummy)470 static __inline uintptr getcallerpc(void* dummy) {
471 ulong lr;
472 __asm__( "mov %0, %%lr;"
473 : "=r" (lr)
474 );
475 return lr;
476 }
477
478
479 extern void setfcr(ulong);
480 extern void setfsr(ulong);
481 extern ulong getfcr(void);
482 extern ulong getfsr(void);
483
484 /* FCR */
485 #define FPINEX (1<<5)
486 #define FPUNFL ((1<<4)|(1<<1))
487 #define FPOVFL (1<<3)
488 #define FPZDIV (1<<2)
489 #define FPINVAL (1<<0)
490 #define FPRNR (0<<10)
491 #define FPRZ (3<<10)
492 #define FPRPINF (2<<10)
493 #define FPRNINF (1<<10)
494 #define FPRMASK (3<<10)
495 #define FPPEXT (3<<8)
496 #define FPPSGL (0<<8)
497 #define FPPDBL (2<<8)
498 #define FPPMASK (3<<8)
499 /* FSR */
500 #define FPAINEX FPINEX
501 #define FPAOVFL FPOVFL
502 #define FPAUNFL FPUNFL
503 #define FPAZDIV FPZDIV
504 #define FPAINVAL FPINVAL
505