Author: rpluem
Date: Sun Oct 4 12:09:57 2009
New Revision: 821524
URL: http://svn.apache.org/viewvc?rev=821524&view=rev
Log:
* Add apr_socket_is_connected to detect whether the remote side of a socket
is still open. The origin of apr_socket_is_connected is r473278 from
http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/proxy/proxy_util.c
in httpd.
Added:
apr/apr/trunk/network_io/os2/socket_util.c (with props)
apr/apr/trunk/network_io/unix/socket_util.c (with props)
Modified:
apr/apr/trunk/CHANGES
apr/apr/trunk/include/apr_network_io.h
apr/apr/trunk/libapr.dsp
apr/apr/trunk/network_io/beos/socketcommon.c
apr/apr/trunk/test/sockchild.c
apr/apr/trunk/test/testsock.c
Modified: apr/apr/trunk/CHANGES
URL: http://svn.apache.org/viewvc/apr/apr/trunk/CHANGES?rev=821524&r1=821523&r2=821524&view=diff
==============================================================================
--- apr/apr/trunk/CHANGES [utf-8] (original)
+++ apr/apr/trunk/CHANGES [utf-8] Sun Oct 4 12:09:57 2009
@@ -1,6 +1,9 @@
-*- coding: utf-8 -*-
Changes for APR 2.0.0
+ *) Add apr_socket_is_connected to detect whether the remote side of
+ a socket is still open. [Ruediger Pluem]
+
*) Transfer the apr-util spec file contents to apr.spec. [Graham
Leggett]
Modified: apr/apr/trunk/include/apr_network_io.h
URL: http://svn.apache.org/viewvc/apr/apr/trunk/include/apr_network_io.h?rev=821524&r1=821523&r2=821524&view=diff
==============================================================================
--- apr/apr/trunk/include/apr_network_io.h (original)
+++ apr/apr/trunk/include/apr_network_io.h Sun Oct 4 12:09:57 2009
@@ -375,6 +375,12 @@
apr_sockaddr_t *sa);
/**
+ * Check whether the remote side of a socket is still open.
+ * @param socket The socket to check
+ */
+APR_DECLARE(int) apr_socket_is_connected(apr_socket_t *socket);
+
+/**
* Create apr_sockaddr_t from hostname, address family, and port.
* @param sa The new apr_sockaddr_t.
* @param hostname The hostname or numeric address string to resolve/parse, or
Modified: apr/apr/trunk/libapr.dsp
URL: http://svn.apache.org/viewvc/apr/apr/trunk/libapr.dsp?rev=821524&r1=821523&r2=821524&view=diff
==============================================================================
--- apr/apr/trunk/libapr.dsp (original)
+++ apr/apr/trunk/libapr.dsp Sun Oct 4 12:09:57 2009
@@ -436,6 +436,10 @@
# End Source File
# Begin Source File
+SOURCE=.\network_io\unix\socket_util.c
+# End Source File
+# Begin Source File
+
SOURCE=.\network_io\win32\sendrecv.c
# End Source File
# Begin Source File
Modified: apr/apr/trunk/network_io/beos/socketcommon.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/network_io/beos/socketcommon.c?rev=821524&r1=821523&r2=821524&view=diff
==============================================================================
--- apr/apr/trunk/network_io/beos/socketcommon.c (original)
+++ apr/apr/trunk/network_io/beos/socketcommon.c Sun Oct 4 12:09:57 2009
@@ -3,3 +3,4 @@
#include "../unix/sockets.c"
#include "../unix/sockaddr.c"
#include "../unix/sockopt.c"
+#include "../unix/socket_util.c"
Added: apr/apr/trunk/network_io/os2/socket_util.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/network_io/os2/socket_util.c?rev=821524&view=auto
==============================================================================
--- apr/apr/trunk/network_io/os2/socket_util.c (added)
+++ apr/apr/trunk/network_io/os2/socket_util.c Sun Oct 4 12:09:57 2009
@@ -0,0 +1 @@
+#include "../unix/socket_util.c"
Propchange: apr/apr/trunk/network_io/os2/socket_util.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: apr/apr/trunk/network_io/unix/socket_util.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/network_io/unix/socket_util.c?rev=821524&view=auto
==============================================================================
--- apr/apr/trunk/network_io/unix/socket_util.c (added)
+++ apr/apr/trunk/network_io/unix/socket_util.c Sun Oct 4 12:09:57 2009
@@ -0,0 +1,57 @@
+/* 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_network_io.h"
+#include "apr_poll.h"
+
+int apr_socket_is_connected(apr_socket_t *socket)
+{
+ apr_pollfd_t pfds[1];
+ apr_status_t status;
+ apr_int32_t nfds;
+
+ pfds[0].reqevents = APR_POLLIN;
+ pfds[0].desc_type = APR_POLL_SOCKET;
+ pfds[0].desc.s = socket;
+
+ do {
+ status = apr_poll(&pfds[0], 1, &nfds, 0);
+ } while (APR_STATUS_IS_EINTR(status));
+
+ if (status == APR_SUCCESS && nfds == 1 &&
+ pfds[0].rtnevents == APR_POLLIN) {
+ apr_sockaddr_t unused;
+ apr_size_t len = 1;
+ char buf[1];
+ /* The socket might be closed in which case
+ * the poll will return POLLIN.
+ * If there is no data available the socket
+ * is closed.
+ */
+ status = apr_socket_recvfrom(&unused, socket, MSG_PEEK,
+ &buf[0], &len);
+ if (status == APR_SUCCESS && len)
+ return 1;
+ else
+ return 0;
+ }
+ else if (APR_STATUS_IS_EAGAIN(status) || APR_STATUS_IS_TIMEUP(status)) {
+ return 1;
+ }
+ return 0;
+
+}
+
Propchange: apr/apr/trunk/network_io/unix/socket_util.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: apr/apr/trunk/test/sockchild.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/test/sockchild.c?rev=821524&r1=821523&r2=821524&view=diff
==============================================================================
--- apr/apr/trunk/test/sockchild.c (original)
+++ apr/apr/trunk/test/sockchild.c Sun Oct 4 12:09:57 2009
@@ -76,5 +76,9 @@
apr_socket_close(sock);
exit((int)length);
}
+ else if (!strcmp("close", argv[1])) {
+ apr_socket_close(sock);
+ exit(0);
+ }
exit(-1);
}
Modified: apr/apr/trunk/test/testsock.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/test/testsock.c?rev=821524&r1=821523&r2=821524&view=diff
==============================================================================
--- apr/apr/trunk/test/testsock.c (original)
+++ apr/apr/trunk/test/testsock.c Sun Oct 4 12:09:57 2009
@@ -204,6 +204,55 @@
APR_ASSERT_SUCCESS(tc, "Problem closing socket", rv);
}
+static void test_is_connected(abts_case *tc, void *data)
+{
+ apr_status_t rv;
+ apr_socket_t *sock;
+ apr_socket_t *sock2;
+ apr_proc_t proc;
+ apr_size_t length = STRLEN;
+ char datastr[STRLEN];
+
+ sock = setup_socket(tc);
+ if (!sock) return;
+
+ launch_child(tc, &proc, "write", p);
+
+ rv = apr_socket_accept(&sock2, sock, p);
+ APR_ASSERT_SUCCESS(tc, "Problem with receiving connection", rv);
+
+ /* Check that the remote socket is still open */
+ ABTS_INT_EQUAL(tc, 1, apr_socket_is_connected(sock2));
+
+ memset(datastr, 0, STRLEN);
+ apr_socket_recv(sock2, datastr, &length);
+
+ /* Make sure that the server received the data we sent */
+ ABTS_STR_EQUAL(tc, DATASTR, datastr);
+ ABTS_SIZE_EQUAL(tc, strlen(datastr), wait_child(tc, &proc));
+
+ /* The child is dead, so should be the remote socket */
+ ABTS_INT_EQUAL(tc, 0, apr_socket_is_connected(sock2));
+
+ rv = apr_socket_close(sock2);
+ APR_ASSERT_SUCCESS(tc, "Problem closing connected socket", rv);
+
+ launch_child(tc, &proc, "close", p);
+
+ rv = apr_socket_accept(&sock2, sock, p);
+ APR_ASSERT_SUCCESS(tc, "Problem with receiving connection", rv);
+
+ /* The child closed the socket instantly */
+ ABTS_INT_EQUAL(tc, 0, apr_socket_is_connected(sock2));
+ wait_child(tc, &proc);
+
+ rv = apr_socket_close(sock2);
+ APR_ASSERT_SUCCESS(tc, "Problem closing connected socket", rv);
+
+ rv = apr_socket_close(sock);
+ APR_ASSERT_SUCCESS(tc, "Problem closing socket", rv);
+}
+
static void test_timeout(abts_case *tc, void *data)
{
apr_status_t rv;
@@ -351,6 +400,7 @@
abts_run_test(suite, test_create_bind_listen, NULL);
abts_run_test(suite, test_send, NULL);
abts_run_test(suite, test_recv, NULL);
+ abts_run_test(suite, test_is_connected, NULL);
abts_run_test(suite, test_timeout, NULL);
abts_run_test(suite, test_print_addr, NULL);
abts_run_test(suite, test_get_addr, NULL);
|