4 * Copyright (c) 2003-2008 Fabrice Bellard
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 #include "qemu/osdep.h"
25 #include "chardev/char-io.h"
27 typedef struct IOWatchPoll
{
33 IOCanReadHandler
*fd_can_read
;
38 static IOWatchPoll
*io_watch_poll_from_source(GSource
*source
)
40 return container_of(source
, IOWatchPoll
, parent
);
43 static gboolean
io_watch_poll_prepare(GSource
*source
,
46 IOWatchPoll
*iwp
= io_watch_poll_from_source(source
);
47 bool now_active
= iwp
->fd_can_read(iwp
->opaque
) > 0;
48 bool was_active
= iwp
->src
!= NULL
;
49 if (was_active
== now_active
) {
54 iwp
->src
= qio_channel_create_watch(
55 iwp
->ioc
, G_IO_IN
| G_IO_ERR
| G_IO_HUP
| G_IO_NVAL
);
56 g_source_set_callback(iwp
->src
, iwp
->fd_read
, iwp
->opaque
, NULL
);
57 g_source_add_child_source(source
, iwp
->src
);
58 g_source_unref(iwp
->src
);
60 g_source_remove_child_source(source
, iwp
->src
);
66 static gboolean
io_watch_poll_dispatch(GSource
*source
, GSourceFunc callback
,
69 return G_SOURCE_CONTINUE
;
72 static GSourceFuncs io_watch_poll_funcs
= {
73 .prepare
= io_watch_poll_prepare
,
74 .dispatch
= io_watch_poll_dispatch
,
77 GSource
*io_add_watch_poll(Chardev
*chr
,
79 IOCanReadHandler
*fd_can_read
,
80 QIOChannelFunc fd_read
,
82 GMainContext
*context
)
87 iwp
= (IOWatchPoll
*) g_source_new(&io_watch_poll_funcs
,
89 iwp
->fd_can_read
= fd_can_read
;
90 iwp
->opaque
= user_data
;
92 iwp
->fd_read
= (GSourceFunc
) fd_read
;
95 name
= g_strdup_printf("chardev-iowatch-%s", chr
->label
);
96 g_source_set_name((GSource
*)iwp
, name
);
99 g_source_attach(&iwp
->parent
, context
);
100 g_source_unref(&iwp
->parent
);
101 return (GSource
*)iwp
;
104 void remove_fd_in_watch(Chardev
*chr
)
107 g_source_destroy(chr
->gsource
);
112 int io_channel_send_full(QIOChannel
*ioc
,
113 const void *buf
, size_t len
,
114 int *fds
, size_t nfds
)
118 while (offset
< len
) {
120 struct iovec iov
= { .iov_base
= (char *)buf
+ offset
,
121 .iov_len
= len
- offset
};
123 ret
= qio_channel_writev_full(
126 if (ret
== QIO_CHANNEL_ERR_BLOCK
) {
133 } else if (ret
< 0) {
144 int io_channel_send(QIOChannel
*ioc
, const void *buf
, size_t len
)
146 return io_channel_send_full(ioc
, buf
, len
, NULL
, 0);