7 changes: 7 additions & 0 deletions monitor/qmp-cmds.c
Expand Up @@ -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"
Expand Down Expand Up @@ -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,
Expand Down
14 changes: 7 additions & 7 deletions net/dgram.c
Expand Up @@ -230,7 +230,7 @@ static int net_dgram_mcast_create(struct sockaddr_in *mcastaddr,
return fd;
fail:
if (fd >= 0) {
closesocket(fd);
close(fd);
}
return -1;
}
Expand Down Expand Up @@ -352,22 +352,22 @@ static int net_dgram_mcast_init(NetClientState *peer,
if (convert_host_port(saddr, local->u.inet.host, local->u.inet.port,
errp) < 0) {
g_free(saddr);
closesocket(fd);
close(fd);
return -1;
}

/* must be bound */
if (saddr->sin_addr.s_addr == 0) {
error_setg(errp, "can't setup multicast destination address");
g_free(saddr);
closesocket(fd);
close(fd);
return -1;
}
/* clone dgram socket */
newfd = net_dgram_mcast_create(saddr, NULL, errp);
if (newfd < 0) {
g_free(saddr);
closesocket(fd);
close(fd);
return -1;
}
/* clone newfd to fd, close newfd */
Expand Down Expand Up @@ -494,14 +494,14 @@ int net_init_dgram(const Netdev *netdev, const char *name,
if (ret < 0) {
error_setg_errno(errp, errno,
"can't set socket option SO_REUSEADDR");
closesocket(fd);
close(fd);
return -1;
}
ret = bind(fd, (struct sockaddr *)&laddr_in, sizeof(laddr_in));
if (ret < 0) {
error_setg_errno(errp, errno, "can't bind ip=%s to socket",
inet_ntoa(laddr_in.sin_addr));
closesocket(fd);
close(fd);
return -1;
}
qemu_socket_set_nonblock(fd);
Expand Down Expand Up @@ -548,7 +548,7 @@ int net_init_dgram(const Netdev *netdev, const char *name,
if (ret < 0) {
error_setg_errno(errp, errno, "can't bind unix=%s to socket",
laddr_un.sun_path);
closesocket(fd);
close(fd);
return -1;
}
qemu_socket_set_nonblock(fd);
Expand Down
16 changes: 14 additions & 2 deletions net/slirp.c
Expand Up @@ -248,12 +248,24 @@ static void net_slirp_timer_mod(void *timer, int64_t expire_timer,

static void net_slirp_register_poll_fd(int fd, void *opaque)
{
qemu_fd_register(fd);
#ifdef WIN32
AioContext *ctxt = qemu_get_aio_context();

if (WSAEventSelect(fd, event_notifier_get_handle(&ctxt->notifier),
FD_READ | FD_ACCEPT | FD_CLOSE |
FD_CONNECT | FD_WRITE | FD_OOB) != 0) {
error_setg_win32(&error_warn, WSAGetLastError(), "failed to WSAEventSelect()");
}
#endif
}

static void net_slirp_unregister_poll_fd(int fd, void *opaque)
{
/* no qemu_fd_unregister */
#ifdef WIN32
if (WSAEventSelect(fd, NULL, 0) != 0) {
error_setg_win32(&error_warn, WSAGetLastError(), "failed to WSAEventSelect()");
}
#endif
}

static void net_slirp_notify(void *opaque)
Expand Down
22 changes: 11 additions & 11 deletions net/socket.c
Expand Up @@ -172,7 +172,7 @@ static void net_socket_send(void *opaque)
if (s->listen_fd != -1) {
qemu_set_fd_handler(s->listen_fd, net_socket_accept, NULL, s);
}
closesocket(s->fd);
close(s->fd);

s->fd = -1;
net_socket_rs_init(&s->rs, net_socket_rs_finalize, false);
Expand Down Expand Up @@ -299,7 +299,7 @@ static int net_socket_mcast_create(struct sockaddr_in *mcastaddr,
return fd;
fail:
if (fd >= 0)
closesocket(fd);
close(fd);
return -1;
}

Expand All @@ -314,7 +314,7 @@ static void net_socket_cleanup(NetClientState *nc)
}
if (s->listen_fd != -1) {
qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL);
closesocket(s->listen_fd);
close(s->listen_fd);
s->listen_fd = -1;
}
}
Expand Down Expand Up @@ -399,7 +399,7 @@ static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer,
return s;

err:
closesocket(fd);
close(fd);
return NULL;
}

Expand Down Expand Up @@ -456,7 +456,7 @@ static NetSocketState *net_socket_fd_init(NetClientState *peer,
if(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&so_type,
(socklen_t *)&optlen)< 0) {
error_setg(errp, "can't get socket option SO_TYPE");
closesocket(fd);
close(fd);
return NULL;
}
switch(so_type) {
Expand All @@ -468,7 +468,7 @@ static NetSocketState *net_socket_fd_init(NetClientState *peer,
default:
error_setg(errp, "socket type=%d for fd=%d must be either"
" SOCK_DGRAM or SOCK_STREAM", so_type, fd);
closesocket(fd);
close(fd);
}
return NULL;
}
Expand Down Expand Up @@ -526,13 +526,13 @@ static int net_socket_listen_init(NetClientState *peer,
if (ret < 0) {
error_setg_errno(errp, errno, "can't bind ip=%s to socket",
inet_ntoa(saddr.sin_addr));
closesocket(fd);
close(fd);
return -1;
}
ret = listen(fd, 0);
if (ret < 0) {
error_setg_errno(errp, errno, "can't listen on socket");
closesocket(fd);
close(fd);
return -1;
}

Expand Down Expand Up @@ -579,7 +579,7 @@ static int net_socket_connect_init(NetClientState *peer,
break;
} else {
error_setg_errno(errp, errno, "can't connect socket");
closesocket(fd);
close(fd);
return -1;
}
} else {
Expand Down Expand Up @@ -671,14 +671,14 @@ static int net_socket_udp_init(NetClientState *peer,
if (ret < 0) {
error_setg_errno(errp, errno,
"can't set socket option SO_REUSEADDR");
closesocket(fd);
close(fd);
return -1;
}
ret = bind(fd, (struct sockaddr *)&laddr, sizeof(laddr));
if (ret < 0) {
error_setg_errno(errp, errno, "can't bind ip=%s to socket",
inet_ntoa(laddr.sin_addr));
closesocket(fd);
close(fd);
return -1;
}
qemu_socket_set_nonblock(fd);
Expand Down
36 changes: 35 additions & 1 deletion qapi/misc.json
Expand Up @@ -14,6 +14,9 @@
# Allow client connections for VNC, Spice and socket based
# character devices to be passed in to QEMU via SCM_RIGHTS.
#
# If the FD associated with @fdname is not a socket, the command will fail and
# the FD will be closed.
#
# @protocol: protocol name. Valid names are "vnc", "spice", "@dbus-display" or
# the name of a character device (eg. from -chardev id=XXXX)
#
Expand Down Expand Up @@ -270,7 +273,38 @@
# <- { "return": {} }
#
##
{ 'command': 'getfd', 'data': {'fdname': 'str'} }
{ 'command': 'getfd', 'data': {'fdname': 'str'}, 'if': 'CONFIG_POSIX' }

##
# @get-win32-socket:
#
# Add a socket that was duplicated to QEMU process with
# WSADuplicateSocketW() via WSASocket() & WSAPROTOCOL_INFOW structure
# and assign it a name (the SOCKET is associated with a CRT file
# descriptor)
#
# @info: the WSAPROTOCOL_INFOW structure (encoded in base64)
#
# @fdname: file descriptor name
#
# Returns: Nothing on success
#
# Since: 8.0
#
# Notes: If @fdname already exists, the file descriptor assigned to
# it will be closed and replaced by the received file
# descriptor.
#
# The 'closefd' command can be used to explicitly close the
# file descriptor when it is no longer needed.
#
# Example:
#
# -> { "execute": "get-win32-socket", "arguments": { "info": "abcd123..", fdname": "skclient" } }
# <- { "return": {} }
#
##
{ 'command': 'get-win32-socket', 'data': {'info': 'str', 'fdname': 'str'}, 'if': 'CONFIG_WIN32' }

##
# @closefd:
Expand Down
6 changes: 3 additions & 3 deletions tests/docker/docker.py
Expand Up @@ -23,10 +23,10 @@
import tempfile
import re
import signal
import getpass
from tarfile import TarFile, TarInfo
from io import StringIO, BytesIO
from shutil import copy, rmtree
from pwd import getpwuid
from datetime import datetime, timedelta


Expand Down Expand Up @@ -316,7 +316,7 @@ def build_image(self, tag, docker_dir, dockerfile,

if user:
uid = os.getuid()
uname = getpwuid(uid).pw_name
uname = getpass.getuser()
tmp_df.write("\n")
tmp_df.write("RUN id %s 2>/dev/null || useradd -u %d -U %s" %
(uname, uid, uname))
Expand Down Expand Up @@ -570,7 +570,7 @@ def run(self, args, argv):

if args.user:
uid = os.getuid()
uname = getpwuid(uid).pw_name
uname = getpass.getuser()
df.write("\n")
df.write("RUN id %s 2>/dev/null || useradd -u %d -U %s" %
(uname, uid, uname))
Expand Down
26 changes: 20 additions & 6 deletions tests/qtest/libqtest.c
Expand Up @@ -124,7 +124,7 @@ static int socket_accept(int sock)
(void *)&timeout, sizeof(timeout))) {
fprintf(stderr, "%s failed to set SO_RCVTIMEO: %s\n",
__func__, strerror(errno));
closesocket(sock);
close(sock);
return -1;
}

Expand All @@ -135,7 +135,7 @@ static int socket_accept(int sock)
if (ret == -1) {
fprintf(stderr, "%s failed: %s\n", __func__, strerror(errno));
}
closesocket(sock);
close(sock);

return ret;
}
Expand Down Expand Up @@ -564,8 +564,8 @@ void qtest_quit(QTestState *s)
qtest_remove_abrt_handler(s);

qtest_kill_qemu(s);
closesocket(s->fd);
closesocket(s->qmp_fd);
close(s->fd);
close(s->qmp_fd);
g_string_free(s->rx, true);

for (GList *it = s->pending_events; it != NULL; it = it->next) {
Expand Down Expand Up @@ -1478,13 +1478,28 @@ void qtest_qmp_device_add(QTestState *qts, const char *driver, const char *id,
qobject_unref(args);
}

#ifndef _WIN32
void qtest_qmp_add_client(QTestState *qts, const char *protocol, int fd)
{
QDict *resp;

#ifdef WIN32
WSAPROTOCOL_INFOW info;
g_autofree char *info64 = NULL;
SOCKET s;

assert(fd_is_socket(fd));
s = _get_osfhandle(fd);
if (WSADuplicateSocketW(s, GetProcessId((HANDLE)qts->qemu_pid), &info) == SOCKET_ERROR) {
g_autofree char *emsg = g_win32_error_message(WSAGetLastError());
g_error("WSADuplicateSocketW failed: %s", emsg);
}
info64 = g_base64_encode((guchar *)&info, sizeof(info));
resp = qtest_qmp(qts, "{'execute': 'get-win32-socket',"
"'arguments': {'fdname': 'fdname', 'info': %s}}", info64);
#else
resp = qtest_qmp_fds(qts, &fd, 1, "{'execute': 'getfd',"
"'arguments': {'fdname': 'fdname'}}");
#endif
g_assert(resp);
g_assert(!qdict_haskey(resp, "event")); /* We don't expect any events */
g_assert(!qdict_haskey(resp, "error"));
Expand All @@ -1498,7 +1513,6 @@ void qtest_qmp_add_client(QTestState *qts, const char *protocol, int fd)
g_assert(!qdict_haskey(resp, "error"));
qobject_unref(resp);
}
#endif

/*
* Generic hot-unplugging test via the device_del QMP command.
Expand Down
5 changes: 2 additions & 3 deletions tests/qtest/libqtest.h
Expand Up @@ -758,17 +758,16 @@ void qtest_qmp_device_add_qdict(QTestState *qts, const char *drv,
void qtest_qmp_device_add(QTestState *qts, const char *driver, const char *id,
const char *fmt, ...) G_GNUC_PRINTF(4, 5);

#ifndef _WIN32
/**
* qtest_qmp_add_client:
* @qts: QTestState instance to operate on
* @protocol: the protocol to add to
* @fd: the client file-descriptor
*
* Call QMP ``getfd`` followed by ``add_client`` with the given @fd.
* Call QMP ``getfd`` (on Windows ``get-win32-socket``) followed by
* ``add_client`` with the given @fd.
*/
void qtest_qmp_add_client(QTestState *qts, const char *protocol, int fd);
#endif /* _WIN32 */

/**
* qtest_qmp_device_del_send:
Expand Down
2 changes: 1 addition & 1 deletion tests/qtest/microbit-test.c
Expand Up @@ -107,7 +107,7 @@ static void test_nrf51_uart(void)
g_assert_true(recv(sock_fd, s, 10, 0) == 5);
g_assert_true(memcmp(s, "world", 5) == 0);

closesocket(sock_fd);
close(sock_fd);

qtest_quit(qts);
}
Expand Down
10 changes: 5 additions & 5 deletions tests/qtest/netdev-socket.c
Expand Up @@ -99,7 +99,7 @@ static int inet_get_free_port_multiple(int nb, int *port, bool ipv6)

nb = i;
for (i = 0; i < nb; i++) {
closesocket(sock[i]);
close(sock[i]);
}

return nb;
Expand Down Expand Up @@ -361,8 +361,8 @@ static void test_stream_fd(void)
qtest_quit(qts1);
qtest_quit(qts0);

closesocket(sock[0]);
closesocket(sock[1]);
close(sock[0]);
close(sock[1]);
}
#endif

Expand Down Expand Up @@ -487,8 +487,8 @@ static void test_dgram_fd(void)
qtest_quit(qts1);
qtest_quit(qts0);

closesocket(sv[0]);
closesocket(sv[1]);
close(sv[0]);
close(sv[1]);
}
#endif

Expand Down
12 changes: 7 additions & 5 deletions tests/qtest/vnc-display-test.c
Expand Up @@ -19,7 +19,7 @@ typedef struct Test {
GMainLoop *loop;
} Test;

#if !defined(WIN32) && !defined(CONFIG_DARWIN)
#if !defined(CONFIG_DARWIN)

static void on_vnc_error(VncConnection* self,
const char* msg)
Expand All @@ -38,10 +38,7 @@ static void on_vnc_auth_failure(VncConnection *self,
static bool
test_setup(Test *test)
{
#ifdef WIN32
g_test_skip("Not supported on Windows yet");
return false;
#elif defined(CONFIG_DARWIN)
#if defined(CONFIG_DARWIN)
g_test_skip("Broken on Darwin");
return false;
#else
Expand All @@ -59,7 +56,12 @@ test_setup(Test *test)
g_signal_connect(test->conn, "vnc-auth-failure",
G_CALLBACK(on_vnc_auth_failure), NULL);
vnc_connection_set_auth_type(test->conn, VNC_CONNECTION_AUTH_NONE);

#ifdef WIN32
vnc_connection_open_fd(test->conn, _get_osfhandle(pair[0]));
#else
vnc_connection_open_fd(test->conn, pair[0]);
#endif

test->loop = g_main_loop_new(NULL, FALSE);
return true;
Expand Down
1 change: 1 addition & 0 deletions tests/unit/meson.build
Expand Up @@ -11,6 +11,7 @@ tests = {
'check-qobject': [],
'check-qjson': [],
'check-qlit': [],
'test-error-report': [],
'test-qobject-output-visitor': [testqapi],
'test-clone-visitor': [testqapi],
'test-qobject-input-visitor': [testqapi],
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/socket-helpers.c
Expand Up @@ -160,7 +160,7 @@ void socket_check_afunix_support(bool *has_afunix)
int fd;

fd = socket(PF_UNIX, SOCK_STREAM, 0);
closesocket(fd);
close(fd);

#ifdef _WIN32
*has_afunix = (fd != (int)INVALID_SOCKET);
Expand Down
139 changes: 139 additions & 0 deletions tests/unit/test-error-report.c
@@ -0,0 +1,139 @@
/*
* Error reporting test
*
* Copyright (C) 2022 Red Hat Inc.
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/

#include "qemu/osdep.h"
#include "glib-compat.h"
#include <locale.h>

#include "qemu/error-report.h"
#include "qapi/error.h"

static void
test_error_report_simple(void)
{
if (g_test_subprocess()) {
error_report("%s", "test error");
warn_report("%s", "test warn");
info_report("%s", "test info");
return;
}

g_test_trap_subprocess(NULL, 0, 0);
g_test_trap_assert_passed();
g_test_trap_assert_stderr("\
test-error-report: test error*\
test-error-report: warning: test warn*\
test-error-report: info: test info*\
");
}

static void
test_error_report_loc(void)
{
if (g_test_subprocess()) {
loc_set_file("some-file.c", 7717);
error_report("%s", "test error1");
loc_set_none();
error_report("%s", "test error2");
return;
}

g_test_trap_subprocess(NULL, 0, 0);
g_test_trap_assert_passed();
g_test_trap_assert_stderr("\
test-error-report:some-file.c:7717: test error1*\
test-error-report: test error2*\
");
}

static void
test_error_report_glog(void)
{
if (g_test_subprocess()) {
g_message("gmessage");
return;
}

g_test_trap_subprocess(NULL, 0, 0);
g_test_trap_assert_passed();
g_test_trap_assert_stderr("test-error-report: info: gmessage*");
}

static void
test_error_report_once(void)
{
int i;

if (g_test_subprocess()) {
for (i = 0; i < 3; i++) {
warn_report_once("warn");
error_report_once("err");
}
return;
}

g_test_trap_subprocess(NULL, 0, 0);
g_test_trap_assert_passed();
g_test_trap_assert_stderr("\
test-error-report: warning: warn*\
test-error-report: err*\
");
}

static void
test_error_report_timestamp(void)
{
if (g_test_subprocess()) {
message_with_timestamp = true;
warn_report("warn");
error_report("err");
return;
}

g_test_trap_subprocess(NULL, 0, 0);
g_test_trap_assert_passed();
g_test_trap_assert_stderr("\
*-*-*:*:* test-error-report: warning: warn*\
*-*-*:*:* test-error-report: err*\
");
}

static void
test_error_warn(void)
{
if (g_test_subprocess()) {
error_setg(&error_warn, "Testing &error_warn");
return;
}

g_test_trap_subprocess(NULL, 0, 0);
g_test_trap_assert_passed();
g_test_trap_assert_stderr("\
test-error-report: warning: Testing &error_warn*\
");
}


int
main(int argc, char *argv[])
{
setlocale(LC_ALL, "");

g_test_init(&argc, &argv, NULL);
error_init("test-error-report");

g_test_add_func("/error-report/simple", test_error_report_simple);
g_test_add_func("/error-report/loc", test_error_report_loc);
g_test_add_func("/error-report/glog", test_error_report_glog);
g_test_add_func("/error-report/once", test_error_report_once);
g_test_add_func("/error-report/timestamp", test_error_report_timestamp);
g_test_add_func("/error-report/warn", test_error_warn);

return g_test_run();
}
2 changes: 1 addition & 1 deletion tests/unit/test-io-channel-command.c
Expand Up @@ -35,7 +35,7 @@ static char *socat = NULL;
static void test_io_channel_command_fifo(bool async)
{
g_autofree gchar *tmpdir = g_dir_make_tmp("qemu-test-io-channel.XXXXXX", NULL);
g_autofree gchar *fifo = g_strdup_printf("%s/%s", tmpdir, TEST_FIFO);
g_autofree gchar *fifo = g_build_filename(tmpdir, TEST_FIFO, NULL);
g_autofree gchar *srcargs = g_strdup_printf("%s - PIPE:%s,wronly", socat, fifo);
g_autofree gchar *dstargs = g_strdup_printf("%s PIPE:%s,rdonly -", socat, fifo);
g_auto(GStrv) srcargv = g_strsplit(srcargs, " ", -1);
Expand Down
6 changes: 3 additions & 3 deletions util/aio-posix.c
Expand Up @@ -180,9 +180,9 @@ void aio_set_fd_handler(AioContext *ctx,
}
}

void aio_set_fd_poll(AioContext *ctx, int fd,
IOHandler *io_poll_begin,
IOHandler *io_poll_end)
static void aio_set_fd_poll(AioContext *ctx, int fd,
IOHandler *io_poll_begin,
IOHandler *io_poll_end)
{
AioHandler *node = find_aio_handler(ctx, fd);

Expand Down
23 changes: 12 additions & 11 deletions util/aio-win32.c
Expand Up @@ -22,6 +22,7 @@
#include "qemu/sockets.h"
#include "qapi/error.h"
#include "qemu/rcu_queue.h"
#include "qemu/error-report.h"

struct AioHandler {
EventNotifier *e;
Expand Down Expand Up @@ -70,13 +71,20 @@ void aio_set_fd_handler(AioContext *ctx,
IOHandler *io_poll_ready,
void *opaque)
{
/* fd is a SOCKET in our case */
AioHandler *old_node;
AioHandler *node = NULL;
SOCKET s;

if (!fd_is_socket(fd)) {
error_report("fd=%d is not a socket, AIO implementation is missing", fd);
return;
}

s = _get_osfhandle(fd);

qemu_lockcnt_lock(&ctx->list_lock);
QLIST_FOREACH(old_node, &ctx->aio_handlers, node) {
if (old_node->pfd.fd == fd && !old_node->deleted) {
if (old_node->pfd.fd == s && !old_node->deleted) {
break;
}
}
Expand All @@ -87,7 +95,7 @@ void aio_set_fd_handler(AioContext *ctx,

/* Alloc and insert if it's not already there */
node = g_new0(AioHandler, 1);
node->pfd.fd = fd;
node->pfd.fd = s;

node->pfd.events = 0;
if (node->io_read) {
Expand Down Expand Up @@ -115,7 +123,7 @@ void aio_set_fd_handler(AioContext *ctx,

QLIST_INSERT_HEAD_RCU(&ctx->aio_handlers, node, node);
event = event_notifier_get_handle(&ctx->notifier);
WSAEventSelect(node->pfd.fd, event, bitmask);
qemu_socket_select(fd, event, bitmask, NULL);
}
if (old_node) {
aio_remove_fd_handler(ctx, old_node);
Expand All @@ -125,13 +133,6 @@ void aio_set_fd_handler(AioContext *ctx,
aio_notify(ctx);
}

void aio_set_fd_poll(AioContext *ctx, int fd,
IOHandler *io_poll_begin,
IOHandler *io_poll_end)
{
/* Not implemented */
}

void aio_set_event_notifier(AioContext *ctx,
EventNotifier *e,
bool is_external,
Expand Down
10 changes: 7 additions & 3 deletions util/error.c
Expand Up @@ -27,8 +27,9 @@ struct Error

Error *error_abort;
Error *error_fatal;
Error *error_warn;

static void error_handle_fatal(Error **errp, Error *err)
static void error_handle(Error **errp, Error *err)
{
if (errp == &error_abort) {
fprintf(stderr, "Unexpected error in %s() at %s:%d:\n",
Expand All @@ -43,6 +44,9 @@ static void error_handle_fatal(Error **errp, Error *err)
error_report_err(err);
exit(1);
}
if (errp == &error_warn) {
warn_report_err(err);
}
}

G_GNUC_PRINTF(6, 0)
Expand Down Expand Up @@ -71,7 +75,7 @@ static void error_setv(Error **errp,
err->line = line;
err->func = func;

error_handle_fatal(errp, err);
error_handle(errp, err);
*errp = err;

errno = saved_errno;
Expand Down Expand Up @@ -284,7 +288,7 @@ void error_propagate(Error **dst_errp, Error *local_err)
if (!local_err) {
return;
}
error_handle_fatal(dst_errp, local_err);
error_handle(dst_errp, local_err);
if (dst_errp && !*dst_errp) {
*dst_errp = local_err;
} else {
Expand Down
11 changes: 0 additions & 11 deletions util/main-loop.c
Expand Up @@ -252,10 +252,6 @@ static int max_priority;
static int glib_pollfds_idx;
static int glib_n_poll_fds;

void qemu_fd_register(int fd)
{
}

static void glib_pollfds_fill(int64_t *cur_timeout)
{
GMainContext *context = g_main_context_default();
Expand Down Expand Up @@ -414,13 +410,6 @@ void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
}
}

void qemu_fd_register(int fd)
{
WSAEventSelect(fd, event_notifier_get_handle(&qemu_aio_context->notifier),
FD_READ | FD_ACCEPT | FD_CLOSE |
FD_CONNECT | FD_WRITE | FD_OOB);
}

static int pollfds_fill(GArray *pollfds, fd_set *rfds, fd_set *wfds,
fd_set *xfds)
{
Expand Down
70 changes: 0 additions & 70 deletions util/oslib-posix.c
Expand Up @@ -583,76 +583,6 @@ char *qemu_get_pid_name(pid_t pid)
}


pid_t qemu_fork(Error **errp)
{
sigset_t oldmask, newmask;
struct sigaction sig_action;
int saved_errno;
pid_t pid;

/*
* Need to block signals now, so that child process can safely
* kill off caller's signal handlers without a race.
*/
sigfillset(&newmask);
if (pthread_sigmask(SIG_SETMASK, &newmask, &oldmask) != 0) {
error_setg_errno(errp, errno,
"cannot block signals");
return -1;
}

pid = fork();
saved_errno = errno;

if (pid < 0) {
/* attempt to restore signal mask, but ignore failure, to
* avoid obscuring the fork failure */
(void)pthread_sigmask(SIG_SETMASK, &oldmask, NULL);
error_setg_errno(errp, saved_errno,
"cannot fork child process");
errno = saved_errno;
return -1;
} else if (pid) {
/* parent process */

/* Restore our original signal mask now that the child is
* safely running. Only documented failures are EFAULT (not
* possible, since we are using just-grabbed mask) or EINVAL
* (not possible, since we are using correct arguments). */
(void)pthread_sigmask(SIG_SETMASK, &oldmask, NULL);
} else {
/* child process */
size_t i;

/* Clear out all signal handlers from parent so nothing
* unexpected can happen in our child once we unblock
* signals */
sig_action.sa_handler = SIG_DFL;
sig_action.sa_flags = 0;
sigemptyset(&sig_action.sa_mask);

for (i = 1; i < NSIG; i++) {
/* Only possible errors are EFAULT or EINVAL The former
* won't happen, the latter we expect, so no need to check
* return value */
(void)sigaction(i, &sig_action, NULL);
}

/* Unmask all signals in child, since we've no idea what the
* caller's done with their signal mask and don't want to
* propagate that to children */
sigemptyset(&newmask);
if (pthread_sigmask(SIG_SETMASK, &newmask, NULL) != 0) {
Error *local_err = NULL;
error_setg_errno(&local_err, errno,
"cannot unblock signals");
error_report_err(local_err);
_exit(1);
}
}
return pid;
}

void *qemu_alloc_stack(size_t *sz)
{
void *ptr, *guardpage;
Expand Down
350 changes: 313 additions & 37 deletions util/oslib-win32.c

Large diffs are not rendered by default.

22 changes: 11 additions & 11 deletions util/qemu-sockets.c
Expand Up @@ -326,7 +326,7 @@ static int inet_listen_saddr(InetSocketAddress *saddr,
* recover from this situation, so we need to recreate the
* socket to allow bind attempts for subsequent ports:
*/
closesocket(slisten);
close(slisten);
slisten = -1;
}
}
Expand All @@ -337,7 +337,7 @@ static int inet_listen_saddr(InetSocketAddress *saddr,
listen_failed:
saved_errno = errno;
if (slisten >= 0) {
closesocket(slisten);
close(slisten);
}
freeaddrinfo(res);
errno = saved_errno;
Expand Down Expand Up @@ -380,7 +380,7 @@ static int inet_connect_addr(const InetSocketAddress *saddr,
if (rc < 0) {
error_setg_errno(errp, errno, "Failed to connect to '%s:%s'",
saddr->host, saddr->port);
closesocket(sock);
close(sock);
return -1;
}

Expand Down Expand Up @@ -483,7 +483,7 @@ int inet_connect_saddr(InetSocketAddress *saddr, Error **errp)

if (ret < 0) {
error_setg_errno(errp, errno, "Unable to set KEEPALIVE");
closesocket(sock);
close(sock);
return -1;
}
}
Expand Down Expand Up @@ -580,7 +580,7 @@ static int inet_dgram_saddr(InetSocketAddress *sraddr,

err:
if (sock != -1) {
closesocket(sock);
close(sock);
}
if (local) {
freeaddrinfo(local);
Expand Down Expand Up @@ -777,7 +777,7 @@ static int vsock_connect_addr(const VsockSocketAddress *vaddr,
if (rc < 0) {
error_setg_errno(errp, errno, "Failed to connect to '%s:%s'",
vaddr->cid, vaddr->port);
closesocket(sock);
close(sock);
return -1;
}

Expand Down Expand Up @@ -814,13 +814,13 @@ static int vsock_listen_saddr(VsockSocketAddress *vaddr,

if (bind(slisten, (const struct sockaddr *)&svm, sizeof(svm)) != 0) {
error_setg_errno(errp, errno, "Failed to bind socket");
closesocket(slisten);
close(slisten);
return -1;
}

if (listen(slisten, num) != 0) {
error_setg_errno(errp, errno, "Failed to listen on socket");
closesocket(slisten);
close(slisten);
return -1;
}
return slisten;
Expand Down Expand Up @@ -978,7 +978,7 @@ static int unix_listen_saddr(UnixSocketAddress *saddr,

err:
g_free(pathbuf);
closesocket(sock);
close(sock);
return -1;
}

Expand Down Expand Up @@ -1041,7 +1041,7 @@ static int unix_connect_saddr(UnixSocketAddress *saddr, Error **errp)
return sock;

err:
closesocket(sock);
close(sock);
return -1;
}

Expand Down Expand Up @@ -1238,7 +1238,7 @@ int socket_listen(SocketAddress *addr, int num, Error **errp)
*/
if (listen(fd, num) != 0) {
error_setg_errno(errp, errno, "Failed to listen on fd socket");
closesocket(fd);
close(fd);
return -1;
}
break;
Expand Down