예제 #1
0
static int __cdecl dup2_nolock(int const source_fh, int const target_fh) throw()
{
    if ((_osfile(source_fh) & FOPEN) == 0)
    {
        // If the source handle is not open, return an error.  Noe that the
        // DuplicateHandle API will not detect this error, because it implies
        // that _osfhnd(source_fh) == INVALID_HANDLE_VALUE, and this is a 
        // legal HANDLE value to be duplicated.
        errno = EBADF;
        _doserrno = 0;
        _ASSERTE(("Invalid file descriptor. File possibly closed by a different thread",0));
        return -1;
    }

    // If the target is open, close it first.  We ignore the possibility of an
    // error here:  an error simply means that the OS handle value may remain
    // bound for the duration of the process.
    if (_osfile(target_fh) & FOPEN)
    {
        _close_nolock(target_fh);
    }

    // Duplicate the source file onto the target file:
    intptr_t new_osfhandle;

    BOOL const result = DuplicateHandle(
        GetCurrentProcess(),
        reinterpret_cast<HANDLE>(_get_osfhandle(source_fh)),
        GetCurrentProcess(),
        &reinterpret_cast<HANDLE&>(new_osfhandle),
        0,
        TRUE,
        DUPLICATE_SAME_ACCESS);

    if (!result)
    {
        __acrt_errno_map_os_error(GetLastError());
        return -1;
    }

    __acrt_lowio_set_os_handle(target_fh, new_osfhandle);

    // Copy the _osfile information, with the FNOINHERIT bit cleared:
    _osfile(target_fh) = _osfile(source_fh) & ~FNOINHERIT;
    _textmode(target_fh) = _textmode(source_fh);
    _tm_unicode(target_fh) = _tm_unicode(source_fh);

    return 0;
}
예제 #2
0
파일: dup.c 프로젝트: flychen50/clib
static int __cdecl _dup_nolock(
        int fh
        )
{
        int newfh;                      /* variable for new file handle */
        ULONG dosretval;                /* o.s. return value */
        char fileinfo;                  /* _osfile info for file */
        intptr_t new_osfhandle;
        int success = FALSE;

        fileinfo = _osfile(fh);         /* get file info for file */

        if ( !(_osfile(fh) & FOPEN) )
                return -1;


        /* create duplicate handle */

        if ( (newfh = _alloc_osfhnd()) == -1 )
        {
                errno = EMFILE;         /* too many files error */
                _doserrno = 0L;         /* not an OS error */
                return -1;              /* return error to caller */
        }
        __TRY

            /*
             * duplicate the file handle
             */
            if ( !(DuplicateHandle(GetCurrentProcess(),
                                   (HANDLE)_get_osfhandle(fh),
                                   GetCurrentProcess(),
                                   (PHANDLE)&new_osfhandle,
                                   0L,
                                   TRUE,
                                   DUPLICATE_SAME_ACCESS)) )
            {
                    dosretval = GetLastError();
            }
            else {
                    _set_osfhnd(newfh, new_osfhandle);
                    dosretval = 0;
            }

            if (dosretval)
                        {
                    /* o.s. error -- map errpr and release handle */
                    _dosmaperr(dosretval);
            }
            else
            {
                    /*
                     * copy the _osfile value, with the FNOINHERIT bit cleared
                     */
                    _osfile(newfh) = fileinfo & ~FNOINHERIT;
                    _textmode(newfh) = _textmode(fh);
                    _tm_unicode(newfh) = _tm_unicode(fh);
                    success = TRUE;
            }

        __FINALLY
            if (!success)
            {
                _osfile(newfh) &= ~FOPEN;
            }
            _unlock_fh(newfh);
        __END_TRY_FINALLY

            return success ? newfh : -1;
}
예제 #3
0
파일: dup2.c 프로젝트: flychen50/clib
static int __cdecl _dup2_nolock (
        int fh1,
        int fh2
        )
{

        ULONG dosretval;                /* o.s. return code */
        intptr_t new_osfhandle;

        /*
         * Re-test and take care of case of unopened source handle. This is
         * necessary only in the multi-thread case where the file have been
         * closed by another thread before the lock was asserted, but after
         * the initial test above.
         */
        if ( !(_osfile(fh1) & FOPEN) ) {
                /*
                 * Source handle isn't open, bail out with an error.
                 * Note that the DuplicateHandle API will not detect this
                 * error since it implies that _osfhnd(fh1) ==
                 * INVALID_HANDLE_VALUE, and this is a legal HANDLE value
                 * (it's the HANDLE for the current process).
                 */
                errno = EBADF;
                _doserrno = 0;  /* not an OS error */
                _ASSERTE(("Invalid file descriptor. File possibly closed by a different thread",0));
                return -1;
        }


        /*
         * Take of the case of equal handles.
         */
        if ( fh1 == fh2 )
                /*
                 * Since fh1 is known to be open, return 0 indicating success.
                 * This is in conformance with the POSIX specification for
                 * dup2.
                 */
                return 0;

        /*
         * if fh2 is open, close it.
         */
        if ( _osfile(fh2) & FOPEN )
                /*
                 * close the handle. ignore the possibility of an error - an
                 * error simply means that an OS handle value may remain bound
                 * for the duration of the process.  Use _close_nolock as we
                 * already own lock
                 */
                (void) _close_nolock(fh2);


        /* Duplicate source file onto target file */

        if ( !(DuplicateHandle(GetCurrentProcess(),
                               (HANDLE)_get_osfhandle(fh1),
                               GetCurrentProcess(),
                               (PHANDLE)&new_osfhandle,
                               0L,
                               TRUE,
                               DUPLICATE_SAME_ACCESS)) )
        {

                dosretval = GetLastError();
        }
        else {
                _set_osfhnd(fh2, new_osfhandle);
                dosretval = 0;
        }

        if (dosretval) {
                _dosmaperr(dosretval);
                return -1;
        }

        /* copy the _osfile information, with the FNOINHERIT bit cleared */
        _osfile(fh2) = _osfile(fh1) & ~FNOINHERIT;
        _textmode(fh2) = _textmode(fh1);
        _tm_unicode(fh2) = _tm_unicode(fh1);

        return 0;
}