httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From r..@locus.apache.org
Subject cvs commit: apache-2.0/src/lib/apr/file_io/unix fileio.h open.c readwrite.c
Date Thu, 06 Apr 2000 21:38:07 GMT
rbb         00/04/06 14:38:06

  Modified:    src/lib/apr/file_io/unix fileio.h open.c readwrite.c
  Log:
  Make ungetc work with un-buffered files on Unix.
  Submitted by:	Jon Travis <jtravis@covalent.net>
  Reviewed by:	Ryan Bloom
  
  Revision  Changes    Path
  1.13      +1 -0      apache-2.0/src/lib/apr/file_io/unix/fileio.h
  
  Index: fileio.h
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/lib/apr/file_io/unix/fileio.h,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- fileio.h	2000/04/03 18:37:00	1.12
  +++ fileio.h	2000/04/06 21:38:04	1.13
  @@ -110,6 +110,7 @@
       int eof_hit;
       int pipe;
       int timeout;
  +    int ungetchar;    /* Last char provided by an unget op. (-1 = no char)*/
   };
   
   struct ap_dir_t {
  
  
  
  1.40      +1 -0      apache-2.0/src/lib/apr/file_io/unix/open.c
  
  Index: open.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/lib/apr/file_io/unix/open.c,v
  retrieving revision 1.39
  retrieving revision 1.40
  diff -u -r1.39 -r1.40
  --- open.c	2000/04/06 16:11:33	1.39
  +++ open.c	2000/04/06 21:38:05	1.40
  @@ -116,6 +116,7 @@
       (*new)->oflags = oflags;
       (*new)->filedes = -1;
       (*new)->filehand = NULL;
  +    (*new)->ungetchar = -1;
   
       if ((flag & APR_READ) && (flag & APR_WRITE)) {
           buf_oflags = ap_pstrdup(cont, "r+");
  
  
  
  1.33      +85 -57    apache-2.0/src/lib/apr/file_io/unix/readwrite.c
  
  Index: readwrite.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/lib/apr/file_io/unix/readwrite.c,v
  retrieving revision 1.32
  retrieving revision 1.33
  diff -u -r1.32 -r1.33
  --- readwrite.c	2000/04/03 19:44:31	1.32
  +++ readwrite.c	2000/04/06 21:38:05	1.33
  @@ -54,6 +54,33 @@
   
   #include "fileio.h"
   
  +static ap_status_t wait_for_io_or_timeout(ap_file_t *file, int for_read)
  +{
  +    struct timeval tv;
  +    fd_set fdset;
  +    int srv;
  +
  +    do {
  +        FD_ZERO(&fdset);
  +        FD_SET(file->filedes, &fdset);
  +        tv.tv_sec = file->timeout;
  +        tv.tv_usec = 0;
  +        srv = select(FD_SETSIZE,
  +            for_read ? &fdset : NULL,
  +            for_read ? NULL : &fdset,
  +            NULL,
  +            file->timeout < 0 ? NULL : &tv);
  +    } while (srv == -1 && errno == EINTR);
  +
  +    if (srv == 0) {
  +        return APR_TIMEUP;
  +    }
  +    else if (srv < 0) {
  +        return errno;
  +    }
  +    return APR_SUCCESS;
  +}
  +
   /* ***APRDOC********************************************************
    * ap_status_t ap_read(ap_file_t *thefile, void *buf, ap_ssize_t *nbytes)
    *    Read data from the specified file.
  @@ -63,11 +90,13 @@
    * NOTE:  ap_read will read up to the specified number of bytes, but never
    * more.  If there isn't enough data to fill that number of bytes, all of
    * the available data is read.  The third argument is modified to reflect the
  - * number of bytes read. 
  + * number of bytes read.  If a char was put back into the stream via
  + * ungetc, it will be the first character returned. 
    */
   ap_status_t ap_read(ap_file_t *thefile, void *buf, ap_ssize_t *nbytes)
   {
       ap_ssize_t rv;
  +    int used_unget = FALSE;
   
       if(thefile == NULL || nbytes == NULL || (buf == NULL && *nbytes != 0))
           return APR_EBADARG;
  @@ -77,42 +106,32 @@
           return APR_EBADF;
       }
       
  +    if(*nbytes <= 0) {
  +        *nbytes = 0;
  +	return APR_SUCCESS;
  +    }
  +
       if (thefile->buffered) {
  -        rv = fread(buf, *nbytes, 1, thefile->filehand);
  +        rv = fread(buf, 1, *nbytes, thefile->filehand);
       }
       else {
  +        if(thefile->ungetchar != -1){
  +	  used_unget = TRUE;
  +	  *(char *)buf++ = (char)thefile->ungetchar;
  +	  (*nbytes)--;
  +          thefile->ungetchar == -1;
  +	}
  +	  
           do {
               rv = read(thefile->filedes, buf, *nbytes);
           } while (rv == -1 && errno == EINTR);
   
           if (rv == -1 && errno == EAGAIN && thefile->timeout != 0) {
  -            struct timeval *tv;
  -            fd_set fdset;
  -            int srv;
  -
  -            do {
  -                FD_ZERO(&fdset);
  -                FD_SET(thefile->filedes, &fdset);
  -                if (thefile->timeout == -1) {
  -                    tv = NULL;
  -                }
  -                else {
  -                    tv = ap_palloc(thefile->cntxt, sizeof(struct timeval));
  -                    tv->tv_sec  = thefile->timeout;
  -                    tv->tv_usec = 0;
  -                }
  -
  -                srv = select(FD_SETSIZE, &fdset, NULL, NULL, tv);
  -            } while (srv == -1 && errno == EINTR);
  -
  -            if (srv == 0) {
  -                (*nbytes) = 0;
  -                return APR_TIMEUP;
  +            ap_status_t arv = wait_for_io_or_timeout(thefile, 1);
  +            if (arv != APR_SUCCESS) {
  +                *nbytes = 0;
  +                return arv;
               }
  -            else if (srv < 0) {
  -                (*nbytes) = 0;
  -                return errno;
  -            }
               else {
                   do {
                       rv = read(thefile->filedes, buf, *nbytes);
  @@ -133,6 +152,10 @@
           return errno;
       }
       *nbytes = rv;
  +    if(used_unget){
  +      thefile->ungetchar = -1;
  +      *nbytes += 1;
  +    }
       return APR_SUCCESS;
   }
   
  @@ -168,32 +191,10 @@
           } while (rv == -1 && errno == EINTR);
   
           if (rv == -1 && errno == EAGAIN && thefile->timeout != 0) {
  -            struct timeval *tv;
  -            fd_set fdset;
  -            int srv;
  -
  -            do {
  -                FD_ZERO(&fdset);
  -                FD_SET(thefile->filedes, &fdset);
  -                if (thefile->timeout == -1) {
  -                    tv = NULL;
  -                }
  -                else {
  -                    tv = ap_palloc(thefile->cntxt, sizeof(struct timeval));
  -                    tv->tv_sec  = thefile->timeout;
  -                    tv->tv_usec = 0;
  -                }
  -
  -                srv = select(FD_SETSIZE, NULL, &fdset, NULL, tv);
  -            } while (srv == -1 && errno == EINTR);
  -
  -            if (srv == 0) {
  -                (*nbytes) = 0;
  -                return APR_TIMEUP;
  -            }
  -            else if (srv < 0) {
  -                (*nbytes) = 0;
  -                return errno;
  +            ap_status_t arv = wait_for_io_or_timeout(thefile, 0);
  +            if (arv != APR_SUCCESS) {
  +                *nbytes = 0;
  +                return arv;
               }
               else {
                   do {
  @@ -281,8 +282,9 @@
               return APR_SUCCESS;
           }
           return errno;
  +    } else {
  +        thefile->ungetchar = (unsigned char)ch;
       }
  -    /* Not sure what to do in this case.  For now, return SUCCESS. */
       return APR_SUCCESS; 
   }
   
  @@ -313,6 +315,12 @@
           }
           return errno;
       }
  +    
  +    if(thefile->ungetchar != -1){
  +        *ch = (char) thefile->ungetchar;
  +        thefile->ungetchar = -1;
  +        return APR_SUCCESS;
  +    }
       rv = read(thefile->filedes, ch, 1); 
       if (rv == 0) {
           thefile->eof_hit = TRUE;
  @@ -384,11 +392,14 @@
   ap_status_t ap_fgets(char *str, int len, ap_file_t *thefile)
   {
       ssize_t rv;
  -    int i;    
  +    int i, used_unget = FALSE, beg_idx;
   
       if(thefile == NULL || str == NULL || len < 0)
           return APR_EBADARG;
   
  +    if(len <= 1)  /* as per fgets() */
  +        return APR_SUCCESS;
  +
       if (thefile->buffered) {
           if (fgets(str, len, thefile->filehand)) {
               return APR_SUCCESS;
  @@ -398,10 +409,25 @@
           }
           return errno;
       }
  -    for (i = 0; i < len; i++) {
  +
  +    if(thefile->ungetchar != -1){
  +        str[0] = thefile->ungetchar;
  +	used_unget = TRUE;
  +	beg_idx = 1;
  +	if(str[0] == '\n' || str[0] == '\r'){
  +	    thefile->ungetchar = -1;
  +	    str[1] = '\0';
  +	    return APR_SUCCESS;
  +	}
  +    } else
  +        beg_idx = 0;
  +    
  +    for (i = beg_idx; i < len; i++) {
           rv = read(thefile->filedes, &str[i], 1); 
           if (rv == 0) {
               thefile->eof_hit = TRUE;
  +	    if(used_unget) thefile->filedes = -1;
  +	    str[i] = '\0';
               return APR_EOF;
           }
           else if (rv != 1) {
  @@ -410,6 +436,8 @@
           if (str[i] == '\n' || str[i] == '\r')
               break;
       }
  +    if(i < len-1)
  +      str[i+1] = '\0';
       return APR_SUCCESS; 
   }
   
  
  
  

Mime
View raw message