Example #1
0
	//------------------------------------------------------------------------------
	int CPosumStream::_close( int fh )
	{
        int r = 0;
        
        //_CHECK_FH_CLEAR_OSSERR_RETURN( fh, EBADF, -1 );
        //_VALIDATE_CLEAR_OSSERR_RETURN((fh >= 0 && (unsigned)fh < (unsigned)_nhandle), EBADF, -1);
        //_VALIDATE_CLEAR_OSSERR_RETURN((_osfile(fh) & FOPEN), EBADF, -1);

		flockfile();

        __try 
		{
            if ( m_chFlags & FOPEN )
			{
				r = _close_nolock( fh );
			}
            else 
			{
                errno = EBADF;
                r = -1;
                //assert(("Invalid file descriptor. File possibly closed by a different thread",0));
            }
        }
        __finally 
		{
			funlockfile();
        }

        return r;
	}
Example #2
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;
}
Example #3
0
// Closes the file associated with the given file handle.  On success, returns 0.
// On failure, returns -1 and sets errno.
extern "C" int __cdecl _close(int const fh)
{
    _CHECK_FH_CLEAR_OSSERR_RETURN(fh, EBADF, -1);
    _VALIDATE_CLEAR_OSSERR_RETURN((fh >= 0 && (unsigned)fh < (unsigned)_nhandle), EBADF, -1);
    _VALIDATE_CLEAR_OSSERR_RETURN((_osfile(fh) & FOPEN), EBADF, -1);

    return __acrt_lowio_lock_fh_and_call(fh, [&]()
    {
        if (_osfile(fh) & FOPEN)
        {
            return _close_nolock(fh);
        }
        else
        {
            errno = EBADF;
            _ASSERTE(("Invalid file descriptor. File possibly closed by a different thread",0));
            return -1;
        }
    });
}
Example #4
0
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;
}