ref: b76a78c1a1973d62ff32c030e29b3ffcc560e50d
dir: /sys/src/lib9p/listen.c/
#include <u.h> #include <libc.h> #include <auth.h> #include <fcall.h> #include <thread.h> #include <9p.h> static void listenproc(void*); static void srvproc(void*); static void srvfree(Srv *); static char *getremotesys(char*); void _listensrv(Srv *os, char *addr) { Srv *s; if(_forker == nil) sysfatal("no forker"); s = emalloc9p(sizeof *s); *s = *os; s->addr = estrdup9p(addr); _forker(listenproc, s, 0); } static void listenproc(void *v) { char ndir[NETPATHLEN], dir[NETPATHLEN]; int ctl, data, nctl; Srv *os, *s; os = v; ctl = announce(os->addr, dir); if(ctl < 0){ fprint(2, "%s: announce %s: %r", argv0, os->addr); return; } for(;;){ nctl = listen(dir, ndir); if(nctl < 0){ fprint(2, "%s: listen %s: %r", argv0, os->addr); break; } data = accept(ctl, ndir); if(data < 0){ fprint(2, "%s: accept %s: %r\n", argv0, ndir); continue; } s = emalloc9p(sizeof *s); *s = *os; s->addr = getremotesys(ndir); s->infd = s->outfd = data; s->fpool = nil; s->rpool = nil; s->rbuf = nil; s->wbuf = nil; s->free = srvfree; _forker(srvproc, s, 0); } free(os->addr); free(os); } static void srvproc(void *v) { srv((Srv*)v); } static void srvfree(Srv *s) { close(s->infd); free(s->addr); free(s); } static char* getremotesys(char *ndir) { char buf[128], *serv, *sys; int fd, n; snprint(buf, sizeof buf, "%s/remote", ndir); sys = nil; fd = open(buf, OREAD); if(fd >= 0){ n = read(fd, buf, sizeof(buf)-1); if(n>0){ buf[n-1] = 0; serv = strchr(buf, '!'); if(serv) *serv = 0; sys = estrdup9p(buf); } close(fd); } if(sys == nil) sys = estrdup9p("unknown"); return sys; }