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:
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"
;;
*)