You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by st...@locus.apache.org on 2000/06/19 21:38:31 UTC
cvs commit: apache-2.0/src/lib/apr/network_io/unix sendrecv.c
stoddard 00/06/19 12:38:31
Modified: src CHANGES
src/lib/apr/network_io/unix sendrecv.c
Log:
Implement ap_sendfile on AIX
Submitted by: Victor Orlikowski
Reviewed by: Bill Stoddard
Revision Changes Path
1.159 +2 -0 apache-2.0/src/CHANGES
Index: CHANGES
===================================================================
RCS file: /home/cvs/apache-2.0/src/CHANGES,v
retrieving revision 1.158
retrieving revision 1.159
diff -u -r1.158 -r1.159
--- CHANGES 2000/06/19 00:45:38 1.158
+++ CHANGES 2000/06/19 19:38:29 1.159
@@ -1,4 +1,6 @@
Changes with Apache 2.0a5
+ *) Add ap_sendfile implementation for AIX
+ [Victor J. Orlikowski]
*) Repair C++ compatibility in ap_config.h, apr_file_io.h,
apr_network_io.h, and apr_thread_proc.h.
1.23 +107 -7 apache-2.0/src/lib/apr/network_io/unix/sendrecv.c
Index: sendrecv.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/network_io/unix/sendrecv.c,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -r1.22 -r1.23
--- sendrecv.c 2000/05/16 20:35:39 1.22
+++ sendrecv.c 2000/06/19 19:38:30 1.23
@@ -65,7 +65,7 @@
#define READ(x,y,z) read(x,y,z)
#endif
-#ifdef HAVE_SENDFILE
+#if defined(HAVE_SENDFILE) || defined(HAVE_SEND_FILE)
/* This file is needed to allow us access to the ap_file_t internals. */
#include "../../file_io/unix/fileio.h"
@@ -76,7 +76,7 @@
#define TCP_CORK 3
#endif
-#endif /* HAVE_SENDFILE */
+#endif /* HAVE_SENDFILE || HAVE_SEND_FILE */
static ap_status_t wait_for_io_or_timeout(ap_socket_t *sock, int for_read)
{
@@ -204,7 +204,7 @@
}
#endif
-#if defined(HAVE_SENDFILE)
+#if defined(HAVE_SENDFILE) || defined(HAVE_SEND_FILE)
/* TODO: Verify that all platforms handle the fd the same way
* (i.e. not moving current file pointer)
@@ -451,8 +451,108 @@
(*len) = rv;
return APR_SUCCESS;
}
-#else
-/* TODO: Add AIX support */
-#endif /* __linux__, __FreeBSD__, __HPUX__ */
-#endif /* HAVE_SENDFILE */
+#elif defined(_AIX)
+/* Need another check to make sure the dependencies are checked */
+/* AIX, version 4.3.2 with APAR IX85388, or version 4.3.3 and above */
+ap_status_t ap_sendfile(ap_socket_t * sock, ap_file_t * file,
+ ap_hdtr_t * hdtr, ap_off_t * offset, ap_size_t * len,
+ ap_int32_t flags)
+{
+ int i, ptr, rv = 0;
+ void * hbuf=NULL, * tbuf=NULL;
+ ap_status_t arv;
+ struct sf_parms parms;
+
+ /* AIX can also send the headers/footers as part of the system call
+ ... badly.*/
+ parms.header_length = 0;
+ if (hdtr && hdtr->numheaders) {
+ if (hdtr->numheaders == 1) {
+ parms.header_data = hdtr->headers[0].iov_base;
+ parms.header_length = hdtr->headers[0].iov_len;
+ }
+ else {
+ for (i = 0; i < hdtr->numheaders; i++) {
+ parms.header_length += hdtr->headers[i].iov_len;
+ }
+ /* Keepalives make ap_palloc a bad idea */
+ hbuf = malloc(parms.header_length);
+ ptr = 0;
+ for (i = 0; i < hdtr->numheaders; i++) {
+ memcpy(hbuf + ptr, hdtr->headers[i].iov_base,
+ hdtr->headers[i].iov_len);
+ ptr += hdtr->headers[i].iov_len;
+ }
+ parms.header_data = hbuf;
+ }
+ }
+ else parms.header_data = NULL;
+ parms.trailer_length = 0;
+ if (hdtr && hdtr->numtrailers) {
+ if (hdtr->numtrailers == 1) {
+ parms.trailer_data = hdtr->trailers[0].iov_base;
+ parms.trailer_length = hdtr->trailers[0].iov_len;
+ }
+ else {
+ for (i = 0; i < hdtr->numtrailers; i++) {
+ parms.trailer_length += hdtr->trailers[i].iov_len;
+ }
+ /* Keepalives make ap_palloc a bad idea */
+ tbuf = malloc(parms.trailer_length);
+ ptr = 0;
+ for (i = 0; i < hdtr->numtrailers; i++) {
+ memcpy(tbuf + ptr, hdtr->trailers[i].iov_base,
+ hdtr->trailers[i].iov_len);
+ ptr += hdtr->trailers[i].iov_len;
+ }
+ parms.trailer_data = tbuf;
+ }
+ }
+ else parms.trailer_data = NULL;
+
+ /* Whew! Headers and trailers set up. Now for the file data */
+
+ parms.file_descriptor = file->filedes;
+ parms.file_offset = *offset;
+ parms.file_bytes = *len;
+
+ /* O.K. All set up now. Let's go to town */
+
+ do {
+ rv = send_file(&(sock->socketdes), /* socket */
+ &(parms), /* all data */
+ flags /* flags */
+ );
+ } while (rv == -1 && errno == EINTR);
+
+ if (rv == -1 &&
+ (errno == EAGAIN || errno == EWOULDBLOCK) &&
+ sock->timeout != 0) {
+ arv = wait_for_io_or_timeout(sock, 0);
+ if (arv != APR_SUCCESS) {
+ *len = 0;
+ return arv;
+ }
+ else {
+ do {
+ rv = send_file(&(sock->socketdes), /* socket */
+ &(parms), /* all data */
+ flags /* flags */
+ );
+ } while (rv == -1 && errno == EINTR);
+ }
+ }
+ (*len) = parms.bytes_sent;
+
+ /* Clean up after ourselves */
+ if(hbuf) free(hbuf);
+ if(tbuf) free(tbuf);
+
+ if (rv == -1) {
+ return errno;
+ }
+ return APR_SUCCESS;
+}
+#endif /* __linux__, __FreeBSD__, __HPUX__, _AIX */
+#endif /* HAVE_SENDFILE */