commit 8ad517944e46710ab832350c0dc3fc4e9239f7e2 from: rsc date: Thu Mar 25 23:03:57 2004 UTC Today's changes. More changes. commit - cb27443abf3d6af6ab52377c71c843e619928433 commit + 8ad517944e46710ab832350c0dc3fc4e9239f7e2 blob - befea2e347dc0e8a5abfeafbfc5e904a4be5cefe blob + 4cee8fb5f25dd82649ab4b4704dc1229dc2f5f46 --- include/fmt.h +++ include/fmt.h @@ -80,6 +80,7 @@ extern int fmtfdflush(Fmt*); extern int fmtstrinit(Fmt*); extern char* fmtstrflush(Fmt*); extern int runefmtstrinit(Fmt*); +extern Rune* runefmtstrflush(Fmt*); extern int quotestrfmt(Fmt *f); extern void quotefmtinstall(void); blob - 1373ce1507f32799232f7be5c3997021c7c05c68 blob + 07a1f976581732cfc565e5e3fbb8ac3cbc9a6784 --- include/lib9.h +++ include/lib9.h @@ -1,874 +1,2 @@ -/* - * Lib9 is miscellany from the Plan 9 C library that doesn't - * fit into libutf or into libfmt, but is still missing from traditional - * Unix C libraries. - */ -#ifndef _LIB9_H_ -#define _LIB9_H_ 1 -#if defined(__cplusplus) -extern "C" { -#endif - -#define _BSD_SOURCE 1 -#define _SVID_SOURCE 1 -#define _XOPEN_SOURCE 1000 -#define _XOPEN_SOURCE_EXTENDED 1 -#define _LARGEFILE64_SOURCE 1 -#define _FILE_OFFSET_BITS 64 -#define __EXTENSIONS__ 1 /* SunOS */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * 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 -# if defined(__USE_MISC) -# undef _NEEDUSHORT -# undef _NEEDUINT -# undef _NEEDULONG -# endif -#endif -#if defined(__sun__) -# include -# undef _NEEDUSHORT -# undef _NEEDUINT -# undef _NEEDULONG -#endif -#if defined(__FreeBSD__) -# include -# if !defined(_POSIX_SOURCE) -# undef _NEEDUSHORT -# undef _NEEDUINT -# endif -#endif -#if defined(__APPLE__) -# include -# undef _NEEDUSHORT -# undef _NEEDUINT -# define _NEEDLL 1 -#endif - -typedef signed char schar; -typedef unsigned int u32int; -#ifdef _NEEDUCHAR - typedef unsigned char uchar; -#endif -#ifdef _NEEDUSHORT - typedef unsigned short ushort; -#endif -#ifdef _NEEDUINT - typedef unsigned int uint; -#endif -#ifdef _NEEDULONG - typedef unsigned long ulong; -#endif -typedef unsigned long long uvlong; -typedef long long vlong; -typedef uvlong u64int; -typedef uchar u8int; -typedef ushort u16int; - -#undef _NEEDUCHAR -#undef _NEEDUSHORT -#undef _NEEDUINT -#undef _NEEDULONG - -/* - * Begin usual libc.h - */ - -#define nil ((void*)0) -#define nelem(x) (sizeof(x)/sizeof((x)[0])) - -#ifndef offsetof -#define offsetof(s, m) (ulong)(&(((s*)0)->m)) -#endif - -/* - * mem routines (provided by system ) - * -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 ) - * -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 -{ - UTFmax = 3, - Runesync = 0x80, - Runeself = 0x80, - Runeerror = 0x80, -}; -*/ - -/* - * rune routines (provided by - * -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 ) - * -extern void* malloc(ulong); - */ -extern void* p9malloc(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*); -*/ -#ifndef NOPLAN9DEFINES -#define malloc p9malloc -#endif - -/* - * print routines (provided by ) - * -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; -}; - -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 ) - * -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 -{ - PNPROC = 1, - PNGROUP = 2, -}; - -/* extern int abs(int); */ -extern int p9atexit(void(*)(void)); -extern void p9atexitdont(void(*)(void)); -extern int atnotify(int(*)(void*, char*), int); -/* - * -extern double atof(char*); -extern int atoi(char*); -extern long atol(char*); - */ -extern vlong atoll(const 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 p9putenv(char*, 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); */ -/* extern double ldexp(double, int); */ -extern void p9longjmp(p9jmp_buf, int); -extern char* mktemp(char*); -extern int opentemp(char*); -/* extern double modf(double, double*); */ -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*); */ -/* extern int p9setjmp(p9jmp_buf); */ -#define p9setjmp(b) sigsetjmp((void*)(b), 1) -/* - * -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 p9syslog(int, char*, char*, ...); -extern long time(long*); -/* extern int tolower(int); */ -/* extern int toupper(int); */ -#ifndef NOPLAN9DEFINES -#define atexit p9atexit -#define atexitdont p9atexitdont -#define encrypt p9encrypt -#define decrypt p9decrypt -#define getenv p9getenv -#define getwd p9getwd -#define longjmp p9longjmp -#undef setjmp -#define setjmp p9setjmp -#define putenv p9putenv -#define notejmp p9notejmp -#define jmp_buf p9jmp_buf -#define syslog p9syslog -#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; - char state; -}; - -typedef -struct QLock -{ - Lock lock; - 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)); /* called only by the thread library */ - -typedef -struct RWLock -{ - Lock lock; - 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; -} 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**); - -/* - * 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 - -/* - * encryption - */ -extern int pushssl(int, char*, char*, char*, int*); -extern int pushtls(int, char*, char*, int, char*, char*); - -/* - * network services - */ -typedef struct NetConnInfo NetConnInfo; -struct NetConnInfo -{ - 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 -#undef RFNAMEG -#undef RFENVG -#undef RFCENVG -#undef RFCFDG -#undef RFCNAMEG -#endif - -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) */ -}; - -extern int ffork(int, void(*)(void*), void*); - -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; - -typedef -struct IOchunk -{ - void *addr; - ulong len; -} IOchunk; - -extern void _exits(char*); - -extern void abort(void); -extern int p9access(char*, int); -extern long p9alarm(ulong); -extern int await(char*, int); -extern int awaitnohang(char*, int); -/* extern int bind(char*, char*, int); give up */ -/* extern int brk(void*); */ -extern int p9chdir(char*); -extern int close(int); -extern int p9create(char*, int, ulong); -extern int p9dup(int, int); -extern int errstr(char*, uint); -extern int p9exec(char*, char*[]); -/* extern int execl(char*, ...); */ -/* 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 p9open(char*, int); -extern int fd2path(int, char*, int); -extern int p9pipe(int*); -/* - * use defs from -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); */ -extern int remove(const char*); -/* extern void* sbrk(ulong); */ -/* 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 Waitmsg* waitnohang(void); -extern int p9waitpid(void); -/* -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 -#define access p9access -#define create p9create -#define open p9open -#define pipe p9pipe -#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*, ...); -extern char* getns(void); -extern int sendfd(int, int); -extern int recvfd(int); -extern int post9pservice(int, 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{} -#define SET(x) ((x)=0) - -/* command line */ -extern char *argv0; -extern void __fixargv0(void); -#define ARGBEGIN for((argv0?0:(argv0=(__fixargv0(),*argv))),argv++,argc--;\ - argv[0] && argv[0][0]=='-' && argv[0][1];\ - argc--, argv++) {\ - char *_args, *_argt;\ - Rune _argc;\ - _args = &argv[0][1];\ - if(_args[0]=='-' && _args[1]==0){\ - argc--; argv++; break;\ - }\ - _argc = 0;\ - while(*_args && (_args += chartorune(&_argc, _args)))\ - switch(_argc) -#define ARGEND SET(_argt);USED(_argt);USED(_argc);USED(_args);}USED(argv);USED(argc); -#define ARGF() (_argt=_args, _args="",\ - (*_argt? _argt: argv[1]? (argc--, *++argv): 0)) -#define EARGF(x) (_argt=_args, _args="",\ - (*_argt? _argt: argv[1]? (argc--, *++argv): ((x), abort(), (char*)0))) - -#define ARGC() _argc - -#if defined(__cplusplus) -} -#endif -#endif /* _LIB9_H_ */ +#include +#include blob - d84870664e9f2ffcd6a93d5a6c514659645d39df blob + 1a560b6fc51ada418265a76d3e16e9849e18d66d --- include/libString.h +++ include/libString.h @@ -43,4 +43,4 @@ typedef struct Sinstack Sinstack; extern char *s_rdinstack(Sinstack*, String*); extern Sinstack *s_allocinstack(char*); extern void s_freeinstack(Sinstack*); -#endif BGETC +#endif /* BGETC */ blob - 25b042c12623573843d640fca918fcfe163e2255 blob + 64bb086743564bc4a54d5178eaa478f5f31dddd7 --- include/libc.h +++ include/libc.h @@ -1,2 +1,794 @@ -#include +/* + * Lib9 is miscellany from the Plan 9 C library that doesn't + * fit into libutf or into libfmt, but is still missing from traditional + * Unix C libraries. + */ +#ifndef _LIBC_H_ +#define _LIBC_H_ 1 +#if defined(__cplusplus) +extern "C" { +#endif + +/* + * Begin usual libc.h + */ + +#define nil ((void*)0) +#define nelem(x) (sizeof(x)/sizeof((x)[0])) + +#ifndef offsetof +#define offsetof(s, m) (ulong)(&(((s*)0)->m)) +#endif + +/* + * mem routines (provided by system ) + * +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 ) + * +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 +{ + UTFmax = 3, + Runesync = 0x80, + Runeself = 0x80, + Runeerror = 0x80, +}; +*/ + +/* + * rune routines (provided by + * +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 ) + * +extern void* malloc(ulong); + */ +extern void* p9malloc(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*); +*/ +#ifndef NOPLAN9DEFINES +#define malloc p9malloc +#endif + +/* + * print routines (provided by ) + * +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; +}; + +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 ) + * +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 +{ + PNPROC = 1, + PNGROUP = 2, +}; + +/* extern int abs(int); */ +extern int p9atexit(void(*)(void)); +extern void p9atexitdont(void(*)(void)); +extern int atnotify(int(*)(void*, char*), int); +/* + * +extern double atof(char*); +extern int atoi(char*); +extern long atol(char*); + */ +extern vlong atoll(const 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 p9putenv(char*, 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); */ +/* extern double ldexp(double, int); */ +extern void p9longjmp(p9jmp_buf, int); +extern char* mktemp(char*); +extern int opentemp(char*); +/* extern double modf(double, double*); */ +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*); */ +/* extern int p9setjmp(p9jmp_buf); */ +#define p9setjmp(b) sigsetjmp((void*)(b), 1) +/* + * +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 p9syslog(int, char*, char*, ...); +extern long p9time(long*); +/* extern int tolower(int); */ +/* extern int toupper(int); */ +#ifndef NOPLAN9DEFINES +#define atexit p9atexit +#define atexitdont p9atexitdont +#define encrypt p9encrypt +#define decrypt p9decrypt +#define getenv p9getenv +#define getwd p9getwd +#define longjmp p9longjmp +#undef setjmp +#define setjmp p9setjmp +#define putenv p9putenv +#define notejmp p9notejmp +#define jmp_buf p9jmp_buf +#define syslog p9syslog +#define time p9time +#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; + char state; +}; + +typedef +struct QLock +{ + Lock lock; + 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)); /* called only by the thread library */ + +typedef +struct RWLock +{ + Lock lock; + 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; +} 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**); + +/* + * 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 + +/* + * encryption + */ +extern int pushssl(int, char*, char*, char*, int*); +extern int pushtls(int, char*, char*, int, char*, char*); + +/* + * network services + */ +typedef struct NetConnInfo NetConnInfo; +struct NetConnInfo +{ + 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 +#undef RFNAMEG +#undef RFENVG +#undef RFCENVG +#undef RFCFDG +#undef RFCNAMEG +#endif + +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) */ +}; + +extern int ffork(int, void(*)(void*), void*); + +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; + +typedef +struct IOchunk +{ + void *addr; + ulong len; +} IOchunk; + +extern void _exits(char*); + +extern void abort(void); +extern int p9access(char*, int); +extern long p9alarm(ulong); +extern int await(char*, int); +extern int awaitnohang(char*, int); +/* extern int bind(char*, char*, int); give up */ +/* extern int brk(void*); */ +extern int p9chdir(char*); +extern int close(int); +extern int p9create(char*, int, ulong); +extern int p9dup(int, int); +extern int errstr(char*, uint); +extern int p9exec(char*, char*[]); +/* extern int execl(char*, ...); */ +/* 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 p9open(char*, int); +extern int fd2path(int, char*, int); +extern int p9pipe(int*); +/* + * use defs from +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); */ +extern int remove(const char*); +/* extern void* sbrk(ulong); */ +/* 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 Waitmsg* waitnohang(void); +extern int p9waitpid(void); +/* +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 +#define access p9access +#define create p9create +#define open p9open +#define pipe p9pipe +#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*, ...); +extern char* getns(void); +extern char* get9root(void); +extern char* unsharp(char*); +extern int sendfd(int, int); +extern int recvfd(int); +extern int post9pservice(int, 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{} +#define SET(x) ((x)=0) + +/* command line */ +extern char *argv0; +extern void __fixargv0(void); +#define ARGBEGIN for((argv0?0:(argv0=(__fixargv0(),*argv))),argv++,argc--;\ + argv[0] && argv[0][0]=='-' && argv[0][1];\ + argc--, argv++) {\ + char *_args, *_argt;\ + Rune _argc;\ + _args = &argv[0][1];\ + if(_args[0]=='-' && _args[1]==0){\ + argc--; argv++; break;\ + }\ + _argc = 0;\ + while(*_args && (_args += chartorune(&_argc, _args)))\ + switch(_argc) +#define ARGEND SET(_argt);USED(_argt);USED(_argc);USED(_args);}USED(argv);USED(argc); +#define ARGF() (_argt=_args, _args="",\ + (*_argt? _argt: argv[1]? (argc--, *++argv): 0)) +#define EARGF(x) (_argt=_args, _args="",\ + (*_argt? _argt: argv[1]? (argc--, *++argv): ((x), abort(), (char*)0))) + +#define ARGC() _argc + +#if defined(__cplusplus) +} +#endif +#endif /* _LIB9_H_ */ blob - e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 blob + 4716ce4f1f987092e4e103fb2b1a16685d0774c7 --- include/u.h +++ include/u.h @@ -0,0 +1,93 @@ +#ifndef _U_H_ +#define _U_H_ 1 +#if defined(__cplusplus) +extern "C" { +#endif + +#define _BSD_SOURCE 1 +#define _SVID_SOURCE 1 +#define _XOPEN_SOURCE 1000 +#define _XOPEN_SOURCE_EXTENDED 1 +#define _LARGEFILE64_SOURCE 1 +#define _FILE_OFFSET_BITS 64 +#define __EXTENSIONS__ 1 /* SunOS */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * 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 +# if defined(__USE_MISC) +# undef _NEEDUSHORT +# undef _NEEDUINT +# undef _NEEDULONG +# endif +#endif +#if defined(__sun__) +# include +# undef _NEEDUSHORT +# undef _NEEDUINT +# undef _NEEDULONG +#endif +#if defined(__FreeBSD__) +# include +# if !defined(_POSIX_SOURCE) +# undef _NEEDUSHORT +# undef _NEEDUINT +# endif +#endif +#if defined(__APPLE__) +# include +# undef _NEEDUSHORT +# undef _NEEDUINT +# define _NEEDLL 1 +#endif + +typedef signed char schar; +typedef unsigned int u32int; +#ifdef _NEEDUCHAR + typedef unsigned char uchar; +#endif +#ifdef _NEEDUSHORT + typedef unsigned short ushort; +#endif +#ifdef _NEEDUINT + typedef unsigned int uint; +#endif +#ifdef _NEEDULONG + typedef unsigned long ulong; +#endif +typedef unsigned long long uvlong; +typedef long long vlong; +typedef uvlong u64int; +typedef uchar u8int; +typedef ushort u16int; + +#undef _NEEDUCHAR +#undef _NEEDUSHORT +#undef _NEEDUINT +#undef _NEEDULONG + +#if defined(__cplusplus) +} +#endif +#endif blob - 8acd5524c8a8a0e49ea4267757663ebab9095dd4 blob + 644385c1a34f61006838ea6e15a16fd6770fb661 --- src/cmd/9pserve.c +++ src/cmd/9pserve.c @@ -1150,7 +1150,7 @@ rewritehdr(Fcall *f, uchar *pkt) } } -#ifdef _LIB9_H_ +#ifdef _LIBC_H_ /* unix select-based polling */ struct Ioproc { blob - c5a2c4244d4e5e41c372ea8b8b487447d87915e3 blob + 50c0cfc92833845183ed261eadd826ddf665eb4b --- src/cmd/9term/9term.c +++ src/cmd/9term/9term.c @@ -1,15 +1,24 @@ -#include "9term.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "term.h" -#define fatal sysfatal - typedef struct Text Text; typedef struct Readbuf Readbuf; enum { - /* these are chosen to use malloc()'s properties well */ HiWater = 640000, /* max size of history */ - LoWater = 330000, /* min size of history after max'ed */ + LoWater = 400000, /* min size of history after max'ed */ + MinWater = 20000, }; /* various geometric paramters */ @@ -30,21 +39,22 @@ enum Scroll, }; - -#define SCROLLKEY Kdown #define ESC 0x1B -#define CUT 0x18 /* ctrl-x */ -#define COPY 0x03 /* crtl-c */ -#define PASTE 0x16 /* crtl-v */ -#define BACKSCROLLKEY Kup +#define CUT 0x18 /* ctrl-x */ +#define COPY 0x03 /* crtl-c */ +#define PASTE 0x16 /* crtl-v */ #define READBUFSIZE 8192 +#define TRUE 1 +#define FALSE 0 + struct Text { Frame *f; /* frame ofr terminal */ Mouse m; uint nr; /* num of runes in term */ + uint maxr; /* max num of runes in r */ Rune *r; /* runes for term */ uint nraw; /* num of runes in raw buffer */ Rune *raw; /* raw buffer */ @@ -72,7 +82,6 @@ void fill(void); void tcheck(void); void updatesel(void); void doreshape(void); -void rcstart(int fd[2], int, char**); void runewrite(Rune*, int); void consread(void); void conswrite(char*, int); @@ -99,11 +108,10 @@ void scrdraw(void); void scroll(int); void hostproc(void *arg); void hoststart(void); -int getchildwd(int, char*, int); void plumbstart(void); void plumb(uint, uint); void plumbclick(uint*, uint*); -int getpts(int fd[], char *slave); +uint insert(Rune*, int, uint, int); #define runemalloc(n) malloc((n)*sizeof(Rune)) #define runerealloc(a, n) realloc(a, (n)*sizeof(Rune)) @@ -115,7 +123,7 @@ int rawon; /* raw mode */ int scrolling; /* window scrolls */ int clickmsec; /* time of last click */ uint clickq0; /* point of last click */ -int rcfd[2]; +int rcfd; int rcpid; int maxtab; int use9wm; @@ -211,7 +219,7 @@ threadmain(int argc, char *argv[]) mc = initmouse(nil, screen); kc = initkeyboard(nil); - rcstart(rcfd, argc, argv); + rcpid = rcstart(argc, argv, &rcfd); hoststart(); plumbstart(); @@ -265,8 +273,9 @@ hostproc(void *arg) i = 0; for(;;){ + /* Let typing have a go -- maybe there's a rubout waiting. */ i = 1-i; /* toggle */ - n = threadread(rcfd[0], rcbuf[i].data, sizeof rcbuf[i].data); + n = threadread(rcfd, rcbuf[i].data, sizeof rcbuf[i].data); if(n <= 0){ if(n < 0) fprint(2, "9term: host read error: %r\n"); @@ -308,7 +317,7 @@ loop(void) a[2].op = CHANNOP;; switch(alt(a)) { default: - fatal("impossible"); + sysfatal("impossible"); case 0: t.m = mc->m; mouse(); @@ -330,23 +339,23 @@ void doreshape(void) { if(getwindow(display, Refnone) < 0) - fatal("can't reattach to window"); + sysfatal("can't reattach to window"); draw(screen, screen->r, cols[BACK], nil, ZP); geom(); scrdraw(); } -struct winsize ows; - void geom(void) { - struct winsize ws; Point p; Rectangle r; r = screen->r; - scrollr = screen->r; + r.min.y++; + r.max.y--; + + scrollr = r; scrollr.max.x = r.min.x+Scrollwid; lastsr = Rect(0,0,0,0); @@ -362,13 +371,7 @@ geom(void) if(p.x == 0 || p.y == 0) return; - ws.ws_row = Dy(r)/p.y; - ws.ws_col = Dx(r)/p.x; - ws.ws_xpixel = Dx(r); - ws.ws_ypixel = Dy(r); - if(ws.ws_row != ows.ws_row || ws.ws_col != ows.ws_col) - if(ioctl(rcfd[0], TIOCSWINSZ, &ws) < 0) - fprint(2, "ioctl: %r\n"); + updatewinsize(Dy(r)/p.y, Dx(r)/p.x, Dx(r), Dy(r)); } void @@ -585,7 +588,10 @@ domenu2(int but) show(t.q0); break; case Send: - snarf(); + if(t.q0 != t.q1) + snarf(); + else + snarfupdate(); t.q0 = t.q1 = t.nr; updatesel(); paste(t.snarf, t.nsnarf, 1); @@ -605,37 +611,182 @@ domenu2(int but) plumb(t.q0, t.q1); break; default: - fatal("bad menu item"); + sysfatal("bad menu item"); } +} + +int +windfilewidth(uint q0, int oneelement) +{ + uint q; + Rune r; + + q = q0; + while(q > 0){ + r = t.r[q-1]; + if(r<=' ') + break; + if(oneelement && r=='/') + break; + --q; + } + return q0-q; } void +showcandidates(Completion *c) +{ + int i; + Fmt f; + Rune *rp; + uint nr, qline, q0; + char *s; + + runefmtstrinit(&f); + if (c->nmatch == 0) + s = "[no matches in "; + else + s = "["; + if(c->nfile > 32) + fmtprint(&f, "%s%d files]\n", s, c->nfile); + else{ + fmtprint(&f, "%s", s); + for(i=0; infile; i++){ + if(i > 0) + fmtprint(&f, " "); + fmtprint(&f, "%s", c->filename[i]); + } + fmtprint(&f, "]\n"); + } + /* place text at beginning of line before host point */ + qline = t.qh; + while(qline>0 && t.r[qline-1] != '\n') + qline--; + + rp = runefmtstrflush(&f); + nr = runestrlen(rp); + + q0 = t.q0; + q0 += insert(rp, nr, qline, 0) - qline; + free(rp); + t.q0 = q0+nr; + t.q1 = q0+nr; + updatesel(); +} + +Rune* +namecomplete(void) +{ + int nstr, npath; + Rune *rp, *path, *str; + Completion *c; + char *s, *dir, *root; + + /* control-f: filename completion; works back to white space or / */ + if(t.q0' ') /* must be at end of word */ + return nil; + nstr = windfilewidth(t.q0, TRUE); + str = runemalloc(nstr); + runemove(str, t.r+(t.q0-nstr), nstr); + npath = windfilewidth(t.q0-nstr, FALSE); + path = runemalloc(npath); + runemove(path, t.r+(t.q0-nstr-npath), npath); + rp = nil; + + /* is path rooted? if not, we need to make it relative to window path */ + if(npath>0 && path[0]=='/'){ + dir = malloc(UTFmax*npath+1); + sprint(dir, "%.*S", npath, path); + }else{ + if(strcmp(wdir, "") == 0) + root = "."; + else + root = wdir; + dir = malloc(strlen(root)+1+UTFmax*npath+1); + sprint(dir, "%s/%.*S", root, npath, path); + } + dir = cleanname(dir); + + s = smprint("%.*S", nstr, str); + c = complete(dir, s); + free(s); + if(c == nil) + goto Return; + + if(!c->advance) + showcandidates(c); + + if(c->advance) + rp = runesmprint("%s", c->string); + + Return: + freecompletion(c); + free(dir); + free(path); + free(str); + return rp; +} + +void key(Rune r) { - uint sig; + Rune *rp; + int nr; if(r == 0) return; - if(r==SCROLLKEY){ /* scroll key */ + switch(r){ + case Kpgup: + setorigin(backnl(t.org, t.f->maxlines*2/3), 1); + return; + case Kpgdown: setorigin(line2q(t.f->maxlines*2/3), 1); if(t.qh<=t.org+t.f->nchars) consread(); return; - }else if(r == BACKSCROLLKEY){ - setorigin(backnl(t.org, t.f->maxlines*2/3), 1); + case Kup: + setorigin(backnl(t.org, t.f->maxlines/3), 1); return; - }else if(r == CUT){ + case Kdown: + setorigin(line2q(t.f->maxlines/3), 1); + if(t.qh<=t.org+t.f->nchars) + consread(); + return; + case Kleft: + if(t.q0 > 0){ + t.q0--; + t.q1 = t.q0; + updatesel(); + show(t.q0); + } + return; + case Kright: + if(t.q1 < t.nr){ + t.q1++; + t.q0 = t.q1; + updatesel(); + show(t.q1); + } + return; + case Khome: + show(0); + return; + case Kend: + case 0x05: + show(t.nr); + return; + case CUT: snarf(); cut(); if(scrolling) show(t.q0); return; - }else if(r == COPY){ + case COPY: snarf(); if(scrolling) show(t.q0); return; - }else if(r == PASTE){ + case PASTE: snarfupdate(); paste(t.snarf, t.nsnarf, 0); if(scrolling) @@ -661,19 +812,21 @@ key(Rune r) snarf(); switch(r) { + case 0x03: /* ^C: send interrupt */ case 0x7F: /* DEL: send interrupt */ t.qh = t.q0 = t.q1 = t.nr; show(t.q0); - goto Default; -fprint(2, "send interrupt to %d group\n", rcpid); -#ifdef TIOCSIG - sig = 2; /* SIGINT */ - if(ioctl(rcfd[0], TIOCSIG, &sig) < 0) - fprint(2, "sending interrupt: %r\n"); -#else - postnote(PNGROUP, rcpid, "interrupt"); -#endif + write(rcfd, "\x7F", 1); break; + case 0x06: /* ^F: file name completion */ + case Kins: /* Insert: file name completion */ + rp = namecomplete(); + if(rp == nil) + return; + nr = runestrlen(rp); + paste(rp, nr, 1); + free(rp); + return; case 0x08: /* ^H: erase character */ case 0x15: /* ^U: erase line */ case 0x17: /* ^W: erase word */ @@ -682,7 +835,6 @@ fprint(2, "send interrupt to %d group\n", rcpid); cut(); break; default: - Default: paste(&r, 1, 1); break; } @@ -773,7 +925,7 @@ consread(void) } /* take out control-d when not doing a zero length write */ n = p-buf; - if(write(rcfd[1], buf, n) < 0) + if(write(rcfd, buf, n) < 0) exits(0); /* mallocstats(); */ } @@ -833,7 +985,6 @@ conswrite(char *p, int n) void runewrite(Rune *r, int n) { - uint m; int i; uint initial; uint q0, q1; @@ -896,37 +1047,7 @@ runewrite(Rune *r, int n) updatesel(); } - if(t.nr>HiWater && t.qh>=t.org){ - m = HiWater-LoWater; - if(m > t.org); - m = t.org; - t.org -= m; - t.qh -= m; - if(t.q0 > m) - t.q0 -= m; - else - t.q0 = 0; - if(t.q1 > m) - t.q1 -= m; - else - t.q1 = 0; - t.nr -= m; - runemove(t.r, t.r+m, t.nr); - } - t.r = runerealloc(t.r, t.nr+n); - runemove(t.r+t.qh+n, t.r+t.qh, t.nr-t.qh); - runemove(t.r+t.qh, r, n); - t.nr += n; - if(t.qh < t.org) - t.org += n; - else if(t.qh <= t.f->nchars+t.org) - frinsert(t.f, r, r+n, t.qh-t.org); - if (t.qh <= t.q0) - t.q0 += n; - if (t.qh <= t.q1) - t.q1 += n; - t.qh += n; - updatesel(); + insert(r, n, t.qh, 1); } @@ -1009,12 +1130,83 @@ snarf(void) putsnarf(sbuf); } +uint +min(uint x, uint y) +{ + if(x < y) + return x; + return y; +} + +uint +max(uint x, uint y) +{ + if(x > y) + return x; + return y; +} + +uint +insert(Rune *r, int n, uint q0, int hostwrite) +{ + uint m; + + if(n == 0) + return q0; + if(t.nr+n>HiWater && q0>=t.org && q0>=t.qh){ + m = min(HiWater-LoWater, min(t.org, t.qh)); + t.org -= m; + t.qh -= m; + if(t.q0 > m) + t.q0 -= m; + else + t.q0 = 0; + if(t.q1 > m) + t.q1 -= m; + else + t.q1 = 0; + t.nr -= m; + runemove(t.r, t.r+m, t.nr); + q0 -= m; + } + if(t.nr+n > t.maxr){ + /* + * Minimize realloc breakage: + * Allocate at least MinWater + * Double allocation size each time + * But don't go much above HiWater + */ + m = max(min(2*(t.nr+n), HiWater), t.nr+n)+MinWater; + if(m > HiWater) + m = max(HiWater+MinWater, t.nr+n); + if(m > t.maxr){ + t.r = runerealloc(t.r, m); + t.maxr = m; + } + } + runemove(t.r+q0+n, t.r+q0, t.nr-q0); + runemove(t.r+q0, r, n); + t.nr += n; + /* if output touches, advance selection, not qh; works best for keyboard and output */ + if(q0 <= t.q1) + t.q1 += n; + if(q0 <= t.q0) + t.q0 += n; + if(q0 < t.qh || (q0==t.qh && hostwrite)) + t.qh += n; + else + consread(); + if(q0 < t.org) + t.org += n; + else if(q0 <= t.org+t.f->nchars) + frinsert(t.f, r, r+n, q0-t.org); + return q0; +} + void paste(Rune *r, int n, int advance) { Rune *rbuf; - uint m; - uint q0; if(rawon && t.q0==t.nr){ addraw(r, n); @@ -1024,6 +1216,7 @@ paste(Rune *r, int n, int advance) cut(); if(n == 0) return; + /* * if this is a button2 execute then we might have been passed * runes inside the buffer. must save them before realloc. @@ -1033,38 +1226,9 @@ paste(Rune *r, int n, int advance) rbuf = runemalloc(n); runemove(rbuf, r, n); r = rbuf; - } - - if(t.nr>HiWater && t.q0>=t.org && t.q0>=t.qh){ - m = HiWater-LoWater; - if(m > t.org) - m = t.org; - if(m > t.qh); - m = t.qh; - t.org -= m; - t.qh -= m; - t.q0 -= m; - t.q1 -= m; - t.nr -= m; - runemove(t.r, t.r+m, t.nr); } - t.r = runerealloc(t.r, t.nr+n); - q0 = t.q0; - runemove(t.r+q0+n, t.r+q0, t.nr-q0); - runemove(t.r+q0, r, n); - t.nr += n; - if(q0 < t.qh) - t.qh += n; - else - consread(); - if(q0 < t.org) - t.org += n; - else if(q0 <= t.f->nchars+t.org) - frinsert(t.f, r, r+n, q0-t.org); - if(advance) - t.q0 += n; - t.q1 += n; + insert(r, n, t.q0, 0); updatesel(); free(rbuf); } @@ -1322,61 +1486,6 @@ clickmatch(int cl, int cr, int dir, uint *q) } void -rcstart(int fd[2], int argc, char **argv) -{ - int pid; - char *xargv[3]; - char slave[256]; - int sfd; - - if(argc == 0){ - argc = 2; - argv = xargv; - argv[0] = getenv("SHELL"); - if(argv[0] == 0) - argv[0] = "rc"; - argv[1] = "-i"; - argv[2] = 0; - } - /* - * fd0 is slave (tty), fd1 is master (pty) - */ - fd[0] = fd[1] = -1; - if(getpts(fd, slave) < 0) - fprint(2, "getpts: %r\n"); - - switch(pid = fork()) { - case 0: - putenv("TERM", "9term"); - close(fd[1]); - setsid(); -// tcsetpgrp(0, pid); - sfd = open(slave, ORDWR); - if(sfd < 0) - fprint(2, "open %s: %r\n", slave); - if(ioctl(sfd, TIOCSCTTY, 0) < 0) - fprint(2, "ioctl TIOCSCTTY: %r\n"); -// ioctl(sfd, I_PUSH, "ptem"); -// ioctl(sfd, I_PUSH, "ldterm"); - dup(sfd, 0); - dup(sfd, 1); - dup(sfd, 2); - system("stty tabs -onlcr -echo erase ^h intr ^?"); - execvp(argv[0], argv); - fprint(2, "exec %s failed: %r\n", argv[0]); - _exits("oops"); - break; - case -1: - fatal("proc failed: %r"); - break; - } - close(fd[0]); - fd[0] = fd[1]; - - rcpid = pid; -} - -void tcheck(void) { Frame *f; @@ -1421,7 +1530,7 @@ scrdraw(void) freeimage(scrx); scrx = allocimage(display, Rect(0, 0, 32, r.max.y), screen->chan, 1, DPaleyellow); if(scrx == 0) - fatal("scroll balloc"); + sysfatal("scroll balloc"); } r1.min.x = 0; r1.max.x = Dx(r); @@ -1525,16 +1634,11 @@ plumb(uint q0, uint q1) char *p; int i, p0, n; char cbuf[100]; - char *w; - if(getchildwd(rcpid, childwdir, sizeof childwdir) == 0) - w = childwdir; - else - w = wdir; pm = malloc(sizeof(Plumbmsg)); pm->src = strdup("9term"); pm->dst = 0; - pm->wdir = strdup(w); + pm->wdir = strdup(wdir); pm->type = strdup("text"); pm->data = nil; if(q1 > q0) blob - 4e8d61f3887e441116c1c29fc1aa70226fc10962 blob + 57a8359e14a0285ea0f2162eb61a27a0f92175fe --- src/cmd/9term/9term.h +++ src/cmd/9term/9term.h @@ -1,19 +1,4 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef __linux__ -#include -#endif - -extern int getchildwd(int, char*, int); extern int getpts(int[], char*); - +extern int childpty(int[], char*); +extern void updatewinsize(int, int, int, int); +extern int rcfd[]; blob - e8b894dc83698fd802a3df51fef6c87a8d32cc60 blob + 7022d4d97bbcc6463743c5896671c5b72df537eb --- src/cmd/9term/FreeBSD.c +++ src/cmd/9term/FreeBSD.c @@ -1,17 +1,43 @@ #include "9term.h" +#include +#include #include int -getchildwd(int pid, char *wdir, int bufn) +getpts(int fd[], char *slave) { - USED(pid); - USED(wdir); - USED(bufn); - return -1; + return openpty(&fd[1], &fd[0], slave, 0, 0); } int -getpts(int fd[], char *slave) +childpty(int fd[], char *slave) { - return openpty(&fd[1], &fd[0], slave, 0, 0); + int sfd; + + close(fd[1]); + setsid(); + sfd = open(slave, ORDWR); + if(sfd < 0) + sysfatal("open %s: %r\n", slave); + if(ioctl(sfd, TIOCSCTTY, 0) < 0) + fprint(2, "ioctl TIOCSCTTY: %r\n"); + return sfd; } + +struct winsize ows; + +void +updatewinsize(int row, int col, int dx, int dy) +{ + struct winsize ws; + + ws.ws_row = row; + ws.ws_col = col; + ws.ws_xpixel = dx; + ws.ws_ypixel = dy; + if(ws.ws_row != ows.ws_row || ws.ws_col != ows.ws_col) + if(ioctl(rcfd[0], TIOCSWINSZ, &ws) < 0) + fprint(2, "ioctl: %r\n"); + ows = ws; +} + blob - 7dd22371be723649b347508f25bcd58ac0b2a4f6 blob + 872417e6c501b8c3f1f8d0bcaba529e0f6110c67 --- src/cmd/9term/Linux.c +++ src/cmd/9term/Linux.c @@ -1,22 +1,46 @@ +#include +#include +#include +#include +#include #include "9term.h" int -getchildwd(int pid, char *wdir, int bufn) +getpts(int fd[], char *slave) { - char path[256]; - int n; - - snprint(path, sizeof path, "/proc/%d/cwd", pid); - n = readlink(path, wdir, bufn); - if(n < 0) - return -1; - wdir[n] = '\0'; + openpty(&fd[1], &fd[0], slave, 0, 0); return 0; } int -getpts(int fd[], char *slave) +childpty(int fd[], char *slave) { - openpty(&fd[1], &fd[0], slave, 0, 0); - return 0; + int sfd; + + close(fd[1]); + setsid(); + sfd = open(slave, ORDWR); + if(sfd < 0) + sysfatal("open %s: %r\n", slave); + if(ioctl(sfd, TIOCSCTTY, 0) < 0) + fprint(2, "ioctl TIOCSCTTY: %r\n"); + return sfd; } + +struct winsize ows; + +void +updatewinsize(int row, int col, int dx, int dy) +{ + struct winsize ws; + + ws.ws_row = row; + ws.ws_col = col; + ws.ws_xpixel = dx; + ws.ws_ypixel = dy; + if(ws.ws_row != ows.ws_row || ws.ws_col != ows.ws_col) + if(ioctl(rcfd[0], TIOCSWINSZ, &ws) < 0) + fprint(2, "ioctl: %r\n"); + ows = ws; +} + blob - 6a37ab337851a56a2708834897f164ae930f066c blob + d7db9fc5de818620c1d86962c3a4befd6154d506 --- src/cmd/9term/SunOS.c +++ src/cmd/9term/SunOS.c @@ -1,23 +1,8 @@ #include "9term.h" +#include +#include int -getchildwd(int pid, char *wdir, int bufn) -{ - char path[256]; - char cwd[256]; - - if(getcwd(cwd, sizeof cwd) < 0) - return -1; - snprint(path, sizeof path, "/proc/%d/cwd", pid); - if(chdir(path) < 0) - return -1; - if(getcwd(wdir, bufn) < 0) - return -1; - chdir(cwd); - return 0; -} - -int getpts(int fd[], char *slave) { fd[1] = open("/dev/ptmx", ORDWR); @@ -28,3 +13,21 @@ getpts(int fd[], char *slave) fd[0] = open(slave, OREAD); return 0; } + +struct winsize ows; + +void +updatewinsize(int row, int col, int dx, int dy) +{ + struct winsize ws; + + ws.ws_row = row; + ws.ws_col = col; + ws.ws_xpixel = dx; + ws.ws_ypixel = dy; + if(ws.ws_row != ows.ws_row || ws.ws_col != ows.ws_col) + if(ioctl(rcfd[0], TIOCSWINSZ, &ws) < 0) + fprint(2, "ioctl: %r\n"); + ows = ws; +} + blob - d0d5ca727ee2bbde366ff4a1fe5983b5a9c0facb blob + 8701ad9c4f21d9c76b8dbe9bbfcde00720c1c51e --- src/cmd/9term/mkfile +++ src/cmd/9term/mkfile @@ -1,15 +1,15 @@ PLAN9=../../.. <$PLAN9/src/mkhdr -TARG=9term +TARG=9term win OFILES=\ - 9term.$O\ + rcstart.$O\ $SYSNAME.$O\ -SHORTLIB=frame draw plumb fs mux thread 9 +SHORTLIB=complete frame draw plumb fs mux thread 9 -<$PLAN9/src/mkone +<$PLAN9/src/mkmany LDFLAGS=-L$X11/lib -lX11 -lutil blob - /dev/null blob + 7596bc41dabe45627fe6e7a63ca4a6d545bde70d (mode 644) --- /dev/null +++ src/cmd/9term/rcstart.c @@ -0,0 +1,51 @@ +#include +#include +#include "term.h" + +int +rcstart(int argc, char **argv, int *pfd) +{ + int pid; + int fd[2]; + char *xargv[3]; + char slave[256]; + int sfd; + + if(argc == 0){ + argc = 2; + argv = xargv; + argv[0] = getenv("SHELL"); + if(argv[0] == 0) + argv[0] = "rc"; + argv[1] = "-i"; + argv[2] = 0; + } + /* + * fd0 is slave (tty), fd1 is master (pty) + */ + fd[0] = fd[1] = -1; + if(getpts(fd, slave) < 0) + fprint(2, "getpts: %r\n"); + + + switch(pid = fork()) { + case 0: + putenv("TERM", "9term"); + sfd = childpty(fd, slave); + dup(sfd, 0); + dup(sfd, 1); + dup(sfd, 2); + system("stty tabs -onlcr -echo erase ^h intr ^?"); + execvp(argv[0], argv); + fprint(2, "exec %s failed: %r\n", argv[0]); + _exits("oops"); + break; + case -1: + sysfatal("proc failed: %r"); + break; + } + close(fd[0]); + *pfd = fd[1]; + return pid; +} + blob - /dev/null blob + a608b7edf837e9ed63229c934b86ee54be73ce8d (mode 644) --- /dev/null +++ src/cmd/9term/term.h @@ -0,0 +1,5 @@ +extern int getpts(int[], char*); +extern int childpty(int[], char*); +extern void updatewinsize(int, int, int, int); +extern int rcfd; +extern int rcstart(int, char*[], int*); blob - /dev/null blob + 95d84a32fa8fb64afae6a062f45c08f989dffdb5 (mode 644) --- /dev/null +++ src/cmd/9term/win.c @@ -0,0 +1,693 @@ +#include +#include +#include +#include +#include +#include "term.h" + +#define EVENTSIZE 256 +#define STACK 32768 + +typedef struct Event Event; +typedef struct Q Q; + +struct Event +{ + int c1; + int c2; + int q0; + int q1; + int flag; + int nb; + int nr; + char b[EVENTSIZE*UTFmax+1]; + Rune r[EVENTSIZE+1]; +}; + +Event blank = { + 'M', + 'X', + 0, 0, 0, 1, 1, + { ' ', 0 }, + { ' ', 0 }, +}; + +struct Q +{ + QLock lk; + int p; + int k; +}; + +Q q; + +Fid *eventfd; +Fid *addrfd; +Fid *datafd; +Fid *ctlfd; +// int bodyfd; + +char *typing; +int ntypeb; +int ntyper; +int ntypebreak; +int debug; +int rcfd; + +char *name; + +char **prog; +Channel *cwait; +int pid = -1; + +int label(char*, int); +void error(char*); +void stdinproc(void*); +void stdoutproc(void*); +void type(Event*, int, Fid*, Fid*); +void sende(Event*, int, Fid*, Fid*, Fid*, int); +char *onestring(int, char**); +int delete(Event*); +void deltype(uint, uint); +void runproc(void*); + +int +fsfidprint(Fid *fid, char *fmt, ...) +{ + char buf[256]; + va_list arg; + int n; + + va_start(arg, fmt); + n = vsnprint(buf, sizeof buf, fmt, arg); + va_end(arg); + return fswrite(fid, buf, n); +} + +void +usage(void) +{ + fprint(2, "usage: win cmd args...\n"); + threadexitsall("usage"); +} + +int +nopipes(void *v, char *msg) +{ + USED(v); + if(strcmp(msg, "sys: write on closed pipe") == 0) + return 1; + return 0; +} + +void +waitthread(void *v) +{ + recvp(cwait); + threadexitsall(nil); +} + +void +threadmain(int argc, char **argv) +{ + int fd, id; + char buf[256]; + char buf1[128]; + Fsys *fs; + + ARGBEGIN{ + case 'd': + debug = 1; + break; + default: + usage(); + }ARGEND + + prog = argv; + + if(argc > 0){ + name = argv[0]; + argc--; + argv++; + }else + name = "gnot"; + + threadnotify(nopipes, 1); + if((fs = nsmount("acme", "")) < 0) + sysfatal("nsmount acme: %r"); + ctlfd = fsopen(fs, "new/ctl", ORDWR|OCEXEC); + if(ctlfd < 0 || fsread(ctlfd, buf, 12) != 12) + sysfatal("ctl: %r"); + id = atoi(buf); + sprint(buf, "%d/tag", id); + fd = fsopenfd(fs, buf, OWRITE|OCEXEC); + write(fd, " Send Delete", 12); + close(fd); + sprint(buf, "%d/event", id); + eventfd = fsopen(fs, buf, ORDWR|OCEXEC); + sprint(buf, "%d/addr", id); + addrfd = fsopen(fs, buf, ORDWR|OCEXEC); + sprint(buf, "%d/data", id); + datafd = fsopen(fs, buf, ORDWR|OCEXEC); + sprint(buf, "%d/body", id); +/* bodyfd = fsopenfd(fs, buf, ORDWR|OCEXEC); */ + if(eventfd==nil || addrfd==nil || datafd==nil) + sysfatal("data files: %r"); +/* + if(eventfd<0 || addrfd<0 || datafd<0 || bodyfd<0) + sysfatal("data files: %r"); +*/ + fsunmount(fs); + + cwait = threadwaitchan(); + threadcreate(waitthread, nil, STACK); + pid = rcstart(argc, argv, &rcfd); + if(pid == -1) + sysfatal("exec failed"); + + getwd(buf1, sizeof buf1); + sprint(buf, "name %s/-%s\n0\n", buf1, name); + fswrite(ctlfd, buf, strlen(buf)); + sprint(buf, "dumpdir %s/\n", buf1); + fswrite(ctlfd, buf, strlen(buf)); + sprint(buf, "dump %s\n", onestring(argc, argv)); + fswrite(ctlfd, buf, strlen(buf)); + + threadcreate(stdoutproc, nil, STACK); + stdinproc(nil); +} + +void +error(char *s) +{ + if(s) + fprint(2, "win: %s: %r\n", s); + else + s = "kill"; + if(pid != -1) + postnote(PNGROUP, pid, "hangup"); + threadexitsall(s); +} + +char* +onestring(int argc, char **argv) +{ + char *p; + int i, n; + static char buf[1024]; + + if(argc == 0) + return ""; + p = buf; + for(i=0; i= buf+sizeof buf) + break; + memmove(p, argv[i], n); + p += n; + *p++ = ' '; + } + p[-1] = 0; + return buf; +} + +int +getec(Fid *efd) +{ + static char buf[8192]; + static char *bufp; + static int nbuf; + + if(nbuf == 0){ + nbuf = fsread(efd, buf, sizeof buf); + if(nbuf <= 0) + error(nil); + bufp = buf; + } + --nbuf; + return *bufp++; +} + +int +geten(Fid *efd) +{ + int n, c; + + n = 0; + while('0'<=(c=getec(efd)) && c<='9') + n = n*10+(c-'0'); + if(c != ' ') + error("event number syntax"); + return n; +} + +int +geter(Fid *efd, char *buf, int *nb) +{ + Rune r; + int n; + + r = getec(efd); + buf[0] = r; + n = 1; + if(r < Runeself) + goto Return; + while(!fullrune(buf, n)) + buf[n++] = getec(efd); + chartorune(&r, buf); + Return: + *nb = n; + return r; +} + +void +gete(Fid *efd, Event *e) +{ + int i, nb; + + e->c1 = getec(efd); + e->c2 = getec(efd); + e->q0 = geten(efd); + e->q1 = geten(efd); + e->flag = geten(efd); + e->nr = geten(efd); + if(e->nr > EVENTSIZE) + error("event string too long"); + e->nb = 0; + for(i=0; inr; i++){ + e->r[i] = geter(efd, e->b+e->nb, &nb); + e->nb += nb; + } + e->r[e->nr] = 0; + e->b[e->nb] = 0; + if(getec(efd) != '\n') + error("event syntax 2"); +} + +int +nrunes(char *s, int nb) +{ + int i, n; + Rune r; + + n = 0; + for(i=0; i0 && (buf[n-1]&0xC0)){ + --n; + npart++; + if((buf[n]&0xC0)!=0x80){ + if(fullrune(buf+n, npart)){ + w = chartorune(&r, buf+n); + n += w; + npart -= w; + } + break; + } + } + if(n > 0){ + memmove(hold, buf+n, npart); + buf[n] = 0; + n = label(buf, n); + buf[n] = 0; + qlock(&q.lk); + m = sprint(x, "#%d", q.p); + if(fswrite(afd, x, m) != m) + error("stdout writing address"); + if(fswrite(dfd, buf, n) != n) + error("stdout writing body"); + q.p += nrunes(buf, n); + qunlock(&q.lk); + memmove(buf, hold, npart); + } + } +} + +char wdir[256]; +int +label(char *sr, int n) +{ + char *sl, *el, *er, *r; + + er = sr+n; + for(r=er-1; r>=sr; r--) + if(*r == '\007') + break; + if(r < sr) + return n; + + el = r+1; + if(el-sr > sizeof wdir) + sr = el - sizeof wdir; + for(sl=el-3; sl>=sr; sl--) + if(sl[0]=='\033' && sl[1]==']' && sl[2]==';') + break; + if(sl < sr) + return n; + + *r = 0; + snprint(wdir, sizeof wdir, "name %s/-%s\n0\n", sl+3, name); + fswrite(ctlfd, wdir, strlen(wdir)); + + memmove(sl, el, er-el); + n -= (el-sl); + return n; +} + +int +delete(Event *e) +{ + uint q0, q1; + int deltap; + + q0 = e->q0; + q1 = e->q1; + if(q1 <= q.p) + return e->q1-e->q0; + if(q0 >= q.p+ntyper) + return 0; + deltap = 0; + if(q0 < q.p){ + deltap = q.p-q0; + q0 = 0; + }else + q0 -= q.p; + if(q1 > q.p+ntyper) + q1 = ntyper; + else + q1 -= q.p; + deltype(q0, q1); + return deltap; +} + +void +addtype(int c, uint p0, char *b, int nb, int nr) +{ + int i, w; + Rune r; + uint p; + char *b0; + + for(i=0; inr > 0) + addtype(e->c1, e->q0-q.p, e->b, e->nb, e->nr); + else{ + m = e->q0; + while(m < e->q1){ + n = sprint(buf, "#%d", m); + fswrite(afd, buf, n); + n = fsread(dfd, buf, sizeof buf); + nr = nrunes(buf, n); + while(m+nr > e->q1){ + do; while(n>0 && (buf[--n]&0xC0)==0x80); + --nr; + } + if(n == 0) + break; + addtype(e->c1, m-q.p, buf, n, nr); + m += nr; + } + } + sendtype(fd0); +} + +void +sende(Event *e, int fd0, Fid *cfd, Fid *afd, Fid *dfd, int donl) +{ + int l, m, n, nr, lastc, end; + char abuf[16], buf[128]; + + end = q.p+ntyper; + l = sprint(abuf, "#%d", end); + fswrite(afd, abuf, l); + if(e->nr > 0){ + fswrite(dfd, e->b, e->nb); + addtype(e->c1, ntyper, e->b, e->nb, e->nr); + lastc = e->r[e->nr-1]; + }else{ + m = e->q0; + lastc = 0; + while(m < e->q1){ + n = sprint(buf, "#%d", m); + fswrite(afd, buf, n); + n = fsread(dfd, buf, sizeof buf); + nr = nrunes(buf, n); + while(m+nr > e->q1){ + do; while(n>0 && (buf[--n]&0xC0)==0x80); + --nr; + } + if(n == 0) + break; + l = sprint(abuf, "#%d", end); + fswrite(afd, abuf, l); + fswrite(dfd, buf, n); + addtype(e->c1, ntyper, buf, n, nr); + lastc = buf[n-1]; + m += nr; + end += nr; + } + } + if(donl && lastc!='\n'){ + fswrite(dfd, "\n", 1); + addtype(e->c1, ntyper, "\n", 1, 1); + } + fswrite(cfd, "dot=addr", 8); + sendtype(fd0); +} blob - d4b4cad83e152a40020d96e612c506e031dab5bf blob + 9636beab1bb66efaf56d803295ed0d052c0100f1 --- src/cmd/acme/acme.c +++ src/cmd/acme/acme.c @@ -161,7 +161,8 @@ threadmain(int argc, char *argv[]) cerr = chancreate(sizeof(char*), 0); cedit = chancreate(sizeof(int), 0); cexit = chancreate(sizeof(int), 0); - if(cwait==nil || ccommand==nil || ckill==nil || cxfidalloc==nil || cxfidfree==nil || cerr==nil || cexit==nil){ + cwarn = chancreate(sizeof(void*), 1); + if(cwait==nil || ccommand==nil || ckill==nil || cxfidalloc==nil || cxfidfree==nil || cerr==nil || cexit==nil || cwarn==nil){ fprint(2, "acme: can't create initial channels: %r\n"); exits("channels"); } @@ -251,7 +252,7 @@ readfile(Column *c, char *s) w = coladd(c, nil, nil, -1); cvttorunes(s, strlen(s), rb, &nb, &nr, nil); - rs = cleanrname((Runestr){rb, nr}); + rs = cleanrname(runestr(rb, nr)); winsetname(w, rs.r, rs.nr); textload(&w->body, 0, s, 1); w->body.file->mod = FALSE; @@ -403,7 +404,6 @@ keyboardthread(void *v) winlock(t->w, 'K'); wincommit(t->w, t); winunlock(t->w); - flushwarnings(1); flushimage(display, 1); } alts[KTimer].c = nil; @@ -430,7 +430,6 @@ keyboardthread(void *v) } if(nbrecv(keyboardctl->c, &r) > 0) goto casekeyboard; - flushwarnings(1); flushimage(display, 1); break; } @@ -447,7 +446,7 @@ mousethread(void *v) Plumbmsg *pm; Mouse m; char *act; - enum { MResize, MMouse, MPlumb, NMALT }; + enum { MResize, MMouse, MPlumb, MWarnings, NMALT }; static Alt alts[NMALT+1]; USED(v); @@ -461,11 +460,18 @@ mousethread(void *v) alts[MPlumb].c = cplumb; alts[MPlumb].v = ± alts[MPlumb].op = CHANRCV; + alts[MWarnings].c = cwarn; + alts[MWarnings].v = nil; + alts[MWarnings].op = CHANRCV; if(cplumb == nil) alts[MPlumb].op = CHANNOP; alts[NMALT].op = CHANEND; for(;;){ + qlock(&row.lk); + flushwarnings(); + qunlock(&row.lk); + flushimage(display, 1); switch(alt(alts)){ case MResize: if(getwindow(display, Refnone) < 0) @@ -473,8 +479,6 @@ mousethread(void *v) draw(screen, screen->r, display->white, nil, ZP); scrlresize(); rowresize(&row, screen->clipr); - flushwarnings(1); - flushimage(display, 1); break; case MPlumb: if(strcmp(pm->type, "text") == 0){ @@ -484,10 +488,10 @@ mousethread(void *v) else if(strcmp(act, "showdata")==0) plumbshow(pm); } - flushwarnings(1); - flushimage(display, 1); - plumbfree(pm); + plumbfree(pm); break; + case MWarnings: + break; case MMouse: /* * Make a copy so decisions are consistent; mousectl changes @@ -570,8 +574,6 @@ mousethread(void *v) goto Continue; } Continue: - flushwarnings(0); - flushimage(display, 1); qunlock(&row.lk); break; } blob - 94cfa38314bd8e724ad7924f39c662e171407604 blob + 338a1ff8ca054a81a9f15302314472f0467d0876 --- src/cmd/acme/dat.h +++ src/cmd/acme/dat.h @@ -543,5 +543,6 @@ Channel *mouseexit1; /* chan(int) */ Channel *cexit; /* chan(int) */ Channel *cerr; /* chan(char*) */ Channel *cedit; /* chan(int) */ +Channel *cwarn; /* chan(void*)[1] (really chan(unit)[1]) */ #define STACK 32768 blob - 0dfae90a11fd9952836e9fb0e0ff28dbe9ff0cb6 blob + 7ccb9427291d83264fb5b72f58febf03d6d87cb3 --- src/cmd/acme/ecmd.c +++ src/cmd/acme/ecmd.c @@ -268,7 +268,7 @@ D_cmd(Text *t, Cmd *cp) runemove(n, dir.r, dir.nr); n[dir.nr] = '/'; runemove(n+dir.nr+1, r, nn); - rs = cleanrname((Runestr){n, dir.nr+1+nn}); + rs = cleanrname(runestr(n, dir.nr+1+nn)); } w = lookfile(rs.r, rs.nr); if(w == nil){ blob - 74f9f47ced2be1ef35faca6300f8ec6837e8276f blob + 0e3389d627b1d0cb7c27b4b0b33caa8dfdaabee2 --- src/cmd/acme/exec.c +++ src/cmd/acme/exec.c @@ -25,6 +25,7 @@ void fontx(Text*, Text*, Text*, int, int, Rune*, int); void get(Text*, Text*, Text*, int, int, Rune*, int); void id(Text*, Text*, Text*, int, int, Rune*, int); void incl(Text*, Text*, Text*, int, int, Rune*, int); +void indent(Text*, Text*, Text*, int, int, Rune*, int); void xkill(Text*, Text*, Text*, int, int, Rune*, int); void local(Text*, Text*, Text*, int, int, Rune*, int); void look(Text*, Text*, Text*, int, int, Rune*, int); @@ -58,6 +59,7 @@ static Rune LFont[] = { 'F', 'o', 'n', 't', 0 }; static Rune LGet[] = { 'G', 'e', 't', 0 }; static Rune LID[] = { 'I', 'D', 0 }; static Rune LIncl[] = { 'I', 'n', 'c', 'l', 0 }; +static Rune LIndent[] = { 'I', 'n', 'd', 'e', 'n', 't', 0 }; static Rune LKill[] = { 'K', 'i', 'l', 'l', 0 }; static Rune LLoad[] = { 'L', 'o', 'a', 'd', 0 }; static Rune LLocal[] = { 'L', 'o', 'c', 'a', 'l', 0 }; @@ -87,6 +89,7 @@ Exectab exectab[] = { { LGet, get, FALSE, TRUE, XXX }, { LID, id, FALSE, XXX, XXX }, { LIncl, incl, FALSE, XXX, XXX }, + { LIndent, indent, FALSE, XXX, XXX }, { LKill, xkill, FALSE, XXX, XXX }, { LLoad, dump, FALSE, FALSE, XXX }, { LLocal, local, FALSE, XXX, XXX }, @@ -1443,7 +1446,6 @@ runproc(void *argvp) goto Fail; Hard: - /* * ugly: set path = (. $cputype /bin) * should honor $path if unusual. blob - 9fba7d7ad79ec07cd4e8ee6de84a0b62b65b0626 blob + c164bb3b50755773e3c3e2c6b38168a8d0611d81 --- src/cmd/acme/fns.h +++ src/cmd/acme/fns.h @@ -69,6 +69,7 @@ Rune* bytetorune(char*, int*); void fsysinit(void); Mntdir* fsysmount(Rune*, int, Rune**, int); void fsysdelid(Mntdir*); +void fsysincid(Mntdir*); Xfid* respond(Xfid*, Fcall*, char*); int rxcompile(Rune*); int rgetc(void*, uint); @@ -86,9 +87,11 @@ int expand(Text*, uint, uint, Expand*); Rune* skipbl(Rune*, int, int*); Rune* findbl(Rune*, int, int*); char* edittext(Window*, int, Rune*, int); -void flushwarnings(int); +void flushwarnings(void); void startplumbing(void); +Runestr runestr(Rune*, uint); + #define runemalloc(a) (Rune*)emalloc((a)*sizeof(Rune)) #define runerealloc(a, b) (Rune*)erealloc((a), (b)*sizeof(Rune)) #define runemove(a, b, c) memmove((a), (b), (c)*sizeof(Rune)) blob - f178f864977513bfc7ca4175b7ce6d449383b8cb blob + af4255c8af359c8647a591be9f3f7cdc1a05acb8 --- src/cmd/acme/fsys.c +++ src/cmd/acme/fsys.c @@ -37,22 +37,25 @@ static Xfid* fsysremove(Xfid*, Fid*); static Xfid* fsysstat(Xfid*, Fid*); static Xfid* fsyswstat(Xfid*, Fid*); -Xfid* (*fcall[Tmax])(Xfid*, Fid*) = +Xfid* (*fcall[Tmax])(Xfid*, Fid*); + +static void +initfcall(void) { - [Tflush] = fsysflush, - [Tversion] = fsysversion, - [Tauth] = fsysauth, - [Tattach] = fsysattach, - [Twalk] = fsyswalk, - [Topen] = fsysopen, - [Tcreate] = fsyscreate, - [Tread] = fsysread, - [Twrite] = fsyswrite, - [Tclunk] = fsysclunk, - [Tremove]= fsysremove, - [Tstat] = fsysstat, - [Twstat] = fsyswstat, -}; + fcall[Tflush] = fsysflush; + fcall[Tversion] = fsysversion; + fcall[Tauth] = fsysauth; + fcall[Tattach] = fsysattach; + fcall[Twalk] = fsyswalk; + fcall[Topen] = fsysopen; + fcall[Tcreate] = fsyscreate; + fcall[Tread] = fsysread; + fcall[Twrite] = fsyswrite; + fcall[Tclunk] = fsysclunk; + fcall[Tremove]= fsysremove; + fcall[Tstat] = fsysstat; + fcall[Twstat] = fsyswstat; +} char Eperm[] = "permission denied"; char Eexist[] = "file does not exist"; @@ -113,6 +116,7 @@ fsysinit(void) int p[2]; char *u; + initfcall(); if(pipe(p) < 0) error("can't create pipe"); if(post9pservice(p[0], "acme") < 0) @@ -187,6 +191,14 @@ fsysaddid(Rune *dir, int ndir, Rune **incl, int nincl) } void +fsysincid(Mntdir *m) +{ + qlock(&mnt.lk); + m->ref++; + qunlock(&mnt.lk); +} + +void fsysdelid(Mntdir *idm) { Mntdir *m, *prev; @@ -331,7 +343,7 @@ fsysattach(Xfid *x, Fid *f) m->ref++; break; } - if(m == nil){ + if(m == nil && x->fcall.aname[0]){ snprint(buf, sizeof buf, "unknown id '%s' in attach", x->fcall.aname); sendp(cerr, estrdup(buf)); } blob - f6c4d4ee5c8abff98f844c983e6dd1aae1463954 blob + 7023382677f9f931f0a5025fcfb1e13de16c3983 --- src/cmd/acme/look.c +++ src/cmd/acme/look.c @@ -259,7 +259,7 @@ plumbshow(Plumbmsg *m) } cvttorunes(name, strlen(name), rb, &nb, &nr, nil); free(p); - rs = cleanrname((Runestr){rb, nr}); + rs = cleanrname(runestr(rb, nr)); winsetname(w, rs.r, rs.nr); r = runemalloc(m->ndata); cvttorunes(m->data, m->ndata, r, &nb, &nr, nil); @@ -385,13 +385,13 @@ includefile(Rune *dir, Rune *file, int nfile) n = access(a, 0); free(a); if(n < 0) - return (Runestr){nil, 0}; + return runestr(nil, 0); r = runemalloc(m+1+nfile); runemove(r, dir, m); runemove(r+m, Lslash, 1); runemove(r+m+1, file, nfile); free(file); - return cleanrname((Runestr){r, m+1+nfile}); + return cleanrname(runestr(r, m+1+nfile)); } static Rune *objdir; @@ -442,7 +442,7 @@ includename(Text *t, Rune *r, int n) return file; Rescue: - return (Runestr){r, n}; + return runestr(r, n); } Runestr @@ -475,11 +475,11 @@ dirname(Text *t, Rune *r, int n) goto Rescue; runemove(b+slash+1, r, n); free(r); - return cleanrname((Runestr){b, slash+1+n}); + return cleanrname(runestr(b, slash+1+n)); Rescue: free(b); - tmp = (Runestr){r, n}; + tmp = runestr(r, n); if(r) return cleanrname(tmp); return tmp; blob - 8bdf0b78c5cca413f6a7f4381490db61ab81262a blob + c0cd7ec150e41361dff3593adeadd1f6b27528d7 --- src/cmd/acme/text.c +++ src/cmd/acme/text.c @@ -578,7 +578,7 @@ textcomplete(Text *t) path[i] = textreadc(t, q++); /* is path rooted? if not, we need to make it relative to window path */ if(npath>0 && path[0]=='/') - dir = (Runestr){path, npath}; + dir = runestr(path, npath); else{ dir = dirname(t, nil, 0); if(dir.nr + 1 + npath > nelem(tmp)){ blob - de71107a5215298b0f46040b6779e55c060c97e6 blob + a7307e0665ecd8b8f81d4216042ccba7fc4950ca --- src/cmd/acme/util.c +++ src/cmd/acme/util.c @@ -14,6 +14,16 @@ static Point prevmouse; static Window *mousew; +Runestr +runestr(Rune *r, uint n) +{ + Runestr rs; + + rs.r = r; + rs.nr = n; + return rs; +} + void cvttorunes(char *p, int n, Rune *r, int *nb, int *nr, int *nulls) { @@ -133,12 +143,17 @@ addwarningtext(Mntdir *md, Rune *r, int nr) } warn = emalloc(sizeof(Warning)); warn->next = warnings; + warn->md = md; + if(md) + fsysincid(md); warnings = warn; bufinsert(&warn->buf, 0, r, nr); + nbsendp(cwarn, 0); } +/* called while row is locked */ void -flushwarnings(int dolock) +flushwarnings(void) { Warning *warn, *next; Window *w; @@ -146,8 +161,6 @@ flushwarnings(int dolock) int owner, nr, q0, n; Rune *r; - if(dolock) - qlock(&row.lk); if(row.ncol == 0){ /* really early error */ rowinit(&row, screen->clipr); rowadd(&row, nil, -1); @@ -189,11 +202,11 @@ flushwarnings(int dolock) winunlock(w); bufclose(&warn->buf); next = warn->next; + if(warn->md) + fsysdelid(warn->md); free(warn); } warnings = nil; - if(dolock) - qunlock(&row.lk); } void blob - b3bef2cd51f648934d4cd4728a211bccefb01dc4 blob + 839308eee1f3a485087ebb2a4b961be738fea8e8 --- src/cmd/acme/xfid.c +++ src/cmd/acme/xfid.c @@ -543,7 +543,6 @@ xfidwrite(Xfid *x) } if(w) winunlock(w); - flushwarnings(1); } void @@ -814,7 +813,6 @@ xfideventwrite(Xfid *x, Window *w) qunlock(&row.lk); goto Rescue; } - flushwarnings(0); qunlock(&row.lk); } @@ -1032,7 +1030,6 @@ xfidindexread(Xfid *x) b[n++] = '\n'; } } - flushwarnings(0); qunlock(&row.lk); off = x->fcall.offset; cnt = x->fcall.count; blob - 8cbf6aac077348accfa714b9d871c472b25009f9 blob + a3ddd890c606e526e29a48d967e2d7675718d955 --- src/cmd/dict/dict.c +++ src/cmd/dict/dict.c @@ -119,6 +119,8 @@ main(int argc, char **argv) line = malloc(strlen(p)+5); sprint(line, "/%s/P\n", p); } + dict->path = unsharp(dict->path); + dict->indexpath = unsharp(dict->indexpath); bdict = Bopen(dict->path, OREAD); if(!bdict) { err("can't open dictionary %s", dict->path); blob - 8e56765fa12bc6e937f89a7b89919d6f218a7919 blob + c809ae81345741acd7d0bc5886606404cb033ba6 --- src/cmd/diff/diff.h +++ src/cmd/diff/diff.h @@ -1,3 +1,5 @@ +#define stdout bstdout + char mode; /* '\0', 'e', 'f', 'h' */ char bflag; /* ignore multiple and trailing blanks */ char rflag; /* recurse down directory trees */ blob - 43eb6dd1c4821af23b1924d1ef4a0154ef0980fe blob + 00f69a3ec78788334760781c74263cb0e47c05ac --- src/cmd/diff/main.c +++ src/cmd/diff/main.c @@ -26,6 +26,8 @@ void done(int status) { rmtmpfiles(); +Bflush(&stdout); +Bterm(&stdout); switch(status) { case 0: blob - f3acfca22cac1dfab9881af5c8d5e4f90cd8b47f blob + 4aa895fec4d0f21d530c4e58a2ec9d76a56cd616 --- src/cmd/fortune.c +++ src/cmd/fortune.c @@ -4,8 +4,8 @@ #define index findex char choice[2048]; -char index[] = "/sys/games/lib/fortunes.index"; -char fortunes[] = "/sys/games/lib/fortunes"; +char *index = "#9/lib/fortunes.index"; +char *fortunes = "#9/lib/fortunes"; #define lrand rand @@ -21,6 +21,9 @@ main(int argc, char *argv[]) Dir *fbuf, *ixbuf; Biobuf *f, g; + index = unsharp(index); + fortunes = unsharp(index); + newindex = 0; oldindex = 0; ix = offs = 0; @@ -55,6 +58,7 @@ main(int argc, char *argv[]) } } if(oldindex){ + srand(getpid()); seek(ix, lrand()%(ixbuf->length/sizeof(offs))*sizeof(offs), 0); read(ix, off, sizeof(off)); Bseek(f, off[0]|(off[1]<<8)|(off[2]<<16)|(off[3]<<24), 0); blob - /dev/null blob + 4a3f3e8f4f80ce77a3caea6b83bb546d3d3296df (mode 644) --- /dev/null +++ src/cmd/grep/comp.c @@ -0,0 +1,277 @@ +#include "grep.h" + +/* + * incremental compiler. + * add the branch c to the + * state s. + */ +void +increment(State *s, int c) +{ + int i; + State *t, **tt; + Re *re1, *re2; + + nfollow = 0; + gen++; + matched = 0; + for(i=0; icount; i++) + fol1(s->re[i], c); + qsort(follow, nfollow, sizeof(*follow), fcmp); + for(tt=&state0; t = *tt;) { + if(t->count > nfollow) { + tt = &t->linkleft; + goto cont; + } + if(t->count < nfollow) { + tt = &t->linkright; + goto cont; + } + for(i=0; ire[i]; + re2 = follow[i]; + if(re1 > re2) { + tt = &t->linkleft; + goto cont; + } + if(re1 < re2) { + tt = &t->linkright; + goto cont; + } + } + if(!!matched && !t->match) { + tt = &t->linkleft; + goto cont; + } + if(!matched && !!t->match) { + tt = &t->linkright; + goto cont; + } + s->next[c] = t; + return; + cont:; + } + + t = sal(nfollow); + *tt = t; + for(i=0; ire[i] = re1; + } + s->next[c] = t; + t->match = matched; +} + +int +fcmp(const void *va, const void *vb) +{ + Re **aa, **bb; + Re *a, *b; + + aa = (Re**)va; + bb = (Re**)vb; + a = *aa; + b = *bb; + if(a > b) + return 1; + if(a < b) + return -1; + return 0; +} + +void +fol1(Re *r, int c) +{ + Re *r1; + +loop: + if(r->gen == gen) + return; + if(nfollow >= maxfollow) + error("nfollow"); + r->gen = gen; + switch(r->type) { + default: + error("fol1"); + + case Tcase: + if(c >= 0 && c < 256) + if(r1 = r->cases[c]) + follow[nfollow++] = r1; + if(r = r->next) + goto loop; + break; + + case Talt: + case Tor: + fol1(r->alt, c); + r = r->next; + goto loop; + + case Tbegin: + if(c == '\n' || c == Cbegin) + follow[nfollow++] = r->next; + break; + + case Tend: + if(c == '\n') + matched = 1; + break; + + case Tclass: + if(c >= r->lo && c <= r->hi) + follow[nfollow++] = r->next; + break; + } +} + +Rune tab1[] = +{ + 0x007f, + 0x07ff, +}; +Rune tab2[] = +{ + 0x003f, + 0x0fff, +}; + +Re2 +rclass(Rune p0, Rune p1) +{ + char xc0[6], xc1[6]; + int i, n, m; + Re2 x; + + if(p0 > p1) + return re2char(0xff, 0xff); // no match + + /* + * bust range into same length + * character sequences + */ + for(i=0; i m) + return re2or(rclass(p0, m), rclass(m+1, p1)); + } + + /* + * bust range into part of a single page + * or into full pages + */ + for(i=0; i p[1]) + continue; + if(p[0] > q[1] || p[1] < q[0]) { + q[2] = p[0]; + q[3] = p[1]; + q += 2; + continue; + } + if(p[0] < q[0]) + q[0] = p[0]; + if(p[1] > q[1]) + q[1] = p[1]; + } + q[2] = 0; + + p = pairs; + if(nc) { + x = rclass(0, p[0]-1); + ov = p[1]+1; + for(p+=2; *p; p+=2) { + x = re2or(x, rclass(ov, p[0]-1)); + ov = p[1]+1; + } + x = re2or(x, rclass(ov, 0xffff)); + } else { + x = rclass(p[0], p[1]); + for(p+=2; *p; p+=2) + x = re2or(x, rclass(p[0], p[1])); + } + return x; +} blob - /dev/null blob + 8445df54a53ffbe2ecb74e2e5fafb2ff7be9a992 (mode 644) --- /dev/null +++ src/cmd/grep/grep.h @@ -0,0 +1,125 @@ +#include +#include +#include + +#ifndef EXTERN +#define EXTERN extern +#endif + +typedef struct Re Re; +typedef struct Re2 Re2; +typedef struct State State; + +struct State +{ + int count; + int match; + Re** re; + State* linkleft; + State* linkright; + State* next[256]; +}; +struct Re2 +{ + Re* beg; + Re* end; +}; +struct Re +{ + uchar type; + ushort gen; + union + { + Re* alt; /* Talt */ + Re** cases; /* case */ + struct /* class */ + { + Rune lo; + Rune hi; + }; + Rune val; /* char */ + }; + Re* next; +}; + +enum +{ + Talt = 1, + Tbegin, + Tcase, + Tclass, + Tend, + Tor, + + Caselim = 7, + Nhunk = 1<<16, + Cbegin = 0x10000, + Flshcnt = (1<<9)-1, + + Cflag = 1<<0, + Hflag = 1<<1, + Iflag = 1<<2, + Llflag = 1<<3, + LLflag = 1<<4, + Nflag = 1<<5, + Sflag = 1<<6, + Vflag = 1<<7, + Bflag = 1<<8 +}; + +EXTERN union +{ + char string[16*1024]; + struct + { + /* + * if a line requires multiple reads, we keep shifting + * buf down into pre and then do another read into + * buf. so you'll get the last 16-32k of the matching line. + * if pre were smaller than buf you'd get a suffix of the + * line with a hole cut out. + */ + uchar pre[16*1024]; /* to save to previous '\n' */ + uchar buf[16*1024]; /* input buffer */ + }; +} u; + +EXTERN char *filename; +EXTERN Biobuf bout; +EXTERN char flags[256]; +EXTERN Re** follow; +EXTERN ushort gen; +EXTERN char* input; +EXTERN long lineno; +EXTERN int literal; +EXTERN int matched; +EXTERN long maxfollow; +EXTERN long nfollow; +EXTERN int peekc; +EXTERN Biobuf* rein; +EXTERN State* state0; +EXTERN Re2 topre; + +extern Re* addcase(Re*); +extern void appendnext(Re*, Re*); +extern void error(char*); +extern int fcmp(const void*, const void*); /* (Re**, Re**) */ +extern void fol1(Re*, int); +extern int getrec(void); +extern void increment(State*, int); +#define initstate grepinitstate +extern State* initstate(Re*); +extern void* mal(int); +extern void patchnext(Re*, Re*); +extern Re* ral(int); +extern Re2 re2cat(Re2, Re2); +extern Re2 re2class(char*); +extern Re2 re2or(Re2, Re2); +extern Re2 re2char(int, int); +extern Re2 re2star(Re2); +extern State* sal(int); +extern int search(char*, int); +extern void str2top(char*); +extern int yyparse(void); +extern void reprint(char*, Re*); +extern void yyerror(char*, ...); blob - /dev/null blob + 94a744cf96931a2244c69961b0b5f1c5c74f339d (mode 644) --- /dev/null +++ src/cmd/grep/grep.y @@ -0,0 +1,226 @@ +%{ +#include "grep.h" +%} + +%union +{ + int val; + char* str; + Re2 re; +} + +%type expr prog +%type expr0 expr1 expr2 expr3 expr4 +%token LCLASS +%token LCHAR +%token LLPAREN LRPAREN LALT LSTAR LPLUS LQUES +%token LBEGIN LEND LDOT LBAD LNEWLINE +%% + +prog: + expr newlines + { + $$.beg = ral(Tend); + $$.end = $$.beg; + $$ = re2cat(re2star(re2or(re2char(0x00, '\n'-1), re2char('\n'+1, 0xff))), $$); + $$ = re2cat($1, $$); + $$ = re2cat(re2star(re2char(0x00, 0xff)), $$); + topre = $$; + } + +expr: + expr0 +| expr newlines expr0 + { + $$ = re2or($1, $3); + } + +expr0: + expr1 +| LSTAR { literal = 1; } expr1 + { + $$ = $3; + } + +expr1: + expr2 +| expr1 LALT expr2 + { + $$ = re2or($1, $3); + } + +expr2: + expr3 +| expr2 expr3 + { + $$ = re2cat($1, $2); + } + +expr3: + expr4 +| expr3 LSTAR + { + $$ = re2star($1); + } +| expr3 LPLUS + { + $$.beg = ral(Talt); + patchnext($1.end, $$.beg); + $$.beg->alt = $1.beg; + $$.end = $$.beg; + $$.beg = $1.beg; + } +| expr3 LQUES + { + $$.beg = ral(Talt); + $$.beg->alt = $1.beg; + $$.end = $1.end; + appendnext($$.end, $$.beg); + } + +expr4: + LCHAR + { + $$.beg = ral(Tclass); + $$.beg->lo = $1; + $$.beg->hi = $1; + $$.end = $$.beg; + } +| LBEGIN + { + $$.beg = ral(Tbegin); + $$.end = $$.beg; + } +| LEND + { + $$.beg = ral(Tend); + $$.end = $$.beg; + } +| LDOT + { + $$ = re2class("^\n"); + } +| LCLASS + { + $$ = re2class($1); + } +| LLPAREN expr1 LRPAREN + { + $$ = $2; + } + +newlines: + LNEWLINE +| newlines LNEWLINE +%% + +void +yyerror(char *e, ...) +{ + if(filename) + fprint(2, "grep: %s:%ld: %s\n", filename, lineno, e); + else + fprint(2, "grep: %s\n", e); + exits("syntax"); +} + +long +yylex(void) +{ + char *q, *eq; + int c, s; + + if(peekc) { + s = peekc; + peekc = 0; + return s; + } + c = getrec(); + if(literal) { + if(c != 0 && c != '\n') { + yylval.val = c; + return LCHAR; + } + literal = 0; + } + switch(c) { + default: + yylval.val = c; + s = LCHAR; + break; + case '\\': + c = getrec(); + yylval.val = c; + s = LCHAR; + if(c == '\n') + s = LNEWLINE; + break; + case '[': + goto getclass; + case '(': + s = LLPAREN; + break; + case ')': + s = LRPAREN; + break; + case '|': + s = LALT; + break; + case '*': + s = LSTAR; + break; + case '+': + s = LPLUS; + break; + case '?': + s = LQUES; + break; + case '^': + s = LBEGIN; + break; + case '$': + s = LEND; + break; + case '.': + s = LDOT; + break; + case 0: + peekc = -1; + case '\n': + s = LNEWLINE; + break; + } + return s; + +getclass: + q = u.string; + eq = q + nelem(u.string) - 5; + c = getrec(); + if(c == '^') { + q[0] = '^'; + q[1] = '\n'; + q[2] = '-'; + q[3] = '\n'; + q += 4; + c = getrec(); + } + for(;;) { + if(q >= eq) + error("class too long"); + if(c == ']' || c == 0) + break; + if(c == '\\') { + *q++ = c; + c = getrec(); + if(c == 0) + break; + } + *q++ = c; + c = getrec(); + } + *q = 0; + if(c == 0) + return LBAD; + yylval.str = u.string; + return LCLASS; +} blob - /dev/null blob + f2a6e040465890d6aef6cb0a21680cd65b70f143 (mode 644) --- /dev/null +++ src/cmd/grep/main.c @@ -0,0 +1,260 @@ +#define EXTERN +#include "grep.h" + +char *validflags = "bchiLlnsv"; +void +usage(void) +{ + fprint(2, "usage: grep [-%s] [-f file] [-e expr] [file ...]\n", validflags); + exits("usage"); +} + +void +main(int argc, char *argv[]) +{ + int i, status; + + ARGBEGIN { + default: + if(utfrune(validflags, ARGC()) == nil) + usage(); + flags[ARGC()]++; + break; + + case 'e': + flags['e']++; + lineno = 0; + str2top(ARGF()); + break; + + case 'f': + flags['f']++; + filename = ARGF(); + rein = Bopen(filename, OREAD); + if(rein == 0) { + fprint(2, "grep: can't open %s: %r\n", filename); + exits("open"); + } + lineno = 1; + str2top(filename); + break; + } ARGEND + + if(flags['f'] == 0 && flags['e'] == 0) { + if(argc <= 0) + usage(); + str2top(argv[0]); + argc--; + argv++; + } + + follow = mal(maxfollow*sizeof(*follow)); + state0 = initstate(topre.beg); + + Binit(&bout, 1, OWRITE); + switch(argc) { + case 0: + status = search(0, 0); + break; + case 1: + status = search(argv[0], 0); + break; + default: + status = 0; + for(i=0; i sizeof(u.pre)) + n = sizeof(u.pre); + memmove(u.buf-n, bol, n); + bol = u.buf-n; + n = read(fid, u.buf, sizeof(u.buf)); + /* if file has no final newline, simulate one to emit matches to last line */ + if(n > 0) { + empty = 0; + nl = u.buf[n-1]=='\n'; + } else { + if(n < 0){ + fprint(2, "grep: read error on %s: %r\n", file); + return count != 0; + } + if(!eof && !nl && !empty) { + u.buf[0] = '\n'; + n = 1; + eof = 1; + } + } + if(n <= 0) { + close(fid); + if(flag & Cflag) { + if(flag & Hflag) + Bprint(&bout, "%s:", file); + Bprint(&bout, "%ld\n", count); + } + if(((flag&Llflag) && count != 0) || ((flag&LLflag) && count == 0)) + Bprint(&bout, "%s\n", file); + Bflush(&bout); + return count != 0; + } + lp = u.buf; + elp = lp+n; + if(flag & Iflag) + goto loopi; + +/* + * normal character loop + */ +loop: + c = *lp; + ns = s->next[c]; + if(ns == 0) { + increment(s, c); + goto loop; + } +// if(flags['2']) +// if(s->match) +// print("%d: %.2x**\n", s, c); +// else +// print("%d: %.2x\n", s, c); + lp++; + s = ns; + if(c == '\n') { + lineno++; + if(!!s->match == !(flag&Vflag)) { + count++; + if(flag & (Cflag|Sflag|Llflag|LLflag)) + goto cont; + if(flag & Hflag) + Bprint(&bout, "%s:", file); + if(flag & Nflag) + Bprint(&bout, "%ld: ", lineno); + /* suppress extra newline at EOF unless we are labeling matches with file name */ + Bwrite(&bout, bol, lp-bol-(eof && !(flag&Hflag))); + if(flag & Bflag) + Bflush(&bout); + } + if((lineno & Flshcnt) == 0) + Bflush(&bout); + cont: + bol = lp; + } + if(lp != elp) + goto loop; + goto loop0; + +/* + * character loop for -i flag + * for speed + */ +loopi: + c = *lp; + if(c >= 'A' && c <= 'Z') + c += 'a'-'A'; + ns = s->next[c]; + if(ns == 0) { + increment(s, c); + goto loopi; + } + lp++; + s = ns; + if(c == '\n') { + lineno++; + if(!!s->match == !(flag&Vflag)) { + count++; + if(flag & (Cflag|Sflag|Llflag|LLflag)) + goto conti; + if(flag & Hflag) + Bprint(&bout, "%s:", file); + if(flag & Nflag) + Bprint(&bout, "%ld: ", lineno); + /* suppress extra newline at EOF unless we are labeling matches with file name */ + Bwrite(&bout, bol, lp-bol-(eof && !(flag&Hflag))); + if(flag & Bflag) + Bflush(&bout); + } + if((lineno & Flshcnt) == 0) + Bflush(&bout); + conti: + bol = lp; + } + if(lp != elp) + goto loopi; + goto loop0; +} + +State* +initstate(Re *r) +{ + State *s; + int i; + + addcase(r); + if(flags['1']) + reprint("r", r); + nfollow = 0; + gen++; + fol1(r, Cbegin); + follow[nfollow++] = r; + qsort(follow, nfollow, sizeof(*follow), fcmp); + + s = sal(nfollow); + for(i=0; ire[i] = follow[i]; + return s; +} blob - /dev/null blob + fd17abdd08f5e050fbf90d8d0f55912aa62e9814 (mode 644) --- /dev/null +++ src/cmd/grep/mkfile @@ -0,0 +1,20 @@ +PLAN9=../../.. +<$PLAN9/src/mkhdr + +# Calling this grep breaks a LOT. Like egrep on Linux. +# And probably configure. + +TARG=9grep +HFILES=\ + grep.h\ + +OFILES=\ + y.tab.$O\ + main.$O\ + comp.$O\ + sub.$O\ + +YFILES=grep.y\ + +SHORTLIB=bio 9 +<$PLAN9/src/mkone blob - /dev/null blob + be2acee35846f9908f2d1e11f26b9a57508f6974 (mode 644) --- /dev/null +++ src/cmd/grep/sub.c @@ -0,0 +1,317 @@ +#include "grep.h" + +void* +mal(int n) +{ + static char *s; + static int m = 0; + void *v; + + n = (n+3) & ~3; + if(m < n) { + if(n > Nhunk) { + v = sbrk(n); + memset(v, 0, n); + return v; + } + s = sbrk(Nhunk); + m = Nhunk; + } + v = s; + s += n; + m -= n; + memset(v, 0, n); + return v; +} + +State* +sal(int n) +{ + State *s; + + s = mal(sizeof(*s)); +// s->next = mal(256*sizeof(*s->next)); + s->count = n; + s->re = mal(n*sizeof(*state0->re)); + return s; +} + +Re* +ral(int type) +{ + Re *r; + + r = mal(sizeof(*r)); + r->type = type; + maxfollow++; + return r; +} + +void +error(char *s) +{ + fprint(2, "grep: internal error: %s\n", s); + exits(s); +} + +int +countor(Re *r) +{ + int n; + + n = 0; +loop: + switch(r->type) { + case Tor: + n += countor(r->alt); + r = r->next; + goto loop; + case Tclass: + return n + r->hi - r->lo + 1; + } + return n; +} + +Re* +oralloc(int t, Re *r, Re *b) +{ + Re *a; + + if(b == 0) + return r; + a = ral(t); + a->alt = r; + a->next = b; + return a; +} + +void +case1(Re *c, Re *r) +{ + int n; + +loop: + switch(r->type) { + case Tor: + case1(c, r->alt); + r = r->next; + goto loop; + + case Tclass: /* add to character */ + for(n=r->lo; n<=r->hi; n++) + c->cases[n] = oralloc(Tor, r->next, c->cases[n]); + break; + + default: /* add everything unknown to next */ + c->next = oralloc(Talt, r, c->next); + break; + } +} + +Re* +addcase(Re *r) +{ + int i, n; + Re *a; + + if(r->gen == gen) + return r; + r->gen = gen; + switch(r->type) { + default: + error("addcase"); + + case Tor: + n = countor(r); + if(n >= Caselim) { + a = ral(Tcase); + a->cases = mal(256*sizeof(*a->cases)); + case1(a, r); + for(i=0; i<256; i++) + if(a->cases[i]) { + r = a->cases[i]; + if(countor(r) < n) + a->cases[i] = addcase(r); + } + return a; + } + return r; + + case Talt: + r->next = addcase(r->next); + r->alt = addcase(r->alt); + return r; + + case Tbegin: + case Tend: + case Tclass: + return r; + } +} + +void +str2top(char *p) +{ + Re2 oldtop; + + oldtop = topre; + input = p; + topre.beg = 0; + topre.end = 0; + yyparse(); + gen++; + if(topre.beg == 0) + yyerror("syntax"); + if(oldtop.beg) + topre = re2or(oldtop, topre); +} + +void +appendnext(Re *a, Re *b) +{ + Re *n; + + while(n = a->next) + a = n; + a->next = b; +} + +void +patchnext(Re *a, Re *b) +{ + Re *n; + + while(a) { + n = a->next; + a->next = b; + a = n; + } +} + +int +getrec(void) +{ + int c; + + if(flags['f']) { + c = Bgetc(rein); + if(c <= 0) + return 0; + } else + c = *input++ & 0xff; + if(flags['i'] && c >= 'A' && c <= 'Z') + c += 'a'-'A'; + if(c == '\n') + lineno++; + return c; +} + +Re2 +re2cat(Re2 a, Re2 b) +{ + Re2 c; + + c.beg = a.beg; + c.end = b.end; + patchnext(a.end, b.beg); + return c; +} + +Re2 +re2star(Re2 a) +{ + Re2 c; + + c.beg = ral(Talt); + c.beg->alt = a.beg; + patchnext(a.end, c.beg); + c.end = c.beg; + return c; +} + +Re2 +re2or(Re2 a, Re2 b) +{ + Re2 c; + + c.beg = ral(Tor); + c.beg->alt = b.beg; + c.beg->next = a.beg; + c.end = b.end; + appendnext(c.end, a.end); + return c; +} + +Re2 +re2char(int c0, int c1) +{ + Re2 c; + + c.beg = ral(Tclass); + c.beg->lo = c0 & 0xff; + c.beg->hi = c1 & 0xff; + c.end = c.beg; + return c; +} + +void +reprint1(Re *a) +{ + int i, j; + +loop: + if(a == 0) + return; + if(a->gen == gen) + return; + a->gen = gen; + print("%p: ", a); + switch(a->type) { + default: + print("type %d\n", a->type); + error("print1 type"); + + case Tcase: + print("case ->%p\n", a->next); + for(i=0; i<256; i++) + if(a->cases[i]) { + for(j=i+1; j<256; j++) + if(a->cases[i] != a->cases[j]) + break; + print(" [%.2x-%.2x] ->%p\n", i, j-1, a->cases[i]); + i = j-1; + } + for(i=0; i<256; i++) + reprint1(a->cases[i]); + break; + + case Tbegin: + print("^ ->%p\n", a->next); + break; + + case Tend: + print("$ ->%p\n", a->next); + break; + + case Tclass: + print("[%.2x-%.2x] ->%p\n", a->lo, a->hi, a->next); + break; + + case Tor: + case Talt: + print("| %p ->%p\n", a->alt, a->next); + reprint1(a->alt); + break; + } + a = a->next; + goto loop; +} + +void +reprint(char *s, Re *r) +{ + print("%s:\n", s); + gen++; + reprint1(r); + print("\n\n"); +} blob - 3ad7ea7a99c444c1502a21d18c3da4b6cb8f9339 blob + 292c051be4bb8679de5007ddbb5a58b09c3e0f5b --- src/cmd/mkfile +++ src/cmd/mkfile @@ -3,11 +3,11 @@ PLAN9=../.. TARG=`ls *.c | sed 's/\.c//'` LDFLAGS=$LDFLAGS -SHORTLIB=sec fs mux regexp9 thread bio 9 +SHORTLIB=mach sec fs mux regexp9 thread bio 9 <$PLAN9/src/mkmany -BUGGERED='CVS|9term|faces|factotum|htmlfmt|mk|rio|upas|vac|venti' +BUGGERED='CVS|faces|factotum|htmlfmt|mk|upas|vac|venti' DIRS=`ls -l |sed -n 's/^d.* //p' |egrep -v "^($BUGGERED)$"` <$PLAN9/src/mkdirs blob - 4776d1278a28a6102a5bbc3689489f14c0244311 blob + 33a4458e04b0f86655b4106c7c84c40eb26fa856 --- src/cmd/plumb/fsys.c +++ src/cmd/plumb/fsys.c @@ -97,6 +97,7 @@ static Dirtab dir[NDIR] = static int ndir = NQID; static int srvfd; +#define clock plumbclock /* SunOS name clash */ static int clock; static Fid *fids[Nhash]; static QLock readlock; blob - 80a57af3ee40e134770b1f70576ceb9cbc2fca67 blob + bf7afa3f80f128e820e1c1665c18009b9b2c92c7 --- src/cmd/plumb/plumber.c +++ src/cmd/plumb/plumber.c @@ -54,9 +54,10 @@ threadmain(int argc, char *argv[]) error("can't initialize $user or $home: %r"); if(plumbfile == nil){ sprint(buf, "%s/lib/plumbing", home); - if(access(buf, 0) < 0) - sprint(buf, "#9/plumb/initial.plumbing"); - plumbfile = estrdup(buf); + if(access(buf, 0) >= 0) + plumbfile = estrdup(buf); + else + plumbfile = unsharp("#9/plumb/initial.plumbing"); } fd = open(plumbfile, OREAD); blob - 689edf5983b22367e7c99e2946f3d7b1a8bb1fc2 blob + ab27787d670cd4dfcfcc7b4e69f89cb8101c38ee --- src/cmd/plumb/rules.c +++ src/cmd/plumb/rules.c @@ -415,7 +415,7 @@ include(char *s) fd = open(t, OREAD); if(fd<0 && t[0]!='/' && strncmp(t, "./", 2)!=0 && strncmp(t, "../", 3)!=0){ snprint(buf, sizeof buf, "#9/plumb/%s", t); - t = buf; + t = unsharp(buf); fd = open(t, OREAD); } if(fd < 0) blob - eb93a4f5280d82b0e65ba73d76180f4eff03644c blob + 6b32a2277c2a9f9d09e6f9bb5c47e9e2dfed3a23 --- src/cmd/rc/plan9ish.c +++ src/cmd/rc/plan9ish.c @@ -27,20 +27,10 @@ char *syssigname[]={ char* Rcmain(void) { - return "#9/rcmain"; -/* - static char buf[256]; - char *root; - - root = getenv("PLAN9"); - if(root == nil) - root = "/usr/local/plan9"; - snprint(buf, sizeof buf, "%s/rcmain", root); - return buf; -*/ + return unsharp("#9/rcmain"); } -char Fdprefix[]="#d/"; +char Fdprefix[]="/dev/fd/"; void execfinit(void); void execbind(void); void execmount(void); blob - /dev/null blob + 43a789318cdba6a358d75ecb3643e16167ea2a5e (mode 644) --- /dev/null +++ src/cmd/rio/Imakefile @@ -0,0 +1,27 @@ +INCLUDES = -I$(TOP) +DEPLIBS = $(DEPXLIB) +LOCAL_LIBRARIES = $(XLIB) +DEFINES = -DSHAPE # -g3 -DDEBUG -DDEBUG_EV +SRCS = main.c event.c manage.c menu.c client.c grab.c cursor.c error.c color.c +OBJS = main.o event.o manage.o menu.o client.o grab.o cursor.o error.o color.o +HFILES = dat.h fns.h patchlevel.h +MFILES = README 9wm.man Imakefile Makefile.no-imake + +ComplexProgramTarget(rio) + +bun: + bundle $(MFILES) $(SRCS) $(HFILES) >bun + +dist: + bundle $(MFILES) main.c event.c manage.c >bun1 + bundle menu.c client.c grab.c cursor.c error.c $(HFILES) >bun2 + +trout: 9wm.man + troff -man 9wm.man >trout + +vu: trout + xditview trout + +clean:: + $(RM) bun bun[12] trout core + blob - 8c5346601466149f832202c4647d0d3e82190e71 blob + 0e3c8d89d49b5875b786f67b13ae3f8e79d32ef1 --- src/cmd/rio/color.c +++ src/cmd/rio/color.c @@ -8,7 +8,7 @@ #include "fns.h" unsigned long -colorpixel(Display *dpy, int depth, ulong rgb) +colorpixel(Display *dpy, int depth, unsigned long rgb) { int r, g, b; blob - 0953f1bded98082226ed3e0157f505e119d3797c blob + 029297735066658d059295bd595e63279b159437 --- src/cmd/rio/main.c +++ src/cmd/rio/main.c @@ -9,6 +9,9 @@ #include #include #include +#ifdef SHAPE +#include +#endif #include "dat.h" #include "fns.h" #include "patchlevel.h" @@ -70,12 +73,15 @@ main(int argc, char *argv[]) int i, background, do_exit, do_restart; char *fname; int shape_event; +#ifdef SHAPE + int dummy; +#endif shape_event = 0; myargv = argv; /* for restart */ do_exit = do_restart = 0; - background = 1; + background = 0; font = 0; fname = 0; for (i = 1; i < argc; i++) @@ -289,12 +295,11 @@ initscreen(ScreenInfo *s, int i, int background) XSync(dpy, False); if (background) { -/* XSetWindowBackgroundPixmap(dpy, s->root, s->root_pixmap); XClearWindow(dpy, s->root); -*/ + } else system("xsetroot -solid grey30"); - } + s->menuwin = XCreateSimpleWindow(dpy, s->root, 0, 0, 1, 1, 2, colorpixel(dpy, s->depth, 0x88CC88), colorpixel(dpy, s->depth, 0xE9FFE9)); s->sweepwin = XCreateSimpleWindow(dpy, s->root, 0, 0, 1, 1, 4, s->red, colorpixel(dpy, s->depth, 0xEEEEEE)); } blob - 8881190c78b5285c442cb9f2d3aba398a344c416 blob + b5e8b11098ad1aa6743b6f0373853af1b4c931fe --- src/cmd/rio/mkfile +++ src/cmd/rio/mkfile @@ -1,3 +1,4 @@ +PLAN9=../../.. <$PLAN9/src/mkhdr OFILES=\ @@ -18,3 +19,7 @@ TARG=rio LDFLAGS=-L$X11/lib -lXext -lX11 <$PLAN9/src/mkone + +CFLAGS=$CFLAGS -DSHAPE -I$X11/include + + blob - e63fbb8705a5c6b413801ff46c0ac7fac81a6cf2 blob + 8d5519efc32b6cf8e0241295c7b207ca5ae43b37 --- src/cmd/spell/sprog.c +++ src/cmd/spell/sprog.c @@ -460,6 +460,9 @@ main(int argc, char *argv[]) int low; Bits h; + codefile = unsharp(codefile); + brfile = unsharp(brfile); + Binit(&bin, 0, OREAD); Binit(&bout, 1, OWRITE); for(i=0; c = "aeiouyAEIOUY"[i]; i++) blob - 7f15f0578886b4bae6df95e1678624a817b82c4d (mode 644) blob + /dev/null --- src/cmd/win.c +++ /dev/null @@ -1,717 +0,0 @@ -#include -#include -#include -#include -#include - -#define EVENTSIZE 256 -#define STACK 32768 - -typedef struct Event Event; -typedef struct Q Q; - -struct Event -{ - int c1; - int c2; - int q0; - int q1; - int flag; - int nb; - int nr; - char b[EVENTSIZE*UTFmax+1]; - Rune r[EVENTSIZE+1]; -}; - -Event blank = { - 'M', - 'X', - 0, 0, 0, 1, 1, - { ' ', 0 }, - { ' ', 0 }, -}; - -struct Q -{ - QLock lk; - int p; - int k; -}; - -Q q; - -Fid *eventfd; -Fid *addrfd; -Fid *datafd; -Fid *ctlfd; -// int bodyfd; - -char *typing; -int ntypeb; -int ntyper; -int ntypebreak; -int debug; -char *name; - -char **prog; -int p[2]; -Channel *cpid; -Channel *cwait; -int pid = -1; - -int label(char*, int); -void error(char*); -void stdinproc(void*); -void stdoutproc(void*); -void type(Event*, int, Fid*, Fid*); -void sende(Event*, int, Fid*, Fid*, Fid*, int); -char *onestring(int, char**); -int delete(Event*); -void deltype(uint, uint); -void runproc(void*); - -int -fsfidprint(Fid *fid, char *fmt, ...) -{ - char buf[256]; - va_list arg; - int n; - - va_start(arg, fmt); - n = vsnprint(buf, sizeof buf, fmt, arg); - va_end(arg); - return fswrite(fid, buf, n); -} - -void -usage(void) -{ - fprint(2, "usage: win cmd args...\n"); - threadexitsall("usage"); -} - -int -nopipes(void *v, char *msg) -{ - USED(v); - if(strcmp(msg, "sys: write on closed pipe") == 0) - return 1; - return 0; -} - -void -waitthread(void *v) -{ - recvp(cwait); - threadexitsall(nil); -} - -void -threadmain(int argc, char **argv) -{ - int fd, id; - char buf[256]; - char buf1[128]; - Fsys *fs; - - ARGBEGIN{ - case 'd': - debug = 1; - break; - default: - usage(); - }ARGEND - - prog = argv; - - if(argc > 0) - name = argv[0]; - else - name = "gnot"; - - threadnotify(nopipes, 1); - if((fs = nsmount("acme", "")) < 0) - sysfatal("nsmount acme: %r"); - ctlfd = fsopen(fs, "new/ctl", ORDWR|OCEXEC); - if(ctlfd < 0 || fsread(ctlfd, buf, 12) != 12) - sysfatal("ctl: %r"); - id = atoi(buf); - sprint(buf, "%d/tag", id); - fd = fsopenfd(fs, buf, OWRITE|OCEXEC); - write(fd, " Send Delete", 12); - close(fd); - sprint(buf, "%d/event", id); - eventfd = fsopen(fs, buf, ORDWR|OCEXEC); - sprint(buf, "%d/addr", id); - addrfd = fsopen(fs, buf, ORDWR|OCEXEC); - sprint(buf, "%d/data", id); - datafd = fsopen(fs, buf, ORDWR|OCEXEC); - sprint(buf, "%d/body", id); -/* bodyfd = fsopenfd(fs, buf, ORDWR|OCEXEC); */ - if(eventfd==nil || addrfd==nil || datafd==nil) - sysfatal("data files: %r"); -/* - if(eventfd<0 || addrfd<0 || datafd<0 || bodyfd<0) - sysfatal("data files: %r"); -*/ - fsunmount(fs); - - if(pipe(p) < 0) - sysfatal("pipe: %r"); - - cpid = chancreate(sizeof(ulong), 1); - cwait = threadwaitchan(); - threadcreate(waitthread, nil, STACK); - threadcreate(runproc, nil, STACK); - pid = recvul(cpid); - if(pid == -1) - sysfatal("exec failed"); - - getwd(buf1, sizeof buf1); - sprint(buf, "name %s/-%s\n0\n", buf1, name); - fswrite(ctlfd, buf, strlen(buf)); - sprint(buf, "dumpdir %s/\n", buf1); - fswrite(ctlfd, buf, strlen(buf)); - sprint(buf, "dump %s\n", onestring(argc, argv)); - fswrite(ctlfd, buf, strlen(buf)); - - threadcreate(stdoutproc, nil, STACK); - stdinproc(nil); -} - -char *shell[] = { "rc", "-i", 0 }; -void -runproc(void *v) -{ - int fd[3]; - char *sh; - - USED(v); - - fd[0] = p[1]; -// fd[1] = bodyfd; -// fd[2] = bodyfd; - fd[1] = p[1]; - fd[2] = p[1]; - - if(prog[0] == nil){ - prog = shell; - if((sh = getenv("SHELL")) != nil) - shell[0] = sh; - } - threadexec(cpid, fd, prog[0], prog); - threadexits(nil); -} - -void -error(char *s) -{ - if(s) - fprint(2, "win: %s: %r\n", s); - else - s = "kill"; - if(pid != -1) - postnote(PNGROUP, pid, "hangup"); - threadexitsall(s); -} - -char* -onestring(int argc, char **argv) -{ - char *p; - int i, n; - static char buf[1024]; - - if(argc == 0) - return ""; - p = buf; - for(i=0; i= buf+sizeof buf) - break; - memmove(p, argv[i], n); - p += n; - *p++ = ' '; - } - p[-1] = 0; - return buf; -} - -int -getec(Fid *efd) -{ - static char buf[8192]; - static char *bufp; - static int nbuf; - - if(nbuf == 0){ - nbuf = fsread(efd, buf, sizeof buf); - if(nbuf <= 0) - error(nil); - bufp = buf; - } - --nbuf; - return *bufp++; -} - -int -geten(Fid *efd) -{ - int n, c; - - n = 0; - while('0'<=(c=getec(efd)) && c<='9') - n = n*10+(c-'0'); - if(c != ' ') - error("event number syntax"); - return n; -} - -int -geter(Fid *efd, char *buf, int *nb) -{ - Rune r; - int n; - - r = getec(efd); - buf[0] = r; - n = 1; - if(r < Runeself) - goto Return; - while(!fullrune(buf, n)) - buf[n++] = getec(efd); - chartorune(&r, buf); - Return: - *nb = n; - return r; -} - -void -gete(Fid *efd, Event *e) -{ - int i, nb; - - e->c1 = getec(efd); - e->c2 = getec(efd); - e->q0 = geten(efd); - e->q1 = geten(efd); - e->flag = geten(efd); - e->nr = geten(efd); - if(e->nr > EVENTSIZE) - error("event string too long"); - e->nb = 0; - for(i=0; inr; i++){ - e->r[i] = geter(efd, e->b+e->nb, &nb); - e->nb += nb; - } - e->r[e->nr] = 0; - e->b[e->nb] = 0; - if(getec(efd) != '\n') - error("event syntax 2"); -} - -int -nrunes(char *s, int nb) -{ - int i, n; - Rune r; - - n = 0; - for(i=0; i0 && (buf[n-1]&0xC0)){ - --n; - npart++; - if((buf[n]&0xC0)!=0x80){ - if(fullrune(buf+n, npart)){ - w = chartorune(&r, buf+n); - n += w; - npart -= w; - } - break; - } - } - if(n > 0){ - memmove(hold, buf+n, npart); - buf[n] = 0; - n = label(buf, n); - buf[n] = 0; - qlock(&q.lk); - m = sprint(x, "#%d", q.p); - if(fswrite(afd, x, m) != m) - error("stdout writing address"); - if(fswrite(dfd, buf, n) != n) - error("stdout writing body"); - q.p += nrunes(buf, n); - qunlock(&q.lk); - memmove(buf, hold, npart); - } - } -} - -char wdir[256]; -int -label(char *sr, int n) -{ - char *sl, *el, *er, *r; - - er = sr+n; - for(r=er-1; r>=sr; r--) - if(*r == '\007') - break; - if(r < sr) - return n; - - el = r+1; - if(el-sr > sizeof wdir) - sr = el - sizeof wdir; - for(sl=el-3; sl>=sr; sl--) - if(sl[0]=='\033' && sl[1]==']' && sl[2]==';') - break; - if(sl < sr) - return n; - - *r = 0; - snprint(wdir, sizeof wdir, "name %s/-%s\n0\n", sl+3, name); - fswrite(ctlfd, wdir, strlen(wdir)); - - memmove(sl, el, er-el); - n -= (el-sl); - return n; -} - -int -delete(Event *e) -{ - uint q0, q1; - int deltap; - - q0 = e->q0; - q1 = e->q1; - if(q1 <= q.p) - return e->q1-e->q0; - if(q0 >= q.p+ntyper) - return 0; - deltap = 0; - if(q0 < q.p){ - deltap = q.p-q0; - q0 = 0; - }else - q0 -= q.p; - if(q1 > q.p+ntyper) - q1 = ntyper; - else - q1 -= q.p; - deltype(q0, q1); - return deltap; -} - -void -addtype(int c, uint p0, char *b, int nb, int nr) -{ - int i, w; - Rune r; - uint p; - char *b0; - - for(i=0; inr > 0) - addtype(e->c1, e->q0-q.p, e->b, e->nb, e->nr); - else{ - m = e->q0; - while(m < e->q1){ - n = sprint(buf, "#%d", m); - fswrite(afd, buf, n); - n = fsread(dfd, buf, sizeof buf); - nr = nrunes(buf, n); - while(m+nr > e->q1){ - do; while(n>0 && (buf[--n]&0xC0)==0x80); - --nr; - } - if(n == 0) - break; - addtype(e->c1, m-q.p, buf, n, nr); - m += nr; - } - } - sendtype(fd0); -} - -void -sende(Event *e, int fd0, Fid *cfd, Fid *afd, Fid *dfd, int donl) -{ - int l, m, n, nr, lastc, end; - char abuf[16], buf[128]; - - end = q.p+ntyper; - l = sprint(abuf, "#%d", end); - fswrite(afd, abuf, l); - if(e->nr > 0){ - fswrite(dfd, e->b, e->nb); - addtype(e->c1, ntyper, e->b, e->nb, e->nr); - lastc = e->r[e->nr-1]; - }else{ - m = e->q0; - lastc = 0; - while(m < e->q1){ - n = sprint(buf, "#%d", m); - fswrite(afd, buf, n); - n = fsread(dfd, buf, sizeof buf); - nr = nrunes(buf, n); - while(m+nr > e->q1){ - do; while(n>0 && (buf[--n]&0xC0)==0x80); - --nr; - } - if(n == 0) - break; - l = sprint(abuf, "#%d", end); - fswrite(afd, abuf, l); - fswrite(dfd, buf, n); - addtype(e->c1, ntyper, buf, n, nr); - lastc = buf[n-1]; - m += nr; - end += nr; - } - } - if(donl && lastc!='\n'){ - fswrite(dfd, "\n", 1); - addtype(e->c1, ntyper, "\n", 1, 1); - } - fswrite(cfd, "dot=addr", 8); - sendtype(fd0); -} blob - 0ff114bda442cba2b11264a84e65d9e8202ca6fd blob + 6614414dffba4790fd17b8ea871f948de0fb859d --- src/cmd/yacc.c +++ src/cmd/yacc.c @@ -399,7 +399,7 @@ others(void) { int c, i, j; - finput = Bopen(parser, OREAD); + finput = Bopen(unsharp(parser), OREAD); if(finput == 0) error("cannot open parser %s: %r", parser); warray("yyr1", levprd, nprod); blob - 4eb6eac9869b53fcafbf301a4f7f596c02ceb242 blob + 84cd65caedb79829a0d3b445b7be553761f47184 --- src/lib9/_p9translate.c +++ src/lib9/_p9translate.c @@ -14,7 +14,7 @@ static struct { }; char* -_p9translate(char *old) +plan9translate(char *old) { char *new; int i, olen, nlen, len; @@ -36,7 +36,7 @@ _p9translate(char *old) len = strlen(old)+nlen-olen; new = malloc(len+1); if(new == nil) - return nil; + return ""; strcpy(new, replace[i].new); strcpy(new+nlen, old+olen); assert(strlen(new) == len); blob - 20b00c32744d1d1cf75af6196b1dbeb9b6905be9 (mode 644) blob + /dev/null --- src/lib9/access.c +++ /dev/null @@ -1,19 +0,0 @@ -#include -#define NOPLAN9DEFINES -#include - -char *_p9translate(char*); - -int -p9access(char *xname, int what) -{ - int ret; - char *name; - - if((name = _p9translate(xname)) == nil) - return -1; - ret = access(name, what); - if(name != xname) - free(name); - return ret; -} blob - 9f07bd2293c96907db947cf5003832c035491786 blob + 8fdf1d40c610b4826f04830e3b618a2c488f3809 --- src/lib9/announce.c +++ src/lib9/announce.c @@ -40,7 +40,8 @@ p9announce(char *addr, char *dir) char *net; u32int host; int port, s; - int n, sn; + int n; + socklen_t sn; struct sockaddr_in sa; struct sockaddr_un sun; @@ -72,7 +73,7 @@ p9announce(char *addr, char *dir) if((s = socket(AF_INET, proto, 0)) < 0) return -1; sn = sizeof n; - if(port && getsockopt(s, SOL_SOCKET, SO_TYPE, (char*)&n, &sn) >= 0 + if(port && getsockopt(s, SOL_SOCKET, SO_TYPE, (void*)&n, &sn) >= 0 && n == SOCK_STREAM){ n = 1; setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&n, sizeof n); blob - bdad5f6a0c8f8e69a6b0f594255deb43adc6ccf7 blob + 97f6e7e2a2540b09548fe7881751401c556a5b9e --- src/lib9/create.c +++ src/lib9/create.c @@ -3,17 +3,11 @@ #include #include -extern char *_p9translate(char*); - int -p9create(char *xpath, int mode, ulong perm) +p9create(char *path, int mode, ulong perm) { int fd, cexec, umode, rclose; - char *path; - if((path = _p9translate(xpath)) == nil) - return -1; - cexec = mode&OCEXEC; rclose = mode&ORCLOSE; mode &= ~(ORCLOSE|OCEXEC); @@ -48,7 +42,5 @@ out: if(rclose) remove(path); } - if(path != xpath) - free(path); return fd; } blob - e9d971bf69d310b26e00a5fcbbfb58ab187234c7 blob + 0782d099feacdb1a59f797fa707967543f57c28a --- src/lib9/ctime.c +++ src/lib9/ctime.c @@ -15,6 +15,7 @@ ct_numb(char *cp, int n) char* asctime(Tm *t) { + int i; char *ncp; static char cbuf[30]; @@ -32,6 +33,12 @@ asctime(Tm *t) ct_numb(cbuf+14, t->min+100); ct_numb(cbuf+17, t->sec+100); ncp = t->zone; + for(i=0; i<3; i++) + if(ncp[i] == 0) + break; + for(; i<3; i++) + ncp[i] = '?'; + ncp = t->zone; cbuf[20] = *ncp++; cbuf[21] = *ncp++; cbuf[22] = *ncp; blob - 8ece0c688819408c91609118d132a62759f967de blob + 8f852de294f80d7971852ac8da157906f3c6bce0 --- src/lib9/date.c +++ src/lib9/date.c @@ -1,6 +1,5 @@ -#include /* setenv etc. */ - #include +#include /* setenv etc. */ #define NOPLAN9DEFINES #include #include @@ -25,6 +24,8 @@ static Tm bigtm; static void tm2Tm(struct tm *tm, Tm *bigtm) { + char *s; + memset(bigtm, 0, sizeof *bigtm); bigtm->sec = tm->tm_sec; bigtm->min = tm->tm_min; @@ -39,6 +40,13 @@ tm2Tm(struct tm *tm, Tm *bigtm) #ifdef _HAVETZOFF bigtm->tzoff = tm->tm_gmtoff; #endif + if(bigtm->zone[0] == 0){ + s = getenv("TIMEZONE"); + if(s){ + strecpy(bigtm->zone, bigtm->zone+4, tm->tm_zone); + free(s); + } + } } static void blob - aef0102f85fae9bb11e921ee5dda0aab3aa5c018 blob + 0a72d62e4d0848176f0bd17fe7e322092faf9d4e --- src/lib9/dirread.c +++ src/lib9/dirread.c @@ -18,7 +18,7 @@ mygetdents(int fd, struct dirent *buf, int n) nn = getdirentries(fd, (void*)buf, n, &off); return nn; } -#elif defined(__APPLE__) || defined(__FreeBSD__) +#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) static int mygetdents(int fd, struct dirent *buf, int n) { @@ -171,7 +171,7 @@ dirreadall(int fd, Dir **d) ts += n; } if(ts >= 0) - ts = dirpackage(fd, buf, ts, d); + ts = dirpackage(fd, (char*)buf, ts, d); free(buf); if(ts == 0 && n < 0) return -1; blob - 0c6ab315d608390321d8864a7b77c56cb8bec82a blob + 578f4895e7fdbe7b24abba707c414f3d8c070593 --- src/lib9/errstr.c +++ src/lib9/errstr.c @@ -5,9 +5,10 @@ * okay. */ +#include #include #include -#include +#include enum { blob - /dev/null blob + 5e677f72e45ae45af3b3d6c6d7a744c881f99cdc (mode 644) --- /dev/null +++ src/lib9/ffork-OpenBSD.c @@ -0,0 +1 @@ +#include "ffork-pthread.c" blob - b53a3892ea57cc897b447af11b7fb56a53cd70dd blob + 09c070419fcf7b0da6e424eca4f277894247243c --- src/lib9/getuser.c +++ src/lib9/getuser.c @@ -1,6 +1,5 @@ -#include - #include +#include #include char* blob - 5d6f2f3e154a56e67cc612b6923393708ad3197e blob + e97b967f2076b2a9abdf07db6143571cd29d3ebe --- src/lib9/lock.c +++ src/lib9/lock.c @@ -1,6 +1,7 @@ +#include #include #include -#include +#include int _ntas; static int blob - c631300887cd2d5adf3062f6c7e7a979717a5926 blob + a3e91510b17797b6b4287f44a601d1fc43c6806d --- src/lib9/mallocz.c +++ src/lib9/mallocz.c @@ -1,6 +1,7 @@ +#include #include #include -#include +#include void* mallocz(unsigned long n, int clr) blob - d388d224e9787a3328043b613193caede3d1ab22 blob + 4dda2e19fd25a41447294d6f63969d08d2250dba --- src/lib9/mkfile +++ src/lib9/mkfile @@ -69,8 +69,6 @@ LIB9OFILES=\ _p9dialparse.$O\ _p9dir.$O\ _p9proc.$O\ - _p9translate.$O\ - access.$O\ announce.$O\ argv0.$O\ atexit.$O\ @@ -100,6 +98,7 @@ LIB9OFILES=\ exec.$O\ fcallfmt.$O\ ffork-$SYSNAME.$O\ + get9root.$O\ getcallerpc-$OBJTYPE.$O\ getenv.$O\ getfields.$O\ @@ -142,6 +141,7 @@ LIB9OFILES=\ u16.$O\ u32.$O\ u64.$O\ + unsharp.$O\ wait.$O\ waitpid.$O\ blob - 2e589de750352136856816e158011977e6a92b2d blob + 4d2a79efc69006750f6a0e526d2812bb09be677c --- src/lib9/notify.c +++ src/lib9/notify.c @@ -1,6 +1,5 @@ -#include - #include +#include #define NOPLAN9DEFINES #include #include "9proc.h" blob - bb597e8f2171fcf792f8ac5b591c0ecd5771981b blob + 0356a7dabc561721f96dfe4fc29cab25526404ae --- src/lib9/open.c +++ src/lib9/open.c @@ -2,12 +2,9 @@ #define NOPLAN9DEFINES #include -extern char* _p9translate(char*); - int -p9open(char *xname, int mode) +p9open(char *name, int mode) { - char *name; int cexec, rclose; int fd, umode; @@ -23,8 +20,6 @@ p9open(char *xname, int mode) werrstr("mode not supported"); return -1; } - if((name = _p9translate(xname)) == nil) - return -1; fd = open(name, umode); if(fd >= 0){ if(cexec) @@ -32,7 +27,5 @@ p9open(char *xname, int mode) if(rclose) remove(name); } - if(name != xname) - free(name); return fd; } blob - 05c52ae734310ff4b438ce004313a539c33d7723 blob + 673818e05550b72a45b9e5b1832403be53f78186 --- src/lib9/rendez-Linux.c +++ src/lib9/rendez-Linux.c @@ -1 +1,3 @@ +/* Could use futex(2) here instead of signals? */ + #include "rendez-signal.c" blob - /dev/null blob + 05c52ae734310ff4b438ce004313a539c33d7723 (mode 644) --- /dev/null +++ src/lib9/rendez-OpenBSD.c @@ -0,0 +1 @@ +#include "rendez-signal.c" blob - b4b95f21d56fe32fe97d1de8d7014a3673eb5382 blob + fe930cef28e9cb52998b7961046f98494d43eb93 --- src/lib9/rendez-pthread.c +++ src/lib9/rendez-pthread.c @@ -32,9 +32,10 @@ * shared memory and mutexes. */ +#include #include #include -#include +#include enum { blob - 169a82f50287cfd9b64a4b4f9f531b96c168c517 blob + 367063678baf5c1e46c9ae06145dea695f5a1f7a --- src/lib9/time.c +++ src/lib9/time.c @@ -1,7 +1,7 @@ +#include #include +#include #include - -#include #define NOPLAN9DEFINES #include blob - a359327b598ca6382449b1d8bacfe2495f1dc61d blob + 05370eacc95899850aaadde56bfd897dd27c6fbe --- src/libdraw/openfont.c +++ src/libdraw/openfont.c @@ -18,8 +18,10 @@ openfont(Display *d, char *name) nambuf = smprint("#9/font/%s", name+14); if(nambuf == nil) return 0; + nambuf = unsharp(nambuf); + if(nambuf == nil) + return 0; if((fd = open(nambuf, OREAD)) < 0){ -fprint(2, "failed at %s\n", nambuf); free(nambuf); return 0; } blob - 1283f430f09ef8b88ea7845511598eeb88f288d4 blob + c959eee4c98e8c7766e4758267c21a1fa2833e8c --- src/libdraw/x11-init.c +++ src/libdraw/x11-init.c @@ -185,26 +185,22 @@ xattach(char *label) /* * Figure out underlying screen format. */ - _x.depth = DefaultDepth(_x.display, xrootid); if(XMatchVisualInfo(_x.display, xrootid, 16, TrueColor, &xvi) || XMatchVisualInfo(_x.display, xrootid, 16, DirectColor, &xvi)){ _x.vis = xvi.visual; _x.depth = 16; - _x.usetable = 1; } else if(XMatchVisualInfo(_x.display, xrootid, 15, TrueColor, &xvi) || XMatchVisualInfo(_x.display, xrootid, 15, DirectColor, &xvi)){ _x.vis = xvi.visual; _x.depth = 15; - _x.usetable = 1; } else if(XMatchVisualInfo(_x.display, xrootid, 24, TrueColor, &xvi) || XMatchVisualInfo(_x.display, xrootid, 24, DirectColor, &xvi)){ _x.vis = xvi.visual; _x.depth = 24; - _x.usetable = 1; } else if(XMatchVisualInfo(_x.display, xrootid, 8, PseudoColor, &xvi) @@ -218,6 +214,7 @@ xattach(char *label) _x.depth = 8; } else{ + _x.depth = DefaultDepth(_x.display, xrootid); if(_x.depth != 8){ werrstr("can't understand depth %d screen", _x.depth); goto err0; @@ -225,6 +222,9 @@ xattach(char *label) _x.vis = DefaultVisual(_x.display, xrootid); } + if(DefaultDepth(_x.display, xrootid) == _x.depth) + _x.usetable = 1; + /* * _x.depth is only the number of significant pixel bits, * not the total number of pixel bits. We need to walk the @@ -298,7 +298,7 @@ xattach(char *label) Dx(r), /* width */ Dy(r), /* height */ 0, /* border width */ - DefaultDepthOfScreen(xscreen), /* depth */ + _x.depth, /* depth */ InputOutput, /* class */ _x.vis, /* visual */ /* valuemask */ @@ -563,6 +563,18 @@ setupcmap(XWindow w) if(_x.depth >= 24) { /* + * This is needed for SunOS. Ask Axel Belinfante. + */ + if(_x.usetable == 0){ + _x.cmap = XCreateColormap(_x.display, w, _x.vis, AllocAll); + XStoreColors(_x.display, _x.cmap, _x.map, 256); + for(i = 0; i < 256; i++){ + _x.tox11[i] = i; + _x.toplan9[i] = i; + } + } + + /* * The pixel value returned from XGetPixel needs to * be converted to RGB so we can call rgb2cmap() * to translate between 24 bit X and our color. Unfortunately, @@ -573,7 +585,6 @@ setupcmap(XWindow w) * some displays say MSB even though they run on LSB. * Besides, this is more anal. */ - c = _x.map[19]; /* known to have different R, G, B values */ if(!XAllocColor(_x.display, _x.cmap, &c)){ werrstr("XAllocColor: %r"); blob - 8e72b011e66d53e9ea0a2a29a7d27f70adea3384 blob + 509b55cfca5067d01dbae74c4dce6643a9796692 --- src/libdraw/x11-itrans.c +++ src/libdraw/x11-itrans.c @@ -11,6 +11,9 @@ #include #include "x11-memdraw.h" +#undef time + + static int __xtoplan9kbd(XEvent *e) { blob - c4094fa485c45e39500cc4a3baabf197000bf5f9 blob + 4b2786955cb006ce47083802e184ea2b5e0348fd --- src/libplumb/mesg.c +++ src/libplumb/mesg.c @@ -68,7 +68,6 @@ plumbsendtofid(Fid *fid, Plumbmsg *m) if(buf == nil) return -1; n = fswrite(fid, buf, n); -fprint(2, "fswrite %d\n", n); free(buf); return n; } blob - /dev/null blob + 35e2ab6f87f746e3acc9434f2e5571c0184b4145 (mode 644) --- /dev/null +++ src/libthread/asm-OpenBSD-386.s @@ -0,0 +1,49 @@ +.globl _setlabel +.type _setlabel,@function + +_setlabel: + movl 4(%esp), %eax + movl 0(%esp), %edx + movl %edx, 0(%eax) + movl %ebx, 4(%eax) + movl %esp, 8(%eax) + movl %ebp, 12(%eax) + movl %esi, 16(%eax) + movl %edi, 20(%eax) + xorl %eax, %eax + ret + +.globl _gotolabel +.type _gotolabel,@function + +_gotolabel: + movl 4(%esp), %edx + movl 0(%edx), %ecx + movl 4(%edx), %ebx + movl 8(%edx), %esp + movl 12(%edx), %ebp + movl 16(%edx), %esi + movl 20(%edx), %edi + xorl %eax, %eax + incl %eax + movl %ecx, 0(%esp) + ret + + +# .globl _xinc +# _xinc: +# movl 4(%esp), %eax +# lock incl 0(%eax) +# ret +# +# .globl _xdec +# _xdec: +# movl 4(%esp), %eax +# lock decl 0(%eax) +# jz iszero +# movl $1, %eax +# ret +# iszero: +# movl $0, %eax +# ret +# blob - bfffa14d4cf6a2d639605e20c9001b506748d7a7 blob + eb31e99e76c4aaa573b1722395dd610c72d4f1f5 --- src/libthread/exec-unix.c +++ src/libthread/exec-unix.c @@ -3,8 +3,8 @@ #include "threadimpl.h" static void efork(int[3], int[2], char*, char**); -void -threadexec(Channel *pidc, int fd[3], char *prog, char *args[]) +static void +_threadexec(Channel *pidc, int fd[3], char *prog, char *args[], int freeargs) { int pfd[2]; int n, pid; @@ -40,6 +40,8 @@ threadexec(Channel *pidc, int fd[3], char *prog, char efork(fd, pfd, prog, args); _exit(0); default: + if(freeargs) + free(args); break; } @@ -69,9 +71,42 @@ Bad: } void +threadexec(Channel *pidc, int fd[3], char *prog, char *args[]) +{ + _threadexec(pidc, fd, prog, args, 0); +} + +/* + * The &f+1 trick doesn't work on SunOS, so we might + * as well bite the bullet and do this correctly. + */ +void threadexecl(Channel *pidc, int fd[3], char *f, ...) { - threadexec(pidc, fd, f, &f+1); + char **args, *s; + int n; + va_list arg; + + va_start(arg, f); + for(n=0; va_arg(arg, char*) != 0; n++) + ; + n++; + va_end(arg); + + args = malloc(n*sizeof(args[0])); + if(args == nil){ + if(pidc) + sendul(pidc, ~0); + return; + } + + va_start(arg, f); + for(n=0; (s=va_arg(arg, char*)) != 0; n++) + args[n] = s; + args[n] = 0; + va_end(arg); + + _threadexec(pidc, fd, f, args, 1); } static void blob - 874fb070f5239dbf1aa1a3b58c149fe0948fc067 blob + 5161e3738095cabb3968ccd220ca0966bc6439a0 --- src/libthread/label.h +++ src/libthread/label.h @@ -7,7 +7,7 @@ typedef struct Label Label; #define LABELDPC 0 -#if defined (__i386__) && (defined(__FreeBSD__) || defined(__linux__)) +#if defined (__i386__) && (defined(__FreeBSD__) || defined(__linux__) || defined(__OpenBSD__)) struct Label { ulong pc; blob - 45683608e52ebb5bcf763e113846686d4af82af0 blob + a81246cd7a13b657f64e2d996a9d3708f32885cd --- src/mkfile +++ src/mkfile @@ -1,6 +1,6 @@