nusb/ptp: fix memory leaks, use libthread/ioprocs, cleanup
This commit is contained in:
parent
c360ea5511
commit
68576f5119
2 changed files with 229 additions and 202 deletions
|
@ -5,7 +5,7 @@ LIB=../lib/usb.a$O
|
||||||
|
|
||||||
TARG=ptp
|
TARG=ptp
|
||||||
HFILES=
|
HFILES=
|
||||||
OFILES=usbptp.$O
|
OFILES=ptp.$O
|
||||||
|
|
||||||
</sys/src/cmd/mkone
|
</sys/src/cmd/mkone
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,9 @@ enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct Ptprpc Ptprpc;
|
typedef struct Ptprpc Ptprpc;
|
||||||
|
typedef struct Node Node;
|
||||||
|
typedef struct Ioflush Ioflush;
|
||||||
|
|
||||||
struct Ptprpc
|
struct Ptprpc
|
||||||
{
|
{
|
||||||
uchar length[4];
|
uchar length[4];
|
||||||
|
@ -47,7 +50,6 @@ struct Ptprpc
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct Node Node;
|
|
||||||
struct Node
|
struct Node
|
||||||
{
|
{
|
||||||
Dir d;
|
Dir d;
|
||||||
|
@ -64,14 +66,21 @@ struct Node
|
||||||
int ndata;
|
int ndata;
|
||||||
};
|
};
|
||||||
|
|
||||||
int debug;
|
struct Ioflush
|
||||||
|
{
|
||||||
|
Channel *c;
|
||||||
|
Ioproc *io;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
In,
|
In,
|
||||||
Out,
|
Out,
|
||||||
};
|
};
|
||||||
|
|
||||||
static Dev *usbep[2];
|
static Dev *usbep[2];
|
||||||
|
|
||||||
|
static int debug;
|
||||||
static ulong time0;
|
static ulong time0;
|
||||||
static int maxpacket = 64;
|
static int maxpacket = 64;
|
||||||
static int sessionId = 0;
|
static int sessionId = 0;
|
||||||
|
@ -80,7 +89,10 @@ static int transId = 0;
|
||||||
static Node **nodes;
|
static Node **nodes;
|
||||||
static int nnodes;
|
static int nnodes;
|
||||||
|
|
||||||
static char *uname;
|
static Channel *iochan;
|
||||||
|
|
||||||
|
char Eperm[] = "permission denied";
|
||||||
|
char Einterrupt[] = "interrupted";
|
||||||
|
|
||||||
#define PATH(type, n) ((uvlong)(type)|((uvlong)(n)<<4))
|
#define PATH(type, n) ((uvlong)(type)|((uvlong)(n)<<4))
|
||||||
#define TYPE(path) ((int)((path)&0xF))
|
#define TYPE(path) ((int)((path)&0xF))
|
||||||
|
@ -117,8 +129,8 @@ wasinterrupt(void)
|
||||||
char err[ERRMAX];
|
char err[ERRMAX];
|
||||||
|
|
||||||
rerrstr(err, sizeof(err));
|
rerrstr(err, sizeof(err));
|
||||||
if(strstr(err, "interrupted") || strstr(err, "request timed out")){
|
if(strstr(err, Einterrupt) || strstr(err, "timed out")){
|
||||||
werrstr("interrupted");
|
werrstr(Einterrupt);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -200,7 +212,7 @@ ptpcheckerr(Ptprpc *rpc, int type, int transid, int length)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
vptprpc(int code, int flags, va_list a)
|
vptprpc(Ioproc *io, int code, int flags, va_list a)
|
||||||
{
|
{
|
||||||
Ptprpc rpc;
|
Ptprpc rpc;
|
||||||
int np, n, t, i, l;
|
int np, n, t, i, l;
|
||||||
|
@ -223,7 +235,7 @@ vptprpc(int code, int flags, va_list a)
|
||||||
hexdump("req>", (uchar*)&rpc, n);
|
hexdump("req>", (uchar*)&rpc, n);
|
||||||
|
|
||||||
werrstr("");
|
werrstr("");
|
||||||
if(write(usbep[Out]->dfd, &rpc, n) != n){
|
if(iowrite(io, usbep[Out]->dfd, &rpc, n) != n){
|
||||||
wasinterrupt();
|
wasinterrupt();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -251,14 +263,14 @@ vptprpc(int code, int flags, va_list a)
|
||||||
|
|
||||||
if(debug)
|
if(debug)
|
||||||
hexdump("data>", (uchar*)&rpc, n);
|
hexdump("data>", (uchar*)&rpc, n);
|
||||||
if(write(usbep[Out]->dfd, &rpc, n) != n){
|
if(iowrite(io, usbep[Out]->dfd, &rpc, n) != n){
|
||||||
wasinterrupt();
|
wasinterrupt();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
while(p < e){
|
while(p < e){
|
||||||
if((n = write(usbep[Out]->dfd, p, e-p)) < 0){
|
if((n = iowrite(io, usbep[Out]->dfd, p, e-p)) < 0){
|
||||||
wasinterrupt();
|
if(!wasinterrupt())
|
||||||
break;
|
return -1;
|
||||||
}
|
}
|
||||||
p += n;
|
p += n;
|
||||||
}
|
}
|
||||||
|
@ -275,11 +287,11 @@ vptprpc(int code, int flags, va_list a)
|
||||||
*prdatalen = 0;
|
*prdatalen = 0;
|
||||||
|
|
||||||
do{
|
do{
|
||||||
if((n = read(usbep[In]->dfd, &rpc, sizeof(rpc))) < 0){
|
if((n = ioread(io, usbep[In]->dfd, &rpc, sizeof(rpc))) < 0){
|
||||||
wasinterrupt();
|
wasinterrupt();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(debug > 1)
|
if(debug)
|
||||||
hexdump("data<", (uchar*)&rpc, n);
|
hexdump("data<", (uchar*)&rpc, n);
|
||||||
if((l = ptpcheckerr(&rpc, 2, t, n)) < 0)
|
if((l = ptpcheckerr(&rpc, 2, t, n)) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -301,7 +313,7 @@ vptprpc(int code, int flags, va_list a)
|
||||||
p += n;
|
p += n;
|
||||||
|
|
||||||
while(p < e){
|
while(p < e){
|
||||||
if((n = read(usbep[In]->dfd, p, e-p)) < 0){
|
if((n = ioread(io, usbep[In]->dfd, p, e-p)) < 0){
|
||||||
wasinterrupt();
|
wasinterrupt();
|
||||||
free(b);
|
free(b);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -313,11 +325,11 @@ vptprpc(int code, int flags, va_list a)
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if((n = read(usbep[In]->dfd, &rpc, sizeof(rpc))) < 0){
|
if((n = ioread(io, usbep[In]->dfd, &rpc, sizeof(rpc))) < 0){
|
||||||
wasinterrupt();
|
wasinterrupt();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(debug > 1)
|
if(debug)
|
||||||
hexdump("resp<", (uchar*)&rpc, n);
|
hexdump("resp<", (uchar*)&rpc, n);
|
||||||
if((l = ptpcheckerr(&rpc, 3, t, n)) < 0)
|
if((l = ptpcheckerr(&rpc, 3, t, n)) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -335,30 +347,60 @@ vptprpc(int code, int flags, va_list a)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ioflusher(void *aux)
|
||||||
|
{
|
||||||
|
Ioflush f = *((Ioflush*)aux);
|
||||||
|
while(recvp(f.c))
|
||||||
|
iointerrupt(f.io);
|
||||||
|
chanfree(f.c);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ptprpc(Req *r, int code, int flags, ...)
|
ptprpc(Req *r, int code, int flags, ...)
|
||||||
{
|
{
|
||||||
static long ptpsem = 1;
|
va_list va;
|
||||||
va_list a;
|
Ioflush f;
|
||||||
|
Alt a[3];
|
||||||
|
char *m;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if(r != nil){
|
i = -1;
|
||||||
r->aux = (void*)getpid();
|
f.c = nil;
|
||||||
|
f.io = nil;
|
||||||
|
m = Einterrupt;
|
||||||
|
a[0].op = CHANRCV;
|
||||||
|
a[0].c = iochan;
|
||||||
|
a[0].v = &f.io;
|
||||||
|
if(r){
|
||||||
|
f.c = chancreate(sizeof(char*), 0);
|
||||||
|
a[1].op = CHANRCV;
|
||||||
|
a[1].c = f.c;
|
||||||
|
a[1].v = &m;
|
||||||
|
a[2].op = CHANEND;
|
||||||
|
r->aux = f.c;
|
||||||
srvrelease(r->srv);
|
srvrelease(r->srv);
|
||||||
}
|
} else
|
||||||
i = semacquire(&ptpsem, 1);
|
a[1].op = CHANEND;
|
||||||
if(i == 1){
|
if(alt(a) == 0){
|
||||||
va_start(a, flags);
|
ioflush(f.io);
|
||||||
i = vptprpc(code, flags, a);
|
if(f.c)
|
||||||
va_end(a);
|
threadcreate(ioflusher, &f, 4*1024);
|
||||||
semrelease(&ptpsem, 1);
|
va_start(va, flags);
|
||||||
}
|
i = vptprpc(f.io, code, flags, va);
|
||||||
if(i < 0 && debug)
|
va_end(va);
|
||||||
fprint(2, "ptprpc: req=%p %r\n", r);
|
} else
|
||||||
if(r != nil){
|
werrstr("%s", m);
|
||||||
|
if(r){
|
||||||
srvacquire(r->srv);
|
srvacquire(r->srv);
|
||||||
r->aux = (void*)-1;
|
r->aux = nil;
|
||||||
}
|
}
|
||||||
|
if(f.io){
|
||||||
|
if(f.c)
|
||||||
|
sendp(f.c, nil);
|
||||||
|
sendp(iochan, f.io);
|
||||||
|
} else if(f.c)
|
||||||
|
chanfree(f.c);
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -433,31 +475,42 @@ copydir(Dir *d, Dir *s)
|
||||||
}
|
}
|
||||||
|
|
||||||
static Node*
|
static Node*
|
||||||
getnode(uvlong path, Req *r)
|
cachednode(uvlong path, Node ***pf)
|
||||||
{
|
{
|
||||||
int i, j;
|
|
||||||
Node *x;
|
Node *x;
|
||||||
uchar *p;
|
int i;
|
||||||
int np;
|
|
||||||
char *s;
|
|
||||||
|
|
||||||
j = -1;
|
if(pf)
|
||||||
|
*pf = nil;
|
||||||
for(i=0; i<nnodes; i++){
|
for(i=0; i<nnodes; i++){
|
||||||
if((x = nodes[i]) == nil){
|
if((x = nodes[i]) == nil){
|
||||||
j = i;
|
if(pf)
|
||||||
|
*pf = &nodes[i];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(x->d.qid.path == path)
|
if(x->d.qid.path == path)
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Node*
|
||||||
|
getnode(Req *r, uvlong path)
|
||||||
|
{
|
||||||
|
Node *x, *y, **f;
|
||||||
|
uchar *p;
|
||||||
|
int np;
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
if(x = cachednode(path, &f))
|
||||||
|
return x;
|
||||||
|
|
||||||
|
y = nil;
|
||||||
x = emalloc9p(sizeof(*x));
|
x = emalloc9p(sizeof(*x));
|
||||||
|
|
||||||
memset(x, 0, sizeof(*x));
|
memset(x, 0, sizeof(*x));
|
||||||
|
|
||||||
x->d.qid.path = path;
|
x->d.qid.path = path;
|
||||||
x->d.uid = estrdup9p(uname);
|
x->d.uid = estrdup9p("ptp");
|
||||||
x->d.gid = estrdup9p(uname);
|
x->d.gid = estrdup9p("usb");
|
||||||
x->d.atime = x->d.mtime = time0;
|
x->d.atime = x->d.mtime = time0;
|
||||||
|
|
||||||
p = nil;
|
p = nil;
|
||||||
|
@ -467,7 +520,7 @@ getnode(uvlong path, Req *r)
|
||||||
x->d.qid.type = QTDIR;
|
x->d.qid.type = QTDIR;
|
||||||
x->d.mode = DMDIR|0777;
|
x->d.mode = DMDIR|0777;
|
||||||
x->d.name = estrdup9p("/");
|
x->d.name = estrdup9p("/");
|
||||||
break;
|
goto Addnode;
|
||||||
|
|
||||||
case Qstore:
|
case Qstore:
|
||||||
x->store = NUM(path);
|
x->store = NUM(path);
|
||||||
|
@ -476,36 +529,29 @@ getnode(uvlong path, Req *r)
|
||||||
x->d.mode = DMDIR|0777;
|
x->d.mode = DMDIR|0777;
|
||||||
x->d.name = emalloc9p(10);
|
x->d.name = emalloc9p(10);
|
||||||
sprint(x->d.name, "%x", x->store);
|
sprint(x->d.name, "%x", x->store);
|
||||||
break;
|
goto Addnode;
|
||||||
|
|
||||||
case Qobj:
|
case Qobj:
|
||||||
case Qthumb:
|
case Qthumb:
|
||||||
if(ptprpc(r, GetObjectInfo, 1|DataRecv, NUM(path), &p, &np) < 0)
|
if(ptprpc(r, GetObjectInfo, 1|DataRecv, NUM(path), &p, &np) < 0)
|
||||||
goto err;
|
break;
|
||||||
if(debug > 1)
|
if(debug)
|
||||||
hexdump("objectinfo", p, np);
|
hexdump("objectinfo", p, np);
|
||||||
if(np < 52){
|
if(np < 52){
|
||||||
werrstr("bad objectinfo");
|
werrstr("bad objectinfo");
|
||||||
goto err;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
j = -1;
|
/*
|
||||||
for(i=0; i<nnodes; i++){
|
* another proc migh'v come in and done it for us,
|
||||||
if(nodes[i] == nil){
|
* so check the cache again.
|
||||||
j = i;
|
*/
|
||||||
continue;
|
if(y = cachednode(path, &f))
|
||||||
}
|
break;
|
||||||
if(nodes[i]->d.qid.path == path){
|
|
||||||
/* never mind */
|
|
||||||
cleardir(&x->d);
|
|
||||||
free(x);
|
|
||||||
return nodes[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if((x->d.name = ptpstring2(p+52, p+np)) == nil){
|
if((x->d.name = ptpstring2(p+52, p+np)) == nil){
|
||||||
werrstr("bad objectinfo");
|
werrstr("bad objectinfo");
|
||||||
goto err;
|
break;
|
||||||
}
|
}
|
||||||
x->handle = NUM(path);
|
x->handle = NUM(path);
|
||||||
x->store = GET4(p);
|
x->store = GET4(p);
|
||||||
|
@ -554,22 +600,19 @@ getnode(uvlong path, Req *r)
|
||||||
free(s);
|
free(s);
|
||||||
}
|
}
|
||||||
free(p);
|
free(p);
|
||||||
break;
|
Addnode:
|
||||||
}
|
if(f == nil){
|
||||||
|
|
||||||
if(j < 0){
|
|
||||||
if(nnodes % 64 == 0)
|
if(nnodes % 64 == 0)
|
||||||
nodes = erealloc9p(nodes, sizeof(nodes[0]) * (nnodes + 64));
|
nodes = erealloc9p(nodes, sizeof(nodes[0]) * (nnodes + 64));
|
||||||
j = nnodes++;
|
f = &nodes[nnodes++];
|
||||||
|
}
|
||||||
|
return *f = x;
|
||||||
}
|
}
|
||||||
return nodes[j] = x;
|
|
||||||
|
|
||||||
err:
|
|
||||||
cleardir(&x->d);
|
cleardir(&x->d);
|
||||||
free(x);
|
free(x);
|
||||||
free(p);
|
free(p);
|
||||||
|
return y;
|
||||||
return nil;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -590,14 +633,15 @@ freenode(Node *nod)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
readchilds(Node *nod, Req *r)
|
readchilds(Req *r, Node *nod)
|
||||||
{
|
{
|
||||||
int i;
|
int e, i;
|
||||||
int *a;
|
int *a;
|
||||||
uchar *p;
|
uchar *p;
|
||||||
int np;
|
int np;
|
||||||
Node *x, **xx;
|
Node *x, **xx;
|
||||||
|
|
||||||
|
e = 0;
|
||||||
switch(TYPE(nod->d.qid.path)){
|
switch(TYPE(nod->d.qid.path)){
|
||||||
case Qroot:
|
case Qroot:
|
||||||
if(ptprpc(r, GetStorageIds, 0|DataRecv, &p, &np) < 0)
|
if(ptprpc(r, GetStorageIds, 0|DataRecv, &p, &np) < 0)
|
||||||
|
@ -605,14 +649,17 @@ readchilds(Node *nod, Req *r)
|
||||||
a = ptparray4(p, p+np);
|
a = ptparray4(p, p+np);
|
||||||
free(p);
|
free(p);
|
||||||
xx = &nod->child;
|
xx = &nod->child;
|
||||||
|
*xx = nil;
|
||||||
for(i=0; a && i<a[0]; i++){
|
for(i=0; a && i<a[0]; i++){
|
||||||
if(x = getnode(PATH(Qstore, a[i+1]), r)){
|
if((x = getnode(r, PATH(Qstore, a[i+1]))) == nil){
|
||||||
|
e = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
x->parent = nod;
|
x->parent = nod;
|
||||||
*xx = x;
|
*xx = x;
|
||||||
xx = &x->next;
|
xx = &x->next;
|
||||||
}
|
|
||||||
}
|
|
||||||
*xx = nil;
|
*xx = nil;
|
||||||
|
}
|
||||||
free(a);
|
free(a);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -623,28 +670,34 @@ readchilds(Node *nod, Req *r)
|
||||||
a = ptparray4(p, p+np);
|
a = ptparray4(p, p+np);
|
||||||
free(p);
|
free(p);
|
||||||
xx = &nod->child;
|
xx = &nod->child;
|
||||||
|
*xx = nil;
|
||||||
for(i=0; a && i<a[0]; i++){
|
for(i=0; a && i<a[0]; i++){
|
||||||
if(x = getnode(PATH(Qobj, a[i+1]), r)){
|
if((x = getnode(r, PATH(Qobj, a[i+1]))) == nil){
|
||||||
|
e = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
x->parent = nod;
|
x->parent = nod;
|
||||||
*xx = x;
|
*xx = x;
|
||||||
xx = &x->next;
|
xx = &x->next;
|
||||||
|
*xx = nil;
|
||||||
|
|
||||||
/* skip thumb when not image format */
|
/* skip thumb when not image format */
|
||||||
if((x->format & 0xFF00) != 0x3800)
|
if((x->format & 0xFF00) != 0x3800)
|
||||||
continue;
|
continue;
|
||||||
|
if((x = getnode(r, PATH(Qthumb, a[i+1]))) == nil){
|
||||||
|
e = -1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if(x = getnode(PATH(Qthumb, a[i+1]), r)){
|
|
||||||
x->parent = nod;
|
x->parent = nod;
|
||||||
*xx = x;
|
*xx = x;
|
||||||
xx = &x->next;
|
xx = &x->next;
|
||||||
}
|
|
||||||
}
|
|
||||||
*xx = nil;
|
*xx = nil;
|
||||||
|
}
|
||||||
free(a);
|
free(a);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -654,8 +707,6 @@ fsattach(Req *r)
|
||||||
respond(r, "invalid attach specifier");
|
respond(r, "invalid attach specifier");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(uname == nil)
|
|
||||||
uname = estrdup9p(r->ifcall.uname);
|
|
||||||
r->fid->qid.path = PATH(Qroot, 0);
|
r->fid->qid.path = PATH(Qroot, 0);
|
||||||
r->fid->qid.type = QTDIR;
|
r->fid->qid.type = QTDIR;
|
||||||
r->fid->qid.vers = 0;
|
r->fid->qid.vers = 0;
|
||||||
|
@ -668,7 +719,7 @@ fsstat(Req *r)
|
||||||
{
|
{
|
||||||
Node *nod;
|
Node *nod;
|
||||||
|
|
||||||
if((nod = getnode(r->fid->qid.path, r)) == nil){
|
if((nod = getnode(r, r->fid->qid.path)) == nil){
|
||||||
responderror(r);
|
responderror(r);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -702,17 +753,13 @@ fswalk1(Req *r, char *name, Qid *qid)
|
||||||
path = fid->qid.path;
|
path = fid->qid.path;
|
||||||
if(!(fid->qid.type&QTDIR))
|
if(!(fid->qid.type&QTDIR))
|
||||||
return "walk in non-directory";
|
return "walk in non-directory";
|
||||||
|
if(nod = getnode(r, path)){
|
||||||
if((nod = getnode(path, r)) == nil)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
if(strcmp(name, "..") == 0){
|
if(strcmp(name, "..") == 0){
|
||||||
if(nod = nod->parent)
|
if(nod = nod->parent)
|
||||||
*qid = nod->d.qid;
|
*qid = nod->d.qid;
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
if(readchilds(nod, r) < 0)
|
if(readchilds(r, nod) == 0){
|
||||||
goto err;
|
|
||||||
for(nod=nod->child; nod; nod=nod->next){
|
for(nod=nod->child; nod; nod=nod->next){
|
||||||
if(strcmp(nod->d.name, name) == 0){
|
if(strcmp(nod->d.name, name) == 0){
|
||||||
*qid = nod->d.qid;
|
*qid = nod->d.qid;
|
||||||
|
@ -720,8 +767,8 @@ fswalk1(Req *r, char *name, Qid *qid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "directory entry not found";
|
return "directory entry not found";
|
||||||
|
}
|
||||||
err:
|
}
|
||||||
rerrstr(buf, sizeof(buf));
|
rerrstr(buf, sizeof(buf));
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
@ -764,32 +811,24 @@ fsread(Req *r)
|
||||||
np = 0;
|
np = 0;
|
||||||
p = nil;
|
p = nil;
|
||||||
path = r->fid->qid.path;
|
path = r->fid->qid.path;
|
||||||
if((nod = getnode(path, r)) == nil)
|
if(nod = getnode(r, path)){
|
||||||
goto err;
|
switch(TYPE(path)){
|
||||||
|
case Qroot:
|
||||||
|
case Qstore:
|
||||||
|
case Qobj:
|
||||||
if(nod->d.qid.type & QTDIR){
|
if(nod->d.qid.type & QTDIR){
|
||||||
if(readchilds(nod, r) < 0)
|
if(readchilds(r, nod) < 0)
|
||||||
goto err;
|
break;
|
||||||
dirread9p(r, nodegen, nod);
|
dirread9p(r, nodegen, nod);
|
||||||
respond(r, nil);
|
respond(r, nil);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
/* no break */
|
||||||
switch(TYPE(path)){
|
|
||||||
default:
|
|
||||||
werrstr("bug in fsread path=%llux", path);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Qobj:
|
|
||||||
case Qthumb:
|
case Qthumb:
|
||||||
if(nod->data == nil){
|
if(nod->data == nil){
|
||||||
if(TYPE(path)==Qthumb){
|
if(ptprpc(r, TYPE(path)==Qthumb ? GetThumb : GetObject,
|
||||||
if(ptprpc(r, GetThumb, 1|DataRecv, nod->handle, &p, &np) < 0)
|
1|DataRecv, nod->handle, &p, &np) < 0)
|
||||||
goto err;
|
break;
|
||||||
} else {
|
|
||||||
if(ptprpc(r, GetObject, 1|DataRecv, nod->handle, &p, &np) < 0)
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
nod->data = p;
|
nod->data = p;
|
||||||
nod->ndata = np;
|
nod->ndata = np;
|
||||||
}
|
}
|
||||||
|
@ -797,7 +836,7 @@ fsread(Req *r)
|
||||||
respond(r, nil);
|
respond(r, nil);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
err:
|
}
|
||||||
free(p);
|
free(p);
|
||||||
responderror(r);
|
responderror(r);
|
||||||
}
|
}
|
||||||
|
@ -809,22 +848,22 @@ fsremove(Req *r)
|
||||||
uvlong path;
|
uvlong path;
|
||||||
|
|
||||||
path = r->fid->qid.path;
|
path = r->fid->qid.path;
|
||||||
if((nod = getnode(path, r)) == nil)
|
if(nod = getnode(r, path)){
|
||||||
goto err;
|
|
||||||
|
|
||||||
switch(TYPE(path)){
|
switch(TYPE(path)){
|
||||||
default:
|
default:
|
||||||
werrstr("bug in fsremove path=%llux", path);
|
werrstr(Eperm);
|
||||||
break;
|
break;
|
||||||
case Qobj:
|
case Qobj:
|
||||||
if(ptprpc(r, DeleteObject, 2, nod->handle, 0) < 0)
|
if(ptprpc(r, DeleteObject, 2, nod->handle, 0) < 0)
|
||||||
goto err;
|
break;
|
||||||
|
/* no break */
|
||||||
case Qthumb:
|
case Qthumb:
|
||||||
|
if(nod = cachednode(path, nil))
|
||||||
freenode(nod);
|
freenode(nod);
|
||||||
respond(r, nil);
|
respond(r, nil);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
err:
|
}
|
||||||
responderror(r);
|
responderror(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -832,7 +871,7 @@ static void
|
||||||
fsopen(Req *r)
|
fsopen(Req *r)
|
||||||
{
|
{
|
||||||
if(r->ifcall.mode != OREAD){
|
if(r->ifcall.mode != OREAD){
|
||||||
respond(r, "permission denied");
|
respond(r, Eperm);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
respond(r, nil);
|
respond(r, nil);
|
||||||
|
@ -841,17 +880,10 @@ fsopen(Req *r)
|
||||||
static void
|
static void
|
||||||
fsflush(Req *r)
|
fsflush(Req *r)
|
||||||
{
|
{
|
||||||
Req *o;
|
Channel *c;
|
||||||
|
|
||||||
if(o = r->oldreq){
|
if(c = r->oldreq->aux)
|
||||||
if(debug)
|
sendp(c, Einterrupt);
|
||||||
fprint(2, "fsflush: req=%p\n", o);
|
|
||||||
int pid = (int)o->aux;
|
|
||||||
if(pid != -1 && pid != 0){
|
|
||||||
o->aux = (void*)-1;
|
|
||||||
postnote(PNPROC, pid, "interrupt");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
respond(r, nil);
|
respond(r, nil);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -865,7 +897,7 @@ fsdestroyfid(Fid *fid)
|
||||||
switch(TYPE(path)){
|
switch(TYPE(path)){
|
||||||
case Qobj:
|
case Qobj:
|
||||||
case Qthumb:
|
case Qthumb:
|
||||||
if(nod = getnode(path, nil)){
|
if(nod = cachednode(path, nil)){
|
||||||
free(nod->data);
|
free(nod->data);
|
||||||
nod->data = nil;
|
nod->data = nil;
|
||||||
nod->ndata = 0;
|
nod->ndata = 0;
|
||||||
|
@ -878,6 +910,7 @@ static void
|
||||||
fsend(Srv *)
|
fsend(Srv *)
|
||||||
{
|
{
|
||||||
ptprpc(nil, CloseSession, 0);
|
ptprpc(nil, CloseSession, 0);
|
||||||
|
closeioproc(recvp(iochan));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -906,39 +939,31 @@ findendpoints(Dev *d, int *epin, int *epout)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
inote(void *, char *msg)
|
|
||||||
{
|
|
||||||
if(strstr(msg, "interrupt"))
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Srv fs =
|
Srv fs =
|
||||||
{
|
{
|
||||||
.attach= fsattach,
|
.attach = fsattach,
|
||||||
.destroyfid= fsdestroyfid,
|
.destroyfid = fsdestroyfid,
|
||||||
.walk= fswalk,
|
.walk = fswalk,
|
||||||
.open= fsopen,
|
.open = fsopen,
|
||||||
.read= fsread,
|
.read = fsread,
|
||||||
.remove= fsremove,
|
.remove = fsremove,
|
||||||
.stat= fsstat,
|
.stat = fsstat,
|
||||||
.flush= fsflush,
|
.flush = fsflush,
|
||||||
.end= fsend,
|
.end = fsend,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
usage(void)
|
usage(void)
|
||||||
{
|
{
|
||||||
fprint(2, "usage: %s [-dD] devid\n", argv0);
|
fprint(2, "usage: %s [-dD] devid\n", argv0);
|
||||||
exits("usage");
|
threadexits("usage");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
main(int argc, char **argv)
|
threadmain(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int epin, epout;
|
|
||||||
char name[64], desc[64];
|
char name[64], desc[64];
|
||||||
|
int epin, epout;
|
||||||
Dev *d;
|
Dev *d;
|
||||||
|
|
||||||
ARGBEGIN {
|
ARGBEGIN {
|
||||||
|
@ -972,16 +997,18 @@ main(int argc, char **argv)
|
||||||
if(usbep[In]->dfd < 0 || usbep[Out]->dfd < 0)
|
if(usbep[In]->dfd < 0 || usbep[Out]->dfd < 0)
|
||||||
sysfatal("open endpoints: %r");
|
sysfatal("open endpoints: %r");
|
||||||
|
|
||||||
|
iochan = chancreate(sizeof(Ioproc*), 1);
|
||||||
|
sendp(iochan, ioproc());
|
||||||
|
|
||||||
sessionId = getpid();
|
sessionId = getpid();
|
||||||
if(ptprpc(nil, OpenSession, 1, sessionId) < 0)
|
if(ptprpc(nil, OpenSession, 1, sessionId) < 0)
|
||||||
return;
|
sysfatal("open session: %r");
|
||||||
|
|
||||||
atnotify(inote, 1);
|
|
||||||
time0 = time(0);
|
time0 = time(0);
|
||||||
|
|
||||||
snprint(name, sizeof name, "sdU%d.0", d->id);
|
snprint(name, sizeof name, "sdU%d.0", d->id);
|
||||||
snprint(desc, sizeof desc, "%d.ptp", d->id);
|
snprint(desc, sizeof desc, "%d.ptp", d->id);
|
||||||
postsharesrv(&fs, nil, name, desc);
|
threadpostsharesrv(&fs, nil, name, desc);
|
||||||
|
|
||||||
exits(0);
|
threadexits(0);
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue