diff options
Diffstat (limited to 'chardev/char-pty.c')
-rw-r--r-- | chardev/char-pty.c | 41 |
1 files changed, 38 insertions, 3 deletions
diff --git a/chardev/char-pty.c b/chardev/char-pty.c index cc2f761..674e9b3 100644 --- a/chardev/char-pty.c +++ b/chardev/char-pty.c @@ -29,6 +29,7 @@ #include "qemu/sockets.h" #include "qemu/error-report.h" #include "qemu/module.h" +#include "qemu/option.h" #include "qemu/qemu-print.h" #include "chardev/char-io.h" @@ -41,6 +42,7 @@ struct PtyChardev { int connected; GSource *timer_src; + char *path; }; typedef struct PtyChardev PtyChardev; @@ -152,7 +154,7 @@ static gboolean pty_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque) Chardev *chr = CHARDEV(opaque); PtyChardev *s = PTY_CHARDEV(opaque); gsize len; - uint8_t buf[CHR_READ_BUF_LEN]; + QEMU_UNINITIALIZED uint8_t buf[CHR_READ_BUF_LEN]; ssize_t ret; len = sizeof(buf); @@ -179,6 +181,9 @@ static void pty_chr_state(Chardev *chr, int connected) if (!connected) { remove_fd_in_watch(chr); + if (s->connected) { + qemu_chr_be_event(chr, CHR_EVENT_CLOSED); + } s->connected = 0; /* (re-)connect poll interval for idle guests: once per second. * We check more frequently in case the guests sends data to @@ -204,10 +209,15 @@ static void char_pty_finalize(Object *obj) Chardev *chr = CHARDEV(obj); PtyChardev *s = PTY_CHARDEV(obj); + /* unlink symlink */ + if (s->path) { + unlink(s->path); + g_free(s->path); + } + pty_chr_state(chr, 0); object_unref(OBJECT(s->ioc)); pty_chr_timer_cancel(s); - qemu_chr_be_event(chr, CHR_EVENT_CLOSED); } #if defined HAVE_PTY_H @@ -330,6 +340,7 @@ static void char_pty_open(Chardev *chr, int master_fd, slave_fd; char pty_name[PATH_MAX]; char *name; + char *path = backend->u.pty.data->path; master_fd = qemu_openpty_raw(&slave_fd, pty_name); if (master_fd < 0) { @@ -354,12 +365,36 @@ static void char_pty_open(Chardev *chr, g_free(name); s->timer_src = NULL; *be_opened = false; + + /* create symbolic link */ + if (path) { + int res = symlink(pty_name, path); + + if (res != 0) { + error_setg_errno(errp, errno, "Failed to create PTY symlink"); + } else { + s->path = g_strdup(path); + } + } +} + +static void char_pty_parse(QemuOpts *opts, ChardevBackend *backend, + Error **errp) +{ + const char *path = qemu_opt_get(opts, "path"); + ChardevPty *pty; + + backend->type = CHARDEV_BACKEND_KIND_PTY; + pty = backend->u.pty.data = g_new0(ChardevPty, 1); + qemu_chr_parse_common(opts, qapi_ChardevPty_base(pty)); + pty->path = g_strdup(path); } -static void char_pty_class_init(ObjectClass *oc, void *data) +static void char_pty_class_init(ObjectClass *oc, const void *data) { ChardevClass *cc = CHARDEV_CLASS(oc); + cc->parse = char_pty_parse; cc->open = char_pty_open; cc->chr_write = char_pty_chr_write; cc->chr_update_read_handler = pty_chr_update_read_handler; |