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