You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ma...@hyperreal.org on 1999/10/20 21:35:34 UTC

cvs commit: apache-2.0/src/os/unix iol_socket.c

manoj       99/10/20 12:35:33

  Modified:    src/include ap_iol.h
               src/main buff.c iol_file.c
               src/os/unix iol_socket.c
  Log:
  Change the IOL API to no longer use errno. Functions now return error
  codes like APR does. iol_socket on non-Unix platforms hasn't been fixed
  yet.
  
  Revision  Changes    Path
  1.6       +20 -18    apache-2.0/src/include/ap_iol.h
  
  Index: ap_iol.h
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/include/ap_iol.h,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -d -u -r1.5 -r1.6
  --- ap_iol.h	1999/09/24 18:58:10	1.5
  +++ ap_iol.h	1999/10/20 19:35:17	1.6
  @@ -60,6 +60,8 @@
   #ifndef AP_IOL_H
   #define AP_IOL_H
   
  +#include "apr_errno.h" /* For ap_status_t and the APR_errnos */
  +
   typedef struct ap_iol ap_iol;
   typedef struct ap_iol_methods ap_iol_methods;
   
  @@ -68,22 +70,19 @@
   } ap_iol_option;
   
   /*
  -    write, writev, read guarantee they won't return EINTR.
  +    write, writev, read guarantee they won't return APR_EINTR.
   
  -    If no error occurs, they return the number of bytes read/written.
  +    If no error occurs, they return APR_SUCCESS.
   
       If timeout is negative, they may block forever, and they still don't
       guarantee they'll write/read the full length.
       
  -    If timeout is 0, they will never block, and will return -1 and
  -    EWOULDBLOCK in the event that they can't read/write any bytes.
  +    If timeout is 0, they will never block, and will return APR_EAGAIN
  +    in the event that they can't read/write any bytes.
   
       If the timeout is positive, they will block up to the specified number
       of seconds.  If the read/write can't be completed in that time,
  -    a -1 will be returned and errno will be set to ETIMEDOUT.
  -
  -    TODO: we've all agreed errno is somewhat evil, and it must be replaced
  -    by a status result code.  I'll leave that to someone else.
  +    APR_ETIMEDOUT will be returned.
   
       Just to drive the point home again -- none of these functions guarantee
       they will read/write the entire length specified.
  @@ -92,7 +91,7 @@
       of care if you're implementing filters.  It may mean you have to keep
       state from one call to the next.  The chunking filter will have an
       example of this.  If you're not sure how to handle the state sitatuation
  -    you will want to return EINVAL when the timeout is set to 0.  This may
  +    you will want to return APR_EINVAL when the timeout is set to 0.  This may
       break various things... hopefully we'll be able to recover gracefully.
   
       Note: implementation tip: if your system doesn't have writev(), you
  @@ -103,12 +102,15 @@
   */
   
   struct ap_iol_methods {
  -    int (*close)(ap_iol *fd);
  -    int (*write)(ap_iol *fd, const char *buf, int len);
  -    int (*writev)(ap_iol *fd, const struct iovec *vec, int nvec);
  -    int (*read)(ap_iol *fd, char *buf, int len);
  -    int (*setopt)(ap_iol *fd, ap_iol_option opt, const void *value);
  -    int (*getopt)(ap_iol *fd, ap_iol_option opt, void *value);
  +    ap_status_t (*close)(ap_iol *fd);
  +    ap_status_t (*write)(ap_iol *fd, const char *buf, int len,
  +                         ap_ssize_t *nbytes);
  +    ap_status_t (*writev)(ap_iol *fd, const struct iovec *vec, int nvec,
  +                          ap_ssize_t *nbytes);
  +    ap_status_t (*read)(ap_iol *fd, char *buf, int len,
  +                        ap_ssize_t *nbytes);
  +    ap_status_t (*setopt)(ap_iol *fd, ap_iol_option opt, const void *value);
  +    ap_status_t (*getopt)(ap_iol *fd, ap_iol_option opt, void *value);
       /* TODO: accept, connect, ... */
   };
   
  @@ -120,9 +122,9 @@
   };
   
   #define iol_close(iol)	((iol)->methods->close((iol)))
  -#define iol_write(iol, a, b) ((iol)->methods->write((iol), (a), (b)))
  -#define iol_writev(iol, a, b) ((iol)->methods->writev((iol), (a), (b)))
  -#define iol_read(iol, a, b) ((iol)->methods->read((iol), (a), (b)))
  +#define iol_write(iol, a, b, c) ((iol)->methods->write((iol), (a), (b), (c)))
  +#define iol_writev(iol, a, b, c) ((iol)->methods->writev((iol), (a), (b), (c)))
  +#define iol_read(iol, a, b, c) ((iol)->methods->read((iol), (a), (b), (c)))
   #define iol_setopt(iol, a, b) ((iol)->methods->setopt((iol), (a), (b)))
   #define iol_getopt(iol, a, b) ((iol)->methods->getopt((iol), (a), (b)))
   
  
  
  
  1.8       +51 -25    apache-2.0/src/main/buff.c
  
  Index: buff.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/main/buff.c,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -d -u -r1.7 -r1.8
  --- buff.c	1999/10/14 14:36:37	1.7
  +++ buff.c	1999/10/20 19:35:24	1.8
  @@ -55,6 +55,9 @@
    *
    */
   
  +/* TODO: Everything involving errno in here is a hack to manage the
  + * transition from errnohood to nonerrnohood - manoj */
  +
   #include "httpd.h"
   #include "http_main.h"
   #include "http_log.h"
  @@ -184,8 +187,7 @@
   {
       BUFF *fb = v;
   
  -    iol_close(fb->iol);
  -    return APR_SUCCESS;
  +    return iol_close(fb->iol);
   }
   
   /*
  @@ -199,6 +201,8 @@
   
   API_EXPORT(int) ap_bsetopt(BUFF *fb, int optname, const void *optval)
   {
  +    int rv;
  +
       switch (optname) {
       case BO_BYTECT:
   	fb->bytes_sent = *(const long int *) optval - (long int) fb->outcnt;
  @@ -210,7 +214,12 @@
   	    fb->flags |= B_NONBLOCK;
   	    /* XXX: should remove B_WR now... */
   	}
  -	return iol_setopt(fb->iol, AP_IOL_TIMEOUT, optval);
  +	rv = iol_setopt(fb->iol, AP_IOL_TIMEOUT, optval);
  +        if (rv == APR_SUCCESS) {
  +            return 0;
  +        }
  +        errno = rv;
  +        return -1;
       }
       errno = EINVAL;
       return -1;
  @@ -219,6 +228,7 @@
   API_EXPORT(int) ap_bgetopt(BUFF *fb, int optname, void *optval)
   {
       long int bs;
  +    int rv;
   
       switch (optname) {
       case BO_BYTECT:
  @@ -229,7 +239,12 @@
   	return 0;
   
       case BO_TIMEOUT:
  -	return iol_getopt(fb->iol, AP_IOL_TIMEOUT, optval);
  +	rv = iol_getopt(fb->iol, AP_IOL_TIMEOUT, optval);
  +        if (rv == APR_SUCCESS) {
  +            return 0;
  +        }
  +        errno = rv;
  +        return -1;
       }
       errno = EINVAL;
       return -1;
  @@ -318,19 +333,21 @@
   /* a wrapper around iol_read which checks for errors and EOFs */
   static int read_with_errors(BUFF *fb, void *buf, int nbyte)
   {
  -    int rv;
  +    int rv, bytes_read;
   
  -    rv = iol_read(fb->iol, buf, nbyte);
  -    if (rv == 0) {
  +    rv = iol_read(fb->iol, buf, nbyte, &bytes_read);
  +    if (rv == APR_SUCCESS && bytes_read == 0) {
   	fb->flags |= B_EOF;
       }
  -    else if (rv == -1) {
  -	fb->saved_errno = errno;
  -	if (errno != EAGAIN) {
  +    else if (rv != APR_SUCCESS) {
  +        errno = rv;
  +	fb->saved_errno = rv;
  +	if (rv != APR_EAGAIN) {
   	    doerror(fb, B_RD);
   	}
  +        return -1;
       }
  -    return rv;
  +    return bytes_read;
   }
   
   
  @@ -539,18 +556,19 @@
    */
   static int writev_with_errors(BUFF *fb, const struct iovec *vec, int nvec)
   {
  -    int rv;
  +    int rv, bytes_written;
   
  -    rv = iol_writev(fb->iol, vec, nvec);
  -    if (rv == -1) {
  -	fb->saved_errno = errno;
  -	if (errno != EAGAIN) {
  +    rv = iol_writev(fb->iol, vec, nvec, &bytes_written);
  +    if (rv != APR_SUCCESS) {
  +        errno = rv;
  +	fb->saved_errno = rv;
  +	if (rv != APR_EAGAIN) {
   	    doerror(fb, B_WR);
   	}
   	return -1;
       }
  -    fb->bytes_sent += rv;
  -    return rv;
  +    fb->bytes_sent += bytes_written;
  +    return bytes_written;
   }
   
   
  @@ -684,18 +702,19 @@
    */
   static int write_with_errors(BUFF *fb, const void *buf, int nbyte)
   {
  -    int rv;
  +    int rv, bytes_written;
   
  -    rv = iol_write(fb->iol, buf, nbyte);
  -    if (rv == -1) {
  -	fb->saved_errno = errno;
  -	if (errno != EAGAIN) {
  +    rv = iol_write(fb->iol, buf, nbyte, &bytes_written);
  +    if (rv != APR_SUCCESS) {
  +        errno = rv;
  +	fb->saved_errno = rv;
  +	if (rv != APR_EAGAIN) {
   	    doerror(fb, B_WR);
   	}
   	return -1;
       }
  -    fb->bytes_sent += rv;
  -    return rv;
  +    fb->bytes_sent += bytes_written;
  +    return bytes_written;
   }
   
   
  @@ -812,6 +831,13 @@
   	rc1 = 0;
       ap_kill_cleanup(fb->pool, fb, bcleanup);
       rc2 = iol_close(fb->iol);
  +    if (rc2 != APR_SUCCESS) {
  +        rc2 = 0;
  +    }
  +    else {
  +        errno = rc2;
  +        rc2 = -1;
  +    }
   
       fb->inptr = fb->inbase;
       fb->incnt = 0;
  
  
  
  1.4       +41 -37    apache-2.0/src/main/iol_file.c
  
  Index: iol_file.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/main/iol_file.c,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -d -u -r1.3 -r1.4
  --- iol_file.c	1999/09/24 18:58:35	1.3
  +++ iol_file.c	1999/10/20 19:35:26	1.4
  @@ -59,6 +59,7 @@
   #include "ap_iol.h"
   
   #if 0
  +/* This is the non-APRed iol_file */
   #include <sys/uio.h>
   
   typedef struct {
  @@ -67,7 +68,7 @@
   } iol_file;
   
   #define method(syscall, args)	\
  -    static int file_##syscall args \
  +    static ap_status_t file_##syscall args \
       { \
   	iol_file *iol = (iol_file *)viol; \
   	int rv; \
  @@ -76,15 +77,21 @@
   	do { \
   	    rv = syscall(iol->fd, arg1, arg2); \
   	} while (rv == -1 && errno == EINTR); \
  -	return rv; \
  +        if (rv >= 0) { \
  +            *nbytes = rv;
  +            return APR_SUCCESS; \
  +        } \
  +        *nbytes = 0;
  +	return errno; \
       }
   
  -method(write, (ap_iol *viol, const char *arg1, int arg2))
  -method(writev, (ap_iol *viol, const struct iovec *arg1, int arg2))
  -method(read, (ap_iol *viol, char *arg1, int arg2))
  +method(write, (ap_iol *viol, const char *arg1, int arg2,
  +               ap_ssize_t *nbytes))
  +method(writev, (ap_iol *viol, const struct iovec *arg1, int arg2, ap_ssize_t *nbytes))
  +method(read, (ap_iol *viol, char *arg1, int arg2, ap_ssize_t *nbytes))
   
   
  -static int file_close(ap_iol *viol)
  +static ap_status_t file_close(ap_iol *viol)
   {
       iol_file *iol = (iol_file *)viol;
       int rv;
  @@ -93,20 +100,21 @@
       rv = close(iol->fd);
       saved_errno = errno;
       free(iol);
  -    errno = saved_errno;
  -    return rv;
  +    if (rv == 0) {
  +        return APR_SUCCESS;
  +    }
  +    return saved_errno;
   }
   
  -static int file_setopt(ap_iol *viol, ap_iol_option opt, const void *value)
  +static ap_status_t file_setopt(ap_iol *viol, ap_iol_option opt,
  +                               const void *value)
   {
  -    errno = EINVAL;
  -    return -1;
  +    return APR_EINVAL;
   }
   
  -static int file_getopt(ap_iol *viol, ap_iol_option opt, void *value)
  +static ap_status_t file_getopt(ap_iol *viol, ap_iol_option opt, void *value)
   {
  -    errno = EINVAL;
  -    return -1;
  +    return APR_EINVAL;
   }
   
   static const ap_iol_methods file_methods = {
  @@ -139,52 +147,48 @@
       ap_file_t *file;
   } iol_file;
   
  -/* TODO: I am not sure I have the return codes right... 
  - * and errno has got to go. It is not thread safe on WIn32...
  - */
   #define method(syscall, args)	\
  -    static int file_##syscall args \
  +    static ap_status_t file_##syscall args \
       { \
           ap_status_t rv; \
   	iol_file *iol = (iol_file *)viol; \
  -	int cnt = arg2; \
  -	/* try writing, ignoring EINTR, the upper layer has to handle \
  -	    partial read/writes anyhow, so we can return early */ \
  +	*nbytes = arg2; \
  +        /* ignore partial reads and writes, the upper layer has to handle \
  +           them anyhow, so we can return early */ \
   	do { \
  -	    rv = syscall(iol->file, (void*)arg1, &cnt); \
  +	    rv = syscall(iol->file, (void*)arg1, nbytes); \
   	} while (rv == APR_EINTR); \
  -	return cnt; \
  +        if (rv != APR_SUCCESS) { \
  +            *nbytes = 0; \
  +        } \
  +	return rv; \
       }
   
  -method(ap_write, (ap_iol *viol, const char *arg1, int arg2))
  -method(ap_writev, (ap_iol *viol, const struct iovec *arg1, int arg2))
  -method(ap_read, (ap_iol *viol, char *arg1, int arg2))
  +method(ap_write, (ap_iol *viol, const char *arg1, int arg2, ap_ssize_t *nbytes))
  +method(ap_writev, (ap_iol *viol, const struct iovec *arg1, int arg2, ap_ssize_t *nbytes))
  +method(ap_read, (ap_iol *viol, char *arg1, int arg2, ap_ssize_t *nbytes))
   
   
   /* This function will clean-up the iol struct and close the file... */
  -static int file_close(ap_iol *viol)
  +static ap_status_t file_close(ap_iol *viol)
   {
       ap_status_t rv;
       iol_file *iol = (iol_file *)viol;
       rv = ap_close(iol->file);
       free(iol);
   
  -    if (rv == APR_SUCCESS)
  -        return 0;
  -    else
  -        return -1;
  +    return rv;
   }
   
  -static int file_setopt(ap_iol *viol, ap_iol_option opt, const void *value)
  +static ap_status_t file_setopt(ap_iol *viol, ap_iol_option opt,
  +                               const void *value)
   {
  -    errno = EINVAL;
  -    return -1;
  +    return APR_EINVAL;
   }
   
  -static int file_getopt(ap_iol *viol, ap_iol_option opt, void *value)
  +static ap_status_t file_getopt(ap_iol *viol, ap_iol_option opt, void *value)
   {
  -    errno = EINVAL;
  -    return -1;
  +    return APR_EINVAL;
   }
   
   static const ap_iol_methods file_methods = {
  
  
  
  1.5       +50 -32    apache-2.0/src/os/unix/iol_socket.c
  
  Index: iol_socket.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/os/unix/iol_socket.c,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -d -u -r1.4 -r1.5
  --- iol_socket.c	1999/08/28 12:22:12	1.4
  +++ iol_socket.c	1999/10/20 19:35:29	1.5
  @@ -73,7 +73,8 @@
       int timeout;
   } iol_socket;
   
  -static int unix_setopt(ap_iol *viol, ap_iol_option opt, const void *value)
  +static ap_status_t unix_setopt(ap_iol *viol, ap_iol_option opt,
  +                               const void *value)
   {
       iol_socket *iol = (iol_socket *)viol;
   
  @@ -82,13 +83,12 @@
   	iol->timeout = *(const int *)value;
   	break;
       default:
  -	errno = EINVAL;
  -	return -1;
  +	return APR_EINVAL;
       }
  -    return 0;
  +    return APR_SUCCESS;
   }
   
  -static int unix_getopt(ap_iol *viol, ap_iol_option opt, void *value)
  +static ap_status_t unix_getopt(ap_iol *viol, ap_iol_option opt, void *value)
   {
       iol_socket *iol = (iol_socket *)viol;
   
  @@ -97,29 +97,33 @@
   	*(int *)value = iol->timeout;
   	break;
       default:
  -	errno = EINVAL;
  -	return -1;
  +	return APR_EINVAL;
       }
  -    return 0;
  +    return APR_SUCCESS;
   }
   
  -static int set_nonblock(int fd)
  +static ap_status_t set_nonblock(int fd)
   {
       int fd_flags;
  +    int rv;
   
       fd_flags = fcntl(fd, F_GETFL, 0);
   #if defined(O_NONBLOCK)
       fd_flags |= O_NONBLOCK;
  -    return fcntl(fd, F_SETFL, fd_flags);
  +    rv = fcntl(fd, F_SETFL, fd_flags);
   #elif defined(O_NDELAY)
       fd_flags |= O_NDELAY;
  -    return fcntl(fd, F_SETFL, fd_flags);
  +    rv = fcntl(fd, F_SETFL, fd_flags);
   #elif defined(FNDELAY)
       fd_flags |= O_FNDELAY;
  -    return fcntl(fd, F_SETFL, fd_flags);
  +    rv = fcntl(fd, F_SETFL, fd_flags);
   #else
   #error "your unix lacks non-blocking i/o, you lose"
   #endif
  +    if (rv == 0) {
  +        return APR_SUCCESS;
  +    }
  +    return errno;
   }
   
   /* the timeout code is a separate routine because it requires
  @@ -129,7 +133,7 @@
   /* this macro expands into the four basic i/o methods */
   
   #define method(name, args, syscall, selread, selwrite)	\
  -    static int unix_##name##_timeout args \
  +    static ap_status_t unix_##name##_timeout args \
       { \
   	iol_socket *iol = (iol_socket *)viol; \
   	fd_set fdset; \
  @@ -144,27 +148,38 @@
   	    rv = select(iol->fd + 1, selread, selwrite, NULL, iol->timeout < 0 ? NULL : &tv); \
   	} while (rv == -1 && errno == EINTR); \
   	if (!FD_ISSET(iol->fd, &fdset)) { \
  -	    errno = ETIMEDOUT; \
  -	    return -1; \
  +	    return APR_ETIMEDOUT; \
   	} \
   	do { \
   	    rv = syscall(iol->fd, arg1, arg2); \
   	} while (rv == -1 && errno == EINTR); \
  -	return rv; \
  +        if (rv >= 0) { \
  +            *nbytes = rv; \
  +            return APR_SUCCESS; \
  +        } \
  +	return errno; \
  +     \
       } \
    \
  -    static int unix_##name args \
  +    static ap_status_t unix_##name args \
       { \
   	iol_socket *iol = (iol_socket *)viol; \
   	int rv; \
    \
  +        /* Present to zero until some bytes are actually written */ \
  +        *nbytes = 0; \
   	if (!(iol->flags & FD_NONBLOCKING_SET)) { \
   	    if (iol->timeout < 0) { \
  -		return syscall(iol->fd, arg1, arg2); \
  +		rv = syscall(iol->fd, arg1, arg2); \
  +                if (rv >= 0) { \
  +                    *nbytes = rv; \
  +                    return APR_SUCCESS; \
  +                } \
  +                return errno; \
   	    } \
   	    /* must shift descriptor to blocking mode now */ \
  -	    if (set_nonblock(iol->fd)) { \
  -		return -1; \
  +	    if ((rv = set_nonblock(iol->fd)) != APR_SUCCESS) { \
  +		return rv; \
   	    } \
   	    iol->flags |= FD_NONBLOCKING_SET; \
   	} \
  @@ -174,20 +189,21 @@
   	do { \
   	    rv = syscall(iol->fd, arg1, arg2); \
   	} while (rv == -1 && errno == EINTR); \
  -	if (rv >= 0) { \
  -	    return rv; \
  -	} \
   	if ((errno == EWOULDBLOCK || errno == EAGAIN) && iol->timeout != 0) { \
  -	    return unix_##name##_timeout(viol, arg1, arg2); \
  +	    return unix_##name##_timeout(viol, arg1, arg2, nbytes); \
   	} \
  -	return -1; \
  -    } \
  +	if (rv >= 0) { \
  +	    *nbytes = rv; \
  +            return APR_SUCCESS; \
  +	} \
  +	return errno; \
  +    }
   
  -method(write, (ap_iol *viol, const char *arg1, int arg2), write, NULL, &fdset)
  -method(writev, (ap_iol *viol, const struct iovec *arg1, int arg2), writev, NULL, &fdset)
  -method(read, (ap_iol *viol, char *arg1, int arg2), read, &fdset, NULL)
  +method(write, (ap_iol *viol, const char *arg1, int arg2, ap_ssize_t *nbytes), write, NULL, &fdset)
  +method(writev, (ap_iol *viol, const struct iovec *arg1, int arg2, ap_ssize_t *nbytes), writev, NULL, &fdset)
  +method(read, (ap_iol *viol, char *arg1, int arg2, ap_ssize_t *nbytes), read, &fdset, NULL)
   
  -static int unix_close(ap_iol *viol)
  +static ap_status_t unix_close(ap_iol *viol)
   {
       iol_socket *iol = (iol_socket *)viol;
       int rv;
  @@ -196,8 +212,10 @@
       rv = close(iol->fd);
       saved_errno = errno;
       free(iol);
  -    errno = saved_errno;
  -    return rv;
  +    if (rv == 0) {
  +        return APR_SUCCESS;
  +    }
  +    return saved_errno;
   }
   
   static const ap_iol_methods socket_methods = {