cae36a52 |
1 | #include <u.h> |
2 | #include <libc.h> |
3 | #include <ureg.h> |
4 | #include <mp.h> |
5 | #include <libsec.h> |
6 | |
7 | #include "dat.h" |
8 | #include "fns.h" |
9 | #include "linux.h" |
10 | |
11 | enum |
12 | { |
13 | Mnull, |
14 | Mzero, |
15 | Mfull, |
16 | Mrandom, |
17 | Murandom, |
18 | Mmax, |
19 | }; |
20 | |
21 | typedef struct Miscfile Miscfile; |
22 | struct Miscfile |
23 | { |
24 | Ufile; |
25 | int m; |
26 | }; |
27 | |
28 | static int |
29 | path2m(char *path) |
30 | { |
31 | int m; |
32 | |
33 | m = -1; |
34 | if(strcmp(path, "/dev/null")==0){ |
35 | m = Mnull; |
36 | } else if(strcmp(path, "/dev/zero")==0){ |
37 | m = Mzero; |
38 | } else if(strcmp(path, "/dev/full")==0){ |
39 | m = Mfull; |
40 | } else if(strcmp(path, "/dev/random")==0){ |
41 | m = Mrandom; |
42 | } else if(strcmp(path, "/dev/urandom")==0){ |
43 | m = Murandom; |
44 | } |
45 | |
46 | return m; |
47 | } |
48 | |
49 | static int |
50 | openmisc(char *path, int mode, int, Ufile **pf) |
51 | { |
52 | Miscfile *f; |
53 | int m; |
54 | |
55 | if((m = path2m(path)) < 0) |
56 | return -ENOENT; |
57 | f = kmallocz(sizeof(*f), 1); |
58 | f->ref = 1; |
59 | f->mode = mode; |
60 | f->path = kstrdup(path); |
61 | f->fd = -1; |
62 | f->dev = MISCDEV; |
63 | f->m = m; |
64 | *pf = f; |
65 | return 0; |
66 | } |
67 | |
68 | static int |
69 | closemisc(Ufile *) |
70 | { |
71 | return 0; |
72 | } |
73 | |
74 | static int |
75 | readmisc(Ufile *f, void *buf, int len, vlong) |
76 | { |
77 | switch(((Miscfile*)f)->m){ |
78 | case Mnull: |
79 | return 0; |
80 | case Mzero: |
81 | memset(buf, 0, len); |
82 | return len; |
83 | case Mfull: |
84 | return -EIO; |
85 | case Mrandom: |
86 | genrandom(buf, len); |
87 | return len; |
88 | case Murandom: |
89 | prng(buf, len); |
90 | return len; |
91 | default: |
92 | return -EIO; |
93 | } |
94 | } |
95 | |
96 | static int |
97 | writemisc(Ufile *f, void *, int len, vlong) |
98 | { |
99 | switch(((Miscfile*)f)->m){ |
100 | case Mnull: |
101 | case Mzero: |
102 | case Mrandom: |
103 | case Murandom: |
104 | return len; |
105 | case Mfull: |
106 | return -ENOSPC; |
107 | default: |
108 | return -EIO; |
109 | } |
110 | } |
111 | |
112 | static int |
113 | statmisc(char *path, int, Ustat *s) |
114 | { |
115 | if(path2m(path) < 0) |
116 | return -ENOENT; |
117 | |
118 | s->mode = 0666 | S_IFCHR; |
119 | s->uid = current->uid; |
120 | s->gid = current->gid; |
121 | s->size = 0; |
122 | s->ino = hashpath(path); |
123 | s->dev = 0; |
124 | s->rdev = 0; |
125 | s->atime = s->mtime = s->ctime = boottime/1000000000LL; |
126 | return 0; |
127 | } |
128 | |
129 | static int |
130 | fstatmisc(Ufile *f, Ustat *s) |
131 | { |
132 | return fsstat(f->path, 0, s); |
133 | }; |
134 | |
135 | static Udev miscdev = |
136 | { |
137 | .open = openmisc, |
138 | .read = readmisc, |
139 | .write = writemisc, |
140 | .close = closemisc, |
141 | .stat = statmisc, |
142 | .fstat = fstatmisc, |
143 | }; |
144 | |
145 | void miscdevinit(void) |
146 | { |
147 | devtab[MISCDEV] = &miscdev; |
148 | |
149 | fsmount(&miscdev, "/dev/null"); |
150 | fsmount(&miscdev, "/dev/zero"); |
151 | fsmount(&miscdev, "/dev/full"); |
152 | fsmount(&miscdev, "/dev/random"); |
153 | fsmount(&miscdev, "/dev/urandom"); |
154 | |
155 | srand(truerand()); |
156 | } |