diff options
Diffstat (limited to 'monitor')
| -rw-r--r-- | monitor/fds.c | 77 | ||||
| -rw-r--r-- | monitor/hmp-cmds.c | 2 | ||||
| -rw-r--r-- | monitor/qmp-cmds.c | 7 |
3 files changed, 72 insertions, 14 deletions
diff --git a/monitor/fds.c b/monitor/fds.c index 26b39a0ce6..d86c2c674c 100644 --- a/monitor/fds.c +++ b/monitor/fds.c @@ -61,45 +61,59 @@ struct MonFdset { static QemuMutex mon_fdsets_lock; static QLIST_HEAD(, MonFdset) mon_fdsets; -void qmp_getfd(const char *fdname, Error **errp) +static bool monitor_add_fd(Monitor *mon, int fd, const char *fdname, Error **errp) { - Monitor *cur_mon = monitor_cur(); mon_fd_t *monfd; - int fd, tmp_fd; - - fd = qemu_chr_fe_get_msgfd(&cur_mon->chr); - if (fd == -1) { - error_setg(errp, "No file descriptor supplied via SCM_RIGHTS"); - return; - } if (qemu_isdigit(fdname[0])) { close(fd); error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "fdname", "a name not starting with a digit"); - return; + return false; } - QEMU_LOCK_GUARD(&cur_mon->mon_lock); - QLIST_FOREACH(monfd, &cur_mon->fds, next) { + /* See close() call below. */ + qemu_mutex_lock(&mon->mon_lock); + QLIST_FOREACH(monfd, &mon->fds, next) { + int tmp_fd; + if (strcmp(monfd->name, fdname) != 0) { continue; } tmp_fd = monfd->fd; monfd->fd = fd; + qemu_mutex_unlock(&mon->mon_lock); /* Make sure close() is outside critical section */ close(tmp_fd); - return; + return true; } monfd = g_new0(mon_fd_t, 1); monfd->name = g_strdup(fdname); monfd->fd = fd; - QLIST_INSERT_HEAD(&cur_mon->fds, monfd, next); + QLIST_INSERT_HEAD(&mon->fds, monfd, next); + qemu_mutex_unlock(&mon->mon_lock); + return true; } +#ifdef CONFIG_POSIX +void qmp_getfd(const char *fdname, Error **errp) +{ + Monitor *cur_mon = monitor_cur(); + int fd; + + fd = qemu_chr_fe_get_msgfd(&cur_mon->chr); + if (fd == -1) { + error_setg(errp, "No file descriptor supplied via SCM_RIGHTS"); + return; + } + + monitor_add_fd(cur_mon, fd, fdname, errp); +} +#endif + void qmp_closefd(const char *fdname, Error **errp) { Monitor *cur_mon = monitor_cur(); @@ -211,6 +225,41 @@ error: return NULL; } +#ifdef WIN32 +void qmp_get_win32_socket(const char *infos, const char *fdname, Error **errp) +{ + g_autofree WSAPROTOCOL_INFOW *info = NULL; + gsize len; + SOCKET sk; + int fd; + + info = (void *)g_base64_decode(infos, &len); + if (len != sizeof(*info)) { + error_setg(errp, "Invalid WSAPROTOCOL_INFOW value"); + return; + } + + sk = WSASocketW(FROM_PROTOCOL_INFO, + FROM_PROTOCOL_INFO, + FROM_PROTOCOL_INFO, + info, 0, 0); + if (sk == INVALID_SOCKET) { + error_setg_win32(errp, WSAGetLastError(), "Couldn't import socket"); + return; + } + + fd = _open_osfhandle(sk, _O_BINARY); + if (fd < 0) { + error_setg_errno(errp, errno, "Failed to associate a FD with the SOCKET"); + closesocket(sk); + return; + } + + monitor_add_fd(monitor_cur(), fd, fdname, errp); +} +#endif + + void qmp_remove_fd(int64_t fdset_id, bool has_fd, int64_t fd, Error **errp) { MonFdset *mon_fdset; diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c index 34bd8c67d7..6c559b48c8 100644 --- a/monitor/hmp-cmds.c +++ b/monitor/hmp-cmds.c @@ -192,6 +192,7 @@ void hmp_change(Monitor *mon, const QDict *qdict) hmp_handle_error(mon, err); } +#ifdef CONFIG_POSIX void hmp_getfd(Monitor *mon, const QDict *qdict) { const char *fdname = qdict_get_str(qdict, "fdname"); @@ -200,6 +201,7 @@ void hmp_getfd(Monitor *mon, const QDict *qdict) qmp_getfd(fdname, &err); hmp_handle_error(mon, err); } +#endif void hmp_closefd(Monitor *mon, const QDict *qdict) { diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c index 859012aef4..b0f948d337 100644 --- a/monitor/qmp-cmds.c +++ b/monitor/qmp-cmds.c @@ -14,6 +14,7 @@ */ #include "qemu/osdep.h" +#include "qemu/sockets.h" #include "monitor-internal.h" #include "monitor/qdev.h" #include "monitor/qmp-helpers.h" @@ -139,6 +140,12 @@ void qmp_add_client(const char *protocol, const char *fdname, return; } + if (!fd_is_socket(fd)) { + error_setg(errp, "parameter @fdname must name a socket"); + close(fd); + return; + } + for (i = 0; i < ARRAY_SIZE(protocol_table); i++) { if (!strcmp(protocol, protocol_table[i].name)) { if (!protocol_table[i].add_client(fd, has_skipauth, skipauth, |