]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/port/devdup.c
pc kernel: fix wrong simd exception mask (fixes go bootstrap)
[plan9front.git] / sys / src / 9 / port / devdup.c
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                 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         return f;
90 }
91
92 static void
93 dupclose(Chan*)
94 {
95 }
96
97 static long
98 dupread(Chan *c, void *va, long n, vlong offset)
99 {
100         char *a = va;
101         char buf[256];
102         int fd, twicefd;
103
104         if(c->qid.type == QTDIR)
105                 return devdirread(c, a, n, (Dirtab *)0, 0L, dupgen);
106         twicefd = c->qid.path - 1;
107         fd = twicefd/2;
108         if(twicefd & 1){
109                 c = fdtochan(fd, -1, 0, 1);
110                 procfdprint(c, fd, buf, sizeof buf);
111                 cclose(c);
112                 return readstr((ulong)offset, va, n, buf);
113         }
114         panic("dupread");
115         return 0;
116 }
117
118 static long
119 dupwrite(Chan*, void*, long, vlong)
120 {
121         error(Eperm);
122         return 0;               /* not reached */
123 }
124
125 Dev dupdevtab = {
126         'd',
127         "dup",
128
129         devreset,
130         devinit,
131         devshutdown,
132         dupattach,
133         dupwalk,
134         dupstat,
135         dupopen,
136         devcreate,
137         dupclose,
138         dupread,
139         devbread,
140         dupwrite,
141         devbwrite,
142         devremove,
143         devwstat,
144 };