summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/nxt_controller.c2
-rw-r--r--src/nxt_listen_socket.c97
-rw-r--r--src/nxt_listen_socket.h2
-rw-r--r--src/nxt_runtime.c2
-rw-r--r--test/unit/main.py5
5 files changed, 90 insertions, 18 deletions
diff --git a/src/nxt_controller.c b/src/nxt_controller.c
index 26f1d53a..f4c3a00d 100644
--- a/src/nxt_controller.c
+++ b/src/nxt_controller.c
@@ -431,7 +431,7 @@ nxt_runtime_controller_socket(nxt_task_t *task, nxt_runtime_t *rt)
#endif
ls->handler = nxt_controller_conn_init;
- if (nxt_listen_socket_create(task, ls) != NXT_OK) {
+ if (nxt_listen_socket_create(task, rt->mem_pool, ls) != NXT_OK) {
return NXT_ERROR;
}
diff --git a/src/nxt_listen_socket.c b/src/nxt_listen_socket.c
index f433cf2b..f10abdef 100644
--- a/src/nxt_listen_socket.c
+++ b/src/nxt_listen_socket.c
@@ -27,13 +27,23 @@ nxt_listen_socket(nxt_task_t *task, nxt_socket_t s, int backlog)
nxt_int_t
-nxt_listen_socket_create(nxt_task_t *task, nxt_listen_socket_t *ls)
+nxt_listen_socket_create(nxt_task_t *task, nxt_mp_t *mp,
+ nxt_listen_socket_t *ls)
{
- nxt_log_t log, *old;
- nxt_uint_t family;
- nxt_socket_t s;
- nxt_thread_t *thr;
- nxt_sockaddr_t *sa;
+ nxt_log_t log, *old;
+ nxt_uint_t family;
+ nxt_socket_t s;
+ nxt_thread_t *thr;
+ nxt_sockaddr_t *sa;
+#if (NXT_HAVE_UNIX_DOMAIN)
+ int ret;
+ u_char *p;
+ nxt_err_t err;
+ nxt_socket_t ts;
+ nxt_sockaddr_t *orig_sa;
+ nxt_file_name_t *name, *tmp;
+ nxt_file_access_t access;
+#endif
sa = ls->sockaddr;
@@ -80,6 +90,36 @@ nxt_listen_socket_create(nxt_task_t *task, nxt_listen_socket_t *ls)
nxt_socket_defer_accept(task, s, sa);
}
+#if (NXT_HAVE_UNIX_DOMAIN)
+
+ if (family == AF_UNIX
+ && sa->type == SOCK_STREAM
+ && sa->u.sockaddr_un.sun_path[0] != '\0')
+ {
+ orig_sa = sa;
+
+ sa = nxt_sockaddr_alloc(mp, sa->socklen + 4, sa->length + 4);
+ if (sa == NULL) {
+ goto fail;
+ }
+
+ sa->type = SOCK_STREAM;
+ sa->u.sockaddr_un.sun_family = AF_UNIX;
+
+ p = nxt_cpystr((u_char *) sa->u.sockaddr_un.sun_path,
+ (u_char *) orig_sa->u.sockaddr_un.sun_path);
+ nxt_memcpy(p, ".tmp", 4);
+
+ nxt_sockaddr_text(sa);
+
+ (void) unlink(sa->u.sockaddr_un.sun_path);
+
+ } else {
+ orig_sa = NULL;
+ }
+
+#endif
+
if (nxt_socket_bind(task, s, sa) != NXT_OK) {
goto fail;
}
@@ -87,9 +127,6 @@ nxt_listen_socket_create(nxt_task_t *task, nxt_listen_socket_t *ls)
#if (NXT_HAVE_UNIX_DOMAIN)
if (family == AF_UNIX) {
- nxt_file_name_t *name;
- nxt_file_access_t access;
-
name = (nxt_file_name_t *) sa->u.sockaddr_un.sun_path;
access = (S_IRUSR | S_IWUSR);
@@ -109,6 +146,46 @@ nxt_listen_socket_create(nxt_task_t *task, nxt_listen_socket_t *ls)
goto listen_fail;
}
+#if (NXT_HAVE_UNIX_DOMAIN)
+
+ if (orig_sa != NULL) {
+ ts = nxt_socket_create(task, AF_UNIX, SOCK_STREAM, 0, 0);
+ if (ts == -1) {
+ goto listen_fail;
+ }
+
+ ret = connect(ts, &orig_sa->u.sockaddr, orig_sa->socklen);
+
+ err = nxt_socket_errno;
+
+ nxt_socket_close(task, ts);
+
+ if (ret == 0) {
+ nxt_alert(task, "connect(%d, %*s) succeed, address already in use",
+ ts, (size_t) orig_sa->length,
+ nxt_sockaddr_start(orig_sa));
+
+ goto listen_fail;
+ }
+
+ if (err != NXT_ENOENT && err != NXT_ECONNREFUSED) {
+ nxt_alert(task, "connect(%d, %*s) failed %E",
+ ts, (size_t) orig_sa->length,
+ nxt_sockaddr_start(orig_sa), err);
+
+ goto listen_fail;
+ }
+
+ tmp = (nxt_file_name_t *) sa->u.sockaddr_un.sun_path;
+ name = (nxt_file_name_t *) orig_sa->u.sockaddr_un.sun_path;
+
+ if (nxt_file_rename(tmp, name) != NXT_OK) {
+ goto listen_fail;
+ }
+ }
+
+#endif
+
ls->socket = s;
thr->log = old;
@@ -119,8 +196,6 @@ listen_fail:
#if (NXT_HAVE_UNIX_DOMAIN)
if (family == AF_UNIX) {
- nxt_file_name_t *name;
-
name = (nxt_file_name_t *) sa->u.sockaddr_un.sun_path;
(void) nxt_file_delete(name);
diff --git a/src/nxt_listen_socket.h b/src/nxt_listen_socket.h
index fac640de..e2435b76 100644
--- a/src/nxt_listen_socket.h
+++ b/src/nxt_listen_socket.h
@@ -54,7 +54,7 @@ typedef struct {
NXT_EXPORT nxt_int_t nxt_listen_socket(nxt_task_t *task, nxt_socket_t s,
int backlog);
-NXT_EXPORT nxt_int_t nxt_listen_socket_create(nxt_task_t *task,
+NXT_EXPORT nxt_int_t nxt_listen_socket_create(nxt_task_t *task, nxt_mp_t *mp,
nxt_listen_socket_t *ls);
NXT_EXPORT nxt_int_t nxt_listen_socket_update(nxt_task_t *task,
nxt_listen_socket_t *ls, nxt_listen_socket_t *prev);
diff --git a/src/nxt_runtime.c b/src/nxt_runtime.c
index 09fad1de..bcd156ee 100644
--- a/src/nxt_runtime.c
+++ b/src/nxt_runtime.c
@@ -1205,7 +1205,7 @@ nxt_runtime_listen_sockets_create(nxt_task_t *task, nxt_runtime_t *rt)
}
}
- if (nxt_listen_socket_create(task, &curr[c]) != NXT_OK) {
+ if (nxt_listen_socket_create(task, rt->mem_pool, &curr[c]) != NXT_OK) {
return NXT_ERROR;
}
diff --git a/test/unit/main.py b/test/unit/main.py
index 060a03a5..4507f71a 100644
--- a/test/unit/main.py
+++ b/test/unit/main.py
@@ -185,10 +185,7 @@ class TestUnit(unittest.TestCase):
atexit.register(self.stop)
- # Due to race between connect() and listen() after the socket binding
- # tests waits for unit.pid file which is created after listen().
-
- if not self.waitforfiles(self.testdir + '/unit.pid'):
+ if not self.waitforfiles(self.testdir + '/control.unit.sock'):
exit("Could not start unit")
self.skip_alerts = [