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