Merge qio 2010/01/24
Fixes accidental deletion of VNC server UNIX listener socket -----BEGIN PGP SIGNATURE----- iQIcBAABCAAGBQJcSa6LAAoJEL6G67QVEE/fkpkP/A79ZN4Mb3i5WTHYBYbzsicJ nqngWLh9m8qkuSgVFVzaFKtV/U4idHdFwt7f2fsboUnhVmOugE4ArDdzSqYVWNky tz/3UyfskZaNH6HtxuNhc1hyFN+zVPIw+0phQF8O2cQ6MVMufOYSocLcxrVF0436 FqLoPjhLdFphJGBWxCRrXDLYu5BOWoupvuDGV7gRtMfvGi5OWiWhAEgewYPn9zUx lGdxCMbh/m+XKYcro8hiCJHnP7SdGrpMl3ZZh0QdTORangNObt8HSSpmdzaf4ueO NOv7rRVhhjvEXDLQguFpQAlt3ewjZ2V72Sdz4sM7WvNDpsYZlLXhSjUdHo1xbqVl PcB4GX8NYbv9idEZGfnvO/C6JrRfcWm8cbN8vs5sMTfSF8KqK7A4ISAJtqQE3r85 y4Mtix5elSNwmCOZIwG6NovQOuK92iaFItPz9lzScSuXhRnR6GC2D03U/e54wDxw TRpoB8nL3hB4KFJEMNkdHS3RAuxuZcl1kz2yio+wPeI0Edm4aB+Y/FxlGw+Fs+kz rPH++pMbod6ZcDCc8PbzS1Th38pzPxYm4Rcbyw+YWz2nbjlz+kz4EVi2esg3fQIl TGB8vOyNYwq/cTaMwxqklK1SoB+sTHWZJKNuiSvyY2ZYNmUcMo/Hgb/I2QTzEqGS vnLp59vcidv73daZw/KT =Crcm -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/berrange/tags/qio-next-pull-request' into staging Merge qio 2010/01/24 Fixes accidental deletion of VNC server UNIX listener socket # gpg: Signature made Thu 24 Jan 2019 12:24:43 GMT # gpg: using RSA key BE86EBB415104FDF # gpg: Good signature from "Daniel P. Berrange <dan@berrange.com>" # gpg: aka "Daniel P. Berrange <berrange@redhat.com>" # Primary key fingerprint: DAF3 A6FD B26B 6291 2D0E 8E3F BE86 EBB4 1510 4FDF * remotes/berrange/tags/qio-next-pull-request: io: ensure UNIX client doesn't unlink server socket Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
feff020891
@ -688,10 +688,13 @@ qio_channel_socket_close(QIOChannel *ioc,
|
||||
int rc = 0;
|
||||
|
||||
if (sioc->fd != -1) {
|
||||
SocketAddress *addr = socket_local_address(sioc->fd, errp);
|
||||
#ifdef WIN32
|
||||
WSAEventSelect(sioc->fd, NULL, 0);
|
||||
#endif
|
||||
if (qio_channel_has_feature(ioc, QIO_CHANNEL_FEATURE_LISTEN)) {
|
||||
socket_listen_cleanup(sioc->fd, errp);
|
||||
}
|
||||
|
||||
if (closesocket(sioc->fd) < 0) {
|
||||
sioc->fd = -1;
|
||||
error_setg_errno(errp, errno,
|
||||
@ -699,20 +702,6 @@ qio_channel_socket_close(QIOChannel *ioc,
|
||||
return -1;
|
||||
}
|
||||
sioc->fd = -1;
|
||||
|
||||
if (addr && addr->type == SOCKET_ADDRESS_TYPE_UNIX
|
||||
&& addr->u.q_unix.path) {
|
||||
if (unlink(addr->u.q_unix.path) < 0 && errno != ENOENT) {
|
||||
error_setg_errno(errp, errno,
|
||||
"Failed to unlink socket %s",
|
||||
addr->u.q_unix.path);
|
||||
rc = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (addr) {
|
||||
qapi_free_SocketAddress(addr);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ static void test_io_channel_set_socket_bufs(QIOChannel *src,
|
||||
|
||||
static void test_io_channel_setup_sync(SocketAddress *listen_addr,
|
||||
SocketAddress *connect_addr,
|
||||
QIOChannel **srv,
|
||||
QIOChannel **src,
|
||||
QIOChannel **dst)
|
||||
{
|
||||
@ -78,7 +79,7 @@ static void test_io_channel_setup_sync(SocketAddress *listen_addr,
|
||||
|
||||
test_io_channel_set_socket_bufs(*src, *dst);
|
||||
|
||||
object_unref(OBJECT(lioc));
|
||||
*srv = QIO_CHANNEL(lioc);
|
||||
}
|
||||
|
||||
|
||||
@ -99,6 +100,7 @@ static void test_io_channel_complete(QIOTask *task,
|
||||
|
||||
static void test_io_channel_setup_async(SocketAddress *listen_addr,
|
||||
SocketAddress *connect_addr,
|
||||
QIOChannel **srv,
|
||||
QIOChannel **src,
|
||||
QIOChannel **dst)
|
||||
{
|
||||
@ -146,21 +148,34 @@ static void test_io_channel_setup_async(SocketAddress *listen_addr,
|
||||
qio_channel_set_delay(*src, false);
|
||||
test_io_channel_set_socket_bufs(*src, *dst);
|
||||
|
||||
object_unref(OBJECT(lioc));
|
||||
*srv = QIO_CHANNEL(lioc);
|
||||
|
||||
g_main_loop_unref(data.loop);
|
||||
}
|
||||
|
||||
|
||||
static void test_io_channel_socket_path_exists(SocketAddress *addr,
|
||||
bool expectExists)
|
||||
{
|
||||
if (addr->type != SOCKET_ADDRESS_TYPE_UNIX) {
|
||||
return;
|
||||
}
|
||||
|
||||
g_assert(g_file_test(addr->u.q_unix.path,
|
||||
G_FILE_TEST_EXISTS) == expectExists);
|
||||
}
|
||||
|
||||
|
||||
static void test_io_channel(bool async,
|
||||
SocketAddress *listen_addr,
|
||||
SocketAddress *connect_addr,
|
||||
bool passFD)
|
||||
{
|
||||
QIOChannel *src, *dst;
|
||||
QIOChannel *src, *dst, *srv;
|
||||
QIOChannelTest *test;
|
||||
if (async) {
|
||||
test_io_channel_setup_async(listen_addr, connect_addr, &src, &dst);
|
||||
test_io_channel_setup_async(listen_addr, connect_addr,
|
||||
&srv, &src, &dst);
|
||||
|
||||
g_assert(!passFD ||
|
||||
qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_FD_PASS));
|
||||
@ -169,14 +184,25 @@ static void test_io_channel(bool async,
|
||||
g_assert(qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_SHUTDOWN));
|
||||
g_assert(qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_SHUTDOWN));
|
||||
|
||||
test_io_channel_socket_path_exists(listen_addr, true);
|
||||
|
||||
test = qio_channel_test_new();
|
||||
qio_channel_test_run_threads(test, true, src, dst);
|
||||
qio_channel_test_validate(test);
|
||||
|
||||
test_io_channel_socket_path_exists(listen_addr, true);
|
||||
|
||||
/* unref without close, to ensure finalize() cleans up */
|
||||
|
||||
object_unref(OBJECT(src));
|
||||
object_unref(OBJECT(dst));
|
||||
test_io_channel_socket_path_exists(listen_addr, true);
|
||||
|
||||
test_io_channel_setup_async(listen_addr, connect_addr, &src, &dst);
|
||||
object_unref(OBJECT(srv));
|
||||
test_io_channel_socket_path_exists(listen_addr, false);
|
||||
|
||||
test_io_channel_setup_async(listen_addr, connect_addr,
|
||||
&srv, &src, &dst);
|
||||
|
||||
g_assert(!passFD ||
|
||||
qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_FD_PASS));
|
||||
@ -189,10 +215,24 @@ static void test_io_channel(bool async,
|
||||
qio_channel_test_run_threads(test, false, src, dst);
|
||||
qio_channel_test_validate(test);
|
||||
|
||||
/* close before unref, to ensure finalize copes with already closed */
|
||||
|
||||
qio_channel_close(src, &error_abort);
|
||||
qio_channel_close(dst, &error_abort);
|
||||
test_io_channel_socket_path_exists(listen_addr, true);
|
||||
|
||||
object_unref(OBJECT(src));
|
||||
object_unref(OBJECT(dst));
|
||||
test_io_channel_socket_path_exists(listen_addr, true);
|
||||
|
||||
qio_channel_close(srv, &error_abort);
|
||||
test_io_channel_socket_path_exists(listen_addr, false);
|
||||
|
||||
object_unref(OBJECT(srv));
|
||||
test_io_channel_socket_path_exists(listen_addr, false);
|
||||
} else {
|
||||
test_io_channel_setup_sync(listen_addr, connect_addr, &src, &dst);
|
||||
test_io_channel_setup_sync(listen_addr, connect_addr,
|
||||
&srv, &src, &dst);
|
||||
|
||||
g_assert(!passFD ||
|
||||
qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_FD_PASS));
|
||||
@ -201,14 +241,25 @@ static void test_io_channel(bool async,
|
||||
g_assert(qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_SHUTDOWN));
|
||||
g_assert(qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_SHUTDOWN));
|
||||
|
||||
test_io_channel_socket_path_exists(listen_addr, true);
|
||||
|
||||
test = qio_channel_test_new();
|
||||
qio_channel_test_run_threads(test, true, src, dst);
|
||||
qio_channel_test_validate(test);
|
||||
|
||||
test_io_channel_socket_path_exists(listen_addr, true);
|
||||
|
||||
/* unref without close, to ensure finalize() cleans up */
|
||||
|
||||
object_unref(OBJECT(src));
|
||||
object_unref(OBJECT(dst));
|
||||
test_io_channel_socket_path_exists(listen_addr, true);
|
||||
|
||||
test_io_channel_setup_sync(listen_addr, connect_addr, &src, &dst);
|
||||
object_unref(OBJECT(srv));
|
||||
test_io_channel_socket_path_exists(listen_addr, false);
|
||||
|
||||
test_io_channel_setup_sync(listen_addr, connect_addr,
|
||||
&srv, &src, &dst);
|
||||
|
||||
g_assert(!passFD ||
|
||||
qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_FD_PASS));
|
||||
@ -221,8 +272,23 @@ static void test_io_channel(bool async,
|
||||
qio_channel_test_run_threads(test, false, src, dst);
|
||||
qio_channel_test_validate(test);
|
||||
|
||||
test_io_channel_socket_path_exists(listen_addr, true);
|
||||
|
||||
/* close before unref, to ensure finalize copes with already closed */
|
||||
|
||||
qio_channel_close(src, &error_abort);
|
||||
qio_channel_close(dst, &error_abort);
|
||||
test_io_channel_socket_path_exists(listen_addr, true);
|
||||
|
||||
object_unref(OBJECT(src));
|
||||
object_unref(OBJECT(dst));
|
||||
test_io_channel_socket_path_exists(listen_addr, true);
|
||||
|
||||
qio_channel_close(srv, &error_abort);
|
||||
test_io_channel_socket_path_exists(listen_addr, false);
|
||||
|
||||
object_unref(OBJECT(srv));
|
||||
test_io_channel_socket_path_exists(listen_addr, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -316,7 +382,6 @@ static void test_io_channel_unix(bool async)
|
||||
|
||||
qapi_free_SocketAddress(listen_addr);
|
||||
qapi_free_SocketAddress(connect_addr);
|
||||
g_assert(g_file_test(TEST_SOCKET, G_FILE_TEST_EXISTS) == FALSE);
|
||||
}
|
||||
|
||||
|
||||
@ -335,7 +400,7 @@ static void test_io_channel_unix_fd_pass(void)
|
||||
{
|
||||
SocketAddress *listen_addr = g_new0(SocketAddress, 1);
|
||||
SocketAddress *connect_addr = g_new0(SocketAddress, 1);
|
||||
QIOChannel *src, *dst;
|
||||
QIOChannel *src, *dst, *srv;
|
||||
int testfd;
|
||||
int fdsend[3];
|
||||
int *fdrecv = NULL;
|
||||
@ -359,7 +424,7 @@ static void test_io_channel_unix_fd_pass(void)
|
||||
connect_addr->type = SOCKET_ADDRESS_TYPE_UNIX;
|
||||
connect_addr->u.q_unix.path = g_strdup(TEST_SOCKET);
|
||||
|
||||
test_io_channel_setup_sync(listen_addr, connect_addr, &src, &dst);
|
||||
test_io_channel_setup_sync(listen_addr, connect_addr, &srv, &src, &dst);
|
||||
|
||||
memcpy(bufsend, "Hello World", G_N_ELEMENTS(bufsend));
|
||||
|
||||
@ -412,6 +477,7 @@ static void test_io_channel_unix_fd_pass(void)
|
||||
|
||||
object_unref(OBJECT(src));
|
||||
object_unref(OBJECT(dst));
|
||||
object_unref(OBJECT(srv));
|
||||
qapi_free_SocketAddress(listen_addr);
|
||||
qapi_free_SocketAddress(connect_addr);
|
||||
unlink(TEST_SOCKET);
|
||||
|
Loading…
Reference in New Issue
Block a user