devdup.c - vx32 - Local 9vx git repository for patches.
 (HTM) git clone git://r-36.net/vx32
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       devdup.c (2332B)
       ---
            1 #include        "u.h"
            2 #include        "lib.h"
            3 #include        "mem.h"
            4 #include        "dat.h"
            5 #include        "fns.h"
            6 #include        "error.h"
            7 
            8 /* Qid is (2*fd + (file is ctl))+1 */
            9 
           10 static int
           11 dupgen(Chan *c, char *name, Dirtab *dt, int ndt, int s, Dir *dp)
           12 {
           13         Fgrp *fgrp = up->fgrp;
           14         Chan *f;
           15         static int perm[] = { 0400, 0200, 0600, 0 };
           16         int p;
           17         Qid q;
           18 
           19         if(s == DEVDOTDOT){
           20                 devdir(c, c->qid, ".", 0, eve, DMDIR|0555, dp);
           21                 return 1;
           22         }
           23         if(s == 0)
           24                 return 0;
           25         s--;
           26         if(s/2 > fgrp->maxfd)
           27                 return -1;
           28         if((f=fgrp->fd[s/2]) == nil)
           29                 return 0;
           30         if(s & 1){
           31                 p = 0400;
           32                 sprint(up->genbuf, "%dctl", s/2);
           33         }else{
           34                 p = perm[f->mode&3];
           35                 sprint(up->genbuf, "%d", s/2);
           36         }
           37         mkqid(&q, s+1, 0, QTFILE);
           38         devdir(c, q, up->genbuf, 0, eve, p, dp);
           39         return 1;
           40 }
           41 
           42 static Chan*
           43 dupattach(char *spec)
           44 {
           45         return devattach('d', spec);
           46 }
           47 
           48 static Walkqid*
           49 dupwalk(Chan *c, Chan *nc, char **name, int nname)
           50 {
           51         return devwalk(c, nc, name, nname, (Dirtab *)0, 0, dupgen);
           52 }
           53 
           54 static int
           55 dupstat(Chan *c, uchar *db, int n)
           56 {
           57         return devstat(c, db, n, (Dirtab *)0, 0L, dupgen);
           58 }
           59 
           60 static Chan*
           61 dupopen(Chan *c, int omode)
           62 {
           63         Chan *f;
           64         int fd, twicefd;
           65 
           66         if(c->qid.type & QTDIR){
           67                 if(omode != 0)
           68                         error(Eisdir);
           69                 c->mode = 0;
           70                 c->flag |= COPEN;
           71                 c->offset = 0;
           72                 return c;
           73         }
           74         if(c->qid.type & QTAUTH)
           75                 error(Eperm);
           76         twicefd = c->qid.path - 1;
           77         fd = twicefd/2;
           78         if((twicefd & 1)){
           79                 /* ctl file */
           80                 f = c;
           81                 f->mode = openmode(omode);
           82                 f->flag |= COPEN;
           83                 f->offset = 0;
           84         }else{
           85                 /* fd file */
           86                 f = fdtochan(fd, openmode(omode), 0, 1);
           87                 cclose(c);
           88         }
           89         if(omode & OCEXEC)
           90                 f->flag |= CCEXEC;
           91         return f;
           92 }
           93 
           94 static void
           95 dupclose(Chan *c)
           96 {
           97 }
           98 
           99 static long
          100 dupread(Chan *c, void *va, long n, vlong offset)
          101 {
          102         char *a = va;
          103         char buf[256];
          104         int fd, twicefd;
          105 
          106         if(c->qid.type == QTDIR)
          107                 return devdirread(c, a, n, (Dirtab *)0, 0L, dupgen);
          108         twicefd = c->qid.path - 1;
          109         fd = twicefd/2;
          110         if(twicefd & 1){
          111                 c = fdtochan(fd, -1, 0, 1);
          112                 procfdprint(c, fd, 0, buf, sizeof buf);
          113                 cclose(c);
          114                 return readstr((ulong)offset, va, n, buf);
          115         }
          116         panic("dupread");
          117         return 0;
          118 }
          119 
          120 static long
          121 dupwrite(Chan *c, void *v, long n, vlong o)
          122 {
          123         error(Eperm);
          124         return 0;                /* not reached */
          125 }
          126 
          127 Dev dupdevtab = {
          128         'd',
          129         "dup",
          130 
          131         devreset,
          132         devinit,
          133         devshutdown,
          134         dupattach,
          135         dupwalk,
          136         dupstat,
          137         dupopen,
          138         devcreate,
          139         dupclose,
          140         dupread,
          141         devbread,
          142         dupwrite,
          143         devbwrite,
          144         devremove,
          145         devwstat,
          146 };