tstart over with plan9's libc.h. - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit f365e600d41badc64b7a13ba385eb876d381abaa
 (DIR) parent fd04aacee17b348da206c13a550dc1029669805f
 (HTM) Author: rsc <devnull@localhost>
       Date:   Sun, 23 Nov 2003 18:13:59 +0000
       
       start over with plan9's libc.h.
       
       Diffstat:
         M include/lib9.h                      |     862 +++++++++++++++++++++++++------
       
       1 file changed, 697 insertions(+), 165 deletions(-)
       ---
 (DIR) diff --git a/include/lib9.h b/include/lib9.h
       t@@ -8,8 +8,7 @@
        
        #if defined(__cplusplus)
        extern "C" {
       -#endif
       -                                                                                
       +#endif                                                                          
        
        #include <unistd.h>
        #include <string.h>
       t@@ -18,19 +17,21 @@ extern "C" {
        #include <fcntl.h>
        #include <assert.h>
        #include <setjmp.h>
       +#include <stddef.h>
       +#include <utf.h>
       +#include <fmt.h>
       +#include <math.h>
        
       -#ifndef _FMTH_
       -#        include <fmt.h>
       -#endif
       -
       -#define        nil        ((void*)0)
       -#define        nelem(x)        (sizeof(x)/sizeof((x)[0]))
       -
       +/*
       + * OS-specific crap
       + */
        #define _NEEDUCHAR 1
        #define _NEEDUSHORT 1
        #define _NEEDUINT 1
        #define _NEEDULONG 1
        
       +typedef long p9jmp_buf[sizeof(sigjmp_buf)/sizeof(long)];
       +
        #if defined(__linux__)
        #        include <sys/types.h>
        #        if defined(__USE_MISC)
       t@@ -39,6 +40,12 @@ extern "C" {
        #                undef _NEEDULONG
        #        endif
        #endif
       +#if defined(__sun__)
       +#        include <sys/types.h>
       +#        undef _NEEDUSHORT
       +#        undef _NEEDUINT
       +#        undef _NEEDULONG
       +#endif
        #if defined(__FreeBSD__)
        #        include <sys/types.h>
        #        if !defined(_POSIX_SOURCE)
       t@@ -68,189 +75,729 @@ typedef unsigned int u32int;
        #endif
        typedef unsigned long long uvlong;
        typedef long long vlong;
       +typedef uvlong u64int;
       +typedef uchar u8int;
       +typedef ushort u16int;
        
       -#define NAMELEN        28
       -#define CHDIR                0x80000000        /* mode bit for directories */
       -#define CHAPPEND        0x40000000        /* mode bit for append only files */
       -#define CHEXCL                0x20000000        /* mode bit for exclusive use files */
       -#define CHMOUNT                0x10000000        /* mode bit for mounted channel */
       -#define CHREAD                0x4                /* mode bit for read permission */
       -#define CHWRITE                0x2                /* mode bit for write permission */
       -#define CHEXEC                0x1                /* mode bit for execute permission */
       +/*
       + * Begin usual libc.h 
       + */
        
       -/* rfork to create new process running fn(arg) */
       +#define        nil        ((void*)0)
       +#define        nelem(x)        (sizeof(x)/sizeof((x)[0]))
        
       -#if defined(__FreeBSD__)
       -#undef RFFDG
       -#undef RFNOTEG
       -#undef RFPROC
       -#undef RFMEM
       -#undef RFNOWAIT
       -#undef RFCFDG
       +#ifndef offsetof
       +#define offsetof(s, m)        (ulong)(&(((s*)0)->m))
        #endif
        
       +/*
       + * mem routines (provided by system <string.h>)
       + *
       +extern        void*        memccpy(void*, void*, int, ulong);
       +extern        void*        memset(void*, int, ulong);
       +extern        int        memcmp(void*, void*, ulong);
       +extern        void*        memcpy(void*, void*, ulong);
       +extern        void*        memmove(void*, void*, ulong);
       +extern        void*        memchr(void*, int, ulong);
       + */
       +
       +/*
       + * string routines (provided by system <string.h>)
       + *
       +extern        char*        strcat(char*, char*);
       +extern        char*        strchr(char*, int);
       +extern        int        strcmp(char*, char*);
       +extern        char*        strcpy(char*, char*);
       + */
       +extern        char*        strecpy(char*, char*, char*);
       + /*
       +extern        char*        strdup(char*);
       +extern        char*        strncat(char*, char*, long);
       +extern        char*        strncpy(char*, char*, long);
       +extern        int        strncmp(char*, char*, long);
       +extern        char*        strpbrk(char*, char*);
       +extern        char*        strrchr(char*, int);
       +extern        char*        strtok(char*, char*);
       +extern        long        strlen(char*);
       +extern        long        strspn(char*, char*);
       +extern        long        strcspn(char*, char*);
       +extern        char*        strstr(char*, char*);
       + */
       +extern        int        cistrncmp(char*, char*, int);
       +extern        int        cistrcmp(char*, char*);
       +extern        char*        cistrstr(char*, char*);
       +extern        int        tokenize(char*, char**, int);
       +
       +/*
        enum
        {
       -/*        RFNAMEG                = (1<<0), */
       -/*        RFENVG                = (1<<1), */
       -        RFFDG                = (1<<2),
       -        RFNOTEG                = (1<<3),
       -        RFPROC                = (1<<4),
       -        RFMEM                = (1<<5),
       -        RFNOWAIT        = (1<<6),
       -/*        RFCNAMEG        = (1<<10), */
       -/*        RFCENVG                = (1<<11), */
       -        RFCFDG                = (1<<12),
       -/*        RFREND                = (1<<13), */
       -/*        RFNOMNT                = (1<<14) */
       +        UTFmax                = 3,
       +        Runesync        = 0x80,
       +        Runeself        = 0x80,
       +        Runeerror        = 0x80,
        };
       -extern int                ffork(int, void(*)(void*), void*);
       +*/
        
       -/* wait for processes */
       -#define wait _p9wait
       -typedef struct Waitmsg Waitmsg;
       -struct Waitmsg
       -{
       -        int pid;        /* of loved one */
       -        ulong time[3];        /* of loved one & descendants */
       -        char        *msg;
       +/*
       + * rune routines (provided by <utf.h>
       + *
       +extern        int        runetochar(char*, Rune*);
       +extern        int        chartorune(Rune*, char*);
       +extern        int        runelen(long);
       +extern        int        runenlen(Rune*, int);
       +extern        int        fullrune(char*, int);
       +extern        int        utflen(char*);
       +extern        int        utfnlen(char*, long);
       +extern        char*        utfrune(char*, long);
       +extern        char*        utfrrune(char*, long);
       +extern        char*        utfutf(char*, char*);
       +extern        char*        utfecpy(char*, char*, char*);
       +
       +extern        Rune*        runestrcat(Rune*, Rune*);
       +extern        Rune*        runestrchr(Rune*, Rune);
       +extern        int        runestrcmp(Rune*, Rune*);
       +extern        Rune*        runestrcpy(Rune*, Rune*);
       +extern        Rune*        runestrncpy(Rune*, Rune*, long);
       +extern        Rune*        runestrecpy(Rune*, Rune*, Rune*);
       +extern        Rune*        runestrdup(Rune*);
       +extern        Rune*        runestrncat(Rune*, Rune*, long);
       +extern        int        runestrncmp(Rune*, Rune*, long);
       +extern        Rune*        runestrrchr(Rune*, Rune);
       +extern        long        runestrlen(Rune*);
       +extern        Rune*        runestrstr(Rune*, Rune*);
       +
       +extern        Rune        tolowerrune(Rune);
       +extern        Rune        totitlerune(Rune);
       +extern        Rune        toupperrune(Rune);
       +extern        int        isalpharune(Rune);
       +extern        int        islowerrune(Rune);
       +extern        int        isspacerune(Rune);
       +extern        int        istitlerune(Rune);
       +extern        int        isupperrune(Rune);
       + */
       +
       +/*
       + * malloc (provied by system <stdlib.h>)
       + *
       +extern        void*        malloc(ulong);
       + */
       +extern        void*        mallocz(ulong, int);
       +/*
       +extern        void        free(void*);
       +extern        ulong        msize(void*);
       +extern        void*        calloc(ulong, ulong);
       +extern        void*        realloc(void*, ulong);
       + */
       +extern        void                setmalloctag(void*, ulong);
       +extern        void                setrealloctag(void*, ulong);
       +extern        ulong        getmalloctag(void*);
       +extern        ulong        getrealloctag(void*);
       +/*
       +extern        void*        malloctopoolblock(void*);
       +*/
       +
       +/*
       + * print routines (provided by <fmt.h>)
       + *
       +typedef struct Fmt        Fmt;
       +struct Fmt{
       +        uchar        runes;
       +        void        *start;
       +        void        *to;
       +        void        *stop;
       +        int        (*flush)(Fmt *);
       +        void        *farg;
       +        int        nfmt;
       +        va_list        args;
       +        int        r;
       +        int        width;
       +        int        prec;
       +        ulong        flags;
        };
       -extern        int                await(char*, int);
       -extern        Waitmsg*        wait(void);
        
       -/* synchronization */
       -typedef struct Lock Lock;
       -struct Lock
       +enum{
       +        FmtWidth        = 1,
       +        FmtLeft                = FmtWidth << 1,
       +        FmtPrec                = FmtLeft << 1,
       +        FmtSharp        = FmtPrec << 1,
       +        FmtSpace        = FmtSharp << 1,
       +        FmtSign                = FmtSpace << 1,
       +        FmtZero                = FmtSign << 1,
       +        FmtUnsigned        = FmtZero << 1,
       +        FmtShort        = FmtUnsigned << 1,
       +        FmtLong                = FmtShort << 1,
       +        FmtVLong        = FmtLong << 1,
       +        FmtComma        = FmtVLong << 1,
       +        FmtByte        = FmtComma << 1,
       +
       +        FmtFlag                = FmtByte << 1
       +};
       +
       +extern        int        print(char*, ...);
       +extern        char*        seprint(char*, char*, char*, ...);
       +extern        char*        vseprint(char*, char*, char*, va_list);
       +extern        int        snprint(char*, int, char*, ...);
       +extern        int        vsnprint(char*, int, char*, va_list);
       +extern        char*        smprint(char*, ...);
       +extern        char*        vsmprint(char*, va_list);
       +extern        int        sprint(char*, char*, ...);
       +extern        int        fprint(int, char*, ...);
       +extern        int        vfprint(int, char*, va_list);
       +
       +extern        int        runesprint(Rune*, char*, ...);
       +extern        int        runesnprint(Rune*, int, char*, ...);
       +extern        int        runevsnprint(Rune*, int, char*, va_list);
       +extern        Rune*        runeseprint(Rune*, Rune*, char*, ...);
       +extern        Rune*        runevseprint(Rune*, Rune*, char*, va_list);
       +extern        Rune*        runesmprint(char*, ...);
       +extern        Rune*        runevsmprint(char*, va_list);
       +
       +extern        int        fmtfdinit(Fmt*, int, char*, int);
       +extern        int        fmtfdflush(Fmt*);
       +extern        int        fmtstrinit(Fmt*);
       +extern        char*        fmtstrflush(Fmt*);
       +extern        int        runefmtstrinit(Fmt*);
       +extern        Rune*        runefmtstrflush(Fmt*);
       +
       +extern        int        fmtinstall(int, int (*)(Fmt*));
       +extern        int        dofmt(Fmt*, char*);
       +extern        int        dorfmt(Fmt*, Rune*);
       +extern        int        fmtprint(Fmt*, char*, ...);
       +extern        int        fmtvprint(Fmt*, char*, va_list);
       +extern        int        fmtrune(Fmt*, int);
       +extern        int        fmtstrcpy(Fmt*, char*);
       +extern        int        fmtrunestrcpy(Fmt*, Rune*);
       + */
       +
       +/*
       + * error string for %r
       + * supplied on per os basis, not part of fmt library
       + *
       + * (provided by lib9, but declared in fmt.h)
       + *
       +extern        int        errfmt(Fmt *f);
       + */
       +
       +/*
       + * quoted strings
       + */
       +extern        char        *unquotestrdup(char*);
       +extern        Rune        *unquoterunestrdup(Rune*);
       +extern        char        *quotestrdup(char*);
       +extern        Rune        *quoterunestrdup(Rune*);
       +/*
       + * in fmt.h
       + *
       +extern        void        quotefmtinstall(void);
       +extern        int        quotestrfmt(Fmt*);
       +extern        int        quoterunestrfmt(Fmt*);
       + */
       +#ifndef NOPLAN9DEFINES
       +#define doquote fmtdoquote
       +#endif
       +extern        int        needsrcquote(int);
       +
       +/*
       + * random number (in <stdlib.h>)
       + *
       +extern        void        srand(long);
       +extern        int        rand(void);
       + */
       +extern        int        nrand(int);
       +extern        long        lrand(void);
       +extern        long        lnrand(long);
       +extern        double        frand(void);
       +extern        ulong        truerand(void);                        /* uses /dev/random */
       +extern        ulong        ntruerand(ulong);                /* uses /dev/random */
       +
       +/*
       + * math
       + */
       +extern        ulong        getfcr(void);
       +extern        void        setfsr(ulong);
       +extern        ulong        getfsr(void);
       +extern        void        setfcr(ulong);
       +extern        double        NaN(void);
       +extern        double        Inf(int);
       +extern        int        isNaN(double);
       +extern        int        isInf(double, int);
       +extern        ulong        umuldiv(ulong, ulong, ulong);
       +extern        long        muldiv(long, long, long);
       +
       +/*
       + * provided by math.h
       + *
       +extern        double        pow(double, double);
       +extern        double        atan2(double, double);
       +extern        double        fabs(double);
       +extern        double        atan(double);
       +extern        double        log(double);
       +extern        double        log10(double);
       +extern        double        exp(double);
       +extern        double        floor(double);
       +extern        double        ceil(double);
       +extern        double        hypot(double, double);
       +extern        double        sin(double);
       +extern        double        cos(double);
       +extern        double        tan(double);
       +extern        double        asin(double);
       +extern        double        acos(double);
       +extern        double        sinh(double);
       +extern        double        cosh(double);
       +extern        double        tanh(double);
       +extern        double        sqrt(double);
       +extern        double        fmod(double, double);
       +#define        HUGE        3.4028234e38
       +#define        PIO2        1.570796326794896619231e0
       +#define        PI        (PIO2+PIO2)
       + */
       +#define PI        M_PI
       +#define        PIO2        M_PI_2
       +
       +/*
       + * Time-of-day
       + */
       +
       +typedef
       +struct Tm
       +{
       +        int        sec;
       +        int        min;
       +        int        hour;
       +        int        mday;
       +        int        mon;
       +        int        year;
       +        int        wday;
       +        int        yday;
       +        char        zone[4];
       +        int        tzoff;
       +} Tm;
       +
       +extern        Tm*        p9gmtime(long);
       +extern        Tm*        p9localtime(long);
       +extern        char*        p9asctime(Tm*);
       +extern        char*        p9ctime(long);
       +extern        double        p9cputime(void);
       +extern        long        p9times(long*);
       +extern        long        p9tm2sec(Tm*);
       +extern        vlong        p9nsec(void);
       +
       +#ifndef NOPLAN9DEFINES
       +#define        gmtime                p9gmtime
       +#define        localtime        p9localtime
       +#define        asctime                p9asctime
       +#define        ctime                p9ctime
       +#define        cputime                p9cputime
       +#define        times                p9times
       +#define        tm2sec                p9tm2sec
       +#define        nsec                p9nsec
       +#endif
       +
       +/*
       + * one-of-a-kind
       + */
       +enum
        {
       -        int val;
       +        PNPROC                = 1,
       +        PNGROUP                = 2,
        };
        
       -extern int                _tas(void*);
       -extern void        lock(Lock*);
       -extern void        unlock(Lock*);
       -extern int                canlock(Lock*);
       +/* extern        int        abs(int); <stdlib.h> */
       +extern        int        atexit(void(*)(void));
       +extern        void        atexitdont(void(*)(void));
       +extern        int        atnotify(int(*)(void*, char*), int);
       +/* 
       + * <stdlib.h>
       +extern        double        atof(char*); <stdlib.h>
       +extern        int        atoi(char*);
       +extern        long        atol(char*);
       + */
       +extern        vlong        atoll(char*);
       +extern        double        charstod(int(*)(void*), void*);
       +extern        char*        cleanname(char*);
       +extern        int        p9decrypt(void*, void*, int);
       +extern        int        p9encrypt(void*, void*, int);
       +extern        int        dec64(uchar*, int, char*, int);
       +extern        int        enc64(char*, int, uchar*, int);
       +extern        int        dec32(uchar*, int, char*, int);
       +extern        int        enc32(char*, int, uchar*, int);
       +extern        int        dec16(uchar*, int, char*, int);
       +extern        int        enc16(char*, int, uchar*, int);
       +extern        int        encodefmt(Fmt*);
       +extern        int        dirmodefmt(Fmt*);
       +extern        void        exits(char*);
       +extern        double        frexp(double, int*);
       +extern        ulong        getcallerpc(void*);
       +extern        char*        p9getenv(char*);
       +extern        int        getfields(char*, char**, int, int, char*);
       +extern        int        gettokens(char *, char **, int, char *);
       +extern        char*        getuser(void);
       +extern        char*        p9getwd(char*, int);
       +extern        int        iounit(int);
       +/* extern        long        labs(long); <math.h> */
       +/* extern        double        ldexp(double, int); <math.h> */
       +extern        void        p9longjmp(p9jmp_buf, int);
       +extern        char*        mktemp(char*);
       +/* extern        double        modf(double, double*); <math.h> */
       +extern        int        netcrypt(void*, void*);
       +extern        void        p9notejmp(void*, p9jmp_buf, int);
       +extern        void        perror(const char*);
       +extern        int        postnote(int, int, char *);
       +extern        double        pow10(int);
       +/* extern        int        putenv(char*, char*); <stdlib.h. */
       +/* extern        void        qsort(void*, long, long, int (*)(void*, void*)); <stdlib.h> */
       +extern        int        p9setjmp(p9jmp_buf);
       +/*
       + * <stdlib.h>
       +extern        double        strtod(char*, char**);
       +extern        long        strtol(char*, char**, int);
       +extern        ulong        strtoul(char*, char**, int);
       +extern        vlong        strtoll(char*, char**, int);
       +extern        uvlong        strtoull(char*, char**, int);
       + */
       +extern        void        sysfatal(char*, ...);
       +extern        void        syslog(int, char*, char*, ...);
       +extern        long        time(long*);
       +/* extern        int        tolower(int); <ctype.h> */
       +/* extern        int        toupper(int); <ctype.h> */
       +#ifndef NOPLAN9DEFINES
       +#define getenv                p9getenv
       +#define        getwd                p9getwd
       +#define        longjmp                p9longjmp
       +#define setjmp                p9setjmp
       +#define notejmp                p9notejmp
       +#define jmp_buf                p9jmp_buf
       +#endif
       +
       +/*
       + *  synchronization
       + */
       +typedef
       +struct Lock {
       +        int        val;
       +} Lock;
       +
       +extern int        _tas(int*);
       +
       +extern        void        lock(Lock*);
       +extern        void        unlock(Lock*);
       +extern        int        canlock(Lock*);
        
        typedef struct QLp QLp;
        struct QLp
        {
       -        int                inuse;
       -        QLp                *next;
       -        int                state;
       +        int        inuse;
       +        QLp        *next;
       +        char        state;
        };
        
       -typedef struct QLock QLock;
       +typedef
        struct QLock
        {
                Lock        lock;
       -        int                locked;
       -        QLp                *head;
       -        QLp                *tail;
       -};
       +        int        locked;
       +        QLp        *head;
       +        QLp         *tail;
       +} QLock;
        
       -extern void        qlock(QLock*);
       -extern void        qunlock(QLock*);
       -extern int                canqlock(QLock*);
       -extern void        _qlockinit(ulong (*)(ulong, ulong));
       +extern        void        qlock(QLock*);
       +extern        void        qunlock(QLock*);
       +extern        int        canqlock(QLock*);
       +extern        void        _qlockinit(ulong (*)(ulong, ulong));        /* called only by the thread library */
        
       -typedef struct RWLock RWLock;
       +typedef
        struct RWLock
        {
                Lock        lock;
       -        int                readers;
       -        int                writer;
       -        QLp                *head;
       -        QLp                *tail;
       -};
       -
       -extern void        rlock(RWLock*);
       -extern void        runlock(RWLock*);
       -extern int                canrlock(RWLock*);
       -extern void        wlock(RWLock*);
       -extern void        wunlock(RWLock*);
       -extern int                canwlock(RWLock*);
       -
       -typedef struct Rendez Rendez;
       +        int        readers;        /* number of readers */
       +        int        writer;                /* number of writers */
       +        QLp        *head;                /* list of waiting processes */
       +        QLp        *tail;
       +} RWLock;
       +
       +extern        void        rlock(RWLock*);
       +extern        void        runlock(RWLock*);
       +extern        int                canrlock(RWLock*);
       +extern        void        wlock(RWLock*);
       +extern        void        wunlock(RWLock*);
       +extern        int                canwlock(RWLock*);
       +
       +typedef
        struct Rendez
        {
       -        QLock        *l;
       -        QLp                *head;
       -        QLp                *tail;
       -};
       +        QLock *l;
       +        QLp        *head;
       +        QLp        *tail;
       +} Rendez;
        
       -extern void        rsleep(Rendez*);
       -extern int                rwakeup(Rendez*);
       -extern int                rwakeupall(Rendez*);
       +extern        void        rsleep(Rendez*);        /* unlocks r->l, sleeps, locks r->l again */
       +extern        int        rwakeup(Rendez*);
       +extern        int        rwakeupall(Rendez*);
       +extern        void**        privalloc(void);
       +extern        void        privfree(void**);
        
       -extern ulong        rendezvous(ulong, ulong);
       +/*
       + *  network dialing
       + */
       +#define NETPATHLEN 40
       +extern        int        p9accept(int, char*);
       +extern        int        p9announce(char*, char*);
       +extern        int        p9dial(char*, char*, char*, int*);
       +extern        void        p9setnetmtpt(char*, int, char*);
       +extern        int        p9hangup(int);
       +extern        int        p9listen(char*, char*);
       +extern        char*        p9netmkaddr(char*, char*, char*);
       +extern        int        p9reject(int, char*, char*);
       +
       +#ifndef NOPLAN9DEFINES
       +#define        accept                p9accept
       +#define        announce        p9announce
       +#define        dial                p9dial
       +#define        setnetmtpt        p9setnetmtpt
       +#define        hangup                p9hangup
       +#define        listen                p9listen
       +#define        netmkaddr        p9netmkaddr
       +#define        reject                p9reject
       +#endif
        
       -typedef        struct        Qid        Qid;
       -typedef        struct        Dir        Dir;
       +/*
       + *  encryption
       + */
       +extern        int        pushssl(int, char*, char*, char*, int*);
       +extern        int        pushtls(int, char*, char*, int, char*, char*);
        
       -struct        Qid
       +/*
       + *  network services
       + */
       +typedef struct NetConnInfo NetConnInfo;
       +struct NetConnInfo
        {
       -        ulong        path;
       -        ulong        vers;
       +        char        *dir;                /* connection directory */
       +        char        *root;                /* network root */
       +        char        *spec;                /* binding spec */
       +        char        *lsys;                /* local system */
       +        char        *lserv;                /* local service */
       +        char        *rsys;                /* remote system */
       +        char        *rserv;                /* remote service */
        };
       +extern        NetConnInfo*        getnetconninfo(char*, int);
       +extern        void                freenetconninfo(NetConnInfo*);
       +
       +/*
       + * system calls
       + *
       + */
       +#define        STATMAX        65535U        /* max length of machine-independent stat structure */
       +#define        DIRMAX        (sizeof(Dir)+STATMAX)        /* max length of Dir structure */
       +#define        ERRMAX        128        /* max length of error string */
       +
       +#define        MORDER        0x0003        /* mask for bits defining order of mounting */
       +#define        MREPL        0x0000        /* mount replaces object */
       +#define        MBEFORE        0x0001        /* mount goes before others in union directory */
       +#define        MAFTER        0x0002        /* mount goes after others in union directory */
       +#define        MCREATE        0x0004        /* permit creation in mounted directory */
       +#define        MCACHE        0x0010        /* cache some data */
       +#define        MMASK        0x0017        /* all bits on */
       +
       +#define        OREAD        0        /* open for read */
       +#define        OWRITE        1        /* write */
       +#define        ORDWR        2        /* read and write */
       +#define        OEXEC        3        /* execute, == read but check execute permission */
       +#define        OTRUNC        16        /* or'ed in (except for exec), truncate file first */
       +#define        OCEXEC        32        /* or'ed in, close on exec */
       +#define        ORCLOSE        64        /* or'ed in, remove on close */
       +#define        OEXCL        0x1000        /* or'ed in, exclusive use (create only) */
       +
       +#define        AEXIST        0        /* accessible: exists */
       +#define        AEXEC        1        /* execute access */
       +#define        AWRITE        2        /* write access */
       +#define        AREAD        4        /* read access */
       +
       +/* Segattch */
       +#define        SG_RONLY        0040        /* read only */
       +#define        SG_CEXEC        0100        /* detach on exec */
       +
       +#define        NCONT        0        /* continue after note */
       +#define        NDFLT        1        /* terminate after note */
       +#define        NSAVE        2        /* clear note but hold state */
       +#define        NRSTR        3        /* restore saved state */
       +
       +/* bits in Qid.type */
       +#define QTDIR                0x80                /* type bit for directories */
       +#define QTAPPEND        0x40                /* type bit for append only files */
       +#define QTEXCL                0x20                /* type bit for exclusive use files */
       +#define QTMOUNT                0x10                /* type bit for mounted channel */
       +#define QTAUTH                0x08                /* type bit for authentication file */
       +#define QTFILE                0x00                /* plain file */
       +
       +/* bits in Dir.mode */
       +#define DMDIR                0x80000000        /* mode bit for directories */
       +#define DMAPPEND        0x40000000        /* mode bit for append only files */
       +#define DMEXCL                0x20000000        /* mode bit for exclusive use files */
       +#define DMMOUNT                0x10000000        /* mode bit for mounted channel */
       +#define DMAUTH                0x08000000        /* mode bit for authentication file */
       +#define DMREAD                0x4                /* mode bit for read permission */
       +#define DMWRITE                0x2                /* mode bit for write permission */
       +#define DMEXEC                0x1                /* mode bit for execute permission */
       +
       +#if defined(__FreeBSD__)
       +#undef RFFDG
       +#undef RFNOTEG
       +#undef RFPROC
       +#undef RFMEM
       +#undef RFNOWAIT
       +#undef RFCFDG
       +#endif
        
       -struct Dir
       +enum
        {
       -        char        name[NAMELEN];
       -        char        uid[NAMELEN];
       -        char        gid[NAMELEN];
       -        Qid        qid;
       -        ulong        mode;
       -        long        atime;
       -        long        mtime;
       -        vlong        length;
       -        ushort        type;
       -        ushort        dev;
       +/*        RFNAMEG                = (1<<0), */
       +/*        RFENVG                = (1<<1), */
       +        RFFDG                = (1<<2),
       +        RFNOTEG                = (1<<3),
       +        RFPROC                = (1<<4),
       +        RFMEM                = (1<<5),
       +        RFNOWAIT        = (1<<6),
       +/*        RFCNAMEG        = (1<<10), */
       +/*        RFCENVG                = (1<<11), */
       +        RFCFDG                = (1<<12),
       +/*        RFREND                = (1<<13), */
       +/*        RFNOMNT                = (1<<14) */
        };
        
       -extern        int        dirstat(char*, Dir*);
       -extern        int        dirfstat(int, Dir*);
       -extern        int        dirwstat(char*, Dir*);
       -extern        int        dirfwstat(int, Dir*);
       -
       +extern int                ffork(int, void(*)(void*), void*);
        
       -/* one of a kind */
       -extern void        sysfatal(char*, ...);
       -extern int        nrand(int);
       -extern long        lrand(void);
       -extern void        setmalloctag(void*, ulong);
       -extern void        setrealloctag(void*, ulong);
       -extern void        *mallocz(ulong, int);
       -extern long        readn(int, void*, long);
       -extern void        exits(char*);
       -extern void        _exits(char*);
       -extern ulong        getcallerpc(void*);
       -extern        char*        cleanname(char*);
       +typedef
       +struct Qid
       +{
       +        uvlong        path;
       +        ulong        vers;
       +        uchar        type;
       +} Qid;
       +
       +typedef
       +struct Dir {
       +        /* system-modified data */
       +        ushort        type;        /* server type */
       +        uint        dev;        /* server subtype */
       +        /* file data */
       +        Qid        qid;        /* unique id from server */
       +        ulong        mode;        /* permissions */
       +        ulong        atime;        /* last read time */
       +        ulong        mtime;        /* last write time */
       +        vlong        length;        /* file length */
       +        char        *name;        /* last element of path */
       +        char        *uid;        /* owner name */
       +        char        *gid;        /* group name */
       +        char        *muid;        /* last modifier name */
       +} Dir;
       +
       +/* keep /sys/src/ape/lib/ap/plan9/sys9.h in sync with this -rsc */
       +typedef
       +struct Waitmsg
       +{
       +        int pid;        /* of loved one */
       +        ulong time[3];        /* of loved one & descendants */
       +        char        *msg;
       +} Waitmsg;
        
       -/* string routines */
       -extern char*        strecpy(char*, char*, char*);
       -extern int                tokenize(char*, char**, int);
       -extern int                cistrncmp(char*, char*, int);
       -extern int                cistrcmp(char*, char*);
       -extern char*        cistrstr(char*, char*);
       -extern int                getfields(char*, char**, int, int, char*);
       -extern int                gettokens(char *, char **, int, char *);
       -
       -/* formatting helpers */
       -extern int                dec64(uchar*, int, char*, int);
       -extern int                enc64(char*, int, uchar*, int);
       -extern int                dec32(uchar*, int, char*, int);
       -extern int                enc32(char*, int, uchar*, int);
       -extern int                dec16(uchar*, int, char*, int);
       -extern int                enc16(char*, int, uchar*, int);
       -extern int                encodefmt(Fmt*);
       -
       -/* error string */
       -enum
       +typedef
       +struct IOchunk
        {
       -        ERRMAX = 128
       -};
       -extern void        rerrstr(char*, uint);
       -extern void        werrstr(char*, ...);
       -extern int                errstr(char*, uint);
       +        void        *addr;
       +        ulong        len;
       +} IOchunk;
       +
       +extern        void        _exits(char*);
       +
       +extern        void        abort(void);
       +/* extern        int        access(char*, int); <unistd.h> */
       +extern        long        p9alarm(ulong);
       +extern        int        await(char*, int);
       +/* extern        int        bind(char*, char*, int); give up */
       +/* extern        int        brk(void*); <unistd.h> */
       +/* extern        int        chdir(char*); <unistd.h> */
       +extern        int        close(int);
       +extern        int        create(char*, int, ulong);
       +extern        int        p9dup(int, int);
       +extern        int        errstr(char*, uint);
       +extern        int        p9exec(char*, char*[]);
       +/* extern        int        execl(char*, ...); <unistd.h> */
       +extern        int        fork(void);
       +extern        int        p9rfork(int);
       +/* not implemented 
       +extern        int        fauth(int, char*);
       +extern        int        fstat(int, uchar*, int);
       +extern        int        fwstat(int, uchar*, int);
       +extern        int        fversion(int, int, char*, int);
       +extern        int        mount(int, int, char*, int, char*);
       +extern        int        unmount(char*, char*);
       +*/
       +extern        int        noted(int);
       +extern        int        notify(void(*)(void*, char*));
       +/* extern        int        open(char*, int); <unistd.h> */
       +extern        int        fd2path(int, char*, int);
       +extern        int        pipe(int*);
       +/* 
       + * use defs from <unistd.h>
       +extern        long        pread(int, void*, long, vlong);
       +extern        long        preadv(int, IOchunk*, int, vlong);
       +extern        long        pwrite(int, void*, long, vlong);
       +extern        long        pwritev(int, IOchunk*, int, vlong);
       +extern        long        read(int, void*, long);
       + */
       +extern        long        readn(int, void*, long);
       +/* extern        long        readv(int, IOchunk*, int); <unistd.h> */
       +extern        int        remove(const char*);
       +/* extern        void*        sbrk(ulong); <unistd.h> */
       +/* extern        long        oseek(int, long, int); */
       +extern        vlong        p9seek(int, vlong, int);
       +/* give up
       +extern        long        segattach(int, char*, void*, ulong);
       +extern        int        segbrk(void*, void*);
       +extern        int        segdetach(void*);
       +extern        int        segflush(void*, ulong);
       +extern        int        segfree(void*, ulong);
       +*/
       +extern        int        p9sleep(long);
       +/* extern        int        stat(char*, uchar*, int); give up */
       +extern        Waitmsg*        p9wait(void);
       +extern        int        p9waitpid(void);
       +/* <unistd.h>
       +extern        long        write(int, void*, long);
       +extern        long        writev(int, IOchunk*, int);
       +*/
       +/* extern        int        wstat(char*, uchar*, int); give up */
       +extern        ulong        rendezvous(ulong, ulong);
       +
       +#ifndef NOPLAN9DEFINES
       +#define alarm                p9alarm
       +#define        dup                p9dup
       +#define        exec                p9exec
       +#define        seek                p9seek
       +#define sleep                p9sleep
       +#define wait                p9wait
       +#define waitpid                p9waitpid
       +#define rfork                p9rfork
       +#endif
       +
       +extern        Dir*        dirstat(char*);
       +extern        Dir*        dirfstat(int);
       +extern        int        dirwstat(char*, Dir*);
       +extern        int        dirfwstat(int, Dir*);
       +extern        long        dirread(int, Dir**);
       +extern        void        nulldir(Dir*);
       +extern        long        dirreadall(int, Dir**);
       +extern        int        getpid(void);
       +extern        int        getppid(void);
       +extern        void        rerrstr(char*, uint);
       +extern        char*        sysname(void);
       +extern        void        werrstr(char*, ...);
       +
       +/* external names that we don't want to step on */
       +#ifndef NOPLAN9DEFINES
       +#define main        p9main
       +#endif
        
        /* compiler directives on plan 9 */
        #define        USED(x)        if(x){}else{}
       t@@ -259,7 +806,7 @@ extern int                errstr(char*, uint);
        /* command line */
        extern char        *argv0;
        extern void __fixargv0(void);
       -#define        ARGBEGIN        for((argv0||(argv0=(__fixargv0(),*argv))),argv++,argc--;\
       +#define        ARGBEGIN        for((argv0?0:(argv0=(__fixargv0(),*argv))),argv++,argc--;\
                                    argv[0] && argv[0][0]=='-' && argv[0][1];\
                                    argc--, argv++) {\
                                        char *_args, *_argt;\
       t@@ -279,21 +826,6 @@ extern void __fixargv0(void);
        
        #define        ARGC()                _argc
        
       -#define OREAD O_RDONLY
       -#define OWRITE O_WRONLY
       -#define ORDWR        O_RDWR
       -#define AEXIST 0
       -#define AREAD 4
       -#define AWRITE 2
       -#define AEXEC 1
       -#define ORCLOSE 8
       -#define OCEXEC 16
       -
       -#define dup dup2
       -#define exec execv
       -#define seek lseek
       -#define getwd getcwd
       -
        #if defined(__cplusplus)
        }
        #endif