rbb 99/05/17 11:37:47
Modified: apr/network_io/beos networkio.h sendrecv.c sockets.c sockopt.c Added: apr/network_io/beos poll.c Log: Update the network I/O stuff for BeOS. Submitted by: David Reid Revision Changes Path 1.2 +21 -6 apache-apr/apr/network_io/beos/networkio.h Index: networkio.h =================================================================== RCS file: /home/cvs/apache-apr/apr/network_io/beos/networkio.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- networkio.h 1999/04/23 15:19:34 1.1 +++ networkio.h 1999/05/17 18:37:43 1.2 @@ -58,20 +58,35 @@ #include <socket.h> #include <netdb.h> +#include "apr_general.h" -/* This is for various routines that need to be removed. */ -#ifndef BEOS -#define BEOS -#endif +#define POLLIN 1 +#define POLLPRI 2 +#define POLLOUT 4 +#define POLLERR 8 +#define POLLHUP 16 +#define POLLNVAL 32 struct socket_t { int socketdes; char *remote_hostname; struct sockaddr_in * addr; - size_t addr_len; + int addr_len; }; -typedef fd_set sd_set_t; +struct pollfd_t { + struct socket_t *sock; + int16 events; + int16 revents; +}; + +struct beos_pollfd_t { + int fd; + int16 events; + int16 revents; +}; + +ap_int16_t get_event(ap_int16_t); #endif /* ! NETWORK_IO_H */ 1.3 +3 -2 apache-apr/apr/network_io/beos/sendrecv.c Index: sendrecv.c =================================================================== RCS file: /home/cvs/apache-apr/apr/network_io/beos/sendrecv.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- sendrecv.c 1999/05/10 14:36:28 1.2 +++ sendrecv.c 1999/05/17 18:37:44 1.3 @@ -58,11 +58,12 @@ #include <sys/time.h> #include <socket.h> #include <netdb.h> +#include "networkio.h" #include "apr_errno.h" #include "apr_general.h" #include "apr_network_io.h" -ap_ssize_t ap_send(ap_socket_t *sock, const char *buf, int len, time_t sec) +ap_ssize_t ap_send(ap_context_t *cont, ap_socket_t *sock, const char *buf, int len, time_t sec) { ap_ssize_t rv; @@ -96,7 +97,7 @@ return (ap_ssize_t) rv; } -ap_ssize_t ap_recv(ap_socket_t *sock, char *buf, int len, time_t sec) +ap_ssize_t ap_recv(ap_context_t *cont, ap_socket_t *sock, char *buf, int len, time_t sec) { ap_ssize_t rv; do { 1.3 +52 -49 apache-apr/apr/network_io/beos/sockets.c Index: sockets.c =================================================================== RCS file: /home/cvs/apache-apr/apr/network_io/beos/sockets.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- sockets.c 1999/05/10 14:36:28 1.2 +++ sockets.c 1999/05/17 18:37:44 1.3 @@ -57,61 +57,65 @@ #include <string.h> #include <socket.h> #include <netdb.h> +#include "networkio.h" #include "apr_network_io.h" #include "apr_general.h" -#include <stdio.h> -ap_socket_t *ap_create_tcp_socket(void) +ap_status_t socket_cleanup(void *sock) { - ap_socket_t *thesocket = (ap_socket_t *)malloc(sizeof(ap_socket_t)); + struct socket_t *thesocket = sock; + if (closesocket(thesocket->socketdes) == 0) { + thesocket->socketdes = -1; + return APR_SUCCESS; + } + else { + return APR_FAILURE; + } +} + +struct socket_t *ap_create_tcp_socket(ap_context_t *cont) +{ + struct socket_t *thesocket = (ap_socket_t *)ap_palloc(cont->pool,sizeof(ap_socket_t)); thesocket->socketdes = socket(AF_INET ,SOCK_STREAM, 0); thesocket->remote_hostname=NULL; - thesocket->addr = (struct sockaddr_in *) malloc(sizeof (struct sockaddr_in)); + thesocket->addr = (struct sockaddr_in *) ap_palloc(cont->pool,sizeof (struct sockaddr_in)); thesocket->addr->sin_family = AF_INET; thesocket->addr_len = sizeof(*thesocket->addr); - memset(&thesocket->addr->sin_zero, '0', sizeof(thesocket->addr->sin_zero)); + memset(&thesocket->addr->sin_zero, 0, sizeof(thesocket->addr->sin_zero)); if (thesocket->socketdes < 0) { - free (thesocket->addr); - free (thesocket); return NULL; } else { + ap_register_cleanup(cont->pool, (void *)thesocket, socket_cleanup, NULL); return thesocket; } } -ap_status_t ap_shutdown(ap_socket_t *thesocket, ap_shutdown_how_e how) +ap_status_t ap_shutdown(ap_context_t *cont, struct socket_t *thesocket, ap_shutdown_how_e how) { - if (shutdown(thesocket->socketdes, how) == 0) { + /*if (shutdown(thesocket->socketdes, how) == 0) {*/ return APR_SUCCESS; - } + /*} else { return APR_FAILURE; - } + }*/ } -ap_status_t ap_close_socket(ap_socket_t *thesocket) +ap_status_t ap_close_socket(ap_context_t *cont, struct socket_t *thesocket) { - if (closesocket(thesocket->socketdes) == 0) { - free(thesocket->addr); - free(thesocket->remote_hostname); - free(thesocket); - return APR_SUCCESS; - } - else { - return APR_FAILURE; - } + socket_cleanup(thesocket); + ap_kill_cleanup(cont->pool,thesocket,socket_cleanup); } -ap_status_t ap_setport(ap_socket_t *sock, ap_uint32_t port) +ap_status_t ap_setport(ap_context_t *cont, struct socket_t *sock, ap_uint32_t port) { sock->addr->sin_port = htons((short)port); return APR_SUCCESS; } -ap_status_t ap_bind(ap_socket_t *sock) +ap_status_t ap_bind(ap_context_t *cont, struct socket_t *sock) { sock->addr->sin_addr.s_addr = INADDR_ANY; if (bind(sock->socketdes, (struct sockaddr *)sock->addr, sock->addr_len) == -1) @@ -120,7 +124,7 @@ return APR_SUCCESS; } -ap_status_t ap_listen(ap_socket_t *sock, ap_int32_t backlog) +ap_status_t ap_listen(ap_context_t *cont, struct socket_t *sock, ap_int32_t backlog) { if (listen(sock->socketdes, backlog) == -1) return APR_FAILURE; @@ -128,50 +132,49 @@ return APR_SUCCESS; } -ap_socket_t *ap_accept(const ap_socket_t *sock) +struct socket_t *ap_accept(ap_context_t *cont, const struct socket_t *sock) { - ap_socket_t *new = (ap_socket_t *)malloc(sizeof(ap_socket_t)); + struct socket_t *new = (ap_socket_t *)ap_palloc(cont->pool,sizeof(ap_socket_t)); struct hostent *hptr; + new->addr = (struct sockaddr_in *)ap_palloc(cont->pool, sizeof(struct sockaddr_in)); + new->addr_len = sizeof(struct sockaddr_in); + + new->socketdes = accept(sock->socketdes, (struct sockaddr *)new->addr, &new->addr_len); - - new->socketdes = accept(sock->socketdes, (struct sockaddr *)new->addr, (int*)new->addr_len); + if (new->socketdes <0){ + return NULL; + } hptr = gethostbyaddr((char*)&new->addr->sin_addr, sizeof(struct in_addr), AF_INET); if (hptr != NULL){ new->remote_hostname = strdup(hptr->h_name); } - free (hptr); - if (new->socketdes >= 0) - return new; - free (new); - return NULL; + + ap_register_cleanup(cont->pool, (void *)new, socket_cleanup, NULL); + return new; } -ap_status_t ap_connect(ap_socket_t *sock, char *hostname, unsigned short port) +ap_status_t ap_connect(ap_context_t *cont, struct socket_t *sock, char *hostname) { struct hostent *hp; hp = gethostbyname(hostname); if ((sock->socketdes < 0) || (!hp) || (!sock->addr)) { - free(sock->addr); - free(sock); return APR_FAILURE; } memcpy((char *)&sock->addr->sin_addr, hp->h_addr , hp->h_length); - sock->addr->sin_port = htons((short)port); + sock->addr->sin_family = AF_INET; memset(sock->addr->sin_zero, 0, sizeof(sock->addr->sin_zero)); - sock->addr_len = sizeof(sock->addr); - if ((connect(sock->socketdes, sock->addr, sock->addr_len) < 0) && - (errno != EINPROGRESS)) { - free(sock->addr); - free(sock); - return APR_FAILURE; - } - else { - sock->remote_hostname = strdup(hostname); - return APR_SUCCESS; - } + sock->addr_len = sizeof(sock->addr); + while ((connect(sock->socketdes, (const struct sockaddr *)sock->addr, sock->addr_len) < 0)){ + if (errno != EALREADY && errno != EINPROGRESS) + return APR_FAILURE; + if (errno == EINPROGRESS) + printf ("EINPROGRESS "); + } + + sock->remote_hostname = strdup(hostname); + return APR_SUCCESS; } - 1.3 +11 -57 apache-apr/apr/network_io/beos/sockopt.c Index: sockopt.c =================================================================== RCS file: /home/cvs/apache-apr/apr/network_io/beos/sockopt.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- sockopt.c 1999/05/10 14:36:28 1.2 +++ sockopt.c 1999/05/17 18:37:45 1.3 @@ -56,85 +56,39 @@ #include <errno.h> #include <string.h> #include <sys/socket.h> -//#include <netinet/tcp.h> -//#include <netinet/in.h> #include <unistd.h> #include <fcntl.h> +#include "networkio.h" #include "apr_network_io.h" #include "apr_general.h" -#include <stdio.h> -int soblock(int sd) +ap_status_t ap_setsocketopt(ap_context_t *cont, struct socket_t *sock, ap_int32_t opt, ap_int32_t on) { - int fd_flags; - - fd_flags = fcntl(sd, F_GETFL, 0); -#if defined(O_NONBLOCK) - fd_flags &= ~O_NONBLOCK; -#elif defined(O_NDELAY) - fd_flags &= ~O_NDELAY; -#elif defined(FNDELAY) - fd_flags &= ~O_FNDELAY; -#else - /* XXXX: this breaks things, but an alternative isn't obvious...*/ - return -1; -#endif - return fcntl(sd, F_SETFL, fd_flags); -} - -int sononblock(int sd) -{ - int fd_flags; - - fd_flags = fcntl(sd, F_GETFL, 0); -#if defined(O_NONBLOCK) - fd_flags |= O_NONBLOCK; -#elif defined(O_NDELAY) - fd_flags |= O_NDELAY; -#eli f defined(FNDELAY) - fd_flags |= O_FNDELAY; -#else - /* XXXX: this breaks things, but an alternative isn't obvious...*/ - return -1; -#endif - return fcntl(sd, F_SETFL, fd_flags); -} - - -ap_status_t ap_setsocketopt(ap_socket_t *sock, ap_int32_t opt, ap_int32_t on) -{ int one; - char *set; if (on){ one = 1; - memset (set,1,sizeof(set)); - }else + }else { one = 0; - + } if (opt & APR_SO_DEBUG) { - if (setsockopt(sock->socketdes, SOL_SOCKET, SO_DEBUG, (char *) one, sizeof(int)) == -1) { + if (setsockopt(sock->socketdes, SOL_SOCKET, SO_DEBUG, &one, sizeof(one)) == -1) { return APR_FAILURE; } } if (opt & APR_SO_REUSEADDR) { - if (setsockopt(sock->socketdes, SOL_SOCKET, SO_REUSEADDR, (char *) one, sizeof(int)) == -1) { + if (setsockopt(sock->socketdes, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) == -1) { return APR_FAILURE; } } if (opt & APR_SO_NONBLOCK) { - if (on) { - if (soblock(sock->socketdes) == -1) - return APR_FAILURE; - } - else { - if (sononblock(sock->socketdes) == -1) - return APR_FAILURE; - } + if (setsockopt(sock->socketdes, SOL_SOCKET, SO_NONBLOCK, &one, sizeof(one)) == -1){ + return APR_FAILURE; + } } return APR_SUCCESS; } -ap_status_t ap_gethostname(char * buf, int len) +ap_status_t ap_gethostname(ap_context_t *cont, char * buf, int len) { if (gethostname(buf, len) == -1){ return APR_FAILURE; @@ -143,7 +97,7 @@ } } -char *ap_get_remote_hostname(ap_socket_t *sock) +char *ap_get_remote_hostname(ap_context_t *cont, struct socket_t *sock) { return sock->remote_hostname; } 1.1 apache-apr/apr/network_io/beos/poll.c Index: poll.c =================================================================== /* ==================================================================== * Copyright (c) 1999 The Apache Group. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by the Apache Group * for use in the Apache HTTP server project (http://www.apache.org/)." * * 4. The names "Apache Server" and "Apache Group" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please contact * [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * 6. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by the Apache Group * for use in the Apache HTTP server project (http://www.apache.org/)." * * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Group. * For more information on the Apache Group and the Apache HTTP server * project, please see <http://www.apache.org/>. * */ #include <errno.h> #include <stdio.h> #include "networkio.h" #include "apr_network_io.h" #include "networkio.h" #include "apr_general.h" /* BeOS R4 doesn't have a poll function, but R5 will have */ /* so for the time being we try our best with an implementaion that */ /* uses select. However, select on beos isn't that hot either, so */ /* until R5 we have to live with a less than perfect implementation */ struct pollfd_t *ap_setup_poll(ap_context_t *context, ap_int32_t num) { struct pollfd_t *new; new = (struct pollfd_t *)ap_palloc(context->pool, sizeof(struct pollfd_t) * num); return new; } ap_int16_t get_event(ap_int16_t event) { ap_int16_t rv = 0; if (event & APR_POLLIN) rv |= POLLIN; if (event & APR_POLLPRI) rv |= POLLPRI; if (event & APR_POLLOUT) rv |= POLLOUT; if (event & APR_POLLERR) rv |= POLLERR; if (event & APR_POLLHUP) rv |= POLLHUP; if (event & APR_POLLNVAL) rv |= POLLNVAL; return rv; } void ap_add_poll_socket(ap_context_t *cont, struct pollfd_t *aprset, struct socket_t *sock, ap_int16_t event, ap_int32_t pos) { aprset[pos].sock = sock; aprset[pos].events = get_event(event); } ap_int32_t ap_poll(ap_context_t *cont, struct pollfd_t *aprset, ap_int32_t nsds, ap_int32_t timeout) { int i; int rv,maxfd; uint32 starttime; char test = 'T'; struct timeval tv; fd_set rd; struct beos_pollfd_t *pollset; pollset = (struct beos_pollfd_t *)ap_palloc(cont->pool, sizeof(struct beos_pollfd_t *) * nsds);; FD_ZERO(&rd); /* try to build the fd_set mask for the read sockets... */ for (i = 0; i < nsds; i++) { pollset[i].fd = aprset[i].sock->socketdes; pollset[i].events = aprset[i].events; if (pollset[i].fd > maxfd) maxfd=pollset[i].fd; if (aprset[i].events & POLLIN) { printf ("Setting socket %d to POLLIN - maxfd is %d...\n",pollset[i].fd, maxfd); FD_SET(pollset[i].fd, &rd); } } /* now we have a timeout value - so set it into the timeval structure */ tv.tv_sec = timeout; tv.tv_usec=0; /*The timeout is given in seconds, so we use the real_time_clock() :-) */ starttime = real_time_clock(); tryselectagain: rv = select(maxfd + 1, &rd, NULL, NULL, &tv); /* if rv == -1 then it's an error */ /* if the errno == EINTR then we need to go again... */ if (rv == -1 && errno == EINTR){ printf ("EINTR\n"); if (timeout == -1){ /* i.e. no timeout */ goto tryselectagain; } else { /* OK - how long did we spend waiting ?? */ if ((real_time_clock() - starttime) < timeout){ tv.tv_sec = (real_time_clock() - starttime); goto tryselectagain; } else { /* we passed our timeout, so we return 0 */ rv=0; } } } /* if we get this far then we have either */ /* 1. a socket to look at... */ /* 2. an error situation */ /**/ /* NB we haven't looked at writing sockets yet!!! */ if (rv >= 0){ /* i.e. we have a read socket to set the revents for */ rv = 0; /* we reset for an independant check ! */ for (i = 0; i < nsds; i++){ int ret = 0; printf ("Looking at pollset %d for ",i); if (pollset[i].events & POLLIN) printf ("POLLIN"); if (pollset[i].events & POLLOUT) printf ("POLLOUT"); printf ("\n"); if ((pollset[i].events & POLLIN) && FD_ISSET(pollset[i].fd, &rd)){ printf ("socket %d is OK to read from.\n", pollset[i].fd); ret |= POLLIN; } if (pollset[i].events & POLLOUT) { printf ("Trying POLLOUT for %d...\n",i); /* we asked if we could send... */ if (send(pollset[i].fd, &test, 0, 0)!=0){ if (errno == EWOULDBLOCK){ /* the socket is blocking... */ /* we still haven't reached the timeout so go back and try again... */ if ((real_time_clock() - starttime)<timeout) goto tryselectagain; } else { /* an error has occurred... */ perror("********* POLLOUT in poll"); ret |= POLLERR; } } else { /* it's OK to send to the socket */ ret |= POLLOUT; } } if (ret != 0){ /* we have a change! */ pollset[i].revents = ret; aprset[i].revents = ret; rv ++; } } } if (rv == 0 && ((real_time_clock() - starttime) < timeout)) goto tryselectagain; return rv; }