summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Zhakov <ivan@apache.org>2022-01-20 12:40:37 +0000
committerIvan Zhakov <ivan@apache.org>2022-01-20 12:40:37 +0000
commita484479e9e36e50fd870eb223c5043fa90211ea4 (patch)
tree1a7eddfa889135959b68f6077a44cdee3bd07abd
parent9ab53c7804e74e3302efafd35182e1f670967d7f (diff)
downloadapr-a484479e9e36e50fd870eb223c5043fa90211ea4.tar.gz
On 'win32-pollset-wakeup-no-file-socket-emulation' branch:
Windows: Use term `socket_pipe` instead for `file_socket_pipe` for internal poll wakeup socket API. Move implementation to network_io/win32/socket_pipe.c from file_io/win32/pipe.c. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/branches/win32-pollset-wakeup-no-file-socket-emulation@1897246 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--CMakeLists.txt1
-rw-r--r--file_io/win32/pipe.c178
-rw-r--r--include/arch/win32/apr_arch_file_io.h8
-rw-r--r--include/arch/win32/apr_arch_networkio.h8
-rw-r--r--network_io/win32/socket_pipe.c195
-rw-r--r--poll/unix/wakeup.c6
6 files changed, 207 insertions, 189 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7fee043dd..adee368af 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -351,6 +351,7 @@ SET(APR_SOURCES
network_io/unix/sockaddr.c
network_io/unix/socket_util.c
network_io/win32/sendrecv.c
+ network_io/win32/socket_pipe.c
network_io/win32/sockets.c
network_io/win32/sockopt.c
passwd/apr_getpass.c
diff --git a/file_io/win32/pipe.c b/file_io/win32/pipe.c
index a28fdb843..3da361cb2 100644
--- a/file_io/win32/pipe.c
+++ b/file_io/win32/pipe.c
@@ -15,7 +15,6 @@
*/
#include "apr_arch_file_io.h"
-#include "apr_arch_networkio.h"
#include "apr_file_io.h"
#include "apr_general.h"
#include "apr_strings.h"
@@ -275,180 +274,3 @@ APR_DECLARE(apr_status_t) apr_os_pipe_put(apr_file_t **file,
{
return apr_os_pipe_put_ex(file, thefile, 0, pool);
}
-
-static apr_status_t create_socket_pipe(SOCKET *rd, SOCKET *wr)
-{
- FD_SET rs;
- SOCKET ls;
- struct timeval socktm;
- struct sockaddr_in pa;
- struct sockaddr_in la;
- struct sockaddr_in ca;
- int nrd;
- apr_status_t rv;
- int ll = sizeof(la);
- int lc = sizeof(ca);
- unsigned long bm = 1;
- char uid[8];
- char iid[8];
-
- *rd = INVALID_SOCKET;
- *wr = INVALID_SOCKET;
-
- /* Create the unique socket identifier
- * so that we know the connection originated
- * from us.
- */
- rv = apr_generate_random_bytes(uid, sizeof(uid));
- if (rv != APR_SUCCESS) {
- return rv;
- }
-
- if ((ls = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {
- return apr_get_netos_error();
- }
-
- pa.sin_family = AF_INET;
- pa.sin_port = 0;
- pa.sin_addr.s_addr = inet_addr("127.0.0.1");
-
- if (bind(ls, (SOCKADDR *)&pa, sizeof(pa)) == SOCKET_ERROR) {
- rv = apr_get_netos_error();
- goto cleanup;
- }
- if (getsockname(ls, (SOCKADDR *)&la, &ll) == SOCKET_ERROR) {
- rv = apr_get_netos_error();
- goto cleanup;
- }
- if (listen(ls, 1) == SOCKET_ERROR) {
- rv = apr_get_netos_error();
- goto cleanup;
- }
- if ((*wr = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {
- rv = apr_get_netos_error();
- goto cleanup;
- }
- if (connect(*wr, (SOCKADDR *)&la, sizeof(la)) == SOCKET_ERROR) {
- rv = apr_get_netos_error();
- goto cleanup;
- }
- if (send(*wr, uid, sizeof(uid), 0) != sizeof(uid)) {
- if ((rv = apr_get_netos_error()) == 0) {
- rv = APR_EINVAL;
- }
- goto cleanup;
- }
- if (ioctlsocket(ls, FIONBIO, &bm) == SOCKET_ERROR) {
- rv = apr_get_netos_error();
- goto cleanup;
- }
- for (;;) {
- int ns;
- int nc = 0;
- /* Listening socket is nonblocking by now.
- * The accept should create the socket
- * immediatelly because we are connected already.
- * However on buys systems this can take a while
- * until winsock gets a chance to handle the events.
- */
- FD_ZERO(&rs);
- FD_SET(ls, &rs);
-
- socktm.tv_sec = 1;
- socktm.tv_usec = 0;
- if ((ns = select(0, &rs, NULL, NULL, &socktm)) == SOCKET_ERROR) {
- /* Accept still not signaled */
- Sleep(100);
- continue;
- }
- if (ns == 0) {
- /* No connections in the last second */
- continue;
- }
- if ((*rd = accept(ls, (SOCKADDR *)&ca, &lc)) == INVALID_SOCKET) {
- rv = apr_get_netos_error();
- goto cleanup;
- }
- /* Verify the connection by reading/waiting for the identification */
- bm = 0;
- if (ioctlsocket(*rd, FIONBIO, &bm) == SOCKET_ERROR) {
- rv = apr_get_netos_error();
- goto cleanup;
- }
- nrd = recv(*rd, iid, sizeof(iid), 0);
- if (nrd == SOCKET_ERROR) {
- rv = apr_get_netos_error();
- goto cleanup;
- }
- if (nrd == (int)sizeof(uid) && memcmp(iid, uid, sizeof(uid)) == 0) {
- /* Got the right identifier, return. */
- break;
- }
- closesocket(*rd);
- }
- /* We don't need the listening socket any more */
- closesocket(ls);
- return 0;
-
-cleanup:
- /* Don't leak resources */
- closesocket(ls);
- if (*rd != INVALID_SOCKET)
- closesocket(*rd);
- if (*wr != INVALID_SOCKET)
- closesocket(*wr);
-
- *rd = INVALID_SOCKET;
- *wr = INVALID_SOCKET;
- return rv;
-}
-
-static apr_status_t socket_pipe_cleanup(void *thefile)
-{
- apr_socket_t *file = thefile;
- if (file->socketdes != INVALID_SOCKET) {
- shutdown(file->socketdes, SD_BOTH);
- closesocket(file->socketdes);
- file->socketdes = INVALID_SOCKET;
- }
- return APR_SUCCESS;
-}
-
-apr_status_t apr_file_socket_pipe_create(apr_socket_t **in,
- apr_socket_t **out,
- apr_pool_t *p)
-{
- apr_status_t rv;
- SOCKET rd;
- SOCKET wr;
-
- *in = NULL;
- *out = NULL;
-
- if ((rv = create_socket_pipe(&rd, &wr)) != APR_SUCCESS) {
- return rv;
- }
- apr_os_sock_put(in, &rd, p);
- apr_os_sock_put(out, &wr, p);
-
- /* read end of the pipe is non-blocking */
- apr_socket_timeout_set(*in, 0);
-
- apr_pool_cleanup_register(p, (void *)(*in), socket_pipe_cleanup,
- apr_pool_cleanup_null);
- apr_pool_cleanup_register(p, (void *)(*out), socket_pipe_cleanup,
- apr_pool_cleanup_null);
-
- return rv;
-}
-
-apr_status_t apr_file_socket_pipe_close(apr_socket_t *socket)
-{
- apr_status_t stat;
- if ((stat = socket_pipe_cleanup(socket)) == APR_SUCCESS) {
- apr_pool_cleanup_kill(socket->pool, socket, socket_pipe_cleanup);
-
- return APR_SUCCESS;
- }
- return stat;
-}
diff --git a/include/arch/win32/apr_arch_file_io.h b/include/arch/win32/apr_arch_file_io.h
index f5d20514b..2bee5abc1 100644
--- a/include/arch/win32/apr_arch_file_io.h
+++ b/include/arch/win32/apr_arch_file_io.h
@@ -250,12 +250,4 @@ apr_status_t filepath_root_case(char **rootpath, char *root, apr_pool_t *p);
apr_status_t file_cleanup(void *);
-extern apr_status_t
-apr_file_socket_pipe_create(apr_socket_t **in,
- apr_socket_t **out,
- apr_pool_t *p);
-
-extern apr_status_t
-apr_file_socket_pipe_close(apr_socket_t *socket);
-
#endif /* ! FILE_IO_H */
diff --git a/include/arch/win32/apr_arch_networkio.h b/include/arch/win32/apr_arch_networkio.h
index a2d0879c1..d02a765be 100644
--- a/include/arch/win32/apr_arch_networkio.h
+++ b/include/arch/win32/apr_arch_networkio.h
@@ -77,5 +77,13 @@ void apr_sockaddr_vars_set(apr_sockaddr_t *, int, apr_port_t);
(skt)->options &= ~(option); \
} while (0)
+extern apr_status_t
+apr_socket_pipe_create(apr_socket_t **in,
+ apr_socket_t **out,
+ apr_pool_t *p);
+
+extern apr_status_t
+apr_socket_pipe_close(apr_socket_t *socket);
+
#endif /* ! NETWORK_IO_H */
diff --git a/network_io/win32/socket_pipe.c b/network_io/win32/socket_pipe.c
new file mode 100644
index 000000000..d9cac504b
--- /dev/null
+++ b/network_io/win32/socket_pipe.c
@@ -0,0 +1,195 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "apr_arch_networkio.h"
+#include "apr_portable.h"
+
+static apr_status_t create_socket_pipe(SOCKET *rd, SOCKET *wr)
+{
+ FD_SET rs;
+ SOCKET ls;
+ struct timeval socktm;
+ struct sockaddr_in pa;
+ struct sockaddr_in la;
+ struct sockaddr_in ca;
+ int nrd;
+ apr_status_t rv;
+ int ll = sizeof(la);
+ int lc = sizeof(ca);
+ unsigned long bm = 1;
+ char uid[8];
+ char iid[8];
+
+ *rd = INVALID_SOCKET;
+ *wr = INVALID_SOCKET;
+
+ /* Create the unique socket identifier
+ * so that we know the connection originated
+ * from us.
+ */
+ rv = apr_generate_random_bytes(uid, sizeof(uid));
+ if (rv != APR_SUCCESS) {
+ return rv;
+ }
+
+ if ((ls = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {
+ return apr_get_netos_error();
+ }
+
+ pa.sin_family = AF_INET;
+ pa.sin_port = 0;
+ pa.sin_addr.s_addr = inet_addr("127.0.0.1");
+
+ if (bind(ls, (SOCKADDR *)&pa, sizeof(pa)) == SOCKET_ERROR) {
+ rv = apr_get_netos_error();
+ goto cleanup;
+ }
+ if (getsockname(ls, (SOCKADDR *)&la, &ll) == SOCKET_ERROR) {
+ rv = apr_get_netos_error();
+ goto cleanup;
+ }
+ if (listen(ls, 1) == SOCKET_ERROR) {
+ rv = apr_get_netos_error();
+ goto cleanup;
+ }
+ if ((*wr = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {
+ rv = apr_get_netos_error();
+ goto cleanup;
+ }
+ if (connect(*wr, (SOCKADDR *)&la, sizeof(la)) == SOCKET_ERROR) {
+ rv = apr_get_netos_error();
+ goto cleanup;
+ }
+ if (send(*wr, uid, sizeof(uid), 0) != sizeof(uid)) {
+ if ((rv = apr_get_netos_error()) == 0) {
+ rv = APR_EINVAL;
+ }
+ goto cleanup;
+ }
+ if (ioctlsocket(ls, FIONBIO, &bm) == SOCKET_ERROR) {
+ rv = apr_get_netos_error();
+ goto cleanup;
+ }
+ for (;;) {
+ int ns;
+ int nc = 0;
+ /* Listening socket is nonblocking by now.
+ * The accept should create the socket
+ * immediatelly because we are connected already.
+ * However on buys systems this can take a while
+ * until winsock gets a chance to handle the events.
+ */
+ FD_ZERO(&rs);
+ FD_SET(ls, &rs);
+
+ socktm.tv_sec = 1;
+ socktm.tv_usec = 0;
+ if ((ns = select(0, &rs, NULL, NULL, &socktm)) == SOCKET_ERROR) {
+ /* Accept still not signaled */
+ Sleep(100);
+ continue;
+ }
+ if (ns == 0) {
+ /* No connections in the last second */
+ continue;
+ }
+ if ((*rd = accept(ls, (SOCKADDR *)&ca, &lc)) == INVALID_SOCKET) {
+ rv = apr_get_netos_error();
+ goto cleanup;
+ }
+ /* Verify the connection by reading/waiting for the identification */
+ bm = 0;
+ if (ioctlsocket(*rd, FIONBIO, &bm) == SOCKET_ERROR) {
+ rv = apr_get_netos_error();
+ goto cleanup;
+ }
+ nrd = recv(*rd, iid, sizeof(iid), 0);
+ if (nrd == SOCKET_ERROR) {
+ rv = apr_get_netos_error();
+ goto cleanup;
+ }
+ if (nrd == (int)sizeof(uid) && memcmp(iid, uid, sizeof(uid)) == 0) {
+ /* Got the right identifier, return. */
+ break;
+ }
+ closesocket(*rd);
+ }
+ /* We don't need the listening socket any more */
+ closesocket(ls);
+ return 0;
+
+cleanup:
+ /* Don't leak resources */
+ closesocket(ls);
+ if (*rd != INVALID_SOCKET)
+ closesocket(*rd);
+ if (*wr != INVALID_SOCKET)
+ closesocket(*wr);
+
+ *rd = INVALID_SOCKET;
+ *wr = INVALID_SOCKET;
+ return rv;
+}
+
+static apr_status_t socket_pipe_cleanup(void *thefile)
+{
+ apr_socket_t *file = thefile;
+ if (file->socketdes != INVALID_SOCKET) {
+ shutdown(file->socketdes, SD_BOTH);
+ closesocket(file->socketdes);
+ file->socketdes = INVALID_SOCKET;
+ }
+ return APR_SUCCESS;
+}
+
+apr_status_t apr_socket_pipe_create(apr_socket_t **in,
+ apr_socket_t **out,
+ apr_pool_t *p)
+{
+ apr_status_t rv;
+ SOCKET rd;
+ SOCKET wr;
+
+ *in = NULL;
+ *out = NULL;
+
+ if ((rv = create_socket_pipe(&rd, &wr)) != APR_SUCCESS) {
+ return rv;
+ }
+ apr_os_sock_put(in, &rd, p);
+ apr_os_sock_put(out, &wr, p);
+
+ /* read end of the pipe is non-blocking */
+ apr_socket_timeout_set(*in, 0);
+
+ apr_pool_cleanup_register(p, (void *)(*in), socket_pipe_cleanup,
+ apr_pool_cleanup_null);
+ apr_pool_cleanup_register(p, (void *)(*out), socket_pipe_cleanup,
+ apr_pool_cleanup_null);
+
+ return rv;
+}
+
+apr_status_t apr_socket_pipe_close(apr_socket_t *socket)
+{
+ apr_status_t stat;
+ if ((stat = socket_pipe_cleanup(socket)) == APR_SUCCESS) {
+ apr_pool_cleanup_kill(socket->pool, socket, socket_pipe_cleanup);
+
+ return APR_SUCCESS;
+ }
+ return stat;
+}
diff --git a/poll/unix/wakeup.c b/poll/unix/wakeup.c
index e2deea172..bb0356444 100644
--- a/poll/unix/wakeup.c
+++ b/poll/unix/wakeup.c
@@ -33,7 +33,7 @@ apr_status_t apr_poll_create_wakeup_socket(apr_pool_t *pool, apr_pollfd_t *pfd,
{
apr_status_t rv;
- if ((rv = apr_file_socket_pipe_create(&wakeup_socket[0], &wakeup_socket[1],
+ if ((rv = apr_socket_pipe_create(&wakeup_socket[0], &wakeup_socket[1],
pool)) != APR_SUCCESS)
return rv;
@@ -50,11 +50,11 @@ apr_status_t apr_poll_close_wakeup_socket(apr_socket_t **wakeup_socket)
/* Close both sides of the wakeup pipe */
if (wakeup_socket[0]) {
- rv0 = apr_file_socket_pipe_close(wakeup_socket[0]);
+ rv0 = apr_socket_pipe_close(wakeup_socket[0]);
wakeup_socket[0] = NULL;
}
if (wakeup_socket[1]) {
- rv1 = apr_file_socket_pipe_close(wakeup_socket[1]);
+ rv1 = apr_socket_pipe_close(wakeup_socket[1]);
wakeup_socket[1] = NULL;
}
return rv0 ? rv0 : rv1;