1 #include "u.h" 2 #include "../port/lib.h" 3 #include "mem.h" 4 #include "dat.h" 5 #include "fns.h" 6 #include "../port/error.h" 7 8 static int 9 dupgen(Chan *c, Dirtab*, int, int s, Dir *dp) 10 { 11 char buf[8]; 12 Fgrp *fgrp = up->fgrp; 13 Chan *f; 14 static int perm[] = { 0400, 0200, 0600, 0 }; 15 16 if(s == DEVDOTDOT){ 17 devdir(c, c->qid, "#d", 0, eve, 0555, dp); 18 return 1; 19 } 20 if(s > fgrp->maxfd) 21 return -1; 22 if((f=fgrp->fd[s]) == 0) 23 return 0; 24 sprint(buf, "%d", s); 25 devdir(c, (Qid){s, 0}, buf, 0, eve, perm[f->mode&3], dp); 26 return 1; 27 } 28 29 static Chan* 30 dupattach(char *spec) 31 { 32 return devattach('d', spec); 33 } 34 35 static int 36 dupwalk(Chan *c, char *name) 37 { 38 return devwalk(c, name, (Dirtab *)0, 0, dupgen); 39 } 40 41 static void 42 dupstat(Chan *c, char *db) 43 { 44 devstat(c, db, (Dirtab *)0, 0L, dupgen); 45 } 46 47 static Chan* 48 dupopen(Chan *c, int omode) 49 { 50 Chan *f; 51 52 if(c->qid.path == CHDIR){ 53 if(omode != 0) 54 error(Eisdir); 55 c->mode = 0; 56 c->flag |= COPEN; 57 c->offset = 0; 58 return c; 59 } 60 fdtochan(c->qid.path, openmode(omode), 0, 0); /* error check only */ 61 f = up->fgrp->fd[c->qid.path]; 62 cclose(c); 63 incref(f); 64 if(omode & OCEXEC) 65 f->flag |= CCEXEC; 66 return f; 67 } 68 69 static void 70 dupclose(Chan*) 71 { 72 } 73 74 static long 75 dupread(Chan *c, void *va, long n, vlong) 76 { 77 char *a = va; 78 79 if(c->qid.path != CHDIR) 80 panic("dupread"); 81 return devdirread(c, a, n, (Dirtab *)0, 0L, dupgen); 82 } 83 84 static long 85 dupwrite(Chan*, void*, long, vlong) 86 { 87 panic("dupwrite"); 88 return 0; /* not reached */ 89 } 90 91 Dev dupdevtab = { 92 'd', 93 "dup", 94 95 devreset, 96 devinit, 97 dupattach, 98 devclone, 99 dupwalk, 100 dupstat, 101 dupopen, 102 devcreate, 103 dupclose, 104 dupread, 105 devbread, 106 dupwrite, 107 devbwrite, 108 devremove, 109 devwstat, 110 }; 111