cae36a52 |
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 | } |