1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include "qemu/osdep.h"
22#include "io/channel-null.h"
23#include "io/channel-watch.h"
24#include "qapi/error.h"
25#include "trace.h"
26#include "qemu/iov.h"
27
28typedef struct QIOChannelNullSource QIOChannelNullSource;
29struct QIOChannelNullSource {
30 GSource parent;
31 QIOChannel *ioc;
32 GIOCondition condition;
33};
34
35
36QIOChannelNull *
37qio_channel_null_new(void)
38{
39 QIOChannelNull *ioc;
40
41 ioc = QIO_CHANNEL_NULL(object_new(TYPE_QIO_CHANNEL_NULL));
42
43 trace_qio_channel_null_new(ioc);
44
45 return ioc;
46}
47
48
49static void
50qio_channel_null_init(Object *obj)
51{
52 QIOChannelNull *ioc = QIO_CHANNEL_NULL(obj);
53 ioc->closed = false;
54}
55
56
57static ssize_t
58qio_channel_null_readv(QIOChannel *ioc,
59 const struct iovec *iov,
60 size_t niov,
61 int **fds G_GNUC_UNUSED,
62 size_t *nfds G_GNUC_UNUSED,
63 int flags,
64 Error **errp)
65{
66 QIOChannelNull *nioc = QIO_CHANNEL_NULL(ioc);
67
68 if (nioc->closed) {
69 error_setg_errno(errp, EINVAL,
70 "Channel is closed");
71 return -1;
72 }
73
74 return 0;
75}
76
77
78static ssize_t
79qio_channel_null_writev(QIOChannel *ioc,
80 const struct iovec *iov,
81 size_t niov,
82 int *fds G_GNUC_UNUSED,
83 size_t nfds G_GNUC_UNUSED,
84 int flags G_GNUC_UNUSED,
85 Error **errp)
86{
87 QIOChannelNull *nioc = QIO_CHANNEL_NULL(ioc);
88
89 if (nioc->closed) {
90 error_setg_errno(errp, EINVAL,
91 "Channel is closed");
92 return -1;
93 }
94
95 return iov_size(iov, niov);
96}
97
98
99static int
100qio_channel_null_set_blocking(QIOChannel *ioc G_GNUC_UNUSED,
101 bool enabled G_GNUC_UNUSED,
102 Error **errp G_GNUC_UNUSED)
103{
104 return 0;
105}
106
107
108static off_t
109qio_channel_null_seek(QIOChannel *ioc G_GNUC_UNUSED,
110 off_t offset G_GNUC_UNUSED,
111 int whence G_GNUC_UNUSED,
112 Error **errp G_GNUC_UNUSED)
113{
114 return 0;
115}
116
117
118static int
119qio_channel_null_close(QIOChannel *ioc,
120 Error **errp G_GNUC_UNUSED)
121{
122 QIOChannelNull *nioc = QIO_CHANNEL_NULL(ioc);
123
124 nioc->closed = true;
125 return 0;
126}
127
128
129static void
130qio_channel_null_set_aio_fd_handler(QIOChannel *ioc G_GNUC_UNUSED,
131 AioContext *ctx G_GNUC_UNUSED,
132 IOHandler *io_read G_GNUC_UNUSED,
133 IOHandler *io_write G_GNUC_UNUSED,
134 void *opaque G_GNUC_UNUSED)
135{
136}
137
138
139static gboolean
140qio_channel_null_source_prepare(GSource *source G_GNUC_UNUSED,
141 gint *timeout)
142{
143 *timeout = -1;
144
145 return TRUE;
146}
147
148
149static gboolean
150qio_channel_null_source_check(GSource *source G_GNUC_UNUSED)
151{
152 return TRUE;
153}
154
155
156static gboolean
157qio_channel_null_source_dispatch(GSource *source,
158 GSourceFunc callback,
159 gpointer user_data)
160{
161 QIOChannelFunc func = (QIOChannelFunc)callback;
162 QIOChannelNullSource *ssource = (QIOChannelNullSource *)source;
163
164 return (*func)(ssource->ioc,
165 ssource->condition,
166 user_data);
167}
168
169
170static void
171qio_channel_null_source_finalize(GSource *source)
172{
173 QIOChannelNullSource *ssource = (QIOChannelNullSource *)source;
174
175 object_unref(OBJECT(ssource->ioc));
176}
177
178
179GSourceFuncs qio_channel_null_source_funcs = {
180 qio_channel_null_source_prepare,
181 qio_channel_null_source_check,
182 qio_channel_null_source_dispatch,
183 qio_channel_null_source_finalize
184};
185
186
187static GSource *
188qio_channel_null_create_watch(QIOChannel *ioc,
189 GIOCondition condition)
190{
191 GSource *source;
192 QIOChannelNullSource *ssource;
193
194 source = g_source_new(&qio_channel_null_source_funcs,
195 sizeof(QIOChannelNullSource));
196 ssource = (QIOChannelNullSource *)source;
197
198 ssource->ioc = ioc;
199 object_ref(OBJECT(ioc));
200
201 ssource->condition = condition;
202
203 return source;
204}
205
206
207static void
208qio_channel_null_class_init(ObjectClass *klass,
209 void *class_data G_GNUC_UNUSED)
210{
211 QIOChannelClass *ioc_klass = QIO_CHANNEL_CLASS(klass);
212
213 ioc_klass->io_writev = qio_channel_null_writev;
214 ioc_klass->io_readv = qio_channel_null_readv;
215 ioc_klass->io_set_blocking = qio_channel_null_set_blocking;
216 ioc_klass->io_seek = qio_channel_null_seek;
217 ioc_klass->io_close = qio_channel_null_close;
218 ioc_klass->io_create_watch = qio_channel_null_create_watch;
219 ioc_klass->io_set_aio_fd_handler = qio_channel_null_set_aio_fd_handler;
220}
221
222
223static const TypeInfo qio_channel_null_info = {
224 .parent = TYPE_QIO_CHANNEL,
225 .name = TYPE_QIO_CHANNEL_NULL,
226 .instance_size = sizeof(QIOChannelNull),
227 .instance_init = qio_channel_null_init,
228 .class_init = qio_channel_null_class_init,
229};
230
231
232static void
233qio_channel_null_register_types(void)
234{
235 type_register_static(&qio_channel_null_info);
236}
237
238type_init(qio_channel_null_register_types);
239