commit 699b4f8cc0d0451e87c381140cd5685949e5347a
parent 3f4d1c6275cbdebcc038a87f12020f0c6326ffb5
Author: Kris Maglione <jg@suckless.org>
Date: Sun, 3 Feb 2008 17:10:10 -0500
Add ixp_namespace, ixp_nsmount, ixp_smprint. Bump API version.
Diffstat:
16 files changed, 197 insertions(+), 39 deletions(-)
diff --git a/include/ixp.h b/include/ixp.h
@@ -7,7 +7,7 @@
#include <sys/types.h>
#include <sys/select.h>
-#define IXP_API 87
+#define IXP_API 89
/* Gunk */
#if defined(IXP_NEEDAPI) && IXP_API < IXP_NEEDAPI
@@ -498,7 +498,6 @@ int ixp_pthread_init(void);
/* client.c */
int ixp_close(IxpCFid*);
-Stat* ixp_fstat(IxpCFid*);
long ixp_pread(IxpCFid*, void*, long, vlong);
int ixp_print(IxpCFid*, const char*, ...);
long ixp_pwrite(IxpCFid*, const void*, long, vlong);
@@ -508,8 +507,10 @@ void ixp_unmount(IxpClient*);
int ixp_vprint(IxpCFid*, const char*, va_list);
long ixp_write(IxpCFid*, const void*, long);
IxpCFid* ixp_create(IxpClient*, const char*, uint perm, uchar mode);
-IxpClient* ixp_mount(char*);
+IxpStat* ixp_fstat(IxpCFid*);
+IxpClient* ixp_mount(const char*);
IxpClient* ixp_mountfd(int);
+IxpClient* ixp_nsmount(const char*);
IxpCFid* ixp_open(IxpClient*, const char*, uchar);
IxpStat* ixp_stat(IxpClient*, const char*);
@@ -566,11 +567,14 @@ long ixp_settimer(IxpServer*, long, void (*)(long, void*), void*);
int ixp_unsettimer(IxpServer*, long);
/* util.c */
+void ixp_cleanname(char*);
void* ixp_emalloc(uint);
void* ixp_emallocz(uint);
+void ixp_eprint(const char*, ...);
void* ixp_erealloc(void*, uint);
char* ixp_estrdup(const char*);
-void ixp_eprint(const char*, ...);
-uint ixp_tokenize(char**, uint len, char*, char);
+char* ixp_namespace(void);
+char* ixp_smprint(const char*, ...);
uint ixp_strlcat(char*, const char*, uint);
+uint ixp_tokenize(char**, uint len, char*, char);
diff --git a/libixp/client.c b/libixp/client.c
@@ -77,7 +77,7 @@ dofcall(IxpClient *c, Fcall *fcall) {
werrstr("received mismatched fcall");
goto fail;
}
- memcpy(fcall, ret, sizeof(*fcall));
+ memcpy(fcall, ret, sizeof *fcall);
free(ret);
return 1;
fail:
@@ -121,15 +121,19 @@ allocmsg(IxpClient *c, int n) {
/**
* Function: ixp_mountfd
* Function: ixp_mount
+ * Function: ixp_nsmount
*
* Params:
* fd - A file descriptor which is already connected
* to a 9P server.
* address - An address (in Plan 9 resource fomat) on
* which to connect to a 9P server.
+ * name - The name of the socket in the process's canonical
+ * namespace directory.
*
- * Initiate a 9P connection with the server at
- * P<address> or connected to on P<fd>.
+ * Initiate a 9P connection with the server at P<address>,
+ * connected to on P<fd>, or under the process's namespace
+ * directory as P<name>.
*
* Returns:
* A pointer to a new 9P client.
@@ -140,7 +144,7 @@ ixp_mountfd(int fd) {
IxpClient *c;
Fcall fcall;
- c = emallocz(sizeof(*c));
+ c = emallocz(sizeof *c);
c->fd = fd;
muxinit(c);
@@ -187,7 +191,7 @@ ixp_mountfd(int fd) {
}
IxpClient*
-ixp_mount(char *address) {
+ixp_mount(const char *address) {
int fd;
fd = ixp_dial(address);
@@ -196,6 +200,21 @@ ixp_mount(char *address) {
return ixp_mountfd(fd);
}
+IxpClient*
+ixp_nsmount(const char *name) {
+ char *address;
+ IxpClient *c;
+
+ address = ixp_namespace();
+ if(address)
+ address = ixp_smprint("unix!%s/%s", address, name);
+ if(address == nil)
+ return nil;
+ c = ixp_mount(address);
+ free(address);
+ return c;
+}
+
static IxpCFid*
walk(IxpClient *c, const char *path) {
IxpCFid *f;
diff --git a/libixp/error.c b/libixp/error.c
@@ -78,7 +78,7 @@ void
errstr(char *buf, int n) {
char tmp[IXP_ERRMAX];
- strncpy(tmp, buf, sizeof(tmp));
+ strncpy(tmp, buf, sizeof tmp);
rerrstr(buf, n);
strncpy(thread->errbuf(), tmp, IXP_ERRMAX);
errno = EPLAN9;
@@ -95,7 +95,7 @@ werrstr(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
- ixp_vsnprint(tmp, sizeof(tmp), fmt, ap);
+ ixp_vsnprint(tmp, sizeof tmp, fmt, ap);
va_end(ap);
strncpy(thread->errbuf(), tmp, IXP_ERRMAX);
errno = EPLAN9;
diff --git a/libixp/intmap.c b/libixp/intmap.c
@@ -100,7 +100,7 @@ insertkey(Intmap *map, ulong id, void *v) {
ov = f->aux;
f->aux = v;
}else{
- f = emallocz(sizeof(*f));
+ f = emallocz(sizeof *f);
f->id = id;
f->aux = v;
h = hashid(map, id);
diff --git a/libixp/request.c b/libixp/request.c
@@ -73,7 +73,7 @@ static void*
createfid(Intmap *map, int fid, Ixp9Conn *pc) {
Fid *f;
- f = emallocz(sizeof(Fid));
+ f = emallocz(sizeof *f);
pc->ref++;
f->conn = pc;
f->fid = fid;
@@ -116,7 +116,7 @@ handlefcall(IxpConn *c) {
goto Fail;
thread->unlock(&pc->rlock);
- req = emallocz(sizeof(Ixp9Req));
+ req = emallocz(sizeof *req);
pc->ref++;
req->conn = pc;
req->srv = pc->srv;
@@ -425,7 +425,7 @@ voidrequest(void *t) {
pc = r->conn;
pc->ref++;
- tr = emallocz(sizeof(Ixp9Req));
+ tr = emallocz(sizeof *tr);
tr->ifcall.type = TFlush;
tr->ifcall.tag = IXP_NOTAG;
tr->ifcall.oldtag = r->ifcall.tag;
@@ -444,7 +444,7 @@ voidfid(void *t) {
pc = f->conn;
pc->ref++;
- tr = emallocz(sizeof(Ixp9Req));
+ tr = emallocz(sizeof *tr);
tr->ifcall.type = TClunk;
tr->ifcall.tag = IXP_NOTAG;
tr->ifcall.fid = f->fid;
@@ -476,7 +476,7 @@ serve_9pcon(IxpConn *c) {
if(fd < 0)
return;
- pc = emallocz(sizeof(Ixp9Conn));
+ pc = emallocz(sizeof *pc);
pc->ref++;
pc->srv = c->aux;
pc->rmsg.size = 1024;
diff --git a/libixp/rpc.c b/libixp/rpc.c
@@ -88,7 +88,7 @@ muxrecv(IxpClient *mux)
thread->lock(&mux->rlock);
if(ixp_recvmsg(mux->fd, &mux->rmsg) == 0)
goto fail;
- f = emallocz(sizeof(Fcall));
+ f = emallocz(sizeof *f);
if(ixp_msg2fcall(&mux->rmsg, f) == 0) {
free(f);
f = nil;
@@ -214,10 +214,10 @@ gettag(IxpClient *mux, IxpRpc *r)
mw = 1;
else
mw <<= 1;
- w = realloc(mux->wait, mw*sizeof(w[0]));
+ w = realloc(mux->wait, mw * sizeof *w);
if(w == nil)
return -1;
- memset(w+mux->mwait, 0, (mw-mux->mwait)*sizeof(w[0]));
+ memset(w+mux->mwait, 0, (mw-mux->mwait) * sizeof *w);
mux->wait = w;
mux->freetag = mux->mwait;
mux->mwait = mw;
diff --git a/libixp/server.c b/libixp/server.c
@@ -38,7 +38,7 @@ ixp_listen(IxpServer *s, int fd, void *aux,
) {
IxpConn *c;
- c = emallocz(sizeof(IxpConn));
+ c = emallocz(sizeof *c);
c->fd = fd;
c->aux = aux;
c->srv = s;
diff --git a/libixp/socket.c b/libixp/socket.c
@@ -52,10 +52,10 @@ static int
sock_unix(char *address, sockaddr_un *sa, socklen_t *salen) {
int fd;
- memset(sa, 0, sizeof(*sa));
+ memset(sa, 0, sizeof *sa);
sa->sun_family = AF_UNIX;
- strncpy(sa->sun_path, address, sizeof(sa->sun_path));
+ strncpy(sa->sun_path, address, sizeof sa->sun_path);
*salen = SUN_LEN(sa);
fd = socket(AF_UNIX, SOCK_STREAM, 0);
@@ -94,7 +94,7 @@ announce_unix(char *file) {
if(fd == -1)
return fd;
- if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*)&yes, sizeof(yes)) < 0)
+ if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*)&yes, sizeof yes) < 0)
goto fail;
unlink(file);
@@ -123,7 +123,7 @@ alookup(char *host, int announce) {
if(port == nil)
return nil;
- memset(&hints, 0, sizeof(hints));
+ memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
diff --git a/libixp/transport.c b/libixp/transport.c
@@ -24,7 +24,7 @@ mread(int fd, IxpMsg *msg, uint count) {
if(n > count)
n = count;
- r = ixp_thread->read(fd, msg->pos, n);
+ r = thread->read(fd, msg->pos, n);
if(r > 0)
msg->pos += r;
return r;
@@ -41,7 +41,7 @@ readn(int fd, IxpMsg *msg, uint count) {
if(r == -1 && errno == EINTR)
continue;
if(r == 0) {
- werrstr("broken pipe");
+ werrstr("broken pipe: %r");
return count - num;
}
num -= r;
@@ -55,11 +55,11 @@ ixp_sendmsg(int fd, IxpMsg *msg) {
msg->pos = msg->data;
while(msg->pos < msg->end) {
- r = ixp_thread->write(fd, msg->pos, msg->end - msg->pos);
+ r = thread->write(fd, msg->pos, msg->end - msg->pos);
if(r < 1) {
if(errno == EINTR)
continue;
- werrstr("broken pipe");
+ werrstr("broken pipe: %r");
return 0;
}
msg->pos += r;
@@ -94,3 +94,4 @@ ixp_recvmsg(int fd, IxpMsg *msg) {
msg->end = msg->pos;
return msize;
}
+
diff --git a/libixp/util.c b/libixp/util.c
@@ -6,8 +6,122 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <pwd.h>
#include "ixp_local.h"
+char*
+ixp_smprint(const char *fmt, ...) {
+ va_list ap;
+ char *s;
+
+ va_start(ap, fmt);
+ s = ixp_vsmprint(fmt, ap);
+ va_end(ap);
+ if(s == nil)
+ ixp_werrstr("no memory");
+ return s;
+}
+
+static char*
+_user(void) {
+ static char *user;
+ struct passwd *pw;
+
+ if(user == nil) {
+ pw = getpwuid(getuid());
+ if(pw)
+ user = strdup(pw->pw_name);
+ }
+ if(user == nil)
+ user = "none";
+ return user;
+}
+
+static int
+rmkdir(char *path, int mode) {
+ char *p;
+ int ret;
+ char c;
+
+ for(p = path+1; ; p++) {
+ c = *p;
+ if((c == '/') || (c == '\0')) {
+ *p = '\0';
+ ret = mkdir(path, mode);
+ if((ret == -1) && (errno != EEXIST)) {
+ ixp_werrstr("Can't create path '%s': %r", path);
+ return 0;
+ }
+ *p = c;
+ }
+ if(c == '\0')
+ break;
+ }
+ return 1;
+}
+
+static char*
+ns_display(void) {
+ char *path, *disp;
+ struct stat st;
+
+ disp = getenv("DISPLAY");
+ if(disp == nil || disp[0] == '\0') {
+ ixp_werrstr("$DISPLAY is unset");
+ return nil;
+ }
+
+ disp = estrdup(disp);
+ path = &disp[strlen(disp) - 2];
+ if(path > disp && !strcmp(path, ".0"))
+ *path = '\0';
+
+ path = ixp_smprint("/tmp/ns.%s.%s", _user(), disp);
+ free(disp);
+
+ if(!rmkdir(path, 0700))
+ ;
+ else if(stat(path, &st))
+ ixp_werrstr("Can't stat ns_path '%s': %r", path);
+ else if(getuid() != st.st_uid)
+ ixp_werrstr("ns_path '%s' exists but is not owned by you", path);
+ else if((st.st_mode & 077) && chmod(path, st.st_mode & ~077))
+ ixp_werrstr("Namespace path '%s' exists, but has wrong permissions: %r", path);
+ else
+ return path;
+ free(path);
+ return nil;
+}
+
+/**
+ * Function: ixp_namespace
+ *
+ * Returns the path of the canonical 9p namespace directory.
+ * Either the value of $NAMESPACE, if it's set, or, roughly,
+ * /tmp/ns.${USER}.${DISPLAY:%.0=%}. In the latter case, the
+ * directory is created if it doesn't exist, and it is
+ * ensured to be owned by the current user, with no group or
+ * other permissions.
+ *
+ * Returns:
+ * A statically allocated string which must not be freed
+ * or altered by the caller. The same value is returned
+ * upon successive calls.
+ */
+/* Not especially threadsafe. */
+char*
+ixp_namespace(void) {
+ static char *namespace;
+
+ if(namespace == nil)
+ namespace = getenv("NAMESPACE");
+ if(namespace == nil)
+ namespace = ns_display();
+ return namespace;
+}
+
void
eprint(const char *fmt, ...) {
va_list ap;
@@ -38,7 +152,7 @@ mfatal(char *name, uint size) {
char sizestr[8];
int i;
- i = sizeof(sizestr);
+ i = sizeof sizestr;
do {
sizestr[--i] = '0' + (size%10);
size /= 10;
@@ -115,12 +229,12 @@ strlcat(char *dst, const char *src, uint size) {
d++;
len = n;
- while(*s != '\0') {
- if(n-- > 0)
- *d++ = *s;
- s++;
- }
+ while(*s != '\0' && n-- > 0)
+ *d++ = *s++;
+ while(*s++ != '\0')
+ n--;
if(len > 0)
*d = '\0';
return size - n - 1;
}
+
diff --git a/libixp_rubythread/thread_ruby.c b/libixp_rubythread/thread_ruby.c
@@ -145,14 +145,26 @@ rwakeall(IxpRendez *r) {
/* Yielding IO */
static ssize_t
_read(int fd, void *buf, size_t size) {
+ int n;
+
rb_thread_wait_fd(fd);
- return read(fd, buf, size);
+ n = read(fd, buf, size);
+
+ if(n < 0 && errno == EINTR)
+ rb_thread_schedule();
+ return n;
}
static ssize_t
_write(int fd, const void *buf, size_t size) {
+ int n;
+
rb_thread_fd_writable(fd);
- return write(fd, buf, size);
+ n = write(fd, buf, size);
+
+ if(n < 0 && errno == EINTR)
+ rb_thread_schedule();
+ return n;
}
static IxpThread ixp_rthread = {
diff --git a/mk/lib.mk b/mk/lib.mk
@@ -11,6 +11,8 @@ depend: ${OBJ:=.depend}
libclean:
for i in $(LIB) $(OFILES); do \
+ [ -e $$i ] && \
+ echo CLEAN $$($(CLEANNAME) $(BASE)$$i); \
rm -f $$i; \
done 2>/dev/null || true
diff --git a/mk/many.mk b/mk/many.mk
@@ -13,6 +13,7 @@ printinstall:
manyclean:
for i in ${TARG:=.o} ${TARG:=.O} $(OFILES); do \
+ [ -e $$i ] && \
echo CLEAN $$($(CLEANNAME) $(BASE)$$i); \
rm -f $$i; \
done 2>/dev/null || true
diff --git a/mk/one.mk b/mk/one.mk
@@ -14,6 +14,7 @@ printinstall:
oneclean:
for i in $(PROG) $(OFILES); do \
+ [ -e $$i ] && \
echo CLEAN $$($(CLEANNAME) $(BASE)$$i); \
rm -f $$i; \
done 2>/dev/null || true
diff --git a/mk/so.mk b/mk/so.mk
@@ -12,6 +12,8 @@ depend: ${OBJ:=.depend}
soclean:
for i in $(SO) $(OFILES_PIC); do \
+ [ -e $$i ] && \
+ echo CLEAN $$($(CLEANNAME) $(BASE)$$i); \
rm -f $$i; \
done 2>/dev/null || true
diff --git a/util/compile b/util/compile
@@ -9,7 +9,7 @@ xtmp=/tmp/cc.$$.$USER.out
echo CC $($bin/cleanname ${BASE}$outfile)
[ -n "$noisycc" ] && echo $CC -o $outfile $CFLAGS $@
-$CC -o $outfile $CFLAGS $@ 2>$xtmp
+$CC -o $outfile $CFLAGS $@ >$xtmp 2>&1
status=$?
base=$(echo $BASE | sed 's/,/\\,/g')
@@ -57,6 +57,8 @@ undup() { # GCC is crap.
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' |
+ awk '$1 == "warning:"{t=$2" "$1; sub(/^[^ ]+ [^ ]+ /, ""); $0 = t" "$0}; //' |
+ awk '{sub(/\[/, ": [", $1); print}' |
undup 1>&2
rm -f $xtmp