qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

channel-null.c (5915B)


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