You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by wr...@apache.org on 2002/01/11 10:51:24 UTC

cvs commit: apr/file_io/win32 filedup.c

wrowe       02/01/11 01:51:24

  Modified:    file_io/win32 filedup.c
  Log:
    Implement apr_file_dup2() for win32.  Don't understand precisely why
    we didn't change new_file to a simple apr_file_t* (???)
  
    Change a number of errors in the existing code, and make no guarentee
    that the new os_handle (if not a std handle) will ever be the same if
    its dup2'ed.  However, for posix similarity, succeed and close the
    original file, if the handle was open.
  
  Revision  Changes    Path
  1.35      +65 -45    apr/file_io/win32/filedup.c
  
  Index: filedup.c
  ===================================================================
  RCS file: /home/cvs/apr/file_io/win32/filedup.c,v
  retrieving revision 1.34
  retrieving revision 1.35
  diff -u -r1.34 -r1.35
  --- filedup.c	18 Jul 2001 19:32:29 -0000	1.34
  +++ filedup.c	11 Jan 2002 09:51:23 -0000	1.35
  @@ -62,62 +62,82 @@
   APR_DECLARE(apr_status_t) apr_file_dup(apr_file_t **new_file,
                                          apr_file_t *old_file, apr_pool_t *p)
   {
  -    BOOLEAN isStdHandle = FALSE;
  -    HANDLE hCurrentProcess = GetCurrentProcess();
  +    HANDLE hproc = GetCurrentProcess();
  +    HANDLE newhand = NULL;
  +        
  +    if (!DuplicateHandle(hproc, old_file->filehand, 
  +                         hproc, newhand, 0, FALSE, 
  +                         DUPLICATE_SAME_ACCESS)) {
  +        return apr_get_os_error();
  +    }
   
  -    if ((*new_file) == NULL) {
  -        if (p == NULL) {
  -            p = old_file->cntxt;
  -        }
  -            
  -        (*new_file) = (apr_file_t *) apr_pcalloc(p, sizeof(apr_file_t));
  -        if ((*new_file) == NULL) {
  -            return APR_ENOMEM;
  -        }
  -        if (!DuplicateHandle(hCurrentProcess, old_file->filehand, 
  -                             hCurrentProcess,
  -                             &(*new_file)->filehand, 0, FALSE, 
  -                             DUPLICATE_SAME_ACCESS)) {
  +    (*new_file) = (apr_file_t *) apr_pcalloc(p, sizeof(apr_file_t));
  +    (*new_file)->filehand = newhand;
  +    (*new_file)->flags = old_file->flags & ~APR_INHERIT;
  +    (*new_file)->cntxt = p;
  +    (*new_file)->fname = apr_pstrdup(p, old_file->fname);
  +    (*new_file)->append = old_file->append;
  +    (*new_file)->buffered = FALSE;
  +
  +    apr_pool_cleanup_register((*new_file)->cntxt, (void *)(*new_file), file_cleanup,
  +                        apr_pool_cleanup_null);
  +
  +    return APR_SUCCESS;
  +}
  +
  +
  +APR_DECLARE(apr_status_t) apr_file_dup2(apr_file_t **new_file,
  +                                        apr_file_t *old_file, apr_pool_t *p)
  +{
  +    DWORD stdhandle = -1;
  +    HANDLE hproc = GetCurrentProcess();
  +    HANDLE newhand = NULL;
  +    apr_int32_t newflags;
  +
  +    /* dup2 is not supported literaly with native Windows handles.
  +     * We can, however, emulate dup2 for the standard i/o handles,
  +     * and close and replace other handles with duped handles.
  +     * The os_handle will change, however.
  +     */
  +    if (old_file->filehand == GetStdHandle(STD_ERROR_HANDLE)) {
  +        stdhandle = STD_ERROR_HANDLE;
  +    }
  +    else if (old_file->filehand == GetStdHandle(STD_OUTPUT_HANDLE)) {
  +        stdhandle = STD_OUTPUT_HANDLE;
  +    }
  +    else if (old_file->filehand == GetStdHandle(STD_INPUT_HANDLE)) {
  +        stdhandle = STD_INPUT_HANDLE;
  +    }
  +
  +    if (stdhandle != -1) {
  +        if (!DuplicateHandle(hproc, old_file->filehand, 
  +                             hproc, newhand, 0,
  +                             TRUE, DUPLICATE_SAME_ACCESS)) {
               return apr_get_os_error();
           }
  -    } else {
  -        HANDLE hFile = (*new_file)->filehand;
  -        /* XXX: need to dup the handle!!! 
  -         */
  -        /* dup2 is not supported with native Windows handles. We 
  -         * can, however, emulate dup2 for the standard i/o handles.
  -         */
  -        if (hFile == GetStdHandle(STD_ERROR_HANDLE)) {
  -            isStdHandle = TRUE;
  -            if (!SetStdHandle(STD_ERROR_HANDLE, old_file->filehand))
  -                return apr_get_os_error();
  +        if (!SetStdHandle(stdhandle, newhand)) {
  +            return apr_get_os_error();
           }
  -        else if (hFile == GetStdHandle(STD_OUTPUT_HANDLE)) {
  -            isStdHandle = TRUE;
  -            if (!SetStdHandle(STD_OUTPUT_HANDLE, old_file->filehand))
  -                return apr_get_os_error();
  +        newflags = old_file->flags | APR_INHERIT;
  +    }
  +    else {
  +        if (!DuplicateHandle(hproc, old_file->filehand, 
  +                             hproc, newhand, 0,
  +                             FALSE, DUPLICATE_SAME_ACCESS)) {
  +            return apr_get_os_error();
           }
  -        else if (hFile == GetStdHandle(STD_INPUT_HANDLE)) {
  -            isStdHandle = TRUE;
  -            if (!SetStdHandle(STD_INPUT_HANDLE, old_file->filehand))
  -                return apr_get_os_error();
  +        if ((*new_file)->filehand) {
  +            CloseHandle((*new_file)->filehand);
           }
  -        else
  -            return APR_ENOTIMPL;
  +        newflags = old_file->flags & ~APR_INHERIT;
       }
   
  -    (*new_file)->flags = old_file->flags & ~APR_INHERIT;
  -    (*new_file)->cntxt = old_file->cntxt;
  -    (*new_file)->fname = apr_pstrdup(old_file->cntxt, old_file->fname);
  +    (*new_file)->flags = newflags;
  +    (*new_file)->filehand = newhand;
  +    (*new_file)->fname = apr_pstrdup((*new_file)->cntxt, old_file->fname);
       (*new_file)->append = old_file->append;
       (*new_file)->buffered = FALSE;
   
  -    if (!isStdHandle) {
  -        apr_pool_cleanup_register((*new_file)->cntxt, (void *)(*new_file), file_cleanup,
  -                            apr_pool_cleanup_null);
  -    }
  -
       return APR_SUCCESS;
   }
  -