More files related to user-level file servers.
Also add acme!
This commit is contained in:
parent
32f69c36e0
commit
b3994ec5c7
35 changed files with 14133 additions and 0 deletions
46
src/lib9/_p9translate.c
Normal file
46
src/lib9/_p9translate.c
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
|
||||
/*
|
||||
* I don't want too many of these,
|
||||
* but the ones we have are just too useful.
|
||||
*/
|
||||
static struct {
|
||||
char *old;
|
||||
char *new;
|
||||
} replace[] = {
|
||||
"#9", nil, /* must be first */
|
||||
"#d", "/dev/fd",
|
||||
};
|
||||
|
||||
char*
|
||||
_p9translate(char *old)
|
||||
{
|
||||
char *new;
|
||||
int i, olen, nlen, len;
|
||||
|
||||
if(replace[0].new == nil){
|
||||
replace[0].new = getenv("PLAN9");
|
||||
if(replace[0].new == nil)
|
||||
replace[0].new = "/usr/local/plan9";
|
||||
}
|
||||
|
||||
for(i=0; i<nelem(replace); i++){
|
||||
if(!replace[i].new)
|
||||
continue;
|
||||
olen = strlen(replace[i].old);
|
||||
if(strncmp(old, replace[i].old, olen) != 0
|
||||
|| (old[olen] != '\0' && old[olen] != '/'))
|
||||
continue;
|
||||
nlen = strlen(replace[i].new);
|
||||
len = strlen(old)+nlen-olen;
|
||||
new = malloc(len+1);
|
||||
if(new == nil)
|
||||
return nil;
|
||||
strcpy(new, replace[i].new);
|
||||
strcpy(new+nlen, old+olen);
|
||||
assert(strlen(new) == len);
|
||||
return new;
|
||||
}
|
||||
return old;
|
||||
}
|
||||
19
src/lib9/access.c
Normal file
19
src/lib9/access.c
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#include <u.h>
|
||||
#define NOPLAN9DEFINES
|
||||
#include <libc.h>
|
||||
|
||||
char *_p9translate(char*);
|
||||
|
||||
int
|
||||
p9access(char *xname, int what)
|
||||
{
|
||||
int ret;
|
||||
char *name;
|
||||
|
||||
if((name = _p9translate(xname)) == nil)
|
||||
return -1;
|
||||
ret = access(name, what);
|
||||
if(name != xname)
|
||||
free(name);
|
||||
return ret;
|
||||
}
|
||||
74
src/lib9/getns.c
Normal file
74
src/lib9/getns.c
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/*
|
||||
* Absent other hints, it works reasonably well to use
|
||||
* the X11 display name as the name space identifier.
|
||||
* This is how sam's B has worked since the early days.
|
||||
* Since most programs using name spaces are also using X,
|
||||
* this still seems reasonable. Terminal-only sessions
|
||||
* can set $NAMESPACE.
|
||||
*/
|
||||
static char*
|
||||
nsfromdisplay(void)
|
||||
{
|
||||
int fd;
|
||||
Dir *d;
|
||||
char *disp, *p;
|
||||
|
||||
if((disp = getenv("DISPLAY")) == nil){
|
||||
werrstr("$DISPLAY not set");
|
||||
return nil;
|
||||
}
|
||||
|
||||
/* canonicalize: xxx:0.0 => xxx:0 */
|
||||
p = strrchr(disp, ':');
|
||||
if(p){
|
||||
p++;
|
||||
while(isdigit((uchar)*p))
|
||||
p++;
|
||||
if(strcmp(p, ".0") == 0)
|
||||
*p = 0;
|
||||
}
|
||||
|
||||
p = smprint("/tmp/ns.%s.%s", getuser(), disp);
|
||||
free(disp);
|
||||
if(p == nil){
|
||||
werrstr("out of memory");
|
||||
return p;
|
||||
}
|
||||
if((fd=create(p, OREAD, DMDIR|0700)) >= 0){
|
||||
close(fd);
|
||||
return p;
|
||||
}
|
||||
if((d = dirstat(p)) == nil){
|
||||
free(d);
|
||||
werrstr("stat %s: %r", p);
|
||||
free(p);
|
||||
return nil;
|
||||
}
|
||||
if((d->mode&0777) != 0700 || strcmp(d->uid, getuser()) != 0){
|
||||
werrstr("bad name space dir %s", p);
|
||||
free(p);
|
||||
free(d);
|
||||
return nil;
|
||||
}
|
||||
free(d);
|
||||
return p;
|
||||
}
|
||||
|
||||
char*
|
||||
getns(void)
|
||||
{
|
||||
char *ns;
|
||||
|
||||
ns = getenv("NAMESPACE");
|
||||
if(ns == nil)
|
||||
ns = nsfromdisplay();
|
||||
if(ns == nil){
|
||||
werrstr("$NAMESPACE not set, %r");
|
||||
return nil;
|
||||
}
|
||||
return ns;
|
||||
}
|
||||
11
src/lib9/malloc.c
Normal file
11
src/lib9/malloc.c
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#include <u.h>
|
||||
#define NOPLAN9DEFINES
|
||||
#include <libc.h>
|
||||
|
||||
void*
|
||||
p9malloc(ulong n)
|
||||
{
|
||||
if(n == 0)
|
||||
n++;
|
||||
return malloc(n);
|
||||
}
|
||||
38
src/lib9/open.c
Normal file
38
src/lib9/open.c
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
#include <u.h>
|
||||
#define NOPLAN9DEFINES
|
||||
#include <libc.h>
|
||||
|
||||
extern char* _p9translate(char*);
|
||||
|
||||
int
|
||||
p9open(char *xname, int mode)
|
||||
{
|
||||
char *name;
|
||||
int cexec, rclose;
|
||||
int fd, umode;
|
||||
|
||||
umode = mode&3;
|
||||
cexec = mode&OCEXEC;
|
||||
rclose = mode&ORCLOSE;
|
||||
mode &= ~(3|OCEXEC|ORCLOSE);
|
||||
if(mode&OTRUNC){
|
||||
umode |= O_TRUNC;
|
||||
mode ^= OTRUNC;
|
||||
}
|
||||
if(mode){
|
||||
werrstr("mode not supported");
|
||||
return -1;
|
||||
}
|
||||
if((name = _p9translate(xname)) == nil)
|
||||
return -1;
|
||||
fd = open(name, umode);
|
||||
if(fd >= 0){
|
||||
if(cexec)
|
||||
fcntl(fd, F_SETFL, FD_CLOEXEC);
|
||||
if(rclose)
|
||||
remove(name);
|
||||
}
|
||||
if(name != xname)
|
||||
free(name);
|
||||
return fd;
|
||||
}
|
||||
10
src/lib9/pipe.c
Normal file
10
src/lib9/pipe.c
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#include <u.h>
|
||||
#define NOPLAN9DEFINES
|
||||
#include <libc.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
int
|
||||
p9pipe(int fd[2])
|
||||
{
|
||||
return socketpair(AF_UNIX, SOCK_STREAM, 0, fd);
|
||||
}
|
||||
40
src/lib9/post9p.c
Normal file
40
src/lib9/post9p.c
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
|
||||
int
|
||||
post9pservice(int fd, char *name)
|
||||
{
|
||||
int i;
|
||||
char *ns, *s;
|
||||
Waitmsg *w;
|
||||
|
||||
if((ns = getns()) == nil)
|
||||
return -1;
|
||||
s = smprint("unix!%s/%s", ns, name);
|
||||
free(ns);
|
||||
if(s == nil)
|
||||
return -1;
|
||||
switch(rfork(RFPROC|RFFDG)){
|
||||
case -1:
|
||||
return -1;
|
||||
case 0:
|
||||
dup(fd, 0);
|
||||
dup(fd, 1);
|
||||
for(i=3; i<20; i++)
|
||||
close(i);
|
||||
execlp("9pserve", "9pserve", "-u", s, (char*)0);
|
||||
fprint(2, "exec 9pserve: %r\n");
|
||||
_exits("exec");
|
||||
default:
|
||||
w = wait();
|
||||
close(fd);
|
||||
free(s);
|
||||
if(w->msg && w->msg[0]){
|
||||
free(w);
|
||||
werrstr("9pserve failed");
|
||||
return -1;
|
||||
}
|
||||
free(w);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
79
src/lib9/sendfd.c
Normal file
79
src/lib9/sendfd.c
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
#include <u.h>
|
||||
#define NOPLAN9DEFINES
|
||||
#include <libc.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/uio.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
typedef struct Sendfd Sendfd;
|
||||
struct Sendfd {
|
||||
struct cmsghdr cmsg;
|
||||
int fd;
|
||||
};
|
||||
|
||||
int
|
||||
sendfd(int s, int fd)
|
||||
{
|
||||
char buf[1];
|
||||
struct iovec iov;
|
||||
struct msghdr msg;
|
||||
int n;
|
||||
Sendfd sfd;
|
||||
|
||||
buf[0] = 0;
|
||||
iov.iov_base = buf;
|
||||
iov.iov_len = 1;
|
||||
|
||||
memset(&msg, 0, sizeof msg);
|
||||
msg.msg_iov = &iov;
|
||||
msg.msg_iovlen = 1;
|
||||
|
||||
sfd.cmsg.cmsg_len = sizeof sfd;
|
||||
sfd.cmsg.cmsg_level = SOL_SOCKET;
|
||||
sfd.cmsg.cmsg_type = SCM_RIGHTS;
|
||||
sfd.fd = fd;
|
||||
|
||||
msg.msg_control = &sfd;
|
||||
msg.msg_controllen = sizeof sfd;
|
||||
|
||||
if((n=sendmsg(s, &msg, 0)) != iov.iov_len)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
recvfd(int s)
|
||||
{
|
||||
int n;
|
||||
char buf[1];
|
||||
struct iovec iov;
|
||||
struct msghdr msg;
|
||||
Sendfd sfd;
|
||||
|
||||
iov.iov_base = buf;
|
||||
iov.iov_len = 1;
|
||||
|
||||
memset(&msg, 0, sizeof msg);
|
||||
msg.msg_name = 0;
|
||||
msg.msg_namelen = 0;
|
||||
msg.msg_iov = &iov;
|
||||
msg.msg_iovlen = 1;
|
||||
|
||||
memset(&sfd, 0, sizeof sfd);
|
||||
sfd.fd = -1;
|
||||
sfd.cmsg.cmsg_len = sizeof sfd;
|
||||
sfd.cmsg.cmsg_level = SOL_SOCKET;
|
||||
sfd.cmsg.cmsg_type = SCM_RIGHTS;
|
||||
|
||||
msg.msg_control = &sfd;
|
||||
msg.msg_controllen = sizeof sfd;
|
||||
|
||||
if((n=recvmsg(s, &msg, 0)) < 0)
|
||||
return -1;
|
||||
if(n==0 && sfd.fd==-1){
|
||||
werrstr("eof in recvfd");
|
||||
return -1;
|
||||
}
|
||||
return sfd.fd;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue