# HG changeset patch # User David du Colombier <0intro@gmail.com> # Date 1377813600 -7200 # Node ID 4267090d7967d13d52d9b91339459a43834d4c47 # Parent 57bc9b941787d9e0dd148ea5d377d60019250edb fossil: console diff -r 57bc9b941787 -r 4267090d7967 include/libc.h --- a/include/libc.h Fri Aug 30 00:00:00 2013 +0200 +++ b/include/libc.h Fri Aug 30 00:00:00 2013 +0200 @@ -840,6 +840,7 @@ extern int sendfd(int, int); extern int recvfd(int); extern int post9pservice(int, char*, char*); +extern int postconservice(int, char*); extern int chattyfuse; /* external names that we don't want to step on */ diff -r 57bc9b941787 -r 4267090d7967 src/cmd/conserve.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cmd/conserve.c Fri Aug 30 00:00:00 2013 +0200 @@ -0,0 +1,291 @@ +#include +#include +#include + +enum +{ + STACK = 1024, + BUFSIZE = 256 +}; + +typedef struct Msg Msg; +typedef struct Conn Conn; + +struct Msg +{ + Conn *c; + uchar *tbuf; + uchar *rbuf; +}; + +struct Conn +{ + int fd; + char dir[40]; + Channel *out; +}; + +int afd; +char adir[40]; +Channel *out; + +void mainproc(void*); +void inputproc(void*); +void outputproc(void*); +void listenproc(void*); +void conninproc(void*); +void connoutproc(void*); + +void *emalloc(int); +Msg *msgnew(void); +Msg *msgget(void); +uchar *readrbuf(int); +uchar *readtbuf(int); +Msg *mread(int); +int mwrite(int, uchar*); + +void +usage(void) +{ + fprint(2, "usage: conserve [-c addr] address\n"); + threadexitsall("usage"); +} + +void +threadmain(int argc, char **argv) +{ + char *addr; + int fd; + + rfork(RFNOTEG); + + ARGBEGIN{ + default: + usage(); + case 'c': + addr = netmkaddr(EARGF(usage()), "net", "9fs"); + if((fd = dial(addr, nil, nil, nil)) < 0) + sysfatal("dial %s: %r", addr); + dup(fd, 0); + dup(fd, 1); + if(fd > 1) + close(fd); + break; + }ARGEND + + if(argc != 1) + usage(); + addr = argv[0]; + + if((afd = announce(addr, adir)) < 0) + sysfatal("announce %s: %r", addr); + + proccreate(mainproc, nil, STACK); +} + +void +mainproc(void *v) +{ + USED(v); + + out = chancreate(sizeof(void*), 0); + + proccreate(inputproc, nil, STACK); + proccreate(outputproc, nil, STACK); + + proccreate(listenproc, nil, STACK); + + threadexits(0); +} + +void +listenproc(void *arg) +{ + Conn *c; + + USED(arg); + threadsetname("listen %s", adir); + for(;;){ + c = emalloc(sizeof(Conn)); + c->fd = listen(adir, c->dir); + if(c->fd < 0){ + close(afd); + free(c); + return; + } + c->out = chancreate(sizeof(void*), 0); + proccreate(conninproc, c, STACK); + } +} + +void +conninproc(void *arg) +{ + int fd; + Conn *c; + Msg *m; + + c = arg; + threadsetname("conn %s", c->dir); + fd = accept(c->fd, c->dir); + if(fd < 0) + goto out; + close(c->fd); + c->fd = fd; + proccreate(connoutproc, c, STACK); + while((m = mread(c->fd)) != nil){ + m->c = c; + sendp(out, m); + } + +out: + close(c->fd); + free(c); +} + +void +connoutproc(void *arg) +{ + Conn *c; + Msg *m; + + c = arg; + threadsetname("connout %s", c->dir); + while((m = recvp(c->out)) != nil){ + if(mwrite(c->fd, m->rbuf) < 0) + break; + } + chanfree(c->out); + c->out = nil; +} + +void +outputproc(void *arg) +{ + Msg *m; + + USED(arg); + threadsetname("output"); + while((m = recvp(out)) != nil){ + if(mwrite(1, m->tbuf) < 0) + sysfatal("output error: %r"); + } + threadexitsall(0); +} + +void +inputproc(void *arg) +{ + uchar *buf; + Msg *m; + + USED(arg); + threadsetname("input"); + while((buf = readrbuf(0)) != nil){ + if((m = msgget()) == nil){ + free(buf); + continue; + } + free(m->rbuf); + m->rbuf = buf; + sendp(m->c->out, m); + } + threadexitsall(0); +} + +Msg *msg; + +Msg* +msgnew(void) +{ + Msg *m; + + if(msg == nil) + msg = emalloc(sizeof(Msg)); + + m = msg; + return m; +} + +Msg* +msgget(void) +{ + Msg *m; + + if(msg == nil) + return nil; + + m = msg; + return m; +} + + +void* +emalloc(int n) +{ + void *v; + + v = mallocz(n, 1); + if(v == nil){ + abort(); + sysfatal("out of memory allocating %d", n); + } + return v; +} + +uchar* +readtbuf(int fd) +{ + uchar *buf; + + buf = emalloc(BUFSIZE); + + buf[0] = '\n'; + if(read(fd, buf+1, BUFSIZE-1) <= 0){ + free(buf); + return nil; + } + + return buf; +} + +uchar* +readrbuf(int fd) +{ + uchar *buf; + + buf = emalloc(BUFSIZE); + + do{ + if(read(fd, buf, BUFSIZE) < 0){ + free(buf); + return nil; + } + }while(strnlen((char*)buf, BUFSIZE) == 0); + + return buf; +} + +Msg* +mread(int fd) +{ + uchar *buf; + Msg *m; + + if((buf = readtbuf(fd)) == nil) + return nil; + + m = msgnew(); + free(m->tbuf); + m->tbuf = buf; + return m; +} + +int +mwrite(int fd, uchar *buf) +{ + if(write(fd, buf, BUFSIZE) != BUFSIZE) + return -1; + + return 0; +} diff -r 57bc9b941787 -r 4267090d7967 src/cmd/fossil/9srv.c --- a/src/cmd/fossil/9srv.c Fri Aug 30 00:00:00 2013 +0200 +++ b/src/cmd/fossil/9srv.c Fri Aug 30 00:00:00 2013 +0200 @@ -77,7 +77,7 @@ } static Srv* -srvAlloc(char* service, int mode, int fd) +srvAlloc(char* service, int mode, int fd, int pflag) { Dir *dir; Srv *srv; @@ -104,7 +104,11 @@ #ifdef PLAN9PORT mntpnt = nil; - if((srvfd = post9pservice(fd, service, mntpnt)) < 0){ + if(pflag) + srvfd = postconservice(fd, service); + else + srvfd = post9pservice(fd, service, mntpnt); + if(srvfd < 0){ #else if((srvfd = srvFd(service, mode, fd, &mntpnt)) < 0){ #endif @@ -210,16 +214,11 @@ return 1; } -#ifdef PLAN9PORT /* fossilcons unsupported */ - if(pflag) - return 1; -#endif - if(pipe(fd) < 0){ werrstr("srv pipe: %r"); return 0; } - if((srv = srvAlloc(argv[0], mode, fd[0])) == nil){ + if((srv = srvAlloc(argv[0], mode, fd[0], pflag)) == nil){ close(fd[0]); close(fd[1]); return 0; } diff -r 57bc9b941787 -r 4267090d7967 src/lib9/mkfile --- a/src/lib9/mkfile Fri Aug 30 00:00:00 2013 +0200 +++ b/src/lib9/mkfile Fri Aug 30 00:00:00 2013 +0200 @@ -130,6 +130,7 @@ pin.$O\ pipe.$O\ post9p.$O\ + postcon.$O\ postnote.$O\ qlock.$O\ quote.$O\ diff -r 57bc9b941787 -r 4267090d7967 src/lib9/postcon.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib9/postcon.c Fri Aug 30 00:00:00 2013 +0200 @@ -0,0 +1,53 @@ +#include +#include + +int +postconservice(int fd, char *name) +{ + int i, pid; + char *ns, *addr; + Waitmsg *w; + + if(name == nil){ + close(fd); + werrstr("nothing to do"); + return -1; + } + + if(name){ + if(strchr(name, '!')) /* assume is already network address */ + addr = strdup(name); + else{ + if((ns = getns()) == nil) + return -1; + addr = smprint("unix!%s/%s", ns, name); + free(ns); + } + if(addr == nil) + return -1; + switch(pid = fork()){ + case -1: + return -1; + case 0: + dup(fd, 0); + dup(fd, 1); + for(i=3; i<20; i++) + close(i); + execlp("conserve", "conserve", addr, (char*)0); + fprint(2, "exec conserve: %r\n"); + _exits("exec"); + } + close(fd); + w = waitfor(pid); + if(w == nil) + return -1; + if(w->msg && w->msg[0]){ + free(w); + werrstr("conserve failed"); + return -1; + } + free(w); + free(addr); + } + return 0; +}