libixp

git clone git://oldgit.suckless.org/libixp/
Log | Files | Refs | LICENSE

commit 22005154bbfe435320f1bf8a38111fcd63cc77f7
parent e101f4fcc436418a2345f014a1c6561814c3108f
Author: Kris Maglione <jg@suckless.org>
Date:   Sun, 20 Jan 2008 12:19:58 -0500

Add timer functions. Change ixp_message to use char*. Add mk/so.mk from wmii.

Diffstat:
cmd/ixpc.c | 2+-
config.mk | 48+++++++++++++++++++++++++-----------------------
include/Makefile | 1-
include/ixp.h | 125++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
include/ixp_local.h | 97++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
libixp/Makefile | 1+
libixp/client.c | 18+++++++++---------
libixp/convert.c | 7++++---
libixp/error.c | 5+++--
libixp/intmap.c | 4++--
libixp/message.c | 5+++--
libixp/request.c | 7++++---
libixp/server.c | 20+++++++++++++++++---
libixp/socket.c | 8+++++++-
libixp/thread.c | 5+++--
libixp/timer.c | 92+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
libixp/transport.c | 4++--
libixp/util.c | 8++++----
libixp_pthread/thread_pthread.c | 2++
libixp_rubythread/thread_ruby.c | 3+++
libixp_task/thread_task.c | 2++
mk/common.mk | 6+++---
mk/dir.mk | 16++++++++--------
mk/gcc.mk | 32+++++++++++++++++++++++---------
mk/hdr.mk | 97++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
mk/ixp.mk | 3++-
mk/lib.mk | 28++++++++++++++++------------
mk/man.mk | 3+--
mk/many.mk | 9++++-----
mk/one.mk | 19+++++++++----------
mk/so.mk | 27+++++++++++++++++++++++++++
util/compile | 41++++++++++++++++++++++++++++++++++++++++-
util/link | 2+-
33 files changed, 506 insertions(+), 241 deletions(-)

diff --git a/cmd/ixpc.c b/cmd/ixpc.c @@ -16,7 +16,7 @@ static IxpClient *client; static void -usage() { +usage(void) { fprintf(stderr, "usage: %1$s [-a <address>] {create | read | ls [-ld] | remove | write} <file>\n" " %1$s [-a <address>] xwrite <file> <data>\n" diff --git a/config.mk b/config.mk @@ -3,42 +3,44 @@ COMPONENTS = \ libixp \ libixp_pthread -IGNORE = \ - libixp_task \ - libixp_rubythread -RUBYINC = -I/usr/local/lib/ruby/1.8/i386-freebsd6 -TASKINC = -I${HOME}/libtask - -# paths +# Paths PREFIX = /usr/local -BIN = ${PREFIX}/bin -MAN = ${PREFIX}/share/man -ETC = ${PREFIX}/etc -LIBDIR = ${PREFIX}/lib -INCLUDE = ${PREFIX}/include + BIN = $(PREFIX)/bin + MAN = $(PREFIX)/share/man + ETC = $(PREFIX)/etc + LIBDIR = $(PREFIX)/lib + INCLUDE = $(PREFIX)/include # Includes and libs -INCPATH = .:${ROOT}/include:${INCLUDE}:/usr/include +INCPATH = .:$(ROOT)/include:$(INCLUDE):/usr/include LIBS = -L/usr/lib -lc -MKDEP = cpp -M # Flags -include ${ROOT}/mk/gcc.mk -CFLAGS = -g ${INCS} -DIXPlint -DVERSION=\"${VERSION}\" -LDFLAGS = -g ${LDLIBS} ${LIBS} +include $(ROOT)/mk/gcc.mk +CFLAGS += $(DEBUGCFLAGS) $(INCS) +LDFLAGS = -g $(LDLIBS) $(LIBS) -# Compiler +# Compiler, Linker. Linker should usually *not* be ld. CC = cc -c -# Linker (Under normal circumstances, this should *not* be 'ld') LD = cc -# Other +# Archiver AR = ar crs #AR = sh -c 'ar cr "$$@" && ranlib "$$@"' # Solaris -#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\" -#LDFLAGS = ${LIBS} -R${PREFIX}/lib -#LDFLAGS += -lsocket -lnsl +#CFLAGS = -fast $(INCS) +#LDFLAGS = $(LIBS) -R$(PREFIX)/lib -lsocket -lnsl #CFLAGS += -xtarget=ultra +# Misc +#MAKESO = 1 + +# Extra Components +IGNORE = \ + libixp_task \ + libixp_rubythread + +RUBYINC = -I/usr/local/lib/ruby/1.8/i386-freebsd6 +TASKINC = -I$(HOME)/libtask + diff --git a/include/Makefile b/include/Makefile @@ -6,4 +6,3 @@ HFILES = ixp.h install: ${HFILES:.h=.install} -include ${ROOT}/mk/common.mk diff --git a/include/ixp.h b/include/ixp.h @@ -1,4 +1,4 @@ -/* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com> +/* Copyright ©2004-2006 Anselm R. Garbe <garbeam at gmail dot com> * Copyright ©2006-2007 Kris Maglione <fbsdaemon@gmail.com> * See LICENSE file for license details. */ @@ -7,7 +7,18 @@ #include <sys/types.h> #include <sys/select.h> +#define IXP_API 86 + /* Gunk */ +#ifdef IXP_NEEDAPI +# if IXP_API < IXP_NEEDAPI +# error A newer version of libixp is needed for this compilation. +# elif IXP_API > IXP_NEEDAPI && \ + (defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(KENC)) +# warning This version of libixp has a newer API than this compilation suggests. +# endif +#endif + #undef uchar #undef ushort #undef uint @@ -21,7 +32,7 @@ #define vlong _ixpvlong #define uvlong _ixpuvlong -#ifdef KENCC +#ifdef KENC # define STRUCT(x) struct {x}; # define UNION(x) union {x}; #elif defined(__GNUC__) && !defined(IXPlint) @@ -220,6 +231,7 @@ typedef struct IxpQid IxpQid; typedef struct IxpRpc IxpRpc; typedef struct IxpServer IxpServer; typedef struct IxpStat IxpStat; +typedef struct IxpTimer IxpTimer; typedef struct IxpMutex IxpMutex; typedef struct IxpRWLock IxpRWLock; @@ -232,23 +244,23 @@ enum { }; struct IxpMutex { - void *aux; + void* aux; }; struct IxpRWLock { - void *aux; + void* aux; }; struct IxpRendez { - IxpMutex *mutex; - void *aux; + IxpMutex* mutex; + void* aux; }; enum { MsgPack, MsgUnpack, }; struct IxpMsg { - char *data; - char *pos; - char *end; + char* data; + char* pos; + char* end; uint size; uint mode; }; @@ -325,15 +337,15 @@ struct IxpStat { ulong atime; ulong mtime; uvlong length; - char *name; - char *uid; - char *gid; - char *muid; + char* name; + char* uid; + char* gid; + char* muid; }; struct IxpConn { - IxpServer *srv; - void *aux; + IxpServer* srv; + void* aux; int fd; void (*read)(IxpConn *); void (*close)(IxpConn *); @@ -344,21 +356,23 @@ struct IxpConn { }; struct IxpServer { - IxpConn *conn; - void (*preselect)(IxpServer*); - void *aux; - int running; - int maxfd; - fd_set rd; + IxpConn* conn; + IxpMutex lk; + IxpTimer* timer; + void (*preselect)(IxpServer*); + void* aux; + int running; + int maxfd; + fd_set rd; }; struct IxpRpc { - IxpClient *mux; - IxpRpc *next; - IxpRpc *prev; + IxpClient* mux; + IxpRpc* next; + IxpRpc* prev; IxpRendez r; uint tag; - IxpFcall *p; + IxpFcall* p; int waiting; int async; }; @@ -372,60 +386,61 @@ struct IxpClient { uint nwait; uint mwait; uint freetag; - IxpCFid *freefid; + IxpCFid* freefid; IxpMsg rmsg; IxpMsg wmsg; IxpMutex lk; IxpMutex rlock; IxpMutex wlock; IxpRendez tagrend; - IxpRpc **wait; - IxpRpc *muxer; + IxpRpc** wait; + IxpRpc* muxer; IxpRpc sleep; int mintag; int maxtag; }; struct IxpCFid { - uint fid; - IxpQid qid; - uchar mode; - uint open; - uint iounit; - uvlong offset; - IxpClient *client; + uint fid; + IxpQid qid; + uchar mode; + uint open; + uint iounit; + uvlong offset; + IxpClient* client; /* internal use only */ - IxpCFid *next; - IxpMutex iolock; + IxpCFid* next; + IxpMutex iolock; }; struct IxpFid { - char *uid; - void *aux; + char* uid; + void* aux; ulong fid; IxpQid qid; signed char omode; + uint iounit; /* Implementation details */ - Ixp9Conn *conn; - Intmap *map; + Ixp9Conn* conn; + Intmap* map; }; struct Ixp9Req { - Ixp9Srv *srv; - IxpFid *fid; - IxpFid *newfid; - Ixp9Req *oldreq; + Ixp9Srv* srv; + IxpFid* fid; + IxpFid* newfid; + Ixp9Req* oldreq; IxpFcall ifcall; IxpFcall ofcall; - void *aux; + void* aux; /* Implementation details */ Ixp9Conn *conn; }; struct Ixp9Srv { - void *aux; + void* aux; void (*attach)(Ixp9Req *r); void (*clunk)(Ixp9Req *r); void (*create)(Ixp9Req *r); @@ -510,12 +525,13 @@ void ixp_pstrings(IxpMsg*, ushort*, char**); void ixp_pqid(IxpMsg*, IxpQid*); void ixp_pqids(IxpMsg*, ushort*, IxpQid*); void ixp_pstat(IxpMsg*, IxpStat*); +void ixp_pfcall(IxpMsg*, Fcall*); /* error.h */ -char *ixp_errbuf(void); -void ixp_errstr(char*, int); -void ixp_rerrstr(char*, int); -void ixp_werrstr(const char*, ...); +char* ixp_errbuf(void); +void ixp_errstr(char*, int); +void ixp_rerrstr(char*, int); +void ixp_werrstr(const char*, ...); /* request.c */ void respond(Ixp9Req*, const char *err); @@ -523,7 +539,7 @@ void serve_9pcon(IxpConn*); /* message.c */ ushort ixp_sizeof_stat(IxpStat*); -IxpMsg ixp_message(uchar*, uint len, uint mode); +IxpMsg ixp_message(char*, uint len, uint mode); void ixp_freestat(IxpStat*); void ixp_freefcall(IxpFcall*); uint ixp_msg2fcall(IxpMsg*, IxpFcall*); @@ -545,6 +561,11 @@ int ixp_announce(char*); uint ixp_sendmsg(int, IxpMsg*); uint ixp_recvmsg(int, IxpMsg*); +/* timer.c */ +long ixp_msec(void); +long ixp_settimer(IxpServer*, long, void (*)(long, void*), void*); +int ixp_unsettimer(IxpServer*, long); + /* util.c */ void* ixp_emalloc(uint); void* ixp_emallocz(uint); diff --git a/include/ixp_local.h b/include/ixp_local.h @@ -3,20 +3,32 @@ #include <ixp.h> char *argv0; -#define ARGBEGIN int _argi, _argtmp, _inargv=0; char *_argv; \ - if(!argv0)argv0=ARGF(); _inargv=1; \ +#define ARGBEGIN \ + int _argtmp=0, _inargv=0; char *_argv=nil; \ + if(!argv0) argv0=*argv; argv++, argc--; \ + _inargv=1; USED(_inargv); \ while(argc && argv[0][0] == '-') { \ - _argi=1; _argv=*argv++; argc--; \ - while(_argv[_argi]) switch(_argv[_argi++]) -#define ARGEND }_inargv=0;USED(_argtmp);USED(_argv);USED(_argi) -#define ARGF() ((_inargv && _argv[_argi]) ? \ - (_argtmp=_argi, _argi=strlen(_argv), _argv+_argtmp) \ - : ((argc > 0) ? (argc--, *argv++) : ((char*)0))) -#define EARGF(f) ((_inargv && _argv[_argi]) ? \ - (_argtmp=_argi, _argi=strlen(_argv), _argv+_argtmp) \ - : ((argc > 0) ? (argc--, *argv++) : ((f), (char*)0))) -#define USED(x) if(x){}else -#define SET(x) ((x)=0) + _argv=&argv[0][1]; argv++; argc--; \ + if(_argv[0] == '-' && _argv[1] == '\0') \ + break; \ + while(*_argv) switch(*_argv++) +#define ARGEND }_inargv=0;USED(_argtmp, _argv, _inargv) + +#define EARGF(f) ((_inargv && *_argv) ? \ + (_argtmp=strlen(_argv), _argv+=_argtmp, _argv-_argtmp) \ + : ((argc > 0) ? \ + (--argc, ++argv, _used(argc), *(argv-1)) \ + : ((f), (char*)0))) +#define ARGF() EARGF(_used(0)) + +#ifndef KENC + static inline void _used(long a, ...) { if(a){} } +# define USED(...) _used((long)__VA_ARGS__) +# define SET(x) USED(&x) +#endif + +#undef nil +#define nil ((void*)0) #define thread ixp_thread @@ -32,42 +44,55 @@ char *argv0; #define muxfree ixp_muxfree #define muxrpc ixp_muxrpc -void muxinit(IxpClient*); -void muxfree(IxpClient*); -Fcall *muxrpc(IxpClient*, Fcall*); +#define initmap ixp_initmap +#define incref ixp_incref +#define decref ixp_decref +#define freemap ixp_freemap +#define execmap ixp_execmap +#define lookupkey ixp_lookupkey +#define insertkey ixp_insertkey +#define deletekey ixp_deletekey +#define caninsertkey ixp_caninsertkey #define errstr ixp_errstr #define rerrstr ixp_rerrstr #define werrstr ixp_werrstr typedef struct Intlist Intlist; +typedef IxpTimer Timer; + +typedef struct timeval timeval; + struct Intmap { ulong nhash; Intlist **hash; IxpRWLock lk; }; -#define initmap ixp_initmap -#define incref ixp_incref -#define decref ixp_decref -#define freemap ixp_freemap -#define execmap ixp_execmap -#define lookupkey ixp_lookupkey -#define insertkey ixp_insertkey -#define deletekey ixp_deletekey -#define caninsertkey ixp_caninsertkey +struct IxpTimer { + Timer* link; + long msec; + long id; + void (*fn)(long, void*); + void* aux; +}; /* intmap.c */ -void initmap(Intmap*, ulong, void*); -void incref_map(Intmap*); -void decref_map(Intmap*); -void freemap(Intmap*, void (*destroy)(void*)); -void execmap(Intmap*, void (*destroy)(void*)); -void *lookupkey(Intmap*, ulong); -void *insertkey(Intmap*, ulong, void*); -void *deletekey(Intmap*, ulong); -int caninsertkey(Intmap*, ulong, void*); +int caninsertkey(Intmap*, ulong, void*); +void decref_map(Intmap*); +void* deletekey(Intmap*, ulong); +void execmap(Intmap*, void (*destroy)(void*)); +void freemap(Intmap*, void (*destroy)(void*)); +void incref_map(Intmap*); +void initmap(Intmap*, ulong, void*); +void* insertkey(Intmap*, ulong, void*); +void* lookupkey(Intmap*, ulong); -#undef nil -#define nil ((void*)0) +/* mux.c */ +void muxfree(IxpClient*); +void muxinit(IxpClient*); +Fcall* muxrpc(IxpClient*, Fcall*); + +/* timer.c */ +long ixp_nexttimer(IxpServer*); diff --git a/libixp/Makefile b/libixp/Makefile @@ -14,6 +14,7 @@ OBJ = client \ server \ socket \ thread \ + timer \ transport \ util diff --git a/libixp/client.c b/libixp/client.c @@ -1,4 +1,4 @@ -/* Copyright ©2007 Kris Maglione <fbsdaemon@gmail.com> +/* Copyright ©2007-2008 Kris Maglione <fbsdaemon@gmail.com> * See LICENSE file for license details. */ #include <assert.h> @@ -24,7 +24,7 @@ min(int a, int b) { return b; } -static IxpCFid * +static IxpCFid* getfid(IxpClient *c) { IxpCFid *f; @@ -112,7 +112,7 @@ allocmsg(IxpClient *c, int n) { c->wmsg.data = erealloc(c->wmsg.data, n); } -IxpClient * +IxpClient* ixp_mountfd(int fd) { IxpClient *c; Fcall fcall; @@ -163,7 +163,7 @@ ixp_mountfd(int fd) { return c; } -IxpClient * +IxpClient* ixp_mount(char *address) { int fd; @@ -173,7 +173,7 @@ ixp_mount(char *address) { return ixp_mountfd(fd); } -static IxpCFid * +static IxpCFid* walk(IxpClient *c, char *path) { IxpCFid *f; Fcall fcall; @@ -202,7 +202,7 @@ fail: return nil; } -static IxpCFid * +static IxpCFid* walkdir(IxpClient *c, char *path, char **rest) { char *p; @@ -332,7 +332,7 @@ ixp_close(IxpCFid *f) { return clunk(f); } -Stat * +Stat* ixp_stat(IxpClient *c, char *path) { IxpMsg msg; Fcall fcall; @@ -349,7 +349,7 @@ ixp_stat(IxpClient *c, char *path) { if(dofcall(c, &fcall) == 0) goto done; - msg = ixp_message(fcall.stat, fcall.nstat, MsgUnpack); + msg = ixp_message((char*)fcall.stat, fcall.nstat, MsgUnpack); stat = emalloc(sizeof(*stat)); ixp_pstat(&msg, stat); @@ -365,7 +365,7 @@ done: } static long -_pread(IxpCFid *f, void *buf, long count, vlong offset) { +_pread(IxpCFid *f, char *buf, long count, vlong offset) { Fcall fcall; int n, len; diff --git a/libixp/convert.c b/libixp/convert.c @@ -1,4 +1,4 @@ -/* Copyright ©2007 Kris Maglione <fbsdaemon@gmail.com> +/* Copyright ©2007-2008 Kris Maglione <fbsdaemon@gmail.com> * See LICENSE file for license details. */ #include <stdio.h> @@ -13,13 +13,13 @@ enum { SQWord = 8, }; -void +static void ixp_puint(IxpMsg *msg, uint size, ulong *val) { uchar *pos; int v; if(msg->pos + size <= msg->end) { - pos = msg->pos; + pos = (uchar*)msg->pos; switch(msg->mode) { case MsgPack: v = *val; @@ -113,6 +113,7 @@ ixp_pstrings(IxpMsg *msg, ushort *num, char *strings[]) { return; } + SET(s); if(msg->mode == MsgUnpack) { s = msg->pos; size = 0; diff --git a/libixp/error.c b/libixp/error.c @@ -1,3 +1,4 @@ +/* Public Domain --Kris Maglione */ #include <errno.h> #include <stdarg.h> #include <stdio.h> @@ -17,12 +18,12 @@ _vsmprint(const char *fmt, va_list ap) { int n; va_copy(al, ap); - n = snprintf(buf, 0, fmt, al); + n = vsnprintf(buf, 0, fmt, al); va_end(al); buf = malloc(++n); if(buf) - snprintf(buf, n, fmt, ap); + vsnprintf(buf, n, fmt, ap); return buf; } diff --git a/libixp/intmap.c b/libixp/intmap.c @@ -74,7 +74,7 @@ execmap(Intmap *map, void (*run)(void*)) { thread->runlock(&map->lk); } -void * +void* lookupkey(Intmap *map, ulong id) { Intlist *f; void *v; @@ -88,7 +88,7 @@ lookupkey(Intmap *map, ulong id) { return v; } -void * +void* insertkey(Intmap *map, ulong id, void *v) { Intlist *f; void *ov; diff --git a/libixp/message.c b/libixp/message.c @@ -1,4 +1,4 @@ -/* Copyright ©2007 Kris Maglione <fbsdaemon@gmail.com> +/* Copyright ©2007-2008 Kris Maglione <fbsdaemon@gmail.com> * See LICENSE file for license details. */ #include <stdlib.h> @@ -19,7 +19,7 @@ enum { }; IxpMsg -ixp_message(uchar *data, uint length, uint mode) { +ixp_message(char *data, uint length, uint mode) { IxpMsg m; m.data = data; @@ -200,3 +200,4 @@ ixp_msg2fcall(IxpMsg *msg, Fcall *fcall) { return msg->pos - msg->data; } + diff --git a/libixp/request.c b/libixp/request.c @@ -1,4 +1,4 @@ -/* Copyright ©2006-2007 Kris Maglione <fbsdaemon@gmail.com> +/* Copyright ©2006-2008 Kris Maglione <fbsdaemon@gmail.com> * See LICENSE file for license details. */ #include <assert.h> @@ -69,7 +69,7 @@ decref_p9conn(Ixp9Conn *pc) { free(pc); } -static void * +static void* createfid(Intmap *map, int fid, Ixp9Conn *pc) { Fid *f; @@ -342,11 +342,12 @@ respond(Ixp9Req *r, const char *error) { case TOpen: case TCreate: if(!error) { + r->ofcall.iounit = pc->rmsg.size - 24; + r->fid->iounit = r->ofcall.iounit; r->fid->omode = r->ifcall.mode; r->fid->qid = r->ofcall.qid; } free(r->ifcall.name); - r->ofcall.iounit = pc->rmsg.size - 24; break; case TWalk: if(error || r->ofcall.nwqid < r->ifcall.nwname) { diff --git a/libixp/server.c b/libixp/server.c @@ -1,4 +1,4 @@ -/* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com> +/* Copyright ©2004-2006 Anselm R. Garbe <garbeam at gmail dot com> * See LICENSE file for license details. */ #include <assert.h> @@ -8,7 +8,7 @@ #include <unistd.h> #include "ixp_local.h" -IxpConn * +IxpConn* ixp_listen(IxpServer *s, int fd, void *aux, void (*read)(IxpConn *c), void (*close)(IxpConn *c) @@ -72,14 +72,27 @@ handle_conns(IxpServer *s) { int ixp_serverloop(IxpServer *s) { + timeval *tvp; + timeval tv; + long timeout; int r; s->running = 1; + thread->initmutex(&s->lk); while(s->running) { if(s->preselect) s->preselect(s); + + tvp = nil; + timeout = ixp_nexttimer(s); + if(timeout > 0) { + tv.tv_sec = timeout/1000; + tv.tv_usec = timeout%1000 * 1000; + tvp = &tv; + } + prepare_select(s); - r = thread->select(s->maxfd + 1, &s->rd, 0, 0, 0); + r = thread->select(s->maxfd + 1, &s->rd, 0, 0, tvp); if(r < 0) { if(errno == EINTR) continue; @@ -98,3 +111,4 @@ ixp_server_close(IxpServer *s) { ixp_hangup(c); } } + diff --git a/libixp/socket.c b/libixp/socket.c @@ -1,4 +1,4 @@ -/* Copyright ©2007 Kris Maglione <fbsdaemon@gmail.com> +/* Copyright ©2007-2008 Kris Maglione <fbsdaemon@gmail.com> * Copyright ©2004-2006 Anselm R. Garbe <garbeam at gmail dot com> * See LICENSE file for license details. */ @@ -20,6 +20,10 @@ * not modified. */ +/* From FreeBSD's sys/su.h */ +#define SUN_LEN(su) \ + (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path)) + typedef struct addrinfo addrinfo; typedef struct sockaddr sockaddr; typedef struct sockaddr_un sockaddr_un; @@ -150,6 +154,7 @@ dial_tcp(char *host) { if(aip == nil) return -1; + SET(fd); for(ai = aip; ai; ai = ai->ai_next) { fd = ai_socket(ai); if(fd == -1) { @@ -179,6 +184,7 @@ announce_tcp(char *host) { return -1; /* Probably don't need to loop */ + SET(fd); for(ai = aip; ai; ai = ai->ai_next) { fd = ai_socket(ai); if(fd == -1) diff --git a/libixp/thread.c b/libixp/thread.c @@ -1,11 +1,12 @@ +/* Public Domain --Kris Maglione */ #include <unistd.h> #include "ixp_local.h" static IxpThread ixp_nothread; -IxpThread *ixp_thread = &ixp_nothread; +IxpThread*ixp_thread = &ixp_nothread; static char* -errbuf() { +errbuf(void) { static char errbuf[IXP_ERRMAX]; return errbuf; diff --git a/libixp/timer.c b/libixp/timer.c @@ -0,0 +1,92 @@ +/* Copyright ©2008 Kris Maglione <fbsdaemon@gmail.com> + * See LICENSE file for license details. + */ +#include <assert.h> +#include <stdlib.h> +#include <sys/time.h> +#include "ixp_local.h" + +/* This really needn't be threadsafe, as it has little use in + * threaded programs, but it is, nonetheless. + */ + +static long lastid = 1; + +long +ixp_msec(void) { + timeval tv; + + if(gettimeofday(&tv, 0) < 0) + return -1; + return tv.tv_sec*1000 + tv.tv_usec/1000; +} + +long +ixp_settimer(IxpServer *s, long msec, void (*fn)(long, void*), void *aux) { + Timer **tp; + Timer *t; + long time; + + time = ixp_msec(); + if(time == -1) + return -1; + msec += time; + + t = emallocz(sizeof *t); + thread->lock(&s->lk); + t->id = lastid++; + t->msec = msec; + t->fn = fn; + t->aux = aux; + + for(tp=&s->timer; *tp; tp=&tp[0]->link) + if(tp[0]->msec < msec) + break; + t->link = *tp; + *tp = t; + thread->unlock(&s->lk); + return t->id; +} + +int +ixp_unsettimer(IxpServer *s, long id) { + Timer **tp; + Timer *t; + + thread->lock(&s->lk); + for(tp=&s->timer; (t=*tp); tp=&t->link) + if(t->id == id) + break; + if(t) { + *tp = t->link; + free(t); + } + thread->unlock(&s->lk); + return t != nil; +} + +long +ixp_nexttimer(IxpServer *s) { + Timer *t; + long time, ret; + + SET(time); + thread->lock(&s->lk); + while((t = s->timer)) { + time = ixp_msec(); + if(t->msec > time) + break; + s->timer = t->link; + + thread->unlock(&s->lk); + t->fn(t->id, t->aux); + free(t); + thread->lock(&s->lk); + } + ret = 0; + if(t) + ret = t->msec - time; + thread->unlock(&s->lk); + return ret; +} + diff --git a/libixp/transport.c b/libixp/transport.c @@ -1,4 +1,4 @@ -/* Copyright ©2007 Kris Maglione <fbsdaemon@gmail.com> +/* Copyright ©2007-2008 Kris Maglione <fbsdaemon@gmail.com> * See LICENSE file for license details. */ #include <errno.h> @@ -82,7 +82,7 @@ ixp_recvmsg(int fd, IxpMsg *msg) { ixp_pu32(msg, &msize); size = msize - SSize; - if(msg->pos + size >= msg->end) { + if(size >= msg->end - msg->pos) { werrstr("message too large"); return 0; } diff --git a/libixp/util.c b/libixp/util.c @@ -53,7 +53,7 @@ mfatal(char *name, uint size) { exit(1); } -void * +void* emalloc(uint size) { void *ret = malloc(size); if(!ret) @@ -61,14 +61,14 @@ emalloc(uint size) { return ret; } -void * +void* emallocz(uint size) { void *ret = emalloc(size); memset(ret, 0, size); return ret; } -void * +void* erealloc(void *ptr, uint size) { void *ret = realloc(ptr, size); if(!ret) @@ -76,7 +76,7 @@ erealloc(void *ptr, uint size) { return ret; } -char * +char* estrdup(const char *str) { void *ret = strdup(str); if(!ret) diff --git a/libixp_pthread/thread_pthread.c b/libixp_pthread/thread_pthread.c @@ -1,3 +1,5 @@ +/* Written by Kris Maglione <fbsdaemon@gmail.com> */ +/* Public domain */ #define _XOPEN_SOURCE 600 #include <errno.h> #include <pthread.h> diff --git a/libixp_rubythread/thread_ruby.c b/libixp_rubythread/thread_ruby.c @@ -1,3 +1,6 @@ +/* Copyright ©2007-2008 Kris Maglione <fbsdaemon@gmail.com> + * See LICENSE file for license details. + */ #include <errno.h> #include <stdlib.h> #include <unistd.h> diff --git a/libixp_task/thread_task.c b/libixp_task/thread_task.c @@ -1,3 +1,5 @@ +/* Written by Kris Maglione <fbsdaemon@gmail.com> */ +/* Public domain */ #include <errno.h> #include <stdlib.h> #include <unistd.h> diff --git a/mk/common.mk b/mk/common.mk @@ -2,9 +2,9 @@ all: install: all -MANDIRS=${MAN}/man1 +MANDIRS=$(MAN)/man1 mkdirs: - for i in ${BIN} ${ETC} ${LIBDIR} ${MANDIRS} ${INCLUDE} ${DIRS}; do \ + for i in $(BIN) $(ETC) $(LIBDIR) $(MANDIRS) $(INCLUDE) $(DIRS); do \ test -d $$i || echo MKDIR $$i; \ mkdir -pm 0755 $$i; \ done @@ -15,6 +15,6 @@ cleandep: DEP:=${shell if test -f .depend;then echo .depend;else echo /dev/null; fi} DEP!=echo /dev/null -include ${DEP} +include $(DEP) .PHONY: all options clean dist install uninstall depend cleandep diff --git a/mk/dir.mk b/mk/dir.mk @@ -3,21 +3,21 @@ MKSUBDIR = targ=$@; \ if [ ! -d $$i ]; then \ echo Skipping nonexistent directory: $$i 1>&2; \ else \ - echo MAKE $${targ\#d} ${BASE}$$i/; \ - (cd $$i && ${MAKE} BASE="${BASE}$$i/" $${targ\#d}) || exit $?; \ + echo MAKE $${targ\#d} $(BASE)$$i/; \ + (cd $$i && $(MAKE) BASE="$(BASE)$$i/" $${targ\#d}) || exit $?; \ fi; \ done dall: - dirs="${DIRS}"; ${MKSUBDIR} + dirs="$(DIRS)"; $(MKSUBDIR) dclean: - dirs="${DIRS}"; ${MKSUBDIR} + dirs="$(DIRS)"; $(MKSUBDIR) dinstall: - dirs="${INSTDIRS}"; ${MKSUBDIR} + dirs="$(INSTDIRS)"; $(MKSUBDIR) duninstall: - dirs="${INSTDIRS}"; ${MKSUBDIR} + dirs="$(INSTDIRS)"; $(MKSUBDIR) ddepend: - dirs="${DIRS}"; ${MKSUBDIR} + dirs="$(DIRS)"; $(MKSUBDIR) all: dall clean: dclean @@ -25,5 +25,5 @@ install: dinstall uninstall: duninstall depend: ddepend -INSTDIRS = ${DIRS} +INSTDIRS = $(DIRS) diff --git a/mk/gcc.mk b/mk/gcc.mk @@ -1,16 +1,30 @@ +DEBUGCFLAGS = \ + -g \ + -O1 \ + -fno-builtin \ + -fno-inline \ + -fno-omit-frame-pointer \ + -fno-optimize-sibling-calls \ + -fno-unroll-loops \ + -DIXPlint CFLAGS += \ - -std=gnu99 \ + -std=c99 \ + -pedantic \ -pipe \ + -fno-strict-aliasing \ -Wall \ - -Wno-parentheses \ - -Wno-missing-braces \ - -Wno-switch \ + -Wimplicit \ + -Wmissing-prototypes \ -Wno-comment \ + -Wno-missing-braces \ + -Wno-parentheses \ -Wno-sign-compare \ - -Wno-unused-parameter \ - -Wimplicit \ + -Wno-switch \ + -Wpointer-arith \ -Wreturn-type \ - -Wtrigraphs \ -Wstrict-prototypes \ - -Wmissing-prototypes \ - -Wpointer-arith \ + -Wtrigraphs +MKDEP = cpp -M +SOCFLAGS += -fPIC +SOLDFLAGS += -shared -soname $(SONAME) + diff --git a/mk/hdr.mk b/mk/hdr.mk @@ -1,72 +1,73 @@ .SILENT: -.SUFFIXES: .O .o .c .sh .rc .awk .1 .depend .install .uninstall .clean +.SUFFIXES: .O .o .o_pic .c .sh .rc .so .awk .1 .depend .install .uninstall .clean all: .c.depend: echo MKDEP $< - ${MKDEP} ${CFLAGS} $< >>.depend + $(MKDEP) $(CFLAGS) $< >>.depend + +.sh.depend .rc.depend .1.depend .awk.depend: + : .c.o: - ${COMPILE} $@ $< + $(COMPILE) $@ $< + +.c.o_pic: + $(COMPILEPIC) $@ $< .o.O: - ${LINK} $@ $< + $(LINK) $@ $< .c.O: ${COMPILE} ${<:.c=.o} $< ${LINK} $@ ${<:.c=.o} -.awk.O: - echo FILTER ${BASE}$< - ${FILTER} $< >$@ - chmod 0755 $@ - -.rc.O: - echo FILTER ${BASE}$< - ${FILTER} $< >$@ - chmod 0755 $@ - .sh.O: - echo FILTER ${BASE}$< - ${FILTER} $< >$@ + echo FILTER $(BASE)$< + $(FILTER) $< >$@ + sh -n $@ + chmod 0755 $@ +.rc.O .awk.O: + echo FILTER $(BASE)$< + $(FILTER) $< >$@ chmod 0755 $@ .O.install: - echo INSTALL $$($(CLEANNAME) ${BASE}$*) - cp -f $< ${BIN}/$* - chmod 0755 ${BIN}/$* + echo INSTALL $$($(CLEANNAME) $(BASE)$*) + cp -f $< $(BIN)/$* + chmod 0755 $(BIN)/$* .O.uninstall: - echo UNINSTALL $$($(CLEANNAME) ${BASE}$*) - rm -f ${BIN}/$* + echo UNINSTALL $$($(CLEANNAME) $(BASE)$*) + rm -f $(BIN)/$* -.a.install: - echo INSTALL $$($(CLEANNAME) ${BASE}$<) - cp -f $< ${LIBDIR}/$< - chmod 0644 ${LIBDIR}/$< -.a.uninstall: - echo UNINSTALL $$($(CLEANNAME) ${BASE}$<) - rm -f ${LIBDIR}/$< +.a.install .so.install: + echo INSTALL $$($(CLEANNAME) $(BASE)$<) + cp -f $< $(LIBDIR)/$< + chmod 0644 $(LIBDIR)/$< +.a.uninstall .so.uninstall: + echo UNINSTALL $$($(CLEANNAME) $(BASE)$<) + rm -f $(LIBDIR)/$< .h.install: - echo INSTALL $$($(CLEANNAME) ${BASE}$<) - cp -f $< ${INCLUDE}/$< - chmod 0644 ${INCLUDE}/$< + echo INSTALL $$($(CLEANNAME) $(BASE)$<) + cp -f $< $(INCLUDE)/$< + chmod 0644 $(INCLUDE)/$< .h.uninstall: - echo UNINSTALL $$($(CLEANNAME) ${BASE}$<) - rm -f ${INCLUDE}/$< + echo UNINSTALL $$($(CLEANNAME) $(BASE)$<) + rm -f $(INCLUDE)/$< .1.install: echo INSTALL man $$($(CLEANNAME) $*'(1)') - ${FILTER} $< >${MAN}/man1/$< - chmod 0644 ${MAN}/man1/$< + $(FILTER) $< >$(MAN)/man1/$< + chmod 0644 $(MAN)/man1/$< .1.uninstall: echo UNINSTALL man $$($(CLEANNAME) $*'(1)') - rm -f ${MAN}/man1/$< + rm -f $(MAN)/man1/$< .O.clean: rm -f $< || true 2>/dev/null rm -f $*.o || true 2>/dev/null -.o.clean: +.o.clean .o_pic.clean: rm -f $< || true 2>/dev/null printinstall: @@ -76,10 +77,20 @@ install: printinstall mkdirs depend: cleandep FILTER = cat -COMPILE= CC="${CC}" CFLAGS="${CFLAGS}" ${ROOT}/util/compile -LINK= LD="${LD}" LDFLAGS="${LDFLAGS}" ${ROOT}/util/link -CLEANNAME=${ROOT}/util/cleanname - -include ${ROOT}/config.mk -CFLAGS += -I$$(echo ${INCPATH}|sed 's/:/ -I/g') +COMPILE= CC="$(CC)" CFLAGS="$(CFLAGS)" $(ROOT)/util/compile +COMPILEPIC= CC="$(CC)" CFLAGS="$(CFLAGS) $(SOCFLAGS)" $(ROOT)/util/compile +LINK= LD="$(LD)" LDFLAGS="$(LDFLAGS)" $(ROOT)/util/link +LINKSO= LD="$(LD)" LDFLAGS="$(SOLDFLAGS)" $(ROOT)/util/link +CLEANNAME=$(ROOT)/util/cleanname + +include $(ROOT)/config.mk + +# I hate this. +MKCFGSH=if test -f $(ROOT)/config.local.mk; then echo $(ROOT)/config.local.mk; else echo /dev/null; fi +MKCFG:=${shell $(MKCFGSH)} +MKCFG!=${MKCFGSH} +include $(MKCFG) + +CFLAGS += -I$$(echo $(INCPATH)|sed 's/:/ -I/g') +include $(ROOT)/mk/common.mk diff --git a/mk/ixp.mk b/mk/ixp.mk @@ -1,4 +1,5 @@ VERSION = 0.4 -${ROOT}/include/ixp.h: ${ROOT}/config.mk +$(ROOT)/include/ixp.h: $(ROOT)/config.mk +CFLAGS += -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600 diff --git a/mk/lib.mk b/mk/lib.mk @@ -1,26 +1,30 @@ -PTARG = ${ROOT}/lib/${TARG} -LIB = ${PTARG}.a +PTARG = $(ROOT)/lib/$(TARG) +LIB = $(PTARG).a OFILES = ${OBJ:=.o} -all: ${HFILES} ${LIB} +all: $(HFILES) $(LIB) -install: ${PTARG}.install -uninstall: ${PTARG}.uninstall +install: $(PTARG).install +uninstall: $(PTARG).uninstall clean: libclean depend: ${OBJ:=.depend} libclean: - for i in ${LIB} ${OFILES}; do \ + for i in $(LIB) $(OFILES); do \ rm -f $$i; \ done 2>/dev/null || true printinstall: echo 'Install directories:' - echo ' Lib: ${LIBDIR}' + echo ' Lib: $(LIBDIR)' -${LIB}: ${OFILES} - echo AR $$($(ROOT)/util/cleanname $(BASE)/$@) - mkdir ${ROOT}/lib 2>/dev/null || true - ${AR} $@ ${OFILES} +$(LIB): $(OFILES) + echo AR $$($(CLEANNAME) $(BASE)/$@) + mkdir $(ROOT)/lib 2>/dev/null || true + $(AR) $@ $(OFILES) + +SOMKSH=case "$(MAKESO)" in 1|[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]) echo $(ROOT)/mk/so.mk;; *) echo /dev/null;; esac +SOMK:=${shell $(SOMKSH)} +SOMK!=$(SOMKSH) +include $(SOMK) -include ${ROOT}/mk/common.mk diff --git a/mk/man.mk b/mk/man.mk @@ -3,6 +3,5 @@ uninstall: ${TARG:.1=.uninstall} printinstall: echo 'Install directories:' - echo ' Man: ${MAN}' + echo ' Man: $(MAN)' -include ${ROOT}/mk/common.mk diff --git a/mk/many.mk b/mk/many.mk @@ -1,19 +1,18 @@ PROGS = ${TARG:=.O} -all: ${OFILES} ${PROGS} +all: $(OFILES) $(PROGS) install: ${TARG:=.install} uninstall: ${TARG:=.uninstall} +depend: ${OFILES:.o=.depend} ${TARG:=.depend} clean: manyclean printinstall: echo 'Install directories:' - echo ' Bin: ${BIN}' + echo ' Bin: $(BIN)' manyclean: - for i in ${TARG:=.o} ${TARG:=.O} ${OFILES}; do \ + for i in ${TARG:=.o} ${TARG:=.O} $(OFILES); do \ rm -f $$i; \ done 2>/dev/null || true -include ${ROOT}/mk/common.mk - diff --git a/mk/one.mk b/mk/one.mk @@ -1,25 +1,24 @@ -PROG = ${TARG}.O +PROG = $(TARG).O OFILES = ${OBJ:=.o} -all: ${PROG} +all: $(PROG) -install: ${TARG}.install -uninstall: ${TARG}.uninstall +install: $(TARG).install +uninstall: $(TARG).uninstall clean: oneclean depend: ${OBJ:=.depend} printinstall: echo 'Install directories:' - echo ' Bin: ${BIN}' + echo ' Bin: $(BIN)' oneclean: - for i in ${PROG} ${OFILES}; do \ + for i in $(PROG) $(OFILES); do \ rm -f $$i; \ done 2>/dev/null || true -${OFILES}: ${HFILES} +$(OFILES): $(HFILES) -${PROG}: ${OFILES} ${LIB} - ${LINK} $@ ${OFILES} ${LIB} +$(PROG): $(OFILES) $(LIB) + $(LINK) $@ $(OFILES) $(LIB) -include ${ROOT}/mk/common.mk diff --git a/mk/so.mk b/mk/so.mk @@ -0,0 +1,27 @@ +SOPTARG = $(ROOT)/lib/$(TARG) +SO = $(SOPTARG).so +SONAME = $(TARG).so +OFILES_PIC = ${OBJ:=.o_pic} + +all: $(HFILES) $(SO) + +install: $(SOPTARG).install +uninstall: $(SOPTARG).uninstall +clean: soclean +depend: ${OBJ:=.depend} + +soclean: + for i in $(SO) $(OFILES_PIC); do \ + rm -f $$i; \ + done 2>/dev/null || true + +printsoinstall: + echo 'Install directories:' + echo ' Lib: $(LIBDIR)' + +printinstall: printsoinstall + +$(SO): $(OFILES_PIC) + mkdir $(ROOT)/lib 2>/dev/null || true + $(LINKSO) $@ $(OFILES_PIC) + diff --git a/util/compile b/util/compile @@ -15,10 +15,49 @@ status=$? base=$(echo $BASE | sed 's/,/\\,/g') re='\([^[:space:]/]*\..:[0-9]\)' +undup() { # GCC is crap. + awk ' + function shift() { + for(n=1; n<=3; n++) + if(2*n <= nl) + for(i=1; i<=n; i++) { + if(l[i] != l[i+n]) + break; + if(i == n) { + for(i=1; i<=n; i++) + print l[i] + nl -= 2*n; + for(i=1; i<=nl; i++) + l[i] = l[i+2*n]; + return; + } + } + if(nl == 0) + return + print l[1] + for(i=1; i<nl; i++) + l[i] = l[i+1] + nl-- + } + BEGIN{ + nl=0 + maxl=6 + } + { + if(nl == maxl) + shift() + l[++nl] = $0 + } + END{ + while(nl > 0) + shift(); + }' +} + cat $xtmp | sed "s,^$re,$base&,g; s,\([[:space:]]\)$re,\1$base\2,g" | egrep -v ': error: .Each undeclared identifier|: error: for each function it appears|is dangerous, better use|is almost always misused|: In function |: At top level:|support .long long.|use of C99 long long|ISO C forbids conversion' | sed 's/ .first use in this function.$//; s/\"\([^\"][^\"]*\)\", line \([0-9][0-9]*\)/\1:\2/g' | - uniq 1>&2 + undup 1>&2 rm -f $xtmp exit $status diff --git a/util/link b/util/link @@ -9,7 +9,7 @@ args="" for i do case "$i" in - *.[ao]) + *.[ao]|*.o_pic) ofiles="$ofiles $i" ;; *)