commit fd04aacee17b348da206c13a550dc1029669805f from: rsc date: Sun Nov 23 18:12:54 2003 UTC Various additions and fixes. commit - 74f990ad84deb1591ddb91be4fc8152ec0c46222 commit + fd04aacee17b348da206c13a550dc1029669805f blob - 5411bd92a4793484300a147ef031cf9fc5f8ba46 (mode 644) blob + /dev/null --- src/lib9/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -PLAN9=../.. -include $(PLAN9)/src/Makehdr - -LIB=lib9.a - -OFILES=\ - _exits.$O\ - argv0.$O\ - await.$O\ - cleanname.$O\ - dirstat.$O\ - encodefmt.$O\ - errstr.$O\ - exits.$O\ - ffork-$(SYSNAME).$O\ - getcallerpc-$(OBJTYPE).$O\ - getfields.$O\ - lock.$O\ - malloctag.$O\ - mallocz.$O\ - nrand.$O\ - qlock.$O\ - readn.$O\ - rendez-$(SYSNAME).$O\ - strecpy.$O\ - sysfatal.$O\ - tas-$(OBJTYPE).$O\ - tokenize.$O\ - u16.$O\ - u32.$O\ - u64.$O\ - wait.$O\ - -HFILES=\ - $(PLAN9)/include/lib9.h\ - -include $(PLAN9)/src/Makesyslib - blob - /dev/null blob + 713b9558d527438137d385224a3582f645889f41 (mode 644) --- /dev/null +++ src/lib9/9proc.h @@ -0,0 +1,23 @@ +enum +{ + NPRIV = 16, + RENDHASH = 33, + PIDHASH = 33, +}; + +typedef struct Uproc Uproc; +struct Uproc +{ + Uproc *next; + int pid; + int pipe[2]; + int state; + void *priv[NPRIV]; + ulong rendval; + ulong rendtag; + Uproc *rendhash; + p9jmp_buf notejb; +}; + +extern Uproc *_p9uproc(void); +extern void _p9uprocdie(void); blob - 35ff4e672821e8e316df7264cef7a2b65f0fb38f blob + 9affe94879a7e4d575ddc1f3ec4092377bd1e739 --- src/lib9/_exits.c +++ src/lib9/_exits.c @@ -1,8 +1,12 @@ -#include +#include +#include +#include "9proc.h" void _exits(char *s) { + _p9uprocdie(); + if(s && *s) _exit(1); _exit(0); blob - /dev/null blob + 93c98425720b350a3d6734c6f1bbffb3f15c2e82 (mode 644) --- /dev/null +++ src/lib9/_p9dialparse.c @@ -0,0 +1,151 @@ +#include +#include + +#include +#include + +static char *nets[] = { "tcp", "udp", nil }; +#define CLASS(p) ((*(uchar*)(p))>>6) + +static int +parseip(char *host, u32int *pip) +{ + uchar addr[4]; + int x, i; + char *p; + + p = host; + for(i=0; i<4 && *p; i++){ + x = strtoul(p, &p, 0); + if(x < 0 || x >= 256) + return -1; + if(*p != '.' && *p != 0) + return -1; + if(*p == '.') + p++; + addr[i] = x; + } + + switch(CLASS(addr)){ + case 0: + case 1: + if(i == 3){ + addr[3] = addr[2]; + addr[2] = addr[1]; + addr[1] = 0; + }else if(i == 2){ + addr[3] = addr[1]; + addr[2] = 0; + addr[1] = 0; + }else if(i != 4) + return -1; + break; + case 2: + if(i == 3){ + addr[3] = addr[2]; + addr[2] = 0; + }else if(i != 4) + return -1; + break; + } + *pip = *(u32int*)addr; + return 0; +} + +int +_p9dialparse(char *addr, char **pnet, char **punix, u32int *phost, int *pport) +{ + char *net, *host, *port, *e; + int i; + struct servent *se; + struct hostent *he; + struct sockaddr_un *sun; + + if(strncmp(addr, "/net/", 5) == 0) + addr += 5; + + net = addr; + if((host = strchr(net, '!')) == nil){ + werrstr("malformed address"); + return -1; + } + *host++ = 0; + if((port = strchr(host, '!')) == nil){ + if(strcmp(net, "unix")==0 || strcmp(net, "net")==0){ + Unix: + if(strlen(host)+1 > sizeof sun->sun_path){ + werrstr("unix socket name too long"); + return -1; + } + *punix = host; + *pnet = "unix"; + *phost = 0; + *pport = 0; + return 0; + } + werrstr("malformed address"); + return -1; + } + *port++ = 0; + + if(*host == 0){ + werrstr("malformed address (empty host)"); + return -1; + } + if(*port == 0){ + werrstr("malformed address (empty port)"); + return -1; + } + + if(strcmp(net, "unix") == 0) + goto Unix; + + if(strcmp(net, "tcp")!=0 && strcmp(net, "udp")!=0){ + werrstr("bad network %s!%s!%s", net, host, port); + return -1; + } + + /* translate host */ + if(strcmp(host, "*") == 0) + *phost = 0; + else if(parseip(host, phost) == 0) + {} + else if((he = gethostbyname(host)) != nil) + *phost = *(u32int*)(he->h_addr); + else{ + werrstr("unknown host %s", host); + return -1; + } + + /* translate network and port; should return list rather than first */ + if(strcmp(net, "net") == 0){ + for(i=0; nets[i]; i++){ + if((se = getservbyname(port, nets[i])) != nil){ + *pnet = nets[i]; + *pport = ntohs(se->s_port); + return 0; + } + } + werrstr("unknown service %s", port); + return -1; + } + + if(strcmp(net, "tcp") != 0 && strcmp(net, "udp") != 0){ + werrstr("unknown network %s", net); + return -1; + } + + *pnet = net; + i = strtol(port, &e, 0); + if(*e == 0){ + *pport = i; + return 0; + } + + if((se = getservbyname(port, net)) != nil){ + *pport = ntohs(se->s_port); + return 0; + } + werrstr("unknown service %s", port); + return -1; +} blob - 49160e766c82011c3d1a63295d944a3859e92ccf blob + 67e99b829c651d94980543cfdda326be750641ed --- src/lib9/await.c +++ src/lib9/await.c @@ -1,12 +1,12 @@ +#define NOPLAN9DEFINES +#include +#include + #include #include -#include #include #include #include -#include -#include -#include static struct { int sig; @@ -18,9 +18,7 @@ static struct { SIGILL, "sys: trap: illegal instruction", SIGTRAP, "sys: trace trap", SIGABRT, "sys: abort", -#ifdef SIGEMT SIGEMT, "sys: emulate instruction executed", -#endif SIGFPE, "sys: fp: trap", SIGKILL, "sys: kill", SIGBUS, "sys: bus error", @@ -40,14 +38,12 @@ static struct { SIGVTALRM, "sys: virtual time alarm", SIGPROF, "sys: profiling timer alarm", SIGWINCH, "sys: window size change", -#ifdef SIGINFO SIGINFO, "sys: status request", -#endif SIGUSR1, "sys: usr1", SIGUSR2, "sys: usr2", }; -static char* +char* _p9sigstr(int sig, char *tmp) { int i; @@ -59,8 +55,7 @@ _p9sigstr(int sig, char *tmp) return tmp; } -/* -static int +int _p9strsig(char *s) { int i; @@ -70,7 +65,6 @@ _p9strsig(char *s) return tab[i].sig; return 0; } -*/ int await(char *str, int n) @@ -89,16 +83,16 @@ await(char *str, int n) if(WIFEXITED(status)){ status = WEXITSTATUS(status); if(status) - snprint(buf, sizeof buf, "%d %lu %lu %lu %d", pid, u, s, u+s, status); + snprint(buf, sizeof buf, "%d %lud %lud %lud %d", pid, u, s, u+s, status); else - snprint(buf, sizeof buf, "%d %lu %lu %lu ''", pid, u, s, u+s); + snprint(buf, sizeof buf, "%d %lud %lud %lud ''", pid, u, s, u+s, status); strecpy(str, str+n, buf); return strlen(str); } if(WIFSIGNALED(status)){ cd = WCOREDUMP(status); USED(cd); - snprint(buf, sizeof buf, "%d %lu %lu %lu '%s'", pid, u, s, u+s, _p9sigstr(WTERMSIG(status), tmp)); + snprint(buf, sizeof buf, "%d %lud %lud %lud '%s'", pid, u, s, u+s, _p9sigstr(WTERMSIG(status), tmp)); strecpy(str, str+n, buf); return strlen(str); } blob - /dev/null blob + 459bd1572bb203767b5d2f303c664a145b2c192d (mode 644) --- /dev/null +++ src/lib9/_p9dir.c @@ -0,0 +1,121 @@ +#include +#define NOPLAN9DEFINES +#include + +#include +#include +#include +#include +#include + +int +_p9dir(struct stat *st, char *name, Dir *d, char **str, char *estr) +{ + char *s; + char tmp[20]; + struct group *g; + struct passwd *p; + int sz; + + sz = 0; + if(d) + memset(d, 0, sizeof *d); + + /* name */ + s = strrchr(name, '/'); + if(s) + s++; + if(!s || !*s) + s = name; + if(*s == '/') + s++; + if(*s == 0) + s = "/"; + if(d){ + if(*str + strlen(s)+1 > estr) + d->name = "oops"; + else{ + strcpy(*str, s); + d->name = *str; + *str += strlen(*str)+1; + } + } + sz += strlen(s)+1; + + /* user */ + p = getpwuid(st->st_uid); + if(p == nil){ + snprint(tmp, sizeof tmp, "%d", (int)st->st_uid); + s = tmp; + }else + s = p->pw_name; + sz += strlen(s)+1; + if(d){ + if(*str+strlen(s)+1 > estr) + d->uid = "oops"; + else{ + strcpy(*str, s); + d->uid = *str; + *str += strlen(*str)+1; + } + } + + /* group */ + g = getgrgid(st->st_gid); + if(g == nil){ + snprint(tmp, sizeof tmp, "%d", (int)st->st_gid); + s = tmp; + }else + s = g->gr_name; + sz += strlen(s)+1; + if(d){ + if(*str + strlen(s)+1 > estr) + d->gid = "oops"; + else{ + strcpy(*str, s); + d->gid = *str; + *str += strlen(*str)+1; + } + } + + if(d){ + d->type = 'M'; + + d->muid = ""; + d->qid.path = ((uvlong)st->st_dev<<32) | st->st_ino; + d->qid.vers = st->st_gen; + d->mode = st->st_mode&0777; + d->atime = st->st_atime; + d->mtime = st->st_mtime; + d->length = st->st_size; + + if(S_ISDIR(st->st_mode)){ + d->length = 0; + d->mode |= DMDIR; + d->qid.type = QTDIR; + } + + /* fetch real size for disks */ + if(S_ISCHR(st->st_mode)){ + int fd, n; + struct disklabel lab; + + if((fd = open(name, O_RDONLY)) < 0) + goto nosize; + if(ioctl(fd, DIOCGDINFO, &lab) < 0) + goto nosize; + n = minor(st->st_rdev)&7; + if(n >= lab.d_npartitions) + goto nosize; + + d->length = (vlong)(lab.d_partitions[n].p_size) * lab.d_secsize; + + nosize: + if(fd >= 0) + close(fd); + } + } + + return sz; +} + blob - /dev/null blob + 6e4010cda8392e47c004f156a8cb2801187e391d (mode 644) --- /dev/null +++ src/lib9/_p9proc.c @@ -0,0 +1,73 @@ +#include +#include +#include "9proc.h" + +static Lock uproclock; +static Uproc *phash[PIDHASH]; + +Uproc* +_p9uproc(void) +{ + /* for now, assume getpid is fast or cached */ + int pid; + Uproc *up; + + pid = getpid(); +again: +if(0)print("find %d\n", pid); + lock(&uproclock); + for(up=phash[pid%PIDHASH]; up; up=up->next){ + if(up->pid == pid){ +if(0)print("found %d\n", pid); + unlock(&uproclock); + return up; + } + } + + up = mallocz(sizeof(Uproc), 1); + if(up == nil){ +if(0)print("again %d\n", pid); + unlock(&uproclock); + sleep(1000); + goto again; + } + +againpipe: + if(pipe(up->pipe) < 0){ +if(0)print("againpipe %d\n", pid); + sleep(1000); + goto againpipe; + } + + up->pid = pid; + up->next = phash[pid%PIDHASH]; + phash[pid%PIDHASH] = up; +if(0)print("link %d\n", pid); + unlock(&uproclock); + return up; +} + +void +_p9uprocdie(void) +{ + Uproc **l, *up; + int pid; + + pid = getpid(); +if(0)print("die %d\n", pid); + lock(&uproclock); + for(l=&phash[pid%33]; *l; l=&(*l)->next){ + if((*l)->pid == pid){ + up = *l; + *l = up->next; +if(0)print("died %d\n", pid); + unlock(&uproclock); + close(up->pipe[0]); + close(up->pipe[1]); + free(up); + return; + } + } +if(0)print("not started %d\n", pid); + unlock(&uproclock); +} blob - fb9cd0acdc83b7d9cb2ae99e49094eb74c458f98 blob + 253a905661eefb2e551080040f2ca697ddba3e06 --- src/lib9/dirstat.c +++ src/lib9/dirstat.c @@ -1,83 +1,28 @@ -#include "u.h" -#include "libc.h" -#include +#include +#define NOPLAN9DEFINES +#include + #include -#include -#include -static void -statconv(Dir *dir, struct stat *s) -{ - struct passwd *p; - struct group *g; - ulong q; +extern int _p9dir(struct stat*, char*, Dir*, char**, char*); - p = getpwuid(s->st_uid); - if (p) - strncpy(dir->uid, p->pw_name, NAMELEN); - g = getgrgid(s->st_gid); - if (g) - strncpy(dir->gid, g->gr_name, NAMELEN); - q = 0; - if(S_ISDIR(s->st_mode)) - q = CHDIR; - q |= s->st_ino & 0x00FFFFFFUL; - dir->qid.path = q; - dir->qid.vers = s->st_mtime; - dir->mode = (dir->qid.path&CHDIR)|(s->st_mode&0777); - dir->atime = s->st_atime; - dir->mtime = s->st_mtime; - dir->length = s->st_size; - dir->dev = s->st_dev; - dir->type = 'M'; - if(S_ISFIFO(s->st_mode)) - dir->type = '|'; -} - -int -dirfstat(int fd, Dir *d) +Dir* +dirstat(char *file) { - struct stat sbuf; + struct stat st; + int nstr; + Dir *d; + char *str; - if(fstat(fd, &sbuf) < 0) - return -1; - statconv(d, &sbuf); - return 0; -} + if(stat(file, &st) < 0) + return nil; -static char * -lelem(char *path) -{ - char *pr; - - pr = utfrrune(path, '/'); - if(pr) - pr++; - else - pr = path; - return pr; + nstr = _p9dir(&st, file, nil, nil, nil); + d = mallocz(sizeof(Dir)+nstr, 1); + if(d == nil) + return nil; + str = (char*)&d[1]; + _p9dir(&st, file, d, &str, str+nstr); + return d; } -int -dirstat(char *f, Dir *d) -{ - struct stat sbuf; - - if(stat(f, &sbuf) < 0) - return -1; - statconv(d, &sbuf); - strncpy(d->name, lelem(f), NAMELEN); - return 0; -} - -int -dirfwstat(int fd, Dir *d) -{ - return -1; -} - -int -dirwstat(char *name, Dir *d) -{ - return -1; -} blob - /dev/null blob + dc8cbbbf4daecd274e51ef2110873c07048d4d0e (mode 644) --- /dev/null +++ src/lib9/announce.c @@ -0,0 +1,137 @@ +#include +#define NOPLAN9DEFINES +#include + +#include +#include +#include + +extern int _p9dialparse(char*, char**, char**, u32int*, int*); + +static int +getfd(char *dir) +{ + int fd; + + if(strncmp(dir, "/dev/fd/", 8) != 0) + return -1; + fd = strtol(dir+8, &dir, 0); + if(*dir != 0) + return -1; + return fd; +} + +static void +putfd(char *dir, int fd) +{ + snprint(dir, NETPATHLEN, "/dev/fd/%d", fd); +} + +#undef unix + +int +p9announce(char *addr, char *dir) +{ + int proto; + char *buf, *unix; + char *net; + u32int host; + int port, s; + int n, sn; + struct sockaddr_in sa; + struct sockaddr_un sun; + + buf = strdup(addr); + if(buf == nil) + return -1; + + if(_p9dialparse(buf, &net, &unix, &host, &port) < 0){ + free(buf); + return -1; + } + if(strcmp(net, "tcp") == 0) + proto = SOCK_STREAM; + else if(strcmp(net, "udp") == 0) + proto = SOCK_DGRAM; + else if(strcmp(net, "unix") == 0) + goto Unix; + else{ + werrstr("can only handle tcp, udp, and unix: not %s", net); + free(buf); + return -1; + } + free(buf); + + memset(&sa, 0, sizeof sa); + memmove(&sa.sin_addr, &host, 4); + sa.sin_family = AF_INET; + sa.sin_port = htons(port); + if((s = socket(AF_INET, proto, 0)) < 0) + return -1; + sn = sizeof n; + if(port && getsockopt(s, SOL_SOCKET, SO_TYPE, (char*)&n, &sn) >= 0 + && n == SOCK_STREAM){ + n = 1; + setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&n, sizeof n); + } + if(bind(s, (struct sockaddr*)&sa, sizeof sa) < 0){ + close(s); + return -1; + } + if(proto == SOCK_STREAM){ + listen(s, 8); + putfd(dir, s); +print("announce dir: %s\n", dir); + } + return s; + +Unix: + memset(&sun, 0, sizeof sun); + sun.sun_family = AF_UNIX; + sun.sun_len = sizeof sun; + strcpy(sun.sun_path, unix); + if((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) + return -1; + sn = sizeof sun; + if(bind(s, (struct sockaddr*)&sun, sizeof sun) < 0){ + close(s); + return -1; + } + listen(s, 8); + putfd(dir, s); + return s; +} + +int +p9listen(char *dir, char *newdir) +{ + int fd; + + if((fd = getfd(dir)) < 0){ + werrstr("bad 'directory' in listen: %s", dir); + return -1; + } + +print("accept %d", fd); + if((fd = accept(fd, nil, nil)) < 0) + return -1; +print(" -> %d\n", fd); + + putfd(newdir, fd); +print("listen dir: %s\n", newdir); + return fd; +} + +int +p9accept(int cfd, char *dir) +{ + int fd; + + if((fd = getfd(dir)) < 0){ + werrstr("bad 'directory' in accept"); + return -1; + } + /* need to dup because the listen fd will be closed */ + return dup(fd); +} + blob - 504ec6ec818671a27805fdc2c6b2e1946cf33cc5 blob + 0c6ab315d608390321d8864a7b77c56cb8bec82a --- src/lib9/errstr.c +++ src/lib9/errstr.c @@ -78,3 +78,16 @@ werrstr(char *fmt, ...) va_end(arg); errstr(buf, ERRMAX); } + +char* +gerrstr(void) +{ + char *s; + + s = getsyserr(); + if(errno != EPLAN9) + strcpy(s, strerror(errno)); + return s; +} + + blob - /dev/null blob + b1d8b9779ea26dde2b7a191972a1801324432b46 (mode 644) --- /dev/null +++ src/lib9/atexit.c @@ -0,0 +1,54 @@ +#include +#include + +#define NEXIT 33 + +static Lock onexlock; +static struct +{ + void (*f)(void); + int pid; +}onex[NEXIT]; + +int +atexit(void (*f)(void)) +{ + int i; + + lock(&onexlock); + for(i=0; i= 0; i--) + if((f = onex[i].f) && pid == onex[i].pid) { + onex[i].f = 0; + (*f)(); + } + _exits(s); +} blob - a449f68e67de2f1414681101cd55be3ad924743e blob + f4206e9ab034a8d359e7e23141b61812543dfeed --- src/lib9/exits.c +++ src/lib9/exits.c @@ -1,10 +1,22 @@ -#include +#include +#include +extern void _privdie(void); + void exits(char *s) { + _privdie(); if(s && *s) exit(1); exit(0); } +void +_exits(char *s) +{ + _privdie(); + if(s && *s) + _exit(1); + _exit(0); +} blob - /dev/null blob + 60e8ad0c036292abbaeced5b89fbddebe82af736 (mode 644) --- /dev/null +++ src/lib9/atnotify.c @@ -0,0 +1,58 @@ +#include +#include + +#define NFN 33 +static int (*onnot[NFN])(void*, char*); +static Lock onnotlock; + +static +void +notifier(void *v, char *s) +{ + int i; + + for(i=0; i -#include - -extern int __isthreaded; -int -ffork(int flags, void(*fn)(void*), void *arg) -{ - void *p; - pthread_t tid; - - if(flags != (RFMEM|RFNOWAIT)){ - werrstr("ffork unsupported"); - return -1; - } - - if(pthread_create(&tid, NULL, (void*(*)(void*))fn, arg) < 0) - return -1; - return (int)tid; -} - -int -getfforkid(void) -{ - return (int)pthread_self(); -} - +#include "ffork-pthread.c" blob - /dev/null blob + a545615b7ff00d0b1a043a42c2407021805342cf (mode 644) --- /dev/null +++ src/lib9/cistrcmp.c @@ -0,0 +1,26 @@ +#include +#include + +int +cistrcmp(char *s1, char *s2) +{ + int c1, c2; + + while(*s1){ + c1 = *(uchar*)s1++; + c2 = *(uchar*)s2++; + + if(c1 == c2) + continue; + + if(c1 >= 'A' && c1 <= 'Z') + c1 -= 'A' - 'a'; + + if(c2 >= 'A' && c2 <= 'Z') + c2 -= 'A' - 'a'; + + if(c1 != c2) + return c1 - c2; + } + return -*s2; +} blob - /dev/null blob + 8f24d411fe1a54795cd0e3878c9b37240158c7a6 (mode 644) --- /dev/null +++ src/lib9/cistrncmp.c @@ -0,0 +1,28 @@ +#include +#include + +int +cistrncmp(char *s1, char *s2, int n) +{ + int c1, c2; + + while(*s1 && n-- > 0){ + c1 = *(uchar*)s1++; + c2 = *(uchar*)s2++; + + if(c1 == c2) + continue; + + if(c1 >= 'A' && c1 <= 'Z') + c1 -= 'A' - 'a'; + + if(c2 >= 'A' && c2 <= 'Z') + c2 -= 'A' - 'a'; + + if(c1 != c2) + return c1 - c2; + } + if(n <= 0) + return 0; + return -*s2; +} blob - /dev/null blob + 0a113226637a13f65335efeeb54f89e3db371a4b (mode 644) --- /dev/null +++ src/lib9/cistrstr.c @@ -0,0 +1,23 @@ +#include +#include + +char* +cistrstr(char *s, char *sub) +{ + int c, csub, n; + + csub = *sub; + if(csub == '\0') + return s; + if(csub >= 'A' && csub <= 'Z') + csub -= 'A' - 'a'; + sub++; + n = strlen(sub); + for(; c = *s; s++){ + if(c >= 'A' && c <= 'Z') + c -= 'A' - 'a'; + if(c == csub && cistrncmp(s+1, sub, n) == 0) + return s; + } + return nil; +} blob - /dev/null blob + abef0c3515d2456d073ff03f3eaacde7f161532e (mode 644) --- /dev/null +++ src/lib9/create.c @@ -0,0 +1,8 @@ +#include +#include + +int +create(char *path, int mode, ulong perm) +{ + return open(path, mode|O_CREAT|O_TRUNC, perm); +} blob - /dev/null blob + e9d971bf69d310b26e00a5fcbbfb58ab187234c7 (mode 644) --- /dev/null +++ src/lib9/ctime.c @@ -0,0 +1,51 @@ +#include +#include + +static +void +ct_numb(char *cp, int n) +{ + + cp[0] = ' '; + if(n >= 10) + cp[0] = (n/10)%10 + '0'; + cp[1] = n%10 + '0'; +} + +char* +asctime(Tm *t) +{ + char *ncp; + static char cbuf[30]; + + strcpy(cbuf, "Thu Jan 01 00:00:00 GMT 1970\n"); + ncp = &"SunMonTueWedThuFriSat"[t->wday*3]; + cbuf[0] = *ncp++; + cbuf[1] = *ncp++; + cbuf[2] = *ncp; + ncp = &"JanFebMarAprMayJunJulAugSepOctNovDec"[t->mon*3]; + cbuf[4] = *ncp++; + cbuf[5] = *ncp++; + cbuf[6] = *ncp; + ct_numb(cbuf+8, t->mday); + ct_numb(cbuf+11, t->hour+100); + ct_numb(cbuf+14, t->min+100); + ct_numb(cbuf+17, t->sec+100); + ncp = t->zone; + cbuf[20] = *ncp++; + cbuf[21] = *ncp++; + cbuf[22] = *ncp; + if(t->year >= 100) { + cbuf[24] = '2'; + cbuf[25] = '0'; + } + ct_numb(cbuf+26, t->year+100); + return cbuf; +} + +char* +ctime(long t) +{ + return asctime(localtime(t)); +} + blob - /dev/null blob + 2e84fd0a08b552a54db4a093f875c821b189a320 (mode 644) --- /dev/null +++ src/lib9/date.c @@ -0,0 +1,77 @@ +#include +#include + +#undef gmtime +#undef localtime +#undef asctime +#undef ctime +#undef cputime +#undef times +#undef tm2sec +#undef nsec + +#include + +static Tm bigtm; + +static void +tm2Tm(struct tm *tm, Tm *bigtm) +{ + memset(bigtm, 0, sizeof *bigtm); + bigtm->sec = tm->tm_sec; + bigtm->min = tm->tm_min; + bigtm->hour = tm->tm_hour; + bigtm->mday = tm->tm_mday; + bigtm->mon = tm->tm_mon; + bigtm->year = tm->tm_year; + bigtm->wday = tm->tm_wday; + strecpy(bigtm->zone, bigtm->zone+4, tm->tm_zone); + bigtm->tzoff = tm->tm_gmtoff; +} + +static void +Tm2tm(Tm *bigtm, struct tm *tm) +{ + memset(tm, 0, sizeof *tm); + tm->tm_sec = bigtm->sec; + tm->tm_min = bigtm->min; + tm->tm_hour = bigtm->hour; + tm->tm_mday = bigtm->mday; + tm->tm_mon = bigtm->mon; + tm->tm_year = bigtm->year; + tm->tm_wday = bigtm->wday; + tm->tm_zone = bigtm->zone; + tm->tm_gmtoff = bigtm->tzoff; +} + +Tm* +p9gmtime(long t) +{ + struct tm tm; + + tm = *gmtime(&t); + tm2Tm(&tm, &bigtm); + return &bigtm; +} + +Tm* +p9localtime(long t) +{ + struct tm tm; + + tm = *localtime(&t); + tm2Tm(&tm, &bigtm); + return &bigtm; +} + +long +p9tm2sec(Tm *bigtm) +{ + struct tm tm; + + Tm2tm(bigtm, &tm); + if(strcmp(bigtm->zone, "GMT") == 0 || strcmp(bigtm->zone, "UCT") == 0) + return timegm(&tm); + return mktime(&tm); /* local time zone */ +} + blob - /dev/null blob + 1d961b4c4f53d896f4f776835fef5ef212c16b31 (mode 644) --- /dev/null +++ src/lib9/dial.c @@ -0,0 +1,92 @@ +#include +#include + +#undef accept +#undef announce +#undef dial +#undef setnetmtpt +#undef hangup +#undef listen +#undef netmkaddr +#undef reject + +#include +#include +#include +#include + + +extern int _p9dialparse(char*, char**, char**, u32int*, int*); +#undef unix + +int +p9dial(char *addr, char *dummy1, char *dummy2, int *dummy3) +{ + char *buf; + char *net, *unix; + u32int host; + int port; + int proto; + struct sockaddr_in sa; + struct sockaddr_un su; + int s; + + if(dummy1 || dummy2 || dummy3){ + werrstr("cannot handle extra arguments in dial"); + return -1; + } + + buf = strdup(addr); + if(buf == nil) + return -1; + + if(_p9dialparse(buf, &net, &unix, &host, &port) < 0){ + free(buf); + return -1; + } + + if(strcmp(net, "tcp") == 0) + proto = SOCK_STREAM; + else if(strcmp(net, "udp") == 0) + proto = SOCK_DGRAM; + else if(strcmp(net, "unix") == 0) + goto Unix; + else{ + werrstr("can only handle tcp, udp, and unix: not %s", net); + free(buf); + return -1; + } + free(buf); + + memset(&sa, 0, sizeof sa); + memmove(&sa.sin_addr, &host, 4); + sa.sin_family = AF_INET; + sa.sin_port = htons(port); + if((s = socket(AF_INET, proto, 0)) < 0) + return -1; + if(connect(s, (struct sockaddr*)&sa, sizeof sa) < 0){ + close(s); + return -1; + } + return s; + +Unix: + memset(&su, 0, sizeof su); + su.sun_len = sizeof su; + su.sun_family = AF_UNIX; + if(strlen(unix)+1 > sizeof su.sun_path){ + werrstr("unix socket name too long"); + free(buf); + return -1; + } + strcpy(su.sun_path, unix); + free(buf); + if((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) + return -1; + if(connect(s, (struct sockaddr*)&su, sizeof su) < 0){ + close(s); + return -1; + } + return s; +} + blob - /dev/null blob + e617bc2f0612f1047f1bbe01586115c6e271aaea (mode 644) --- /dev/null +++ src/lib9/dirfstat.c @@ -0,0 +1,29 @@ +#include +#define NOPLAN9DEFINES +#include + +#include + +extern int _p9dir(struct stat*, char*, Dir*, char**, char*); + +Dir* +dirfstat(int fd) +{ + struct stat st; + int nstr; + Dir *d; + char *str, tmp[100]; + + if(fstat(fd, &st) < 0) + return nil; + + snprint(tmp, sizeof tmp, "/dev/fd/%d", fd); + nstr = _p9dir(&st, tmp, nil, nil, nil); + d = mallocz(sizeof(Dir)+nstr, 1); + if(d == nil) + return nil; + str = (char*)&d[1]; + _p9dir(&st, tmp, d, &str, str+nstr); + return d; +} + blob - /dev/null blob + 7f6c54aa36629a678b69974817e5f788e0c732bb (mode 644) --- /dev/null +++ src/lib9/dirfwstat.c @@ -0,0 +1,21 @@ +#include +#define NOPLAN9DEFINES +#include + +#include + +int +dirfwstat(int fd, Dir *dir) +{ + struct timeval tv[2]; + + /* BUG handle more */ + if(dir->mtime == ~0ULL) + return 0; + + tv[0].tv_sec = dir->mtime; + tv[0].tv_usec = 0; + tv[1].tv_sec = dir->mtime; + tv[1].tv_usec = 0; + return futimes(fd, tv); +} blob - /dev/null blob + 8d796354e09c47aecce19fd1d2aebd38ccdda18a (mode 644) --- /dev/null +++ src/lib9/dirmodefmt.c @@ -0,0 +1,47 @@ +#include +#include + +static char *modes[] = +{ + "---", + "--x", + "-w-", + "-wx", + "r--", + "r-x", + "rw-", + "rwx", +}; + +static void +rwx(long m, char *s) +{ + strncpy(s, modes[m], 3); +} + +int +dirmodefmt(Fmt *f) +{ + static char buf[16]; + ulong m; + + m = va_arg(f->args, ulong); + + if(m & DMDIR) + buf[0]='d'; + else if(m & DMAPPEND) + buf[0]='a'; + else if(m & DMAUTH) + buf[0]='A'; + else + buf[0]='-'; + if(m & DMEXCL) + buf[1]='l'; + else + buf[1]='-'; + rwx((m>>6)&7, buf+2); + rwx((m>>3)&7, buf+5); + rwx((m>>0)&7, buf+8); + buf[11] = 0; + return fmtstrcpy(f, buf); +} blob - /dev/null blob + f4610f6888f1c0312185de0c9ef83acf901a86fa (mode 644) --- /dev/null +++ src/lib9/dirread.c @@ -0,0 +1,155 @@ +#include +#include + +#undef asctime +#undef ctime +#undef gmtime +#undef localtime + +#include +#include + +extern int _p9dir(struct stat*, char*, Dir*, char**, char*); + +static int +countde(char *p, int n) +{ + char *e; + int m; + struct dirent *de; + + e = p+n; + m = 0; + while(p < e){ + de = (struct dirent*)p; + if(de->d_reclen <= 4+2+2+1 || p+de->d_reclen > e) + break; + if(de->d_namlen == 1 && de->d_name[0]=='.') + de->d_namlen = 0; + else if(de->d_namlen == 2 && de->d_name[0]=='.' && de->d_name[1]=='.') + de->d_namlen = 0; + else + m++; + p += de->d_reclen; + } + return m; +} + +static int +dirpackage(int fd, char *buf, int n, Dir **dp) +{ + int oldwd; + char *p, *str, *estr; + int i, nstr, m; + struct dirent *de; + struct stat st; + Dir *d; + + n = countde(buf, n); + if(n <= 0) + return n; + + if((oldwd = open(".", O_RDONLY)) < 0) + return -1; + if(fchdir(fd) < 0) + return -1; + + p = buf; + nstr = 0; + for(i=0; id_name, &st) < 0) + de->d_namlen = 0; + else + nstr += _p9dir(&st, de->d_name, nil, nil, nil); + p += de->d_reclen; + } + + d = malloc(sizeof(Dir)*n+nstr); + if(d == nil){ + fchdir(oldwd); + close(oldwd); + return -1; + } + str = (char*)&d[n]; + estr = str+nstr; + + p = buf; + m = 0; + for(i=0; id_namlen != 0 && stat(de->d_name, &st) >= 0) + _p9dir(&st, de->d_name, &d[m++], &str, estr); + p += de->d_reclen; + } + + fchdir(oldwd); + close(oldwd); + *dp = d; + return m; +} + +long +dirread(int fd, Dir **dp) +{ + char *buf; + struct stat st; + int n; + + *dp = 0; + + if(fstat(fd, &st) < 0) + return -1; + + if(st.st_blksize < 8192) + st.st_blksize = 8192; + + buf = malloc(st.st_blksize); + if(buf == nil) + return -1; + + n = getdents(fd, buf, st.st_blksize); + if(n < 0){ + free(buf); + return -1; + } + n = dirpackage(fd, buf, n, dp); + free(buf); + return n; +} + + +long +dirreadall(int fd, Dir **d) +{ + uchar *buf, *nbuf; + long n, ts; + struct stat st; + + if(fstat(fd, &st) < 0) + return -1; + + if(st.st_blksize < 8192) + st.st_blksize = 8192; + + buf = nil; + ts = 0; + for(;;){ + nbuf = realloc(buf, ts+st.st_blksize); + if(nbuf == nil){ + free(buf); + return -1; + } + buf = nbuf; + n = getdents(fd, buf+ts, st.st_blksize); + if(n <= 0) + break; + ts += n; + } + if(ts >= 0) + ts = dirpackage(fd, buf, ts, d); + free(buf); + if(ts == 0 && n < 0) + return -1; + return ts; +} blob - /dev/null blob + 573dd3769ead1c079a5177afc259c0fa73fc54d6 (mode 644) --- /dev/null +++ src/lib9/dirwstat.c @@ -0,0 +1,21 @@ +#include +#define NOPLAN9DEFINES +#include + +#include + +int +dirwstat(char *file, Dir *dir) +{ + struct timeval tv[2]; + + /* BUG handle more */ + if(dir->mtime == ~0ULL) + return 0; + + tv[0].tv_sec = dir->mtime; + tv[0].tv_usec = 0; + tv[1].tv_sec = dir->mtime; + tv[1].tv_usec = 0; + return utimes(file, tv); +} blob - /dev/null blob + feec1b77dcb792e38a38ee40af88e35713fcd89b (mode 644) --- /dev/null +++ src/lib9/dup.c @@ -0,0 +1,12 @@ +#include +#include + +#undef dup + +int +p9dup(int old, int new) +{ + if(new == -1) + return dup(old); + return dup2(old, new); +} blob - 9b5d4342691dbd4800fe66ca16963ff81ddfc542 blob + b4b95f21d56fe32fe97d1de8d7014a3673eb5382 --- src/lib9/rendez-pthread.c +++ src/lib9/rendez-pthread.c @@ -33,6 +33,7 @@ */ #include +#include #include enum blob - /dev/null blob + ffe813439c18b33c70021c72819f44a824c73618 (mode 644) --- /dev/null +++ src/lib9/exec.c @@ -0,0 +1,9 @@ +#include +#include + +int +exec(char *prog, char *argv[]) +{ + /* to mimic plan 9 should be just exec, but execvp is a better fit for unix */ + return execvp(prog, argv); +} blob - /dev/null blob + 5e677f72e45ae45af3b3d6c6d7a744c881f99cdc (mode 644) --- /dev/null +++ src/lib9/ffork-SunOS.c @@ -0,0 +1 @@ +#include "ffork-pthread.c" blob - /dev/null blob + 189ac94f1cfa816bb255fe000fdf22e564b5dbe4 (mode 644) --- /dev/null +++ src/lib9/ffork-pthread.c @@ -0,0 +1,26 @@ +#include +#include + +extern int __isthreaded; +int +ffork(int flags, void(*fn)(void*), void *arg) +{ + void *p; + pthread_t tid; + + if(flags != (RFMEM|RFNOWAIT)){ + werrstr("ffork unsupported"); + return -1; + } + + if(pthread_create(&tid, NULL, (void*(*)(void*))fn, arg) < 0) + return -1; + return (int)tid; +} + +int +getfforkid(void) +{ + return (int)pthread_self(); +} + blob - /dev/null blob + f28e57f18b4630d158f136171082983b1fcadc70 (mode 644) --- /dev/null +++ src/lib9/getcallerpc-sun4u.s @@ -0,0 +1,5 @@ +.text +.globl getcallerpc +getcallerpc: + retl + or %o7, %r0, %o0 blob - 14af715685be4051f7723d483389019a23d76750 blob + 6dc137b1645a85ff723ac6c6de9f287f0e15260e --- src/lib9/wait.c +++ src/lib9/wait.c @@ -1,4 +1,5 @@ -#include +#include +#include Waitmsg* wait(void) blob - /dev/null blob + c6ff71605ee17216a5d8b68a00c1d3541c53610f (mode 644) --- /dev/null +++ src/lib9/getenv.c @@ -0,0 +1,15 @@ +#include +#define NOPLAN9DEFINES +#include + +char* +p9getenv(char *s) +{ + char *t; + + t = getenv(s); + if(t == 0) + return 0; + return strdup(t); +} + blob - /dev/null blob + b53a3892ea57cc897b447af11b7fb56a53cd70dd (mode 644) --- /dev/null +++ src/lib9/getuser.c @@ -0,0 +1,17 @@ +#include + +#include +#include + +char* +getuser(void) +{ + static char user[64]; + struct passwd *pw; + + pw = getpwuid(getuid()); + if(pw == nil) + return "none"; + strecpy(user, user+sizeof user, pw->pw_name); + return user; +} blob - /dev/null blob + d6f7a131feec988dcdb80dcef0ddd9cf04bbbe15 (mode 644) --- /dev/null +++ src/lib9/getwd.c @@ -0,0 +1,10 @@ +#include +#include + +#undef getwd + +char* +p9getwd(char *s, int ns) +{ + return getcwd(s, ns); +} blob - /dev/null blob + 6e52b686653243f749f6b3077b03ffd18978f363 (mode 644) --- /dev/null +++ src/lib9/jmp-FreeBSD.s @@ -0,0 +1,3 @@ +.globl sigsetjmp, p9setjmp +p9setjmp: + jmp sigsetjmp blob - /dev/null blob + 6f928bab3caf720b041be0cf47a1874af7df2bdf (mode 644) --- /dev/null +++ src/lib9/jmp.c @@ -0,0 +1,17 @@ +#include +#define NOPLAN9DEFINES +#include + +void +p9longjmp(p9jmp_buf buf, int val) +{ + siglongjmp((void*)buf, val); +} + +void +p9notejmp(void *x, p9jmp_buf buf, int val) +{ + USED(x); + siglongjmp((void*)buf, val); +} + blob - /dev/null blob + 4a42905446379952cf1fb10f4db507a095a2aafb (mode 644) --- /dev/null +++ src/lib9/main.c @@ -0,0 +1,13 @@ +#include +#define NOPLAN9DEFINES +#include + +extern void p9main(int, char**); + +int +main(int argc, char **argv) +{ + p9main(argc, argv); + exits("main"); + return 99; +} blob - /dev/null blob + 9f5971abcc793f5b7afff24f902eb1cd7b18faf7 (mode 644) --- /dev/null +++ src/lib9/mkfile @@ -0,0 +1,73 @@ +PLAN9=../.. +<$PLAN9/src/mkhdr + +LIB=lib9.a + +OFILES=\ + _exits.$O\ + _p9dialparse.$O\ + _p9dir.$O\ + _p9proc.$O\ + announce.$O\ + argv0.$O\ + atexit.$O\ + atnotify.$O\ + await.$O\ + cistrcmp.$O\ + cistrncmp.$O\ + cistrstr.$O\ + cleanname.$O\ + create.$O\ + ctime.$O\ + date.$O\ + dial.$O\ + dirfstat.$O\ + dirfwstat.$O\ + dirmodefmt.$O\ + dirread.$O\ + dirstat.$O\ + dirwstat.$O\ + dup.$O\ + encodefmt.$O\ + errstr.$O\ + exec.$O\ + ffork-$SYSNAME.$O\ + getcallerpc-$OBJTYPE.$O\ + getenv.$O\ + getfields.$O\ + getuser.$O\ + getwd.$O\ + jmp.$O\ + jmp-FreeBSD.$O\ + lock.$O\ + main.$O\ + malloctag.$O\ + mallocz.$O\ + needsrcquote.$O\ + netmkaddr.$O\ + notify.$O\ + nrand.$O\ + nulldir.$O\ + postnote.$O\ + qlock.$O\ + quote.$O\ + readn.$O\ + rendez-$SYSNAME.$O\ + rfork.$O\ + seek.$O\ + sleep.$O\ + strecpy.$O\ + sysfatal.$O\ + tas-$OBJTYPE.$O\ + time.$O\ + tokenize.$O\ + u16.$O\ + u32.$O\ + u64.$O\ + wait.$O\ + waitpid.$O\ + +HFILES=\ + $PLAN9/include/lib9.h\ + +<$PLAN9/src/mksyslib blob - /dev/null blob + f4cf460cf38c2b3561923376fc3878b04d5a0558 (mode 644) --- /dev/null +++ src/lib9/needsrcquote.c @@ -0,0 +1,12 @@ +#include +#include + +int +needsrcquote(int c) +{ + if(c <= ' ') + return 1; + if(strchr("`^#*[]=|\\?${}()'<>&;", c)) + return 1; + return 0; +} blob - /dev/null blob + fd53f46842dadad237031e814feb21cf026ed025 (mode 644) --- /dev/null +++ src/lib9/netmkaddr.c @@ -0,0 +1,52 @@ +#include +#include +#include + +/* + * make an address, add the defaults + */ +char * +netmkaddr(char *linear, char *defnet, char *defsrv) +{ + static char addr[256]; + char *cp; + + /* + * dump network name + */ + cp = strchr(linear, '!'); + if(cp == 0){ + if(defnet==0){ + if(defsrv) + snprint(addr, sizeof(addr), "net!%s!%s", + linear, defsrv); + else + snprint(addr, sizeof(addr), "net!%s", linear); + } + else { + if(defsrv) + snprint(addr, sizeof(addr), "%s!%s!%s", defnet, + linear, defsrv); + else + snprint(addr, sizeof(addr), "%s!%s", defnet, + linear); + } + return addr; + } + + /* + * if there is already a service, use it + */ + cp = strchr(cp+1, '!'); + if(cp) + return linear; + + /* + * add default service + */ + if(defsrv == 0) + return linear; + snprint(addr, sizeof(addr), "%s!%s", linear, defsrv); + + return addr; +} blob - /dev/null blob + 095a3f5413d96ad561bf548c4f52717cfb7a0a4d (mode 644) --- /dev/null +++ src/lib9/notify.c @@ -0,0 +1,83 @@ +#include + +#include +#define NOPLAN9DEFINES +#include +#include "9proc.h" + +extern char *_p9sigstr(int, char*); + +static int sigs[] = { + SIGHUP, + SIGINT, + SIGQUIT, + SIGILL, + SIGTRAP, + SIGABRT, + SIGEMT, + SIGFPE, + SIGBUS, + SIGSEGV, + SIGSYS, + SIGPIPE, + SIGALRM, + SIGTERM, + SIGTSTP, + SIGTTIN, + SIGTTOU, + SIGXCPU, + SIGXFSZ, + SIGVTALRM, + SIGUSR1, + SIGUSR2, +}; + +static void (*notifyf)(void*, char*); + +static void +notifysigf(int sig) +{ + int v; + char tmp[64]; + Uproc *up; + + up = _p9uproc(); + v = p9setjmp(up->notejb); + if(v == 0 && notifyf) + (*notifyf)(nil, _p9sigstr(sig, tmp)); + else if(v == 2){ +if(0)print("HANDLED %d\n", sig); + return; + } +if(0)print("DEFAULT %d\n", sig); + signal(sig, SIG_DFL); + kill(getpid(), sig); +} + +int +notify(void (*f)(void*, char*)) +{ + int i; + void (*sf)(int); + + if(f == nil) + sf = SIG_DFL; + else{ + notifyf = f; + sf = notifysigf; + } + for(i=0; inotejb, v==NCONT ? 2 : 1); + abort(); + return 0; +} blob - /dev/null blob + 612725d812dc22ff5ea240c46f6cc8bb145045c9 (mode 644) --- /dev/null +++ src/lib9/nulldir.c @@ -0,0 +1,9 @@ +#include +#include + +void +nulldir(Dir *d) +{ + memset(d, ~0, sizeof(Dir)); + d->name = d->uid = d->gid = d->muid = ""; +} blob - /dev/null blob + 9124bd5c7839218cb201a06c7837b3e5f2e792b4 (mode 644) --- /dev/null +++ src/lib9/postnote.c @@ -0,0 +1,34 @@ +#include + +#include +#define _NO9DEFINES_ +#include + + +extern int _p9strsig(char*); + +int +postnote(int who, int pid, char *msg) +{ + int sig; + + sig = _p9strsig(msg); + if(sig == 0){ + werrstr("unknown note"); + return -1; + } + + switch(who){ + default: + werrstr("bad who in postnote"); + return -1; + case PNPROC: + return kill(pid, sig); + case PNGROUP: + if((pid = getpgid(pid)) < 0) + return -1; + return killpg(pid, sig); + } +} + + blob - /dev/null blob + 651c48c1cca66d4bdffaa4df76e82a3e5bf842c2 (mode 644) --- /dev/null +++ src/lib9/priv.c @@ -0,0 +1,32 @@ +#include +#include +#include "9proc.h" + +static Lock privlock; +static ulong privmap; + +int +privalloc(void) +{ + int i; + + lock(&privlock); + for(i=0; ipriv[i]; +} + blob - /dev/null blob + 4467377ae1b2732aa3f33fa54b41d8b0e3731bcd (mode 644) --- /dev/null +++ src/lib9/quote.c @@ -0,0 +1,136 @@ +#include +#include + +int (*doquote)(int); + +/* in libfmt */ +extern int __needsquotes(char*, int*); +extern int __runeneedsquotes(Rune*, int*); + +char* +unquotestrdup(char *s) +{ + char *t, *ret; + int quoting; + + ret = s = strdup(s); /* return unquoted copy */ + if(ret == nil) + return ret; + quoting = 0; + t = s; /* s is output string, t is input string */ + while(*t!='\0' && (quoting || (*t!=' ' && *t!='\t'))){ + if(*t != '\''){ + *s++ = *t++; + continue; + } + /* *t is a quote */ + if(!quoting){ + quoting = 1; + t++; + continue; + } + /* quoting and we're on a quote */ + if(t[1] != '\''){ + /* end of quoted section; absorb closing quote */ + t++; + quoting = 0; + continue; + } + /* doubled quote; fold one quote into two */ + t++; + *s++ = *t++; + } + if(t != s) + memmove(s, t, strlen(t)+1); + return ret; +} + +Rune* +unquoterunestrdup(Rune *s) +{ + Rune *t, *ret; + int quoting; + + ret = s = runestrdup(s); /* return unquoted copy */ + if(ret == nil) + return ret; + quoting = 0; + t = s; /* s is output string, t is input string */ + while(*t!='\0' && (quoting || (*t!=' ' && *t!='\t'))){ + if(*t != '\''){ + *s++ = *t++; + continue; + } + /* *t is a quote */ + if(!quoting){ + quoting = 1; + t++; + continue; + } + /* quoting and we're on a quote */ + if(t[1] != '\''){ + /* end of quoted section; absorb closing quote */ + t++; + quoting = 0; + continue; + } + /* doubled quote; fold one quote into two */ + t++; + *s++ = *t++; + } + if(t != s) + memmove(s, t, (runestrlen(t)+1)*sizeof(Rune)); + return ret; +} + +char* +quotestrdup(char *s) +{ + char *t, *u, *ret; + int quotelen; + Rune r; + + if(__needsquotes(s, "elen) == 0) + return strdup(s); + + ret = malloc(quotelen+1); + if(ret == nil) + return nil; + u = ret; + *u++ = '\''; + for(t=s; *t; t++){ + r = *t; + if(r == L'\'') + *u++ = r; /* double the quote */ + *u++ = r; + } + *u++ = '\''; + *u = '\0'; + return ret; +} + +Rune* +quoterunestrdup(Rune *s) +{ + Rune *t, *u, *ret; + int quotelen; + Rune r; + + if(__runeneedsquotes(s, "elen) == 0) + return runestrdup(s); + + ret = malloc((quotelen+1)*sizeof(Rune)); + if(ret == nil) + return nil; + u = ret; + *u++ = '\''; + for(t=s; *t; t++){ + r = *t; + if(r == L'\'') + *u++ = r; /* double the quote */ + *u++ = r; + } + *u++ = '\''; + *u = '\0'; + return ret; +} blob - /dev/null blob + eabb9a754e69016bc1b9a18f63affaedd9094a19 (mode 644) --- /dev/null +++ src/lib9/rendez-SunOS.c @@ -0,0 +1 @@ +#include "rendez-pthread.c" blob - /dev/null blob + cf23a4e5ad63df9024dc09195b27dc7b8c0f56c1 (mode 644) --- /dev/null +++ src/lib9/rendez.c @@ -0,0 +1,42 @@ +#include +#include +#include "9proc.h" + +static Lock rendlock; +static Uproc *rendhash[RENDHASH]; + +ulong +rendezvous(ulong tag, ulong val) +{ + char c; + ulong ret; + Uproc *t, *self, **l; + + self = _p9uproc(); + lock(&rendlock); + l = &rendhash[tag%RENDHASH]; + for(t=*l; t; l=&t->rendhash, t=*l){ + if(t->rendtag==tag){ + *l = t->rendhash; + ret = t->rendval; + t->rendval = val; + t->rendtag++; + c = 0; + unlock(&rendlock); + write(t->pipe[1], &c, 1); + return ret; + } + } + + /* Going to sleep here. */ + t = self; + t->rendtag = tag; + t->rendval = val; + t->rendhash = *l; + *l = t; + unlock(&rendlock); + do + read(t->pipe[0], &c, 1); + while(t->rendtag == tag); + return t->rendval; +} blob - /dev/null blob + e248cd78ef328e4b849c599f99e1bd3dbddc67a1 (mode 644) --- /dev/null +++ src/lib9/rfork.c @@ -0,0 +1,20 @@ +#define NOPLAN9DEFINES +#include + +int +p9rfork(int flags) +{ + if(flags&RFPROC){ + werrstr("cannot use rfork to fork -- use ffork"); + return -1; + } + if(flags&RFNOTEG){ + setpgrp(0, 0); + flags &= ~RFNOTEG; + } + if(flags){ + werrstr("unknown flags %08ux in rfork", flags); + return -1; + } + return 0; +} blob - /dev/null blob + b626355fbb2c33f331ca84df19ee14d2d1c693f2 (mode 644) --- /dev/null +++ src/lib9/seek.c @@ -0,0 +1,8 @@ +#include +#include + +vlong +seek(int fd, vlong offset, int whence) +{ + return lseek(fd, offset, whence); +} blob - /dev/null blob + 9cafdcf6ecc7c96b69cc415e5f6e34db2b118940 (mode 644) --- /dev/null +++ src/lib9/sleep.c @@ -0,0 +1,35 @@ +#include +#define NOPLAN9DEFINES +#include +#include +#include + +int +p9sleep(long milli) +{ + struct timeval tv; + + if(milli == 0){ + sched_yield(); + return 0; + } + + tv.tv_sec = milli/1000; + tv.tv_usec = (milli%1000)*1000; + return select(0, 0, 0, 0, &tv); +} + +long +p9alarm(ulong milli) +{ + struct itimerval itv; + struct itimerval oitv; + + itv.it_interval.tv_sec = 0; + itv.it_interval.tv_usec = 0; + itv.it_value.tv_sec = milli/1000; + itv.it_value.tv_usec = (milli%1000)*1000; + if(setitimer(ITIMER_REAL, &itv, &oitv) < 0) + return -1; + return oitv.it_value.tv_sec*1000+oitv.it_value.tv_usec/1000; +} blob - /dev/null blob + 51f5bf289581b9f74d425364d0200697893e3118 (mode 644) --- /dev/null +++ src/lib9/stat2dir.c @@ -0,0 +1,116 @@ +#include +#include + +#include +#include +#include +#include +#include + +int +_p9dir(struct stat *st, char *name, Dir *d, char **str, char *estr) +{ + char *s; + char tmp[20]; + struct group *g; + struct pwd *p; + int sz; + + sz = 0; + + /* name */ + s = strrchr(name, '/'); + if(s && s[1]) + s++; + else + s = "/"; + if(d){ + if(*str + strlen(s)+1 > estr) + d->name = "oops"; + else{ + strcpy(*str, s); + d->name = *str; + *str += strlen(*str)+1; + } + } + sz += strlen(s)+1; + + /* user */ + p = getpwuid(st->st_uid); + if(p == nil){ + snprint(tmp, sizeof tmp, "%d", (int)st->st_uid); + s = tmp; + }else + s = p->pw_name; + sz += strlen(s)+1; + if(d){ + if(*str+strlen(s)+1 > estr) + d->uid = "oops"; + else{ + strcpy(*str, s); + d->uid = *str; + *str += strlen(*str)+1; + } + } + + /* group */ + g = getgrgid(st->st_gid); + if(g == nil){ + snprint(tmp, sizeof tmp, "%d", (int)st->st_gid); + s = tmp; + }else + s = g->gr_name; + sz += strlen(s)+1; + if(d){ + if(*str + strlen(s)+1 > estr){ + d->gid = "oops"; + else{ + strcpy(*str, s); + d->gid = *str; + *str += strlen(*str)+1; + } + } + + if(d){ + d->muid = ""; + d->qid.path = ((uvlong)st->st_dev<<32) | st->st_ino; + d->qid.vers = st->st_gen; + d->mode = st->st_mode&0777; + if(S_ISDIR(st->st_mode)){ + d->mode |= DMDIR; + d->qid.type = QTDIR; + } + d->atime = st->st_atime; + d->mtime = st->st_mtime; + d->length = st->st_size; + + /* fetch real size for disks */ + if(S_ISCHR(st->st_mode)){ + int fd, n; + struct disklabel lab; + + if((fd = open(name, O_RDONLY)) < 0) + goto nosize; + if(ioctl(fd, DIOCGDINFO, &lab) < 0) + goto nosize; + n = minor(st->st_rdev)&0xFFFF; + if(n >= lab.d_npartitions) + goto nosize; + d->length = (vlong)lab.d_npartitions[n].p_size * lab.d_secsize; + nosize: + if(fd >= 0) + close(fd); + } + } + + return sz; +} + +Dir* +_dirfstat(char *name, int fd) +{ + Dir *d; + int size; + + +} blob - /dev/null blob + b960a26a040fe6982a26f619cbec942660a27d9a (mode 644) --- /dev/null +++ src/lib9/tas-sun4u.s @@ -0,0 +1,4 @@ +.globl _tas +_tas: + retl + ldstub [%o0], %o0 blob - /dev/null blob + 169a82f50287cfd9b64a4b4f9f531b96c168c517 (mode 644) --- /dev/null +++ src/lib9/time.c @@ -0,0 +1,58 @@ +#include +#include + +#include +#define NOPLAN9DEFINES +#include + +long +p9times(long *t) +{ + struct rusage ru, cru; + + if(getrusage(0, &ru) < 0 || getrusage(-1, &cru) < 0) + return -1; + + t[0] = ru.ru_utime.tv_sec*1000 + ru.ru_utime.tv_usec/1000; + t[1] = ru.ru_stime.tv_sec*1000 + ru.ru_stime.tv_usec/1000; + t[2] = cru.ru_utime.tv_sec*1000 + cru.ru_utime.tv_usec/1000; + t[3] = cru.ru_stime.tv_sec*1000 + cru.ru_stime.tv_usec/1000; + + /* BUG */ + return t[0]+t[1]+t[2]+t[3]; +} + +double +p9cputime(void) +{ + long t[4]; + double d; + + if(p9times(t) < 0) + return -1.0; + + d = (double)t[0]+(double)t[1]+(double)t[2]+(double)t[3]; + return d/1000.0; +} + +vlong +p9nsec(void) +{ + struct timeval tv; + + if(gettimeofday(&tv, 0) < 0) + return -1; + + return (vlong)tv.tv_sec*1000*1000*1000 + tv.tv_usec*1000; +} + +long +p9time(long *tt) +{ + long t; + t = time(0); + if(tt) + *tt = t; + return t; +} + blob - /dev/null blob + a11647236b0b6ae9ea55486e0dca057041d030cd (mode 644) --- /dev/null +++ src/lib9/udp.c @@ -0,0 +1,52 @@ +#include +#define NOPLAN9DEFINES +#include +#include + +#include +#include + +/* + * prefix of all v4 addresses + * copied from libip because libc cannot depend on libip + */ +static uchar v4prefix[IPaddrlen] = { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0xff, 0xff, + 0, 0, 0, 0 +}; + +long +udpread(int fd, Udphdr *hdr, void *buf, long n) +{ + struct sockaddr_in sin; + socklen_t len; + + len = sizeof sin; + n = recvfrom(fd, buf, n, 0, (struct sockaddr*)&sin, &len); + if(len != sizeof sin){ + werrstr("recvfrom acting weird"); + return -1; + } + if(n < 0) + return -1; + memset(hdr, 0, sizeof *hdr); + memmove(hdr->raddr, v4prefix, IPaddrlen); + *(u32int*)(hdr->raddr+12) = *(u32int*)&sin.sin_addr; + *(u16int*)hdr->rport = *(u16int*)&sin.sin_port; + return n; +} + +long +udpwrite(int fd, Udphdr *hdr, void *buf, long n) +{ + struct sockaddr_in sin; + + memset(&sin, 0, sizeof sin); + sin.sin_family = AF_INET; + *(u32int*)&sin.sin_addr = *(u32int*)(hdr->raddr+12); + *(u16int*)&sin.sin_port = *(u16int*)hdr->rport; + return sendto(fd, buf, n, 0, (struct sockaddr*)&sin, sizeof sin); +} + blob - /dev/null blob + 3df8ef89cda2c503373c8212112314f279ea0f29 (mode 644) --- /dev/null +++ src/lib9/waitpid.c @@ -0,0 +1,20 @@ +#include +#include + +int +waitpid(void) +{ + int n; + char buf[512], *fld[5]; + + n = await(buf, sizeof buf-1); + if(n <= 0) + return -1; + buf[n] = '\0'; + if(tokenize(buf, fld, nelem(fld)) != nelem(fld)){ + werrstr("couldn't parse wait message"); + return -1; + } + return atoi(fld[0]); +} +