2 * QEMU I/O channels files driver
4 * Copyright (c) 2015 Red Hat, Inc.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 #include "qemu/osdep.h"
22 #include "io/channel-file.h"
23 #include "io/channel-util.h"
24 #include "io/channel-watch.h"
25 #include "qapi/error.h"
26 #include "qemu/module.h"
27 #include "qemu/sockets.h"
31 qio_channel_file_new_fd(int fd
)
35 ioc
= QIO_CHANNEL_FILE(object_new(TYPE_QIO_CHANNEL_FILE
));
39 if (lseek(fd
, 0, SEEK_CUR
) != (off_t
)-1) {
40 qio_channel_set_feature(QIO_CHANNEL(ioc
), QIO_CHANNEL_FEATURE_SEEKABLE
);
43 trace_qio_channel_file_new_fd(ioc
, fd
);
49 qio_channel_file_new_dupfd(int fd
, Error
**errp
)
54 error_setg_errno(errp
, errno
, "Could not dup FD %d", fd
);
58 return qio_channel_file_new_fd(newfd
);
62 qio_channel_file_new_path(const char *path
,
69 ioc
= QIO_CHANNEL_FILE(object_new(TYPE_QIO_CHANNEL_FILE
));
71 if (flags
& O_CREAT
) {
72 ioc
->fd
= qemu_create(path
, flags
& ~O_CREAT
, mode
, errp
);
74 ioc
->fd
= qemu_open(path
, flags
, errp
);
77 object_unref(OBJECT(ioc
));
81 if (lseek(ioc
->fd
, 0, SEEK_CUR
) != (off_t
)-1) {
82 qio_channel_set_feature(QIO_CHANNEL(ioc
), QIO_CHANNEL_FEATURE_SEEKABLE
);
85 trace_qio_channel_file_new_path(ioc
, path
, flags
, mode
, ioc
->fd
);
91 static void qio_channel_file_init(Object
*obj
)
93 QIOChannelFile
*ioc
= QIO_CHANNEL_FILE(obj
);
97 static void qio_channel_file_finalize(Object
*obj
)
99 QIOChannelFile
*ioc
= QIO_CHANNEL_FILE(obj
);
107 static ssize_t
qio_channel_file_readv(QIOChannel
*ioc
,
108 const struct iovec
*iov
,
115 QIOChannelFile
*fioc
= QIO_CHANNEL_FILE(ioc
);
119 ret
= readv(fioc
->fd
, iov
, niov
);
121 if (errno
== EAGAIN
) {
122 return QIO_CHANNEL_ERR_BLOCK
;
124 if (errno
== EINTR
) {
128 error_setg_errno(errp
, errno
,
129 "Unable to read from file");
136 static ssize_t
qio_channel_file_writev(QIOChannel
*ioc
,
137 const struct iovec
*iov
,
144 QIOChannelFile
*fioc
= QIO_CHANNEL_FILE(ioc
);
148 ret
= writev(fioc
->fd
, iov
, niov
);
150 if (errno
== EAGAIN
) {
151 return QIO_CHANNEL_ERR_BLOCK
;
153 if (errno
== EINTR
) {
156 error_setg_errno(errp
, errno
,
157 "Unable to write to file");
164 static ssize_t
qio_channel_file_preadv(QIOChannel
*ioc
,
165 const struct iovec
*iov
,
170 QIOChannelFile
*fioc
= QIO_CHANNEL_FILE(ioc
);
174 ret
= preadv(fioc
->fd
, iov
, niov
, offset
);
176 if (errno
== EAGAIN
) {
177 return QIO_CHANNEL_ERR_BLOCK
;
179 if (errno
== EINTR
) {
183 error_setg_errno(errp
, errno
, "Unable to read from file");
190 static ssize_t
qio_channel_file_pwritev(QIOChannel
*ioc
,
191 const struct iovec
*iov
,
196 QIOChannelFile
*fioc
= QIO_CHANNEL_FILE(ioc
);
200 ret
= pwritev(fioc
->fd
, iov
, niov
, offset
);
202 if (errno
== EAGAIN
) {
203 return QIO_CHANNEL_ERR_BLOCK
;
205 if (errno
== EINTR
) {
208 error_setg_errno(errp
, errno
, "Unable to write to file");
213 #endif /* CONFIG_PREADV */
215 static int qio_channel_file_set_blocking(QIOChannel
*ioc
,
220 /* not implemented */
221 error_setg_errno(errp
, errno
, "Failed to set FD nonblocking");
224 QIOChannelFile
*fioc
= QIO_CHANNEL_FILE(ioc
);
226 if (!g_unix_set_fd_nonblocking(fioc
->fd
, !enabled
, NULL
)) {
227 error_setg_errno(errp
, errno
, "Failed to set FD nonblocking");
235 static off_t
qio_channel_file_seek(QIOChannel
*ioc
,
240 QIOChannelFile
*fioc
= QIO_CHANNEL_FILE(ioc
);
243 ret
= lseek(fioc
->fd
, offset
, whence
);
244 if (ret
== (off_t
)-1) {
245 error_setg_errno(errp
, errno
,
246 "Unable to seek to offset %lld whence %d in file",
247 (long long int)offset
, whence
);
254 static int qio_channel_file_close(QIOChannel
*ioc
,
257 QIOChannelFile
*fioc
= QIO_CHANNEL_FILE(ioc
);
259 if (qemu_close(fioc
->fd
) < 0) {
260 error_setg_errno(errp
, errno
,
261 "Unable to close file");
269 static void qio_channel_file_set_aio_fd_handler(QIOChannel
*ioc
,
270 AioContext
*read_ctx
,
272 AioContext
*write_ctx
,
276 QIOChannelFile
*fioc
= QIO_CHANNEL_FILE(ioc
);
278 qio_channel_util_set_aio_fd_handler(fioc
->fd
, read_ctx
, io_read
,
279 fioc
->fd
, write_ctx
, io_write
,
283 static GSource
*qio_channel_file_create_watch(QIOChannel
*ioc
,
284 GIOCondition condition
)
286 QIOChannelFile
*fioc
= QIO_CHANNEL_FILE(ioc
);
287 return qio_channel_create_fd_watch(ioc
,
292 static void qio_channel_file_class_init(ObjectClass
*klass
,
293 void *class_data G_GNUC_UNUSED
)
295 QIOChannelClass
*ioc_klass
= QIO_CHANNEL_CLASS(klass
);
297 ioc_klass
->io_writev
= qio_channel_file_writev
;
298 ioc_klass
->io_readv
= qio_channel_file_readv
;
299 ioc_klass
->io_set_blocking
= qio_channel_file_set_blocking
;
301 ioc_klass
->io_pwritev
= qio_channel_file_pwritev
;
302 ioc_klass
->io_preadv
= qio_channel_file_preadv
;
304 ioc_klass
->io_seek
= qio_channel_file_seek
;
305 ioc_klass
->io_close
= qio_channel_file_close
;
306 ioc_klass
->io_create_watch
= qio_channel_file_create_watch
;
307 ioc_klass
->io_set_aio_fd_handler
= qio_channel_file_set_aio_fd_handler
;
310 static const TypeInfo qio_channel_file_info
= {
311 .parent
= TYPE_QIO_CHANNEL
,
312 .name
= TYPE_QIO_CHANNEL_FILE
,
313 .instance_size
= sizeof(QIOChannelFile
),
314 .instance_init
= qio_channel_file_init
,
315 .instance_finalize
= qio_channel_file_finalize
,
316 .class_init
= qio_channel_file_class_init
,
319 static void qio_channel_file_register_types(void)
321 type_register_static(&qio_channel_file_info
);
324 type_init(qio_channel_file_register_types
);