add linux_emul base, reorganize docs
[openbsd_emul.git] / linux_emul_base / miscdev.c
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 }