Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
/* Qid is (2*fd + (file is ctl))+1 */
9
 
10
static int
11
dupgen(Chan *c, char *, Dirtab*, int, 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
		snprint(up->genbuf, sizeof up->genbuf, "%dctl", s/2);
33
	}else{
34
		p = perm[f->mode&3];
35
		snprint(up->genbuf, sizeof 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*)
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*, void*, long, vlong)
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
};