source: mainline/uspace/lib/c/generic/io/con_srv.c@ b7fd2a0

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since b7fd2a0 was b7fd2a0, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

Use errno_t in all uspace and kernel code.

Change type of every variable, parameter and return value that holds an
<errno.h> constant to either errno_t (the usual case), or sys_errno_t
(some places in kernel). This is for the purpose of self-documentation,
as well as for type-checking with a bit of type definition hackery.

Although this is a massive commit, it is a simple text replacement, and thus
is very easy to verify. Simply do the following:

`
git checkout <this commit's hash>
git reset HEAD
git add .
tools/srepl '\berrno_t\b' int
git add .
tools/srepl '\bsys_errno_t\b' sysarg_t
git reset
git diff
`

While this doesn't ensure that the replacements are correct, it does ensure
that the commit doesn't do anything except those replacements. Since errno_t
is typedef'd to int in the usual case (and sys_errno_t to sysarg_t), even if
incorrect, this commit cannot change behavior.

  • Property mode set to 100644
File size: 9.6 KB
Line 
1/*
2 * Copyright (c) 2012 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup libc
30 * @{
31 */
32/**
33 * @file
34 * @brief Console protocol server stub
35 */
36#include <errno.h>
37#include <io/cons_event.h>
38#include <ipc/console.h>
39#include <stdlib.h>
40#include <stddef.h>
41
42#include <io/con_srv.h>
43
44static errno_t console_ev_encode(cons_event_t *event, ipc_call_t *call)
45{
46 IPC_SET_ARG1(*call, event->type);
47
48 switch (event->type) {
49 case CEV_KEY:
50 IPC_SET_ARG2(*call, event->ev.key.type);
51 IPC_SET_ARG3(*call, event->ev.key.key);
52 IPC_SET_ARG4(*call, event->ev.key.mods);
53 IPC_SET_ARG5(*call, event->ev.key.c);
54 break;
55 case CEV_POS:
56 IPC_SET_ARG2(*call, (event->ev.pos.pos_id << 16) | (event->ev.pos.type & 0xffff));
57 IPC_SET_ARG3(*call, event->ev.pos.btn_num);
58 IPC_SET_ARG4(*call, event->ev.pos.hpos);
59 IPC_SET_ARG5(*call, event->ev.pos.vpos);
60 break;
61 default:
62 return EIO;
63 }
64
65 return EOK;
66}
67
68static void con_read_srv(con_srv_t *srv, ipc_callid_t callid,
69 ipc_call_t *call)
70{
71 void *buf;
72 size_t size;
73 errno_t rc;
74 ipc_callid_t rcallid;
75
76 if (!async_data_read_receive(&rcallid, &size)) {
77 async_answer_0(callid, EINVAL);
78 return;
79 }
80
81 buf = malloc(size);
82 if (buf == NULL) {
83 async_answer_0(rcallid, ENOMEM);
84 async_answer_0(callid, ENOMEM);
85 return;
86 }
87
88 if (srv->srvs->ops->read == NULL) {
89 async_answer_0(rcallid, ENOTSUP);
90 async_answer_0(callid, ENOTSUP);
91 free(buf);
92 return;
93 }
94
95 size_t nread;
96 rc = srv->srvs->ops->read(srv, buf, size, &nread);
97 if (rc != EOK) {
98 async_answer_0(rcallid, rc);
99 async_answer_0(callid, rc);
100 free(buf);
101 return;
102 }
103
104 async_data_read_finalize(rcallid, buf, nread);
105 free(buf);
106
107 async_answer_1(callid, EOK, nread);
108}
109
110static void con_write_srv(con_srv_t *srv, ipc_callid_t callid,
111 ipc_call_t *call)
112{
113 void *data;
114 size_t size;
115 errno_t rc;
116
117 rc = async_data_write_accept(&data, false, 0, 0, 0, &size);
118 if (rc != EOK) {
119 async_answer_0(callid, rc);
120 return;
121 }
122
123 if (srv->srvs->ops->write == NULL) {
124 async_answer_0(callid, ENOTSUP);
125 return;
126 }
127
128 size_t nwritten = 0;
129 rc = srv->srvs->ops->write(srv, data, size, &nwritten);
130 free(data);
131
132 async_answer_1(callid, rc, nwritten);
133}
134
135static void con_sync_srv(con_srv_t *srv, ipc_callid_t callid,
136 ipc_call_t *call)
137{
138 if (srv->srvs->ops->sync == NULL) {
139 async_answer_0(callid, ENOTSUP);
140 return;
141 }
142
143 srv->srvs->ops->sync(srv);
144 async_answer_0(callid, EOK);
145}
146
147static void con_clear_srv(con_srv_t *srv, ipc_callid_t callid,
148 ipc_call_t *call)
149{
150 if (srv->srvs->ops->clear == NULL) {
151 async_answer_0(callid, ENOTSUP);
152 return;
153 }
154
155 srv->srvs->ops->clear(srv);
156 async_answer_0(callid, EOK);
157}
158
159static void con_set_pos_srv(con_srv_t *srv, ipc_callid_t callid,
160 ipc_call_t *call)
161{
162 sysarg_t col;
163 sysarg_t row;
164
165 col = IPC_GET_ARG1(*call);
166 row = IPC_GET_ARG2(*call);
167
168 if (srv->srvs->ops->set_pos == NULL) {
169 async_answer_0(callid, ENOTSUP);
170 return;
171 }
172
173 srv->srvs->ops->set_pos(srv, col, row);
174 async_answer_0(callid, EOK);
175}
176
177static void con_get_pos_srv(con_srv_t *srv, ipc_callid_t callid,
178 ipc_call_t *call)
179{
180 errno_t rc;
181 sysarg_t col;
182 sysarg_t row;
183
184 if (srv->srvs->ops->get_pos == NULL) {
185 async_answer_0(callid, ENOTSUP);
186 return;
187 }
188
189 rc = srv->srvs->ops->get_pos(srv, &col, &row);
190 async_answer_2(callid, rc, col, row);
191}
192
193static void con_get_size_srv(con_srv_t *srv, ipc_callid_t callid,
194 ipc_call_t *call)
195{
196 errno_t rc;
197 sysarg_t cols;
198 sysarg_t rows;
199
200 if (srv->srvs->ops->get_size == NULL) {
201 async_answer_0(callid, ENOTSUP);
202 return;
203 }
204
205 rc = srv->srvs->ops->get_size(srv, &cols, &rows);
206 async_answer_2(callid, rc, cols, rows);
207}
208
209static void con_get_color_cap_srv(con_srv_t *srv, ipc_callid_t callid,
210 ipc_call_t *call)
211{
212 errno_t rc;
213 console_caps_t ccap;
214
215 if (srv->srvs->ops->get_color_cap == NULL) {
216 async_answer_0(callid, ENOTSUP);
217 return;
218 }
219
220 rc = srv->srvs->ops->get_color_cap(srv, &ccap);
221 async_answer_1(callid, rc, (sysarg_t)ccap);
222}
223
224static void con_set_style_srv(con_srv_t *srv, ipc_callid_t callid,
225 ipc_call_t *call)
226{
227 console_style_t style;
228
229 style = IPC_GET_ARG1(*call);
230
231 if (srv->srvs->ops->set_style == NULL) {
232 async_answer_0(callid, ENOTSUP);
233 return;
234 }
235
236 srv->srvs->ops->set_style(srv, style);
237 async_answer_0(callid, EOK);
238}
239
240static void con_set_color_srv(con_srv_t *srv, ipc_callid_t callid,
241 ipc_call_t *call)
242{
243 console_color_t bgcolor;
244 console_color_t fgcolor;
245 console_color_attr_t flags;
246
247 bgcolor = IPC_GET_ARG1(*call);
248 fgcolor = IPC_GET_ARG2(*call);
249 flags = IPC_GET_ARG3(*call);
250
251 if (srv->srvs->ops->set_color == NULL) {
252 async_answer_0(callid, ENOTSUP);
253 return;
254 }
255
256 srv->srvs->ops->set_color(srv, bgcolor, fgcolor, flags);
257 async_answer_0(callid, EOK);
258}
259
260static void con_set_rgb_color_srv(con_srv_t *srv, ipc_callid_t callid,
261 ipc_call_t *call)
262{
263 pixel_t bgcolor;
264 pixel_t fgcolor;
265
266 bgcolor = IPC_GET_ARG1(*call);
267 fgcolor = IPC_GET_ARG2(*call);
268
269 if (srv->srvs->ops->set_rgb_color == NULL) {
270 async_answer_0(callid, ENOTSUP);
271 return;
272 }
273
274 srv->srvs->ops->set_rgb_color(srv, bgcolor, fgcolor);
275 async_answer_0(callid, EOK);
276}
277
278static void con_set_cursor_visibility_srv(con_srv_t *srv, ipc_callid_t callid,
279 ipc_call_t *call)
280{
281 bool show;
282
283 show = IPC_GET_ARG1(*call);
284
285 if (srv->srvs->ops->set_cursor_visibility == NULL) {
286 async_answer_0(callid, ENOTSUP);
287 return;
288 }
289
290 srv->srvs->ops->set_cursor_visibility(srv, show);
291 async_answer_0(callid, EOK);
292}
293
294static void con_get_event_srv(con_srv_t *srv, ipc_callid_t callid,
295 ipc_call_t *call)
296{
297 errno_t rc;
298 cons_event_t event;
299 ipc_call_t result;
300
301 if (srv->srvs->ops->get_event == NULL) {
302 async_answer_0(callid, ENOTSUP);
303 return;
304 }
305
306 rc = srv->srvs->ops->get_event(srv, &event);
307 if (rc != EOK) {
308 async_answer_0(callid, rc);
309 return;
310 }
311
312 rc = console_ev_encode(&event, &result);
313 if (rc != EOK) {
314 async_answer_0(callid, rc);
315 return;
316 }
317
318 async_answer_5(callid, rc, IPC_GET_ARG1(result), IPC_GET_ARG2(result),
319 IPC_GET_ARG3(result), IPC_GET_ARG4(result), IPC_GET_ARG5(result));
320}
321
322static con_srv_t *con_srv_create(con_srvs_t *srvs)
323{
324 con_srv_t *srv;
325
326 srv = calloc(1, sizeof(*srv));
327 if (srv == NULL)
328 return NULL;
329
330 srv->srvs = srvs;
331 return srv;
332}
333
334void con_srvs_init(con_srvs_t *srvs)
335{
336 srvs->ops = NULL;
337 srvs->sarg = NULL;
338 srvs->abort_timeout = 0;
339 srvs->aborted = false;
340}
341
342errno_t con_conn(ipc_callid_t iid, ipc_call_t *icall, con_srvs_t *srvs)
343{
344 con_srv_t *srv;
345 errno_t rc;
346
347 /* Accept the connection */
348 async_answer_0(iid, EOK);
349
350 srv = con_srv_create(srvs);
351 if (srv == NULL)
352 return ENOMEM;
353
354/* async_sess_t *sess = async_callback_receive(EXCHANGE_SERIALIZE);
355 if (sess == NULL)
356 return ENOMEM;
357
358 srv->client_sess = sess;
359*/
360 srv->client_sess = NULL;
361
362 rc = srvs->ops->open(srvs, srv);
363 if (rc != EOK)
364 return rc;
365
366 while (true) {
367 ipc_call_t call;
368 ipc_callid_t callid = 0;
369
370 while (callid == 0) {
371 /* XXX Need to be able to abort immediately */
372 callid = async_get_call_timeout(&call,
373 srvs->abort_timeout);
374
375 if (srv->srvs->aborted) {
376 if (callid != 0)
377 async_answer_0(callid, EINTR);
378 break;
379 }
380 }
381
382 if (callid == 0)
383 break;
384
385 sysarg_t method = IPC_GET_IMETHOD(call);
386
387 if (!method) {
388 /* The other side has hung up */
389 async_answer_0(callid, EOK);
390 break;
391 }
392
393 switch (method) {
394 case VFS_OUT_READ:
395 con_read_srv(srv, callid, &call);
396 break;
397 case VFS_OUT_WRITE:
398 con_write_srv(srv, callid, &call);
399 break;
400 case VFS_OUT_SYNC:
401 con_sync_srv(srv, callid, &call);
402 break;
403 case CONSOLE_CLEAR:
404 con_clear_srv(srv, callid, &call);
405 break;
406 case CONSOLE_SET_POS:
407 con_set_pos_srv(srv, callid, &call);
408 break;
409 case CONSOLE_GET_POS:
410 con_get_pos_srv(srv, callid, &call);
411 break;
412 case CONSOLE_GET_SIZE:
413 con_get_size_srv(srv, callid, &call);
414 break;
415 case CONSOLE_GET_COLOR_CAP:
416 con_get_color_cap_srv(srv, callid, &call);
417 break;
418 case CONSOLE_SET_STYLE:
419 con_set_style_srv(srv, callid, &call);
420 break;
421 case CONSOLE_SET_COLOR:
422 con_set_color_srv(srv, callid, &call);
423 break;
424 case CONSOLE_SET_RGB_COLOR:
425 con_set_rgb_color_srv(srv, callid, &call);
426 break;
427 case CONSOLE_SET_CURSOR_VISIBILITY:
428 con_set_cursor_visibility_srv(srv, callid, &call);
429 break;
430 case CONSOLE_GET_EVENT:
431 con_get_event_srv(srv, callid, &call);
432 break;
433 default:
434 async_answer_0(callid, ENOTSUP);
435 }
436 }
437
438 rc = srvs->ops->close(srv);
439 free(srv);
440
441 return rc;
442}
443
444/** @}
445 */
Note: See TracBrowser for help on using the repository browser.