Various additions and fixes.
This commit is contained in:
parent
74f990ad84
commit
fd04aacee1
57 changed files with 2176 additions and 159 deletions
23
src/lib9/9proc.h
Normal file
23
src/lib9/9proc.h
Normal file
|
|
@ -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);
|
||||||
|
|
@ -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
|
|
||||||
|
|
||||||
|
|
@ -1,8 +1,12 @@
|
||||||
#include <lib9.h>
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include "9proc.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
_exits(char *s)
|
_exits(char *s)
|
||||||
{
|
{
|
||||||
|
_p9uprocdie();
|
||||||
|
|
||||||
if(s && *s)
|
if(s && *s)
|
||||||
_exit(1);
|
_exit(1);
|
||||||
_exit(0);
|
_exit(0);
|
||||||
|
|
|
||||||
151
src/lib9/_p9dialparse.c
Normal file
151
src/lib9/_p9dialparse.c
Normal file
|
|
@ -0,0 +1,151 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
121
src/lib9/_p9dir.c
Normal file
121
src/lib9/_p9dir.c
Normal file
|
|
@ -0,0 +1,121 @@
|
||||||
|
#include <u.h>
|
||||||
|
#define NOPLAN9DEFINES
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/disklabel.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <grp.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
73
src/lib9/_p9proc.c
Normal file
73
src/lib9/_p9proc.c
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#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);
|
||||||
|
}
|
||||||
137
src/lib9/announce.c
Normal file
137
src/lib9/announce.c
Normal file
|
|
@ -0,0 +1,137 @@
|
||||||
|
#include <u.h>
|
||||||
|
#define NOPLAN9DEFINES
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
54
src/lib9/atexit.c
Normal file
54
src/lib9/atexit.c
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
|
#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<NEXIT; i++)
|
||||||
|
if(onex[i].f == 0) {
|
||||||
|
onex[i].pid = getpid();
|
||||||
|
onex[i].f = f;
|
||||||
|
unlock(&onexlock);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
unlock(&onexlock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
atexitdont(void (*f)(void))
|
||||||
|
{
|
||||||
|
int i, pid;
|
||||||
|
|
||||||
|
pid = getpid();
|
||||||
|
for(i=0; i<NEXIT; i++)
|
||||||
|
if(onex[i].f == f && onex[i].pid == pid)
|
||||||
|
onex[i].f = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
exits(char *s)
|
||||||
|
{
|
||||||
|
int i, pid;
|
||||||
|
void (*f)(void);
|
||||||
|
|
||||||
|
pid = getpid();
|
||||||
|
for(i = NEXIT-1; i >= 0; i--)
|
||||||
|
if((f = onex[i].f) && pid == onex[i].pid) {
|
||||||
|
onex[i].f = 0;
|
||||||
|
(*f)();
|
||||||
|
}
|
||||||
|
_exits(s);
|
||||||
|
}
|
||||||
58
src/lib9/atnotify.c
Normal file
58
src/lib9/atnotify.c
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
|
#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<NFN; i++)
|
||||||
|
if(onnot[i] && ((*onnot[i])(v, s))){
|
||||||
|
noted(NCONT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
noted(NDFLT);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
atnotify(int (*f)(void*, char*), int in)
|
||||||
|
{
|
||||||
|
int i, n, ret;
|
||||||
|
static int init;
|
||||||
|
|
||||||
|
if(!init){
|
||||||
|
notify(notifier);
|
||||||
|
init = 1; /* assign = */
|
||||||
|
}
|
||||||
|
ret = 0;
|
||||||
|
lock(&onnotlock);
|
||||||
|
if(in){
|
||||||
|
for(i=0; i<NFN; i++)
|
||||||
|
if(onnot[i] == 0) {
|
||||||
|
onnot[i] = f;
|
||||||
|
ret = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
n = 0;
|
||||||
|
for(i=0; i<NFN; i++)
|
||||||
|
if(onnot[i]){
|
||||||
|
if(ret==0 && onnot[i]==f){
|
||||||
|
onnot[i] = 0;
|
||||||
|
ret = 1;
|
||||||
|
}else
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
if(n == 0){
|
||||||
|
init = 0;
|
||||||
|
notify(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unlock(&onnotlock);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
|
#define NOPLAN9DEFINES
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <lib9.h>
|
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
int sig;
|
int sig;
|
||||||
|
|
@ -18,9 +18,7 @@ static struct {
|
||||||
SIGILL, "sys: trap: illegal instruction",
|
SIGILL, "sys: trap: illegal instruction",
|
||||||
SIGTRAP, "sys: trace trap",
|
SIGTRAP, "sys: trace trap",
|
||||||
SIGABRT, "sys: abort",
|
SIGABRT, "sys: abort",
|
||||||
#ifdef SIGEMT
|
|
||||||
SIGEMT, "sys: emulate instruction executed",
|
SIGEMT, "sys: emulate instruction executed",
|
||||||
#endif
|
|
||||||
SIGFPE, "sys: fp: trap",
|
SIGFPE, "sys: fp: trap",
|
||||||
SIGKILL, "sys: kill",
|
SIGKILL, "sys: kill",
|
||||||
SIGBUS, "sys: bus error",
|
SIGBUS, "sys: bus error",
|
||||||
|
|
@ -40,14 +38,12 @@ static struct {
|
||||||
SIGVTALRM, "sys: virtual time alarm",
|
SIGVTALRM, "sys: virtual time alarm",
|
||||||
SIGPROF, "sys: profiling timer alarm",
|
SIGPROF, "sys: profiling timer alarm",
|
||||||
SIGWINCH, "sys: window size change",
|
SIGWINCH, "sys: window size change",
|
||||||
#ifdef SIGINFO
|
|
||||||
SIGINFO, "sys: status request",
|
SIGINFO, "sys: status request",
|
||||||
#endif
|
|
||||||
SIGUSR1, "sys: usr1",
|
SIGUSR1, "sys: usr1",
|
||||||
SIGUSR2, "sys: usr2",
|
SIGUSR2, "sys: usr2",
|
||||||
};
|
};
|
||||||
|
|
||||||
static char*
|
char*
|
||||||
_p9sigstr(int sig, char *tmp)
|
_p9sigstr(int sig, char *tmp)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
@ -59,8 +55,7 @@ _p9sigstr(int sig, char *tmp)
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
int
|
||||||
static int
|
|
||||||
_p9strsig(char *s)
|
_p9strsig(char *s)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
@ -70,7 +65,6 @@ _p9strsig(char *s)
|
||||||
return tab[i].sig;
|
return tab[i].sig;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
int
|
||||||
await(char *str, int n)
|
await(char *str, int n)
|
||||||
|
|
@ -89,16 +83,16 @@ await(char *str, int n)
|
||||||
if(WIFEXITED(status)){
|
if(WIFEXITED(status)){
|
||||||
status = WEXITSTATUS(status);
|
status = WEXITSTATUS(status);
|
||||||
if(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
|
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);
|
strecpy(str, str+n, buf);
|
||||||
return strlen(str);
|
return strlen(str);
|
||||||
}
|
}
|
||||||
if(WIFSIGNALED(status)){
|
if(WIFSIGNALED(status)){
|
||||||
cd = WCOREDUMP(status);
|
cd = WCOREDUMP(status);
|
||||||
USED(cd);
|
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);
|
strecpy(str, str+n, buf);
|
||||||
return strlen(str);
|
return strlen(str);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
26
src/lib9/cistrcmp.c
Normal file
26
src/lib9/cistrcmp.c
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
28
src/lib9/cistrncmp.c
Normal file
28
src/lib9/cistrncmp.c
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
23
src/lib9/cistrstr.c
Normal file
23
src/lib9/cistrstr.c
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
8
src/lib9/create.c
Normal file
8
src/lib9/create.c
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
create(char *path, int mode, ulong perm)
|
||||||
|
{
|
||||||
|
return open(path, mode|O_CREAT|O_TRUNC, perm);
|
||||||
|
}
|
||||||
51
src/lib9/ctime.c
Normal file
51
src/lib9/ctime.c
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
77
src/lib9/date.c
Normal file
77
src/lib9/date.c
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
|
#undef gmtime
|
||||||
|
#undef localtime
|
||||||
|
#undef asctime
|
||||||
|
#undef ctime
|
||||||
|
#undef cputime
|
||||||
|
#undef times
|
||||||
|
#undef tm2sec
|
||||||
|
#undef nsec
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
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 */
|
||||||
|
}
|
||||||
|
|
||||||
92
src/lib9/dial.c
Normal file
92
src/lib9/dial.c
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
|
#undef accept
|
||||||
|
#undef announce
|
||||||
|
#undef dial
|
||||||
|
#undef setnetmtpt
|
||||||
|
#undef hangup
|
||||||
|
#undef listen
|
||||||
|
#undef netmkaddr
|
||||||
|
#undef reject
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
29
src/lib9/dirfstat.c
Normal file
29
src/lib9/dirfstat.c
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
#include <u.h>
|
||||||
|
#define NOPLAN9DEFINES
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
21
src/lib9/dirfwstat.c
Normal file
21
src/lib9/dirfwstat.c
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
#include <u.h>
|
||||||
|
#define NOPLAN9DEFINES
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
47
src/lib9/dirmodefmt.c
Normal file
47
src/lib9/dirmodefmt.c
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
155
src/lib9/dirread.c
Normal file
155
src/lib9/dirread.c
Normal file
|
|
@ -0,0 +1,155 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
|
#undef asctime
|
||||||
|
#undef ctime
|
||||||
|
#undef gmtime
|
||||||
|
#undef localtime
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
|
||||||
|
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; i<n; i++){
|
||||||
|
de = (struct dirent*)p;
|
||||||
|
if(stat(de->d_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; i<n; i++){
|
||||||
|
de = (struct dirent*)p;
|
||||||
|
if(de->d_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;
|
||||||
|
}
|
||||||
|
|
@ -1,83 +1,28 @@
|
||||||
#include "u.h"
|
#include <u.h>
|
||||||
#include "libc.h"
|
#define NOPLAN9DEFINES
|
||||||
#include <sys/types.h>
|
#include <libc.h>
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <pwd.h>
|
|
||||||
#include <grp.h>
|
|
||||||
|
|
||||||
static void
|
extern int _p9dir(struct stat*, char*, Dir*, char**, char*);
|
||||||
statconv(Dir *dir, struct stat *s)
|
|
||||||
|
Dir*
|
||||||
|
dirstat(char *file)
|
||||||
{
|
{
|
||||||
struct passwd *p;
|
struct stat st;
|
||||||
struct group *g;
|
int nstr;
|
||||||
ulong q;
|
Dir *d;
|
||||||
|
char *str;
|
||||||
|
|
||||||
p = getpwuid(s->st_uid);
|
if(stat(file, &st) < 0)
|
||||||
if (p)
|
return nil;
|
||||||
strncpy(dir->uid, p->pw_name, NAMELEN);
|
|
||||||
g = getgrgid(s->st_gid);
|
nstr = _p9dir(&st, file, nil, nil, nil);
|
||||||
if (g)
|
d = mallocz(sizeof(Dir)+nstr, 1);
|
||||||
strncpy(dir->gid, g->gr_name, NAMELEN);
|
if(d == nil)
|
||||||
q = 0;
|
return nil;
|
||||||
if(S_ISDIR(s->st_mode))
|
str = (char*)&d[1];
|
||||||
q = CHDIR;
|
_p9dir(&st, file, d, &str, str+nstr);
|
||||||
q |= s->st_ino & 0x00FFFFFFUL;
|
return d;
|
||||||
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)
|
|
||||||
{
|
|
||||||
struct stat sbuf;
|
|
||||||
|
|
||||||
if(fstat(fd, &sbuf) < 0)
|
|
||||||
return -1;
|
|
||||||
statconv(d, &sbuf);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *
|
|
||||||
lelem(char *path)
|
|
||||||
{
|
|
||||||
char *pr;
|
|
||||||
|
|
||||||
pr = utfrrune(path, '/');
|
|
||||||
if(pr)
|
|
||||||
pr++;
|
|
||||||
else
|
|
||||||
pr = path;
|
|
||||||
return pr;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
21
src/lib9/dirwstat.c
Normal file
21
src/lib9/dirwstat.c
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
#include <u.h>
|
||||||
|
#define NOPLAN9DEFINES
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
12
src/lib9/dup.c
Normal file
12
src/lib9/dup.c
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
|
#undef dup
|
||||||
|
|
||||||
|
int
|
||||||
|
p9dup(int old, int new)
|
||||||
|
{
|
||||||
|
if(new == -1)
|
||||||
|
return dup(old);
|
||||||
|
return dup2(old, new);
|
||||||
|
}
|
||||||
|
|
@ -78,3 +78,16 @@ werrstr(char *fmt, ...)
|
||||||
va_end(arg);
|
va_end(arg);
|
||||||
errstr(buf, ERRMAX);
|
errstr(buf, ERRMAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char*
|
||||||
|
gerrstr(void)
|
||||||
|
{
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
s = getsyserr();
|
||||||
|
if(errno != EPLAN9)
|
||||||
|
strcpy(s, strerror(errno));
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
9
src/lib9/exec.c
Normal file
9
src/lib9/exec.c
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
@ -1,10 +1,22 @@
|
||||||
#include <lib9.h>
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
|
extern void _privdie(void);
|
||||||
|
|
||||||
void
|
void
|
||||||
exits(char *s)
|
exits(char *s)
|
||||||
{
|
{
|
||||||
|
_privdie();
|
||||||
if(s && *s)
|
if(s && *s)
|
||||||
exit(1);
|
exit(1);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_exits(char *s)
|
||||||
|
{
|
||||||
|
_privdie();
|
||||||
|
if(s && *s)
|
||||||
|
_exit(1);
|
||||||
|
_exit(0);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1 @@
|
||||||
#include <lib9.h>
|
#include "ffork-pthread.c"
|
||||||
#include <pthread.h>
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
||||||
1
src/lib9/ffork-SunOS.c
Normal file
1
src/lib9/ffork-SunOS.c
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
#include "ffork-pthread.c"
|
||||||
26
src/lib9/ffork-pthread.c
Normal file
26
src/lib9/ffork-pthread.c
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
#include <lib9.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
5
src/lib9/getcallerpc-sun4u.s
Normal file
5
src/lib9/getcallerpc-sun4u.s
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
.text
|
||||||
|
.globl getcallerpc
|
||||||
|
getcallerpc:
|
||||||
|
retl
|
||||||
|
or %o7, %r0, %o0
|
||||||
15
src/lib9/getenv.c
Normal file
15
src/lib9/getenv.c
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
#include <u.h>
|
||||||
|
#define NOPLAN9DEFINES
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
|
char*
|
||||||
|
p9getenv(char *s)
|
||||||
|
{
|
||||||
|
char *t;
|
||||||
|
|
||||||
|
t = getenv(s);
|
||||||
|
if(t == 0)
|
||||||
|
return 0;
|
||||||
|
return strdup(t);
|
||||||
|
}
|
||||||
|
|
||||||
17
src/lib9/getuser.c
Normal file
17
src/lib9/getuser.c
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
#include <pwd.h>
|
||||||
|
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
10
src/lib9/getwd.c
Normal file
10
src/lib9/getwd.c
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
|
#undef getwd
|
||||||
|
|
||||||
|
char*
|
||||||
|
p9getwd(char *s, int ns)
|
||||||
|
{
|
||||||
|
return getcwd(s, ns);
|
||||||
|
}
|
||||||
3
src/lib9/jmp-FreeBSD.s
Normal file
3
src/lib9/jmp-FreeBSD.s
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
.globl sigsetjmp, p9setjmp
|
||||||
|
p9setjmp:
|
||||||
|
jmp sigsetjmp
|
||||||
17
src/lib9/jmp.c
Normal file
17
src/lib9/jmp.c
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
#include <u.h>
|
||||||
|
#define NOPLAN9DEFINES
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
13
src/lib9/main.c
Normal file
13
src/lib9/main.c
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
#include <u.h>
|
||||||
|
#define NOPLAN9DEFINES
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
|
extern void p9main(int, char**);
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
p9main(argc, argv);
|
||||||
|
exits("main");
|
||||||
|
return 99;
|
||||||
|
}
|
||||||
73
src/lib9/mkfile
Normal file
73
src/lib9/mkfile
Normal file
|
|
@ -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
|
||||||
12
src/lib9/needsrcquote.c
Normal file
12
src/lib9/needsrcquote.c
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
needsrcquote(int c)
|
||||||
|
{
|
||||||
|
if(c <= ' ')
|
||||||
|
return 1;
|
||||||
|
if(strchr("`^#*[]=|\\?${}()'<>&;", c))
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
52
src/lib9/netmkaddr.c
Normal file
52
src/lib9/netmkaddr.c
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
83
src/lib9/notify.c
Normal file
83
src/lib9/notify.c
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
#include <u.h>
|
||||||
|
#define NOPLAN9DEFINES
|
||||||
|
#include <libc.h>
|
||||||
|
#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; i<nelem(sigs); i++)
|
||||||
|
signal(sigs[i], sf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
noted(int v)
|
||||||
|
{
|
||||||
|
Uproc *up;
|
||||||
|
|
||||||
|
up = _p9uproc();
|
||||||
|
p9longjmp(up->notejb, v==NCONT ? 2 : 1);
|
||||||
|
abort();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
9
src/lib9/nulldir.c
Normal file
9
src/lib9/nulldir.c
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
nulldir(Dir *d)
|
||||||
|
{
|
||||||
|
memset(d, ~0, sizeof(Dir));
|
||||||
|
d->name = d->uid = d->gid = d->muid = "";
|
||||||
|
}
|
||||||
34
src/lib9/postnote.c
Normal file
34
src/lib9/postnote.c
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
#include <u.h>
|
||||||
|
#define _NO9DEFINES_
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
32
src/lib9/priv.c
Normal file
32
src/lib9/priv.c
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include "9proc.h"
|
||||||
|
|
||||||
|
static Lock privlock;
|
||||||
|
static ulong privmap;
|
||||||
|
|
||||||
|
int
|
||||||
|
privalloc(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
lock(&privlock);
|
||||||
|
for(i=0; i<NPRIV; i++)
|
||||||
|
if((privmap&(1<<i)) == 0){
|
||||||
|
privmap |= (1<<i);
|
||||||
|
unlock(&privlock);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
unlock(&privlock);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void**
|
||||||
|
privmem(int i)
|
||||||
|
{
|
||||||
|
Uproc *up;
|
||||||
|
|
||||||
|
up = _p9uproc();
|
||||||
|
return &up->priv[i];
|
||||||
|
}
|
||||||
|
|
||||||
136
src/lib9/quote.c
Normal file
136
src/lib9/quote.c
Normal file
|
|
@ -0,0 +1,136 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
1
src/lib9/rendez-SunOS.c
Normal file
1
src/lib9/rendez-SunOS.c
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
#include "rendez-pthread.c"
|
||||||
|
|
@ -33,6 +33,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <signal.h>
|
||||||
#include <lib9.h>
|
#include <lib9.h>
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
|
|
||||||
42
src/lib9/rendez.c
Normal file
42
src/lib9/rendez.c
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#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;
|
||||||
|
}
|
||||||
20
src/lib9/rfork.c
Normal file
20
src/lib9/rfork.c
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
#define NOPLAN9DEFINES
|
||||||
|
#include <lib9.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
8
src/lib9/seek.c
Normal file
8
src/lib9/seek.c
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
|
vlong
|
||||||
|
seek(int fd, vlong offset, int whence)
|
||||||
|
{
|
||||||
|
return lseek(fd, offset, whence);
|
||||||
|
}
|
||||||
35
src/lib9/sleep.c
Normal file
35
src/lib9/sleep.c
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
#include <u.h>
|
||||||
|
#define NOPLAN9DEFINES
|
||||||
|
#include <libc.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sched.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
116
src/lib9/stat2dir.c
Normal file
116
src/lib9/stat2dir.c
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/disklabel.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <grp.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
4
src/lib9/tas-sun4u.s
Normal file
4
src/lib9/tas-sun4u.s
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
.globl _tas
|
||||||
|
_tas:
|
||||||
|
retl
|
||||||
|
ldstub [%o0], %o0
|
||||||
58
src/lib9/time.c
Normal file
58
src/lib9/time.c
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/resource.h>
|
||||||
|
|
||||||
|
#include <u.h>
|
||||||
|
#define NOPLAN9DEFINES
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
52
src/lib9/udp.c
Normal file
52
src/lib9/udp.c
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
#include <u.h>
|
||||||
|
#define NOPLAN9DEFINES
|
||||||
|
#include <libc.h>
|
||||||
|
#include <ip.h>
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#include <lib9.h>
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
Waitmsg*
|
Waitmsg*
|
||||||
wait(void)
|
wait(void)
|
||||||
|
|
|
||||||
20
src/lib9/waitpid.c
Normal file
20
src/lib9/waitpid.c
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
|
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]);
|
||||||
|
}
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue