]> Git Repo - qemu.git/blobdiff - include/sysemu/char.h
char: use qemu_chr_fe* functions with CharBackend argument
[qemu.git] / include / sysemu / char.h
index edf76693d9ee00b8fca4549bcb11bbda4679c9dd..816c5367899627dc7839901a7c79044308707e7f 100644 (file)
@@ -9,6 +9,7 @@
 #include "qapi/qmp/qobject.h"
 #include "qapi/qmp/qstring.h"
 #include "qemu/main-loop.h"
+#include "qemu/bitmap.h"
 
 /* character device */
 
@@ -41,6 +42,11 @@ typedef struct {
 #define CHR_IOCTL_PP_EPP_WRITE       11
 #define CHR_IOCTL_PP_DATA_DIR        12
 
+struct ParallelIOArg {
+    void *buffer;
+    int count;
+};
+
 #define CHR_IOCTL_SERIAL_SET_TIOCM   13
 #define CHR_IOCTL_SERIAL_GET_TIOCM   14
 
@@ -53,23 +59,45 @@ typedef struct {
 
 typedef void IOEventHandler(void *opaque, int event);
 
+typedef enum {
+    /* Whether the chardev peer is able to close and
+     * reopen the data channel, thus requiring support
+     * for qemu_chr_wait_connected() to wait for a
+     * valid connection */
+    QEMU_CHAR_FEATURE_RECONNECTABLE,
+    /* Whether it is possible to send/recv file descriptors
+     * over the data channel */
+    QEMU_CHAR_FEATURE_FD_PASS,
+
+    QEMU_CHAR_FEATURE_LAST,
+} CharDriverFeature;
+
+/* This is the backend as seen by frontend, the actual backend is
+ * CharDriverState */
+typedef struct CharBackend {
+    CharDriverState *chr;
+    int tag;
+} CharBackend;
+
 struct CharDriverState {
     QemuMutex chr_write_lock;
-    void (*init)(struct CharDriverState *s);
     int (*chr_write)(struct CharDriverState *s, const uint8_t *buf, int len);
     int (*chr_sync_read)(struct CharDriverState *s,
                          const uint8_t *buf, int len);
     GSource *(*chr_add_watch)(struct CharDriverState *s, GIOCondition cond);
-    void (*chr_update_read_handler)(struct CharDriverState *s);
+    void (*chr_update_read_handler)(struct CharDriverState *s,
+                                    GMainContext *context, int tag);
     int (*chr_ioctl)(struct CharDriverState *s, int cmd, void *arg);
     int (*get_msgfds)(struct CharDriverState *s, int* fds, int num);
     int (*set_msgfds)(struct CharDriverState *s, int *fds, int num);
     int (*chr_add_client)(struct CharDriverState *chr, int fd);
+    int (*chr_wait_connected)(struct CharDriverState *chr, Error **errp);
     IOEventHandler *chr_event;
     IOCanReadHandler *chr_can_read;
     IOReadHandler *chr_read;
     void *handler_opaque;
     void (*chr_close)(struct CharDriverState *chr);
+    void (*chr_disconnect)(struct CharDriverState *chr);
     void (*chr_accept_input)(struct CharDriverState *chr);
     void (*chr_set_echo)(struct CharDriverState *chr, bool echo);
     void (*chr_set_fe_open)(struct CharDriverState *chr, int fe_open);
@@ -77,6 +105,7 @@ struct CharDriverState {
     void *opaque;
     char *label;
     char *filename;
+    int logfd;
     int be_open;
     int fe_open;
     int explicit_fe_open;
@@ -84,18 +113,21 @@ struct CharDriverState {
     int avail_connections;
     int is_mux;
     guint fd_in_tag;
-    QemuOpts *opts;
+    bool replay;
+    DECLARE_BITMAP(features, QEMU_CHAR_FEATURE_LAST);
     QTAILQ_ENTRY(CharDriverState) next;
 };
 
 /**
- * @qemu_chr_alloc:
+ * qemu_chr_alloc:
+ * @backend: the common backend config
+ * @errp: pointer to a NULL-initialized error object
  *
  * Allocate and initialize a new CharDriverState.
  *
- * Returns: a newly allocated CharDriverState.
+ * Returns: a newly allocated CharDriverState, or NULL on error.
  */
-CharDriverState *qemu_chr_alloc(void);
+CharDriverState *qemu_chr_alloc(ChardevCommon *backend, Error **errp);
 
 /**
  * @qemu_chr_new_from_opts:
@@ -103,13 +135,21 @@ CharDriverState *qemu_chr_alloc(void);
  * Create a new character backend from a QemuOpts list.
  *
  * @opts see qemu-config.c for a list of valid options
- * @init not sure..
  *
  * Returns: a new character backend
  */
 CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
-                                    void (*init)(struct CharDriverState *s),
-                                    Error **errp);
+                                        Error **errp);
+
+/**
+ * @qemu_chr_parse_common:
+ *
+ * Parse the common options available to all character backends.
+ *
+ * @opts the options that still need parsing
+ * @backend a new backend
+ */
+void qemu_chr_parse_common(QemuOpts *opts, ChardevCommon *backend);
 
 /**
  * @qemu_chr_new:
@@ -118,20 +158,62 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
  *
  * @label the name of the backend
  * @filename the URI
- * @init not sure..
  *
  * Returns: a new character backend
  */
-CharDriverState *qemu_chr_new(const char *label, const char *filename,
-                              void (*init)(struct CharDriverState *s));
+CharDriverState *qemu_chr_new(const char *label, const char *filename);
+
+
+/**
+ * @qemu_chr_fe_disconnect:
+ *
+ * Close a fd accpeted by character backend.
+ */
+void qemu_chr_fe_disconnect(CharBackend *be);
+
+/**
+ * @qemu_chr_cleanup:
+ *
+ * Delete all chardevs (when leaving qemu)
+ */
+void qemu_chr_cleanup(void);
+
+/**
+ * @qemu_chr_fe_wait_connected:
+ *
+ * Wait for characted backend to be connected.
+ */
+int qemu_chr_fe_wait_connected(CharBackend *be, Error **errp);
+
+/**
+ * @qemu_chr_new_noreplay:
+ *
+ * Create a new character backend from a URI.
+ * Character device communications are not written
+ * into the replay log.
+ *
+ * @label the name of the backend
+ * @filename the URI
+ *
+ * Returns: a new character backend
+ */
+CharDriverState *qemu_chr_new_noreplay(const char *label, const char *filename);
 
 /**
  * @qemu_chr_delete:
  *
- * Destroy a character backend.
+ * Destroy a character backend and remove it from the list of
+ * identified character backends.
  */
 void qemu_chr_delete(CharDriverState *chr);
 
+/**
+ * @qemu_chr_free:
+ *
+ * Destroy a character backend.
+ */
+void qemu_chr_free(CharDriverState *chr);
+
 /**
  * @qemu_chr_fe_set_echo:
  *
@@ -141,7 +223,7 @@ void qemu_chr_delete(CharDriverState *chr);
  *
  * @echo true to enable echo, false to disable echo
  */
-void qemu_chr_fe_set_echo(struct CharDriverState *chr, bool echo);
+void qemu_chr_fe_set_echo(CharBackend *be, bool echo);
 
 /**
  * @qemu_chr_fe_set_open:
@@ -149,7 +231,7 @@ void qemu_chr_fe_set_echo(struct CharDriverState *chr, bool echo);
  * Set character frontend open status.  This is an indication that the
  * front end is ready (or not) to begin doing I/O.
  */
-void qemu_chr_fe_set_open(struct CharDriverState *chr, int fe_open);
+void qemu_chr_fe_set_open(CharBackend *be, int fe_open);
 
 /**
  * @qemu_chr_fe_event:
@@ -158,7 +240,7 @@ void qemu_chr_fe_set_open(struct CharDriverState *chr, int fe_open);
  *
  * @event the event to send
  */
-void qemu_chr_fe_event(CharDriverState *s, int event);
+void qemu_chr_fe_event(CharBackend *be, int event);
 
 /**
  * @qemu_chr_fe_printf:
@@ -168,11 +250,23 @@ void qemu_chr_fe_event(CharDriverState *s, int event);
  *
  * @fmt see #printf
  */
-void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...)
+void qemu_chr_fe_printf(CharBackend *be, const char *fmt, ...)
     GCC_FMT_ATTR(2, 3);
 
-int qemu_chr_fe_add_watch(CharDriverState *s, GIOCondition cond,
-                          GIOFunc func, void *user_data);
+/**
+ * @qemu_chr_fe_add_watch:
+ *
+ * If the backend is connected, create and add a #GSource that fires
+ * when the given condition (typically G_IO_OUT|G_IO_HUP or G_IO_HUP)
+ * is active; return the #GSource's tag.  If it is disconnected,
+ * return 0.
+ *
+ * @cond the condition to poll for
+ * @func the function to call when the condition happens
+ * @user_data the opaque pointer to pass to @func
+ */
+guint qemu_chr_fe_add_watch(CharBackend *be, GIOCondition cond,
+                            GIOFunc func, void *user_data);
 
 /**
  * @qemu_chr_fe_write:
@@ -186,7 +280,7 @@ int qemu_chr_fe_add_watch(CharDriverState *s, GIOCondition cond,
  *
  * Returns: the number of bytes consumed
  */
-int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len);
+int qemu_chr_fe_write(CharBackend *be, const uint8_t *buf, int len);
 
 /**
  * @qemu_chr_fe_write_all:
@@ -201,7 +295,7 @@ int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len);
  *
  * Returns: the number of bytes consumed
  */
-int qemu_chr_fe_write_all(CharDriverState *s, const uint8_t *buf, int len);
+int qemu_chr_fe_write_all(CharBackend *be, const uint8_t *buf, int len);
 
 /**
  * @qemu_chr_fe_read_all:
@@ -213,7 +307,7 @@ int qemu_chr_fe_write_all(CharDriverState *s, const uint8_t *buf, int len);
  *
  * Returns: the number of bytes read
  */
-int qemu_chr_fe_read_all(CharDriverState *s, uint8_t *buf, int len);
+int qemu_chr_fe_read_all(CharBackend *be, uint8_t *buf, int len);
 
 /**
  * @qemu_chr_fe_ioctl:
@@ -226,7 +320,7 @@ int qemu_chr_fe_read_all(CharDriverState *s, uint8_t *buf, int len);
  * Returns: if @cmd is not supported by the backend, -ENOTSUP, otherwise the
  *          return value depends on the semantics of @cmd
  */
-int qemu_chr_fe_ioctl(CharDriverState *s, int cmd, void *arg);
+int qemu_chr_fe_ioctl(CharBackend *be, int cmd, void *arg);
 
 /**
  * @qemu_chr_fe_get_msgfd:
@@ -239,7 +333,7 @@ int qemu_chr_fe_ioctl(CharDriverState *s, int cmd, void *arg);
  *          this function will return -1 until a client sends a new file
  *          descriptor.
  */
-int qemu_chr_fe_get_msgfd(CharDriverState *s);
+int qemu_chr_fe_get_msgfd(CharBackend *be);
 
 /**
  * @qemu_chr_fe_get_msgfds:
@@ -252,7 +346,7 @@ int qemu_chr_fe_get_msgfd(CharDriverState *s);
  *          this function will return -1 until a client sends a new set of file
  *          descriptors.
  */
-int qemu_chr_fe_get_msgfds(CharDriverState *s, int *fds, int num);
+int qemu_chr_fe_get_msgfds(CharBackend *be, int *fds, int num);
 
 /**
  * @qemu_chr_fe_set_msgfds:
@@ -265,13 +359,13 @@ int qemu_chr_fe_get_msgfds(CharDriverState *s, int *fds, int num);
  *
  * Returns: -1 if fd passing isn't supported.
  */
-int qemu_chr_fe_set_msgfds(CharDriverState *s, int *fds, int num);
+int qemu_chr_fe_set_msgfds(CharBackend *be, int *fds, int num);
 
 /**
  * @qemu_chr_fe_claim:
  *
  * Claim a backend before using it, should be called before calling
- * qemu_chr_add_handlers(). 
+ * qemu_chr_fe_set_handlers().
  *
  * Returns: -1 if the backend is already in use by another frontend, 0 on
  *          success.
@@ -287,7 +381,7 @@ int qemu_chr_fe_claim(CharDriverState *s);
 void qemu_chr_fe_claim_no_fail(CharDriverState *s);
 
 /**
- * @qemu_chr_fe_claim:
+ * @qemu_chr_fe_release:
  *
  * Release a backend for use by another frontend.
  *
@@ -320,6 +414,15 @@ int qemu_chr_be_can_write(CharDriverState *s);
  */
 void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len);
 
+/**
+ * @qemu_chr_be_write_impl:
+ *
+ * Implementation of back end writing. Used by replay module.
+ *
+ * @buf a buffer to receive data from the front end
+ * @len the number of bytes to receive from the front end
+ */
+void qemu_chr_be_write_impl(CharDriverState *s, uint8_t *buf, int len);
 
 /**
  * @qemu_chr_be_event:
@@ -330,18 +433,59 @@ void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len);
  */
 void qemu_chr_be_event(CharDriverState *s, int event);
 
-void qemu_chr_add_handlers(CharDriverState *s,
-                           IOCanReadHandler *fd_can_read,
-                           IOReadHandler *fd_read,
-                           IOEventHandler *fd_event,
-                           void *opaque);
+/**
+ * @qemu_chr_fe_init:
+ *
+ * Initializes a front end for the given CharBackend and
+ * CharDriver.
+ *
+ * Returns: false on error.
+ */
+bool qemu_chr_fe_init(CharBackend *b, CharDriverState *s, Error **errp);
+
+/**
+ * @qemu_chr_fe_get_driver:
+ *
+ * Returns the driver associated with a CharBackend or NULL.
+ */
+CharDriverState *qemu_chr_fe_get_driver(CharBackend *be);
+
+/**
+ * @qemu_chr_fe_set_handlers:
+ * @b: a CharBackend
+ * @fd_can_read: callback to get the amount of data the frontend may
+ *               receive
+ * @fd_read: callback to receive data from char
+ * @fd_event: event callback
+ * @opaque: an opaque pointer for the callbacks
+ * @context: a main loop context or NULL for the default
+ *
+ * Set the front end char handlers.
+ */
+void qemu_chr_fe_set_handlers(CharBackend *b,
+                              IOCanReadHandler *fd_can_read,
+                              IOReadHandler *fd_read,
+                              IOEventHandler *fd_event,
+                              void *opaque,
+                              GMainContext *context);
+
+/**
+ * @qemu_chr_fe_take_focus:
+ *
+ * Take the focus (if the front end is muxed)
+ */
+void qemu_chr_fe_take_focus(CharBackend *b);
 
 void qemu_chr_be_generic_open(CharDriverState *s);
-void qemu_chr_accept_input(CharDriverState *s);
+void qemu_chr_fe_accept_input(CharBackend *be);
 int qemu_chr_add_client(CharDriverState *s, int fd);
 CharDriverState *qemu_chr_find(const char *name);
 bool chr_is_ringbuf(const CharDriverState *chr);
 
+bool qemu_chr_has_feature(CharDriverState *chr,
+                          CharDriverFeature feature);
+void qemu_chr_set_feature(CharDriverState *chr,
+                          CharDriverFeature feature);
 QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename);
 
 void register_char_driver(const char *name, ChardevBackendKind kind,
@@ -349,12 +493,8 @@ void register_char_driver(const char *name, ChardevBackendKind kind,
         CharDriverState *(*create)(const char *id, ChardevBackend *backend,
                                    ChardevReturn *ret, Error **errp));
 
-/* add an eventfd to the qemu devices that are polled */
-CharDriverState *qemu_chr_open_eventfd(int eventfd);
-
 extern int term_escape_char;
 
-CharDriverState *qemu_char_get_next_serial(void);
 
 /* console.c */
 typedef CharDriverState *(VcHandler)(ChardevVC *vc, Error **errp);
This page took 0.034288 seconds and 4 git commands to generate.