apr-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dr...@apache.org
Subject cvs commit: apr/file_io/unix filedup.c
Date Fri, 11 Jan 2002 09:04:51 GMT
dreid       02/01/11 01:04:51

  Modified:    include  apr_file_io.h
               file_io/unix filedup.c
  Log:
  Add apr_file_dup2.
  
  This has implications in that we now only do dup2 when we call
  apr_file_dup2 and this will potentially cause problems for code
  using apr_file_dup. The changes attempt to follow posix more closely.
  
  Will Rowe is going to tackle Win32 and OS/2 today.
  Changes to apache on the way.
  
  Issues: what should we do for dup2 when we have differing pools being
  used?
  
  Revision  Changes    Path
  1.113     +12 -0     apr/include/apr_file_io.h
  
  Index: apr_file_io.h
  ===================================================================
  RCS file: /home/cvs/apr/include/apr_file_io.h,v
  retrieving revision 1.112
  retrieving revision 1.113
  diff -u -r1.112 -r1.113
  --- apr_file_io.h	8 Jan 2002 06:26:09 -0000	1.112
  +++ apr_file_io.h	11 Jan 2002 09:04:51 -0000	1.113
  @@ -391,6 +391,18 @@
                                         apr_pool_t *p);
   
   /**
  + * duplicate the specified file descriptor and close the original
  + * @param new_file The structure to duplicate into
  + * @param old_file The file to duplicate
  + * @param p        The pool to use for the new file
  + *
  + * @remark *arg1 MUST point at a valid apr_file_t. It cannot point at NULL
  + */
  +APR_DECLARE(apr_status_t) apr_file_dup2(apr_file_t **new_file,
  +                                        apr_file_t *old_file,
  +                                        apr_pool_t *p);
  +
  +/**
    * Move the read/write file offset to a specified byte within a file.
    * @param thefile The file descriptor
    * @param where How to move the pointer, one of:
  
  
  
  1.41      +56 -26    apr/file_io/unix/filedup.c
  
  Index: filedup.c
  ===================================================================
  RCS file: /home/cvs/apr/file_io/unix/filedup.c,v
  retrieving revision 1.40
  retrieving revision 1.41
  diff -u -r1.40 -r1.41
  --- filedup.c	8 Jan 2002 04:24:24 -0000	1.40
  +++ filedup.c	11 Jan 2002 09:04:51 -0000	1.41
  @@ -58,54 +58,84 @@
   #include "apr_thread_mutex.h"
   #include "inherit.h"
   
  -apr_status_t apr_file_dup(apr_file_t **new_file, apr_file_t *old_file, apr_pool_t *p)
  +static apr_status_t _file_dup(apr_file_t **new_file, 
  +                              apr_file_t *old_file, apr_pool_t *p,
  +                              int which_dup)
   {
  -    int have_file = 0;
  -
       if ((*new_file) == NULL) {
  -        (*new_file) = (apr_file_t *)apr_pcalloc(p, sizeof(apr_file_t));
  -        if ((*new_file) == NULL) {
  -            return APR_ENOMEM;
  +        if (which_dup == 1) {
  +            (*new_file) = (apr_file_t *)apr_pcalloc(p, sizeof(apr_file_t));
  +            if ((*new_file) == NULL) {
  +                return APR_ENOMEM;
  +            }
  +            (*new_file)->cntxt = p;
  +        } else {
  +            /* We can't dup2 unless we have a valid new_file */
  +            return APR_EINVAL;
           }
  -    } else {
  -        have_file = 1;
       }
  -    
  -    (*new_file)->cntxt = p; 
  -    if (have_file) {
  +
  +    if (which_dup == 2) {
           dup2(old_file->filedes, (*new_file)->filedes);
  -    }
  -    else {
  +    } else {
           (*new_file)->filedes = dup(old_file->filedes); 
       }
  +
       (*new_file)->fname = apr_pstrdup(p, old_file->fname);
       (*new_file)->buffered = old_file->buffered;
  -    if ((*new_file)->buffered) {
  +
  +    /* If the existing socket in a dup2 is already buffered, we
  +     * have an existing and valid (hopefully) mutex, so we don't
  +     * want to create it again as we could leak!
  +     */
   #if APR_HAS_THREADS
  +    if ((*new_file)->buffered && !(*new_file)->thlock) {
           apr_thread_mutex_create(&((*new_file)->thlock),
                                   APR_THREAD_MUTEX_DEFAULT, p);
  +    }
   #endif
  +    /* As above, only create the buffer if we haven't already
  +     * got one.
  +     */
  +    if ((*new_file)->buffered && !(*new_file)->buffer) {
           (*new_file)->buffer = apr_palloc(p, APR_FILE_BUFSIZE);
       }
  +
       /* this is the way dup() works */
       (*new_file)->blocking = old_file->blocking; 
  +
       /* make sure unget behavior is consistent */
       (*new_file)->ungetchar = old_file->ungetchar;
  +
       /* apr_file_dup() clears the inherit attribute, user must call 
        * apr_file_set_inherit() again on the dupped handle, as necessary.
  -     * If the user has dup2'ed fd 0-2 (stdin, stdout or stderr) we will
  -     * never, never, never close the handle, under any circumstance.
        */
  -    if (have_file && ((*new_file)->filedes >= 0) && ((*new_file)->filedes
<= 2)) {
  -        (*new_file)->flags = old_file->flags | APR_INHERIT;
  -        apr_pool_cleanup_register((*new_file)->cntxt, (void *)(*new_file), 
  -                                  apr_pool_cleanup_null, apr_pool_cleanup_null);
  -    }
  -    else {
  -        (*new_file)->flags = old_file->flags & ~APR_INHERIT;
  -        apr_pool_cleanup_register((*new_file)->cntxt, (void *)(*new_file), 
  -                                  apr_unix_file_cleanup, apr_unix_file_cleanup);
  -    }
  +    (*new_file)->flags = old_file->flags & ~APR_INHERIT;
  +
       return APR_SUCCESS;
  +}
  +
  +APR_DECLARE(apr_status_t) apr_file_dup(apr_file_t **new_file,
  +                                       apr_file_t *old_file, apr_pool_t *p)
  +{
  +    apr_status_t rv;
  +
  +    rv = _file_dup(new_file, old_file, p, 1);
  +    if (rv != APR_SUCCESS)
  +        return rv;
  +
  +    /* we do this here as we don't want to double register an existing 
  +     * apr_file_t for cleanup
  +     */
  +    apr_pool_cleanup_register((*new_file)->cntxt, (void *)(*new_file),
  +                              apr_unix_file_cleanup, apr_unix_file_cleanup);
  +    return rv;
  +
  +}
  +
  +APR_DECLARE(apr_status_t) apr_file_dup2(apr_file_t **new_file,
  +                                        apr_file_t *old_file, apr_pool_t *p)
  +{
  +    return _file_dup(new_file, old_file, p, 2);
   }
   
  
  
  

Mime
View raw message