aboutsummaryrefslogtreecommitdiff
path: root/include/lib9.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/lib9.h')
-rw-r--r--include/lib9.h254
1 files changed, 254 insertions, 0 deletions
diff --git a/include/lib9.h b/include/lib9.h
new file mode 100644
index 00000000..dd624484
--- /dev/null
+++ b/include/lib9.h
@@ -0,0 +1,254 @@
+/*
+ * 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 _LIB9H_
+#define _LIB9H_ 1
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <setjmp.h>
+
+#ifndef _FMTH_
+# include <fmt.h>
+#endif
+
+#define nil ((void*)0)
+#define nelem(x) (sizeof(x)/sizeof((x)[0]))
+
+#define _NEEDUCHAR 1
+#define _NEEDUSHORT 1
+#define _NEEDUINT 1
+#define _NEEDULONG 1
+
+#if defined(__linux__)
+# include <sys/types.h>
+# if defined(__USE_MISC)
+# undef _NEEDUSHORT
+# undef _NEEDUINT
+# undef _NEEDULONG
+# endif
+#endif
+#if defined(__FreeBSD__)
+# include <sys/types.h>
+# if !defined(_POSIX_SOURCE)
+# undef _NEEDUSHORT
+# undef _NEEDUINT
+# endif
+#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;
+
+/* rfork to create new process running fn(arg) */
+
+#if defined(__FreeBSD__)
+#undef RFFDG
+#undef RFNOTEG
+#undef RFPROC
+#undef RFMEM
+#undef RFNOWAIT
+#undef RFCFDG
+#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*);
+
+/* wait for processes */
+#define wait _p9wait
+typedef struct Waitmsg Waitmsg;
+struct Waitmsg
+{
+ int pid; /* of loved one */
+ ulong time[3]; /* of loved one & descendants */
+ char *msg;
+};
+extern int await(char*, int);
+extern Waitmsg* wait(void);
+
+/* synchronization */
+typedef struct Lock Lock;
+struct Lock
+{
+ int val;
+};
+
+extern int _tas(void*);
+extern void lock(Lock*);
+extern void unlock(Lock*);
+extern int canlock(Lock*);
+
+typedef struct QLp QLp;
+struct QLp
+{
+ int inuse;
+ QLp *next;
+ int state;
+};
+
+typedef struct QLock QLock;
+struct QLock
+{
+ Lock lock;
+ int locked;
+ QLp *head;
+ QLp *tail;
+};
+
+extern void qlock(QLock*);
+extern void qunlock(QLock*);
+extern int canqlock(QLock*);
+extern void _qlockinit(ulong (*)(ulong, ulong));
+
+typedef struct RWLock RWLock;
+struct RWLock
+{
+ Lock lock;
+ int readers;
+ int writer;
+ QLp *head;
+ QLp *tail;
+};
+
+extern void rlock(RWLock*);
+extern void runlock(RWLock*);
+extern int canrlock(RWLock*);
+extern void wlock(RWLock*);
+extern void wunlock(RWLock*);
+extern int canwlock(RWLock*);
+
+typedef struct Rendez Rendez;
+struct Rendez
+{
+ QLock *l;
+ QLp *head;
+ QLp *tail;
+};
+
+extern void rsleep(Rendez*);
+extern int rwakeup(Rendez*);
+extern int rwakeupall(Rendez*);
+
+extern ulong rendezvous(ulong, ulong);
+
+/* one of a kind */
+extern void sysfatal(char*, ...);
+extern int nrand(int);
+extern void setmalloctag(void*, ulong);
+extern void setrealloctag(void*, ulong);
+extern void *mallocz(ulong, int);
+extern long readn(int, void*, long);
+extern void exits(char*);
+extern void _exits(char*);
+extern ulong getcallerpc(void*);
+
+/* string routines */
+extern char* strecpy(char*, char*, char*);
+extern int tokenize(char*, char**, int);
+extern int cistrncmp(char*, char*, int);
+extern int cistrcmp(char*, char*);
+extern char* cistrstr(char*, char*);
+extern int getfields(char*, char**, int, int, char*);
+extern int gettokens(char *, char **, int, char *);
+
+/* formatting helpers */
+extern int dec64(uchar*, int, char*, int);
+extern int enc64(char*, int, uchar*, int);
+extern int dec32(uchar*, int, char*, int);
+extern int enc32(char*, int, uchar*, int);
+extern int dec16(uchar*, int, char*, int);
+extern int enc16(char*, int, uchar*, int);
+extern int encodefmt(Fmt*);
+
+/* error string */
+enum
+{
+ ERRMAX = 128
+};
+extern void rerrstr(char*, uint);
+extern void werrstr(char*, ...);
+extern int errstr(char*, uint);
+
+/* compiler directives on plan 9 */
+#define USED(x) if(x){}else{}
+#define SET(x) ((x)=0)
+
+/* command line */
+extern char *argv0;
+#define ARGBEGIN for((argv0||(argv0=*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
+
+#define OREAD O_RDONLY
+#define OWRITE O_WRONLY
+#define AEXIST 0
+#define AREAD 4
+#define AWRITE 2
+#define AEXEC 1
+#define ORCLOSE 8
+#define OCEXEC 16
+
+#define dup dup2
+#define exec execv
+#define seek lseek
+#define getwd getcwd
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* _LIB9H_ */