summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--file_io/unix/fileacc.c1
-rw-r--r--include/apr.h.in8
-rw-r--r--include/apr_network_io.h18
-rw-r--r--network_io/unix/poll.c14
-rw-r--r--test/testfile.c29
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);