add linux_emul base, reorganize docs
[openbsd_emul.git] / linux_emul_base / consdev.c
1 #include <u.h>
2 #include <libc.h>
3 #include <ureg.h>
4 #include "dat.h"
5 #include "fns.h"
6 #include "linux.h"
7
8 typedef struct Cons Cons;
9
10 struct Cons
11 {
12 Ufile;
13 void *bufproc;
14 };
15
16 static int
17 closecons(Ufile *file)
18 {
19 Cons *cons = (Cons*)file;
20
21 freebufproc(cons->bufproc);
22
23 return 0;
24 }
25
26 static void*
27 bufproccons(Cons *cons)
28 {
29 if(cons->bufproc == nil)
30 cons->bufproc = newbufproc(0);
31 return cons->bufproc;
32 }
33
34 static int
35 pollcons(Ufile *file, void *tab)
36 {
37 Cons *cons = (Cons*)file;
38 return pollbufproc(bufproccons(cons), cons, tab);
39 }
40
41 static int
42 readcons(Ufile *file, void *buf, int len, vlong)
43 {
44 Cons *cons = (Cons*)file;
45 int ret;
46
47 if((cons->mode & O_NONBLOCK) || (cons->bufproc != nil)){
48 ret = readbufproc(bufproccons(cons), buf, len, 0, (cons->mode & O_NONBLOCK));
49 } else {
50 if(notifyme(1))
51 return -ERESTART;
52 ret = read(0, buf, len);
53 notifyme(0);
54 if(ret < 0)
55 ret = mkerror();
56 }
57 return ret;
58 }
59
60 static int
61 writecons(Ufile *, void *buf, int len, vlong)
62 {
63 int ret;
64
65 if(notifyme(1))
66 return -ERESTART;
67 ret = write(1, buf, len);
68 notifyme(0);
69 if(ret < 0)
70 ret = mkerror();
71 return ret;
72 }
73
74 static int
75 ioctlcons(Ufile *file, int cmd, void *arg)
76 {
77 Cons *cons = (Cons*)file;
78
79 switch(cmd){
80 default:
81 return -ENOTTY;
82
83 case 0x541B:
84 {
85 int r;
86
87 if(arg == nil)
88 return -EINVAL;
89 if((r = nreadablebufproc(bufproccons(cons))) < 0){
90 *((int*)arg) = 0;
91 return r;
92 }
93 *((int*)arg) = r;
94 }
95 return 0;
96 }
97 }
98
99 static int
100 opencons(char *path, int mode, int, Ufile **pf)
101 {
102 Cons *file;
103
104 if(strcmp(path, "/dev/cons")!=0)
105 return -ENOENT;
106
107 file = mallocz(sizeof(Cons), 1);
108 file->ref = 1;
109 file->mode = mode;
110 file->dev = CONSDEV;
111 file->fd = 0;
112 file->path = kstrdup(path);
113 *pf = file;
114
115 return 0;
116 }
117
118 static int
119 statcons(char *path, int, Ustat *s)
120 {
121 if(strcmp(path, "/dev/cons")!=0)
122 return -ENOENT;
123
124 s->mode = 0666 | S_IFCHR;
125 s->uid = current->uid;
126 s->gid = current->gid;
127 s->size = 0;
128 s->ino = hashpath(path);
129 s->dev = 0;
130 s->rdev = 0;
131 return 0;
132 }
133
134 static int
135 fstatcons(Ufile *f, Ustat *s)
136 {
137 return fsstat(f->path, 0, s);
138 };
139
140 static Udev consdev =
141 {
142 .open = opencons,
143 .read = readcons,
144 .write = writecons,
145 .poll = pollcons,
146 .close = closecons,
147 .ioctl = ioctlcons,
148 .fstat = fstatcons,
149 .stat = statcons,
150 };
151
152 void consdevinit(void)
153 {
154 devtab[CONSDEV] = &consdev;
155
156 fsmount(&consdev, "/dev/cons");
157 }