From 24b7fb3c6faedc7f29fa8918b9367beb22d97d04 Mon Sep 17 00:00:00 2001 From: trawick Date: Mon, 4 Dec 2000 16:09:32 +0000 Subject: Add apr_make_os_sock() for constructing a fully-capable APR socket. The BeOS sockets.c doesn't look up-to-date and I think David is(has) switching(switched) to using the Unix sockets.c. Thus, I have not messed with it. git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@60882 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 3 +++ aprlib.def | 1 + include/apr_portable.h | 28 ++++++++++++++++++++++++++++ libapr.def | 1 + network_io/os2/sockets.c | 26 ++++++++++++++++++++++++++ network_io/unix/sockets.c | 31 +++++++++++++++++++++++++++++++ network_io/win32/sockets.c | 29 +++++++++++++++++++++++++++++ 7 files changed, 119 insertions(+) diff --git a/CHANGES b/CHANGES index 74121bd24..8cae6c51e 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,7 @@ Changes with APR a9 + *) Add apr_make_os_sock() for constructing a fully-capable APR + socket. [Jeff Trawick] + *) Make APR's shared memory routines always allocate enough memory for the requested segment, the MM internal types, and the APR internal types. diff --git a/aprlib.def b/aprlib.def index 485597e3e..8c0c2b539 100644 --- a/aprlib.def +++ b/aprlib.def @@ -75,6 +75,7 @@ EXPORTS apr_set_socketdata apr_get_polldata apr_set_polldata + apr_make_os_sock apr_put_os_sock apr_get_os_sock apr_remove_poll_socket diff --git a/include/apr_portable.h b/include/apr_portable.h index 6faf91447..ffa1246f9 100644 --- a/include/apr_portable.h +++ b/include/apr_portable.h @@ -184,6 +184,20 @@ typedef struct timeval apr_os_imp_time_t; typedef struct tm apr_os_exp_time_t; #endif +/** + * everything APR needs to know about an active socket to construct + * an APR socket from it; currently, this is platform-independent + */ +struct apr_os_sock_info_t { + apr_os_sock_t *os_sock; /* always required */ + struct sockaddr *local; /* NULL if not yet bound */ + struct sockaddr *remote; /* NULL if not connected */ + int family; /* always required (APR_INET, APR_INET6, etc. */ + int type; /* always required (SOCK_STREAM, SOCK_DGRAM, etc. */ +}; + +typedef struct apr_os_sock_info_t apr_os_sock_info_t; + /** * convert the file from apr type to os specific type. * @param thefile The os specific file we are converting to @@ -274,6 +288,20 @@ apr_status_t apr_put_os_dir(apr_dir_t **dir, apr_os_dir_t *thedir, apr_status_t apr_put_os_sock(apr_socket_t **sock, apr_os_sock_t *thesock, apr_pool_t *cont); +/** + * Create a socket from an existing descriptor and local and remote + * socket addresses. + * @param apr_sock The new socket that has been set up + * @param os_sock_info The os representation of the socket handle and + * other characteristics of the socket + * @param cont The pool to use + * @tip If you only know the descriptor/handle or if it isn't really + * a true socket, use apr_put_os_sock() instead. + */ +apr_status_t apr_make_os_sock(apr_socket_t **apr_sock, + apr_os_sock_info_t *os_sock_info, + apr_pool_t *cont); + /** * Convert the lock from os specific type to apr type * @param lock The apr lock we are converting to. diff --git a/libapr.def b/libapr.def index 485597e3e..8c0c2b539 100644 --- a/libapr.def +++ b/libapr.def @@ -75,6 +75,7 @@ EXPORTS apr_set_socketdata apr_get_polldata apr_set_polldata + apr_make_os_sock apr_put_os_sock apr_get_os_sock apr_remove_poll_socket diff --git a/network_io/os2/sockets.c b/network_io/os2/sockets.c index 4c5071742..f8f782ef4 100644 --- a/network_io/os2/sockets.c +++ b/network_io/os2/sockets.c @@ -263,7 +263,33 @@ apr_status_t apr_get_os_sock(apr_os_sock_t *thesock, apr_socket_t *sock) return APR_SUCCESS; } +apr_status_t apr_make_os_sock(apr_socket_t **apr_sock, + apr_os_sock_info_t *os_sock_info, + apr_pool_t *cont) +{ + alloc_socket(apr_sock, cont); + set_socket_vars(*apr_sock, os_sock_info->family); + (*apr_sock)->timeout = -1; + (*apr_sock)->socketdes = *os_sock_info->os_sock; + if (os_sock_info->local) { + memcpy(&(*apr_sock)->local_addr->sa.sin, + os_sock_info->local, + (*apr_sock)->local_addr->salen); + } + else { + (*apr_sock)->local_port_unknown = (*apr_sock)->local_interface_unknown = 1; + } + if (os_sock_info->remote) { + memcpy(&(*apr_sock)->remote_addr->sa.sin, + os_sock_info->remote, + (*apr_sock)->remote_addr->salen); + } + + apr_register_cleanup((*apr_sock)->cntxt, (void *)(*apr_sock), + socket_cleanup, apr_null_cleanup); + return APR_SUCCESS; +} apr_status_t apr_put_os_sock(apr_socket_t **sock, apr_os_sock_t *thesock, apr_pool_t *cont) { diff --git a/network_io/unix/sockets.c b/network_io/unix/sockets.c index 3e055e62e..9f4cd6b20 100644 --- a/network_io/unix/sockets.c +++ b/network_io/unix/sockets.c @@ -282,6 +282,37 @@ apr_status_t apr_get_os_sock(apr_os_sock_t *thesock, apr_socket_t *sock) return APR_SUCCESS; } +apr_status_t apr_make_os_sock(apr_socket_t **apr_sock, + apr_os_sock_info_t *os_sock_info, + apr_pool_t *cont) +{ + alloc_socket(apr_sock, cont); + set_socket_vars(*apr_sock, os_sock_info->family); + (*apr_sock)->timeout = -1; + (*apr_sock)->socketdes = *os_sock_info->os_sock; + if (os_sock_info->local) { + memcpy(&(*apr_sock)->local_addr->sa.sin, + os_sock_info->local, + (*apr_sock)->local_addr->salen); + } + else { + (*apr_sock)->local_port_unknown = (*apr_sock)->local_interface_unknown = 1; + } + if (os_sock_info->remote) { +#ifndef HAVE_POLL + (*apr_sock)->connected = 1; +#endif + memcpy(&(*apr_sock)->remote_addr->sa.sin, + os_sock_info->remote, + (*apr_sock)->remote_addr->salen); + } + + apr_register_cleanup((*apr_sock)->cntxt, (void *)(*apr_sock), + socket_cleanup, apr_null_cleanup); + + return APR_SUCCESS; +} + apr_status_t apr_put_os_sock(apr_socket_t **sock, apr_os_sock_t *thesock, apr_pool_t *cont) { diff --git a/network_io/win32/sockets.c b/network_io/win32/sockets.c index 13df55c11..0aed50f27 100644 --- a/network_io/win32/sockets.c +++ b/network_io/win32/sockets.c @@ -305,6 +305,35 @@ apr_status_t apr_get_os_sock(apr_os_sock_t *thesock, apr_socket_t *sock) return APR_SUCCESS; } +apr_status_t apr_make_os_sock(apr_socket_t **apr_sock, + apr_os_sock_info_t *os_sock_info, + apr_pool_t *cont) +{ + alloc_socket(apr_sock, cont); + set_socket_vars(*apr_sock, os_sock_info->family); + (*apr_sock)->timeout = -1; + (*apr_sock)->disconnected = 0; + (*apr_sock)->sock = *os_sock_info->os_sock; + if (os_sock_info->local) { + memcpy(&(*apr_sock)->local_addr->sa.sin, + os_sock_info->local, + (*apr_sock)->local_addr->salen); + } + else { + (*apr_sock)->local_port_unknown = (*apr_sock)->local_interface_unknown = 1; + } + if (os_sock_info->remote) { + memcpy(&(*apr_sock)->remote_addr->sa.sin, + os_sock_info->remote, + (*apr_sock)->remote_addr->salen); + } + + apr_register_cleanup((*apr_sock)->cntxt, (void *)(*apr_sock), + socket_cleanup, apr_null_cleanup); + + return APR_SUCCESS; +} + apr_status_t apr_put_os_sock(apr_socket_t **sock, apr_os_sock_t *thesock, apr_pool_t *cont) { -- cgit v1.2.1