* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
- *
*/
#include "qemu/osdep.h"
+#include "qemu-common.h"
#include "qapi/error.h"
#include "qapi/qapi-visit-sockets.h"
+#include "qemu/module.h"
#include "io/channel-socket.h"
#include "io/channel-watch.h"
#include "trace.h"
int qio_channel_socket_listen_sync(QIOChannelSocket *ioc,
SocketAddress *addr,
+ int num,
Error **errp)
{
int fd;
- trace_qio_channel_socket_listen_sync(ioc, addr);
- fd = socket_listen(addr, errp);
+ trace_qio_channel_socket_listen_sync(ioc, addr, num);
+ fd = socket_listen(addr, num, errp);
if (fd < 0) {
trace_qio_channel_socket_listen_fail(ioc);
return -1;
}
+struct QIOChannelListenWorkerData {
+ SocketAddress *addr;
+ int num; /* amount of expected connections */
+};
+
+static void qio_channel_listen_worker_free(gpointer opaque)
+{
+ struct QIOChannelListenWorkerData *data = opaque;
+
+ qapi_free_SocketAddress(data->addr);
+ g_free(data);
+}
+
static void qio_channel_socket_listen_worker(QIOTask *task,
gpointer opaque)
{
QIOChannelSocket *ioc = QIO_CHANNEL_SOCKET(qio_task_get_source(task));
- SocketAddress *addr = opaque;
+ struct QIOChannelListenWorkerData *data = opaque;
Error *err = NULL;
- qio_channel_socket_listen_sync(ioc, addr, &err);
+ qio_channel_socket_listen_sync(ioc, data->addr, data->num, &err);
qio_task_set_error(task, err);
}
void qio_channel_socket_listen_async(QIOChannelSocket *ioc,
SocketAddress *addr,
+ int num,
QIOTaskFunc callback,
gpointer opaque,
GDestroyNotify destroy,
{
QIOTask *task = qio_task_new(
OBJECT(ioc), callback, opaque, destroy);
- SocketAddress *addrCopy;
+ struct QIOChannelListenWorkerData *data;
- addrCopy = QAPI_CLONE(SocketAddress, addr);
+ data = g_new0(struct QIOChannelListenWorkerData, 1);
+ data->addr = QAPI_CLONE(SocketAddress, addr);
+ data->num = num;
/* socket_listen() blocks in DNS lookups, so we must use a thread */
- trace_qio_channel_socket_listen_async(ioc, addr);
+ trace_qio_channel_socket_listen_async(ioc, addr, num);
qio_task_run_in_thread(task,
qio_channel_socket_listen_worker,
- addrCopy,
- (GDestroyNotify)qapi_free_SocketAddress,
+ data,
+ qio_channel_listen_worker_free,
context);
}
memset(control, 0, CMSG_SPACE(sizeof(int) * SOCKET_MAX_FDS));
-#ifdef MSG_CMSG_CLOEXEC
- sflags |= MSG_CMSG_CLOEXEC;
-#endif
-
msg.msg_iov = (struct iovec *)iov;
msg.msg_iovlen = niov;
if (fds && nfds) {
msg.msg_control = control;
msg.msg_controllen = sizeof(control);
+#ifdef MSG_CMSG_CLOEXEC
+ sflags |= MSG_CMSG_CLOEXEC;
+#endif
+
}
retry:
{
QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
int rc = 0;
+ Error *err = NULL;
if (sioc->fd != -1) {
#ifdef WIN32
if (closesocket(sioc->fd) < 0) {
sioc->fd = -1;
- error_setg_errno(errp, errno,
- "Unable to close socket");
+ error_setg_errno(&err, errno, "Unable to close socket");
+ error_propagate(errp, err);
return -1;
}
sioc->fd = -1;