uvt: new library implementing VTs in user-space
[platform/upstream/kmscon.git] / src / uvt_tty_null.c
1 /*
2  * UVT - Userspace Virtual Terminals
3  *
4  * Copyright (c) 2011-2013 David Herrmann <dh.herrmann@gmail.com>
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining
7  * a copy of this software and associated documentation files
8  * (the "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sublicense, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included
15  * in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  */
25
26 /*
27  * Null TTY
28  * This tty simply discards all incoming messages and never produces any
29  * outgoing messages. Ioctls return static data or fail with some generic error
30  * code if they would modify internal state that we cannot emulate easily.
31  */
32
33 #include <eloop.h>
34 #include <errno.h>
35 #include <fcntl.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <unistd.h>
39 #include "shl_llog.h"
40 #include "uvt.h"
41 #include "uvt_internal.h"
42
43 #define LLOG_SUBSYSTEM "uvt_tty_null"
44
45 struct uvt_tty_null {
46         unsigned long ref;
47         struct uvt_ctx *ctx;
48         llog_submit_t llog;
49         void *llog_data;
50 };
51
52 static void tty_null_ref(void *data)
53 {
54         uvt_tty_null_ref(data);
55 }
56
57 static void tty_null_unref(void *data)
58 {
59         uvt_tty_null_unref(data);
60 }
61
62 static int tty_null_register_cb(void *data, uvt_tty_cb cb, void *cb_data)
63 {
64         return 0;
65 }
66
67 static void tty_null_unregister_cb(void *data, uvt_tty_cb cb, void *cb_data)
68 {
69 }
70
71 static int tty_null_read(void *data, uint8_t *buf, size_t size)
72 {
73         return -EAGAIN;
74 }
75
76 static int tty_null_write(void *data, const uint8_t *buf, size_t size)
77 {
78         return size;
79 }
80
81 static unsigned int tty_null_poll(void *data)
82 {
83         return UVT_TTY_WRITE;
84 }
85
86 const struct uvt_tty_ops uvt_tty_null_ops = {
87         .ref = tty_null_ref,
88         .unref = tty_null_unref,
89         .register_cb = tty_null_register_cb,
90         .unregister_cb = tty_null_unregister_cb,
91
92         .read = tty_null_read,
93         .write = tty_null_write,
94         .poll = tty_null_poll,
95 };
96
97 int uvt_tty_null_new(struct uvt_tty_null **out, struct uvt_ctx *ctx)
98 {
99         struct uvt_tty_null *tty;
100
101         if (!ctx)
102                 return -EINVAL;
103         if (!out)
104                 return llog_EINVAL(ctx);
105
106         tty = malloc(sizeof(*tty));
107         if (!tty)
108                 return llog_ENOMEM(ctx);
109         memset(tty, 0, sizeof(*tty));
110         tty->ref = 1;
111         tty->ctx = ctx;
112         tty->llog = tty->ctx->llog;
113         tty->llog_data = tty->ctx->llog_data;
114
115         uvt_ctx_ref(tty->ctx);
116         *out = tty;
117         return 0;
118 }
119
120 void uvt_tty_null_ref(struct uvt_tty_null *tty)
121 {
122         if (!tty || !tty->ref)
123                 return;
124
125         ++tty->ref;
126 }
127
128 void uvt_tty_null_unref(struct uvt_tty_null *tty)
129 {
130         if (!tty || !tty->ref || --tty->ref)
131                 return;
132
133         uvt_ctx_unref(tty->ctx);
134         free(tty);
135 }