vx32

Local 9vx git repository for patches.
git clone git://r-36.net/vx32
Log | Files | 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 };