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
|
||||
_exits(char *s)
|
||||
{
|
||||
_p9uprocdie();
|
||||
|
||||
if(s && *s)
|
||||
_exit(1);
|
||||
_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 <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/time.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <lib9.h>
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
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 "libc.h"
|
||||
#include <sys/types.h>
|
||||
#include <u.h>
|
||||
#define NOPLAN9DEFINES
|
||||
#include <libc.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
|
||||
static void
|
||||
statconv(Dir *dir, struct stat *s)
|
||||
extern int _p9dir(struct stat*, char*, Dir*, char**, char*);
|
||||
|
||||
Dir*
|
||||
dirstat(char *file)
|
||||
{
|
||||
struct passwd *p;
|
||||
struct group *g;
|
||||
ulong q;
|
||||
struct stat st;
|
||||
int nstr;
|
||||
Dir *d;
|
||||
char *str;
|
||||
|
||||
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 = '|';
|
||||
if(stat(file, &st) < 0)
|
||||
return nil;
|
||||
|
||||
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
|
||||
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);
|
||||
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
|
||||
exits(char *s)
|
||||
{
|
||||
_privdie();
|
||||
if(s && *s)
|
||||
exit(1);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void
|
||||
_exits(char *s)
|
||||
{
|
||||
_privdie();
|
||||
if(s && *s)
|
||||
_exit(1);
|
||||
_exit(0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +1 @@
|
|||
#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();
|
||||
}
|
||||
|
||||
#include "ffork-pthread.c"
|
||||
|
|
|
|||
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 <signal.h>
|
||||
#include <lib9.h>
|
||||
|
||||
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*
|
||||
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