add linux_emul base, reorganize docs
[openbsd_emul.git] / linux_emul_base / miscdev.c
CommitLineData
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
11enum
12{
13 Mnull,
14 Mzero,
15 Mfull,
16 Mrandom,
17 Murandom,
18 Mmax,
19};
20
21typedef struct Miscfile Miscfile;
22struct Miscfile
23{
24 Ufile;
25 int m;
26};
27
28static int
29path2m(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
49static int
50openmisc(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
68static int
69closemisc(Ufile *)
70{
71 return 0;
72}
73
74static int
75readmisc(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
96static int
97writemisc(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
112static int
113statmisc(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
129static int
130fstatmisc(Ufile *f, Ustat *s)
131{
132 return fsstat(f->path, 0, s);
133};
134
135static Udev miscdev =
136{
137 .open = openmisc,
138 .read = readmisc,
139 .write = writemisc,
140 .close = closemisc,
141 .stat = statmisc,
142 .fstat = fstatmisc,
143};
144
145void 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}