diff options
-rw-r--r-- | file_io/unix/fileacc.c | 1 | ||||
-rw-r--r-- | include/apr.h.in | 8 | ||||
-rw-r--r-- | include/apr_network_io.h | 18 | ||||
-rw-r--r-- | network_io/unix/poll.c | 14 | ||||
-rw-r--r-- | test/testfile.c | 29 |
5 files changed, 69 insertions, 1 deletions
diff --git a/file_io/unix/fileacc.c b/file_io/unix/fileacc.c index 7ff1d2cdc..32a574dc3 100644 --- a/file_io/unix/fileacc.c +++ b/file_io/unix/fileacc.c @@ -132,4 +132,3 @@ ap_status_t ap_set_filedata(ap_file_t *file, void *data, char *key, return APR_ENOFILE; } } - diff --git a/include/apr.h.in b/include/apr.h.in index 921779594..581ac5b34 100644 --- a/include/apr.h.in +++ b/include/apr.h.in @@ -66,6 +66,14 @@ #define APR_HAS_XLATE @iconv@ #define APR_HAS_OTHER_CHILD @oc@ +/* Any time a file and socket are represented as the same type, this macro + * should be true. I don't know of any platforms using Autoconf where this + * isn't true (OS/2? maybe), but I know it isn't true for Windows. For right + * now, just define it as 1, and Windows will define it correctly, if this + * turns out to not work, we can devise an Autoconf test for it later. rbb + */ +#define APR_FILES_AS_SOCKETS 1 + /* Typedefs that APR needs. */ typedef @short_value@ ap_int16_t; diff --git a/include/apr_network_io.h b/include/apr_network_io.h index 3509f2f5e..9d2b08f33 100644 --- a/include/apr_network_io.h +++ b/include/apr_network_io.h @@ -711,6 +711,24 @@ B<Return the pool associated with the current poll.> ap_status_t ap_set_polldata(ap_pollfd_t *pollfd, void *data, char *key, ap_status_t (*cleanup) (void *)); +/* + +=head1 ap_status_t ap_socket_from_file(ap_socket_t **newsock, ap_file_t *file) + +B<Convert a File type to a socket so that it can be used in a poll operation.> + + arg 1) the newly created socket which represents a file. + arg 2) the file to mask as a socket. + +B<NOTE>: This is not available on all platforms. Platforms that have the + ability to poll files for data to be read/written/exceptions will + have the APR_FILES_AS_SOCKETS macro defined as true. + +=cut + */ +ap_status_t ap_socket_from_file(ap_socket_t **newsock, ap_file_t *file); + + /* accessor functions */ #ifdef __cplusplus diff --git a/network_io/unix/poll.c b/network_io/unix/poll.c index fedffdc53..5c33be865 100644 --- a/network_io/unix/poll.c +++ b/network_io/unix/poll.c @@ -53,6 +53,7 @@ */ #include "networkio.h" +#include "../../file_io/unix/fileio.h" #ifdef HAVE_POLL /* We can just use poll to do our socket polling. */ @@ -395,3 +396,16 @@ ap_status_t ap_set_polldata(ap_pollfd_t *pollfd, void *data, char *key, } } +#if APR_FILES_AS_SOCKETS +/* I'm not sure if this needs to return an ap_status_t or not, but + * for right now, we'll leave it this way, and change it later if + * necessary. + */ +ap_status_t ap_socket_from_file(ap_socket_t **newsock, ap_file_t *file) +{ + (*newsock) = ap_pcalloc(file->cntxt, sizeof(**newsock)); + (*newsock)->socketdes = file->filedes; + (*newsock)->cntxt = file->cntxt; + return APR_SUCCESS; +} +#endif diff --git a/test/testfile.c b/test/testfile.c index 1b164515e..32311354a 100644 --- a/test/testfile.c +++ b/test/testfile.c @@ -55,6 +55,7 @@ #include <stdio.h> #include <stdlib.h> #include "apr_file_io.h" +#include "apr_network_io.h" #include "apr_errno.h" #include "apr_general.h" #include "apr_lib.h" @@ -70,9 +71,12 @@ int main() ap_pool_t *context; ap_pool_t *cont2; ap_file_t *thefile = NULL; + ap_socket_t *testsock = NULL; + ap_pollfd_t *sdset = NULL; ap_status_t status = 0; ap_int32_t flag = APR_READ | APR_WRITE | APR_CREATE; ap_ssize_t nbytes = 0; + ap_int32_t rv; ap_off_t zer = 0; char *buf; char *str; @@ -143,6 +147,31 @@ int main() fprintf(stdout, "OK\n"); } +#if APR_FILES_AS_SOCKETS + fprintf(stdout, "\tThis platform supports files_like_sockets\n"); + fprintf(stdout, "\t\tMaking file look like a socket......."); + if (ap_socket_from_file(&testsock, thefile) != APR_SUCCESS) { + perror("Something went wrong"); + exit(-1); + } + fprintf(stdout, "OK\n"); + + fprintf(stdout, "\t\tChecking for incoming data......."); + ap_setup_poll(&sdset, 1, context); + ap_add_poll_socket(sdset, testsock, APR_POLLIN); + rv = 1; + if (ap_poll(sdset, &rv, -1) != APR_SUCCESS) { + fprintf(stderr, "Select caused an error\n"); + exit(-1); + } + else if (rv == 0) { + fprintf(stderr, "I should not return until rv == 1\n"); + exit(-1); + } + fprintf(stdout, "OK\n"); +#endif + + fprintf(stdout, "\tReading from the file......."); nbytes = (ap_ssize_t)strlen("this is a test"); buf = (char *)ap_palloc(context, nbytes + 1); |