mirror of
https://github.com/zeromq/libzmq.git
synced 2024-12-26 23:01:04 +08:00
Problem: Race condition in IPC sockets
Solution: Don't unlink file on close File may not belong to the socket at that point.
This commit is contained in:
parent
44f96a3652
commit
656cdb959a
1
.gitignore
vendored
1
.gitignore
vendored
@ -47,6 +47,7 @@ test_last_endpoint
|
|||||||
test_pair_inproc
|
test_pair_inproc
|
||||||
test_pair_ipc
|
test_pair_ipc
|
||||||
test_pair_tcp
|
test_pair_tcp
|
||||||
|
test_rebind_ipc
|
||||||
test_reqrep_inproc
|
test_reqrep_inproc
|
||||||
test_reqrep_ipc
|
test_reqrep_ipc
|
||||||
test_reqrep_tcp
|
test_reqrep_tcp
|
||||||
|
@ -684,6 +684,7 @@ test_apps += \
|
|||||||
tests/test_shutdown_stress \
|
tests/test_shutdown_stress \
|
||||||
tests/test_ipc_wildcard \
|
tests/test_ipc_wildcard \
|
||||||
tests/test_pair_ipc \
|
tests/test_pair_ipc \
|
||||||
|
tests/test_rebind_ipc \
|
||||||
tests/test_reqrep_ipc \
|
tests/test_reqrep_ipc \
|
||||||
tests/test_use_fd_ipc \
|
tests/test_use_fd_ipc \
|
||||||
tests/test_use_fd_tcp \
|
tests/test_use_fd_tcp \
|
||||||
@ -702,6 +703,9 @@ tests_test_pair_ipc_SOURCES = \
|
|||||||
tests/testutil.hpp
|
tests/testutil.hpp
|
||||||
tests_test_pair_ipc_LDADD = src/libzmq.la
|
tests_test_pair_ipc_LDADD = src/libzmq.la
|
||||||
|
|
||||||
|
tests_test_rebind_ipc_SOURCES = tests/test_rebind_ipc.cpp
|
||||||
|
tests_test_rebind_ipc_LDADD = src/libzmq.la
|
||||||
|
|
||||||
tests_test_reqrep_ipc_SOURCES = \
|
tests_test_reqrep_ipc_SOURCES = \
|
||||||
tests/test_reqrep_ipc.cpp \
|
tests/test_reqrep_ipc.cpp \
|
||||||
tests/testutil.hpp
|
tests/testutil.hpp
|
||||||
|
@ -803,6 +803,17 @@
|
|||||||
'libzmq'
|
'libzmq'
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
'target_name': 'test_rebind_ipc',
|
||||||
|
'type': 'executable',
|
||||||
|
'sources': [
|
||||||
|
'../../tests/test_rebind_ipc.cpp',
|
||||||
|
'../../tests/testutil.hpp'
|
||||||
|
],
|
||||||
|
'dependencies': [
|
||||||
|
'libzmq'
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
'target_name': 'test_reqrep_ipc',
|
'target_name': 'test_reqrep_ipc',
|
||||||
'type': 'executable',
|
'type': 'executable',
|
||||||
|
@ -72,6 +72,7 @@
|
|||||||
<test name = "test_udp" />
|
<test name = "test_udp" />
|
||||||
<test name = "test_shutdown_stress" />
|
<test name = "test_shutdown_stress" />
|
||||||
<test name = "test_pair_ipc" />
|
<test name = "test_pair_ipc" />
|
||||||
|
<test name = "test_rebind_ipc" />
|
||||||
<test name = "test_reqrep_ipc" />
|
<test name = "test_reqrep_ipc" />
|
||||||
<test name = "test_use_fd_ipc" />
|
<test name = "test_use_fd_ipc" />
|
||||||
<test name = "test_use_fd_tcp" />
|
<test name = "test_use_fd_tcp" />
|
||||||
|
@ -294,21 +294,12 @@ int zmq::ipc_listener_t::close ()
|
|||||||
|
|
||||||
s = retired_fd;
|
s = retired_fd;
|
||||||
|
|
||||||
// If there's an underlying UNIX domain socket, get rid of the file it
|
|
||||||
// is associated with.
|
|
||||||
// MUST NOT unlink if the FD is managed by the user, or it will stop
|
|
||||||
// working after the first client connects. The user will take care of
|
|
||||||
// cleaning up the file after the service is stopped.
|
|
||||||
if (has_file && options.use_fd == -1) {
|
if (has_file && options.use_fd == -1) {
|
||||||
rc = 0;
|
rc = 0;
|
||||||
|
|
||||||
if ( !filename.empty () ) {
|
|
||||||
rc = ::unlink(filename.c_str ());
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( rc == 0 && !tmp_socket_dirname.empty() ) {
|
if ( rc == 0 && !tmp_socket_dirname.empty() ) {
|
||||||
rc = ::rmdir(tmp_socket_dirname.c_str ());
|
rc = ::rmdir(tmp_socket_dirname.c_str ());
|
||||||
tmp_socket_dirname.clear();
|
tmp_socket_dirname.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
|
@ -80,6 +80,7 @@ if(NOT WIN32)
|
|||||||
list(APPEND tests
|
list(APPEND tests
|
||||||
test_ipc_wildcard
|
test_ipc_wildcard
|
||||||
test_pair_ipc
|
test_pair_ipc
|
||||||
|
test_rebind_ipc
|
||||||
test_reqrep_ipc
|
test_reqrep_ipc
|
||||||
test_proxy
|
test_proxy
|
||||||
test_proxy_single_socket
|
test_proxy_single_socket
|
||||||
|
83
tests/test_rebind_ipc.cpp
Normal file
83
tests/test_rebind_ipc.cpp
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2007-2017 Contributors as noted in the AUTHORS file
|
||||||
|
|
||||||
|
This file is part of libzmq, the ZeroMQ core engine in C++.
|
||||||
|
|
||||||
|
libzmq is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU Lesser General Public License (LGPL) as published
|
||||||
|
by the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
As a special exception, the Contributors give you permission to link
|
||||||
|
this library with independent modules to produce an executable,
|
||||||
|
regardless of the license terms of these independent modules, and to
|
||||||
|
copy and distribute the resulting executable under terms of your choice,
|
||||||
|
provided that you also meet, for each linked independent module, the
|
||||||
|
terms and conditions of the license of that module. An independent
|
||||||
|
module is a module which is not derived from or based on this library.
|
||||||
|
If you modify this library, you must extend this exception to your
|
||||||
|
version of the library.
|
||||||
|
|
||||||
|
libzmq is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "testutil.hpp"
|
||||||
|
|
||||||
|
static const char* SOCKET_ADDR = "ipc:///tmp/tester";
|
||||||
|
|
||||||
|
|
||||||
|
int main (void)
|
||||||
|
{
|
||||||
|
setup_test_environment();
|
||||||
|
|
||||||
|
void *ctx = zmq_ctx_new ();
|
||||||
|
assert (ctx);
|
||||||
|
|
||||||
|
void *sb = zmq_socket (ctx, ZMQ_PUSH);
|
||||||
|
assert (sb);
|
||||||
|
int rc = zmq_bind (sb, SOCKET_ADDR);
|
||||||
|
assert (rc == 0);
|
||||||
|
|
||||||
|
void *sc = zmq_socket (ctx, ZMQ_PULL);
|
||||||
|
assert (sc);
|
||||||
|
rc = zmq_connect (sc, SOCKET_ADDR);
|
||||||
|
assert (rc == 0);
|
||||||
|
|
||||||
|
rc = zmq_send (sb, "42", 2, 0);
|
||||||
|
assert (rc == 2);
|
||||||
|
|
||||||
|
char buffer [2];
|
||||||
|
rc = zmq_recv(sc, buffer, 2, 0);
|
||||||
|
assert (rc == 2);
|
||||||
|
|
||||||
|
rc = zmq_close (sb);
|
||||||
|
assert (rc == 0);
|
||||||
|
|
||||||
|
sb = zmq_socket (ctx, ZMQ_PUSH);
|
||||||
|
assert (sb);
|
||||||
|
rc = zmq_bind (sb, SOCKET_ADDR);
|
||||||
|
assert (rc == 0);
|
||||||
|
|
||||||
|
rc = zmq_send (sb, "42", 2, 0);
|
||||||
|
assert (rc == 2);
|
||||||
|
|
||||||
|
rc = zmq_recv(sc, buffer, 2, 0);
|
||||||
|
assert (rc == 2);
|
||||||
|
|
||||||
|
rc = zmq_close (sc);
|
||||||
|
assert (rc == 0);
|
||||||
|
|
||||||
|
rc = zmq_close (sb);
|
||||||
|
assert (rc == 0);
|
||||||
|
|
||||||
|
rc = zmq_ctx_term (ctx);
|
||||||
|
assert (rc == 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user