예제 #1
0
파일: dup.c 프로젝트: flychen50/clib
int __cdecl _dup (
        int fh
        )
{
        int newfh =-1;                      /* variable for new file handle */

        /* validate file handle */
        _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);



        _lock_fh(fh);                   /* lock file handle */
        __TRY
                if ( _osfile(fh) & FOPEN )
                        newfh = _dup_nolock(fh);
                else {
                        errno = EBADF;
                        _doserrno = 0;
                        newfh = -1;
                        _ASSERTE(("Invalid file descriptor. File possibly closed by a different thread",0));
                }
        __FINALLY
                _unlock_fh(fh);
        __END_TRY_FINALLY

        return newfh;
}
예제 #2
0
파일: read.c 프로젝트: jetlive/skiaming
/* define normal version that locks/unlocks, validates fh */
int __cdecl _read (
        int fh,
        void *buf,
        unsigned cnt
        )
{
        int r;                          /* return value */

        /* validate handle */
        _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);

        _lock_fh(fh);                   /* lock file */

        __try {
            if ( _osfile(fh) & FOPEN )
                r = _read_nolock(fh, buf, cnt); /* read bytes */
            else {
                errno = EBADF;
                _doserrno = 0;
                r = -1;
                _ASSERTE(("Invalid file descriptor. File possibly closed by a different thread",0));
            }
        }
        __finally {
            _unlock_fh(fh);             /* unlock file */
        }

        return r;
}
예제 #3
0
파일: lseek.c 프로젝트: jetlive/skiaming
/* define locking/validating lseek */
long __cdecl _lseek (
        int fh,
        long pos,
        int mthd
        )
{
        int r;

        /* validate 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);

        _lock_fh(fh);                   /* lock file handle */

        __try {
                if ( _osfile(fh) & FOPEN )
                        r = _lseek_nolock(fh, pos, mthd);   /* seek */
                else {
                        errno = EBADF;
                        _doserrno = 0;
                        r = -1;
                        _ASSERTE(("Invalid file descriptor. File possibly closed by a different thread",0));
                }
        }
        __finally {
                _unlock_fh(fh);         /* unlock file handle */
        }

        return r;
}
예제 #4
0
파일: setmode.c 프로젝트: mysticTot/learn_c
int __cdecl _setmode(
    int fh,
    int mode
) {
    int retval;
    _VALIDATE_RETURN(((mode == _O_TEXT) ||
                      (mode == _O_BINARY) ||
                      (mode == _O_WTEXT) ||
                      (mode == _O_U8TEXT) ||
                      (mode == _O_U16TEXT)),
                     EINVAL, -1);
    _CHECK_FH_RETURN(fh, EBADF, -1);
    _VALIDATE_RETURN((fh >= 0 && (unsigned)fh < (unsigned)_nhandle), EBADF, -1);
    _VALIDATE_RETURN((_osfile(fh) & FOPEN), EBADF, -1);
    /* lock the file */
    _lock_fh(fh);

    __try {
        if (_osfile(fh) & FOPEN)
            /* set the text/binary mode */
        {
            retval = _setmode_nolock(fh, mode);
        } else {
            errno = EBADF;
            _ASSERTE(("Invalid file descriptor. File possibly closed by a different thread", 0));
            retval = -1;
        }
    } __finally {
        /* unlock the file */
        _unlock_fh(fh);
    }

    /* Return to user (_setmode_nolock sets errno, if needed) */
    return (retval);
}
예제 #5
0
// Closes the underlying OS file handle, if and only if nt needs to be closed.
// Returns 0 on success; returns the OS error on failure.
static DWORD close_os_handle_nolock(int const fh) throw()
{
    // If the underlying handle is INVALID_HANDLE_VALUE, don't try to acutally
    // close it:
    if (_get_osfhandle(fh) == (intptr_t)INVALID_HANDLE_VALUE)
        return 0;

    // If the file handle is stdout or stderr, and if stdout and stderr are
    // mapped to the same OS file handle, skip the CloseHandle without error.
    //
    // stdout and stderr are the only handles for which this support is
    // provided.  Other handles may be mapped to the same OS file handle only
    // at the programmer's risk.
    bool is_other_std_handle_open =
        fh == 1 && (_osfile(2) & FOPEN) ||
        fh == 2 && (_osfile(1) & FOPEN);

    if (is_other_std_handle_open && _get_osfhandle(1) == _get_osfhandle(2))
        return 0;

    // Otherwise, we can go ahead and close the handle:
    if (CloseHandle(reinterpret_cast<HANDLE>(_get_osfhandle(fh))))
        return 0;

    return GetLastError();
}
예제 #6
0
// Locks or unlocks the requested number of bytes in the specified file.
//
// Note that this function acquires the lock for the specified file and holds
// this lock for the entire duration of the call, even during the one second
// delays between calls into the operating system.  This is to prevent other
// threads from changing the file during the call.
//
// Returns 0 on success; returns -1 and sets errno on failure.
extern "C" int __cdecl _locking(int const fh, int const locking_mode, long const number_of_bytes)
{
    _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);
    _VALIDATE_CLEAR_OSSERR_RETURN(number_of_bytes >= 0, EINVAL, -1);

    __acrt_lowio_lock_fh(fh);
    int result = -1;
    __try
    {
        if ((_osfile(fh) & FOPEN) == 0)
        {
            errno = EBADF;
            _doserrno = 0;
            _ASSERTE(("Invalid file descriptor. File possibly closed by a different thread",0)); 
            __leave;
        }

        result = locking_nolock(fh, locking_mode, number_of_bytes);
    }
    __finally
    {
        __acrt_lowio_unlock_fh(fh);
    }
    return result;
}
예제 #7
0
static Integer __cdecl common_lseek(int const fh, Integer const offset, int const origin) throw()
{
    _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);

    __acrt_lowio_lock_fh(fh);
    Integer result = -1;
    __try
    {
        if ((_osfile(fh) & FOPEN) == 0)
        {
            errno = EBADF;
            _doserrno = 0;
            _ASSERTE(("Invalid file descriptor. File possibly closed by a different thread",0));      
            __leave;
        }
        
        result = common_lseek_nolock(fh, offset, origin);
    }
    __finally
    {
        __acrt_lowio_unlock_fh(fh);
    }
    return result;
}
예제 #8
0
/***
*virtual int filebuf::sync() - synchronize buffers with external file postion.
*
*Purpose:
*	Synchronizes buffer with external file, by flushing any output and/or
*	discarding any unread input data.  Discards any get or put area(s).
*
*Entry:
*	None.
*
*Exit:
*	Returns EOF if error, else 0.
*
*Exceptions:
*	Returns EOF if error.
*
*******************************************************************************/
int filebuf::sync()
{
        long count, nout;
        char * p;
        if (x_fd==-1)
            return(EOF);

        if (!unbuffered())
        {
            if ((count=out_waiting())!=0)
            {
                if ((nout =_write(x_fd,(void *) pbase(),(unsigned int)count)) != count)
                {
                    if (nout > 0) {
                        // should set _pptr -= nout
                        pbump(-(int)nout);
                        memmove(pbase(), pbase()+nout, (int)(count-nout));
                    }
                    return(EOF);
                }
            }
            setp(0,0); // empty put area

            if ((count=in_avail()) > 0)
            {
                // can't use seekoff here!!
#ifdef  _WIN32
                if (_osfile(x_fd) & FTEXT)
#else
                if (_osfile[x_fd] & FTEXT)
#endif
                {
                    // If text mode, need to account for CR/LF etc.
                    for (p = gptr(); p < egptr(); p++)
                        if (*p == '\n')
                            count++;

                    // account for EOF if read, not counted by _read
#ifdef  _WIN32
                    if ((_osfile(x_fd) & FEOFLAG))
#else
                    if ((_osfile[x_fd] & FEOFLAG))
#endif
                        count++;

                }
                if (_lseek(x_fd, -count, SEEK_CUR)==-1L)
                {
//                  unlock();
                    return (EOF);
                }
            }
            setg(0,0,0); // empty get area
        }
//      unlock();
        return(0);
}
예제 #9
0
파일: close.c 프로젝트: chunhualiu/OpenNT
/* now define version that doesn't lock/unlock, validate fh */
int __cdecl _close_lk (
	int fh
	)
{
	DWORD dosretval;

#else

/* now define normal version */
int __cdecl _close (
	int fh
	)
{
	DWORD dosretval;

	/* validate file handle */
	if ( ((unsigned)fh >= (unsigned)_nhandle) ||
             !(_osfile(fh) & FOPEN) )
        {
		/* bad file handle, set errno and abort */
		errno = EBADF;
		_doserrno = 0;	/* no o.s. error */
		return -1;
	}
#endif
	/*
	 * Close the underlying OS file handle. Note that if fh is STDOUT
	 * or STDERR, and if STDOUT and STDERR are mapped to the same OS
	 * file handle, the close is skipped (without error). STDOUT and
	 * STDERR are the only handles for which this support is provided.
	 * Other handles are mapped to the same OS file handle only at the
	 * programmer's risk.
	 */
	if ( ( ((fh == 1) || (fh == 2)) &&
	       (_get_osfhandle(1) == _get_osfhandle(2)) ) ||
	     CloseHandle( (HANDLE)_get_osfhandle(fh) ) )
	{

		dosretval = 0L;
	}
	else
		dosretval = GetLastError();

        _free_osfhnd(fh);

        if (dosretval) {
		/* OS error */
		_dosmaperr(dosretval);
		return -1;
	}
	_osfile(fh) = 0;		/* clear file flags */

	return 0;			/* good return */
}
static int
do_fcntl (int fd, int cmd, void *arg)
{
  switch (cmd) {
	case F_DUPFD:		/* Duplicate file descriptor */
		return dup (fd);
	case F_GETFD: 		/* Get file descriptor flags */
		if (_osfile (fd) & FNOINHERIT)
			return FD_CLOEXEC;
		else
			return 0;
	case F_SETFD: {		/* Set file descriptor flags */
		int newflags = (int) arg;
		if (newflags & FD_CLOEXEC) {
			newflags &= ~FD_CLOEXEC;
			newflags |= FNOINHERIT;
		}
		_osfile (fd) = newflags;
		return 0;
	}
	case F_GETFL: 		/* Get file status flags and file access modes */
		return osflags2mode (_osfile (fd));
	case F_SETFL: 		/* Set file status flags */
		_osfile (fd) = mode2osflags ( (int) arg);
		return 0;
	case F_GETLK: 		/* Get record locking information */
		break;
	case F_SETLK: 		/* Set record locking information */
	case F_SETLKW: {		/* Set record locking information; wait if blocked */
		 if (sizeof (*arg) == sizeof (struct flock64)) {
			 struct flock64 *fl = arg;
			 return lock64 (fd, cmd, fl);
		}
		else if (sizeof (*arg) == sizeof (struct flock)) {
			 struct flock *fl = arg;
			 return lock (fd, cmd, fl);
		}			 
		else {
		    __set_errno (EINVAL);
			return -1;
		}
	  }
	case F_GETOWN: 		/* Get process or process group ID to receive SIGURG signals */
		break;
	case F_SETOWN: 		/* Set process or process group ID to receive SIGURG signals */
		break;
	default:
      __set_errno (EINVAL);
      return -1;
	}
  __set_errno (ENOSYS);
  return -1;
}
예제 #11
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;
}
예제 #12
0
파일: eof.c 프로젝트: flychen50/clib
int __cdecl _eof (
        int filedes
        )
{
        __int64 here;
        __int64 end;
        int retval;

        _CHECK_FH_CLEAR_OSSERR_RETURN( filedes, EBADF, -1 );
        _VALIDATE_CLEAR_OSSERR_RETURN((filedes >= 0 && (unsigned)filedes < (unsigned)_nhandle), EBADF, -1);
        _VALIDATE_CLEAR_OSSERR_RETURN((_osfile(filedes) & FOPEN), EBADF, -1);


        /* Lock the file */
        _lock_fh(filedes);
        __try {
                if ( _osfile(filedes) & FOPEN ) {


        /* See if the current position equals the end of the file. */

        if ( ((here = _lseeki64_nolock(filedes, 0i64, SEEK_CUR)) == -1i64) ||
             ((end = _lseeki64_nolock(filedes, 0i64, SEEK_END)) == -1i64) )
                retval = -1;
        else if ( here == end )
                retval = 1;
        else {
                _lseeki64_nolock(filedes, here, SEEK_SET);
                retval = 0;
        }


                }
                else {
                        errno = EBADF;
                        _doserrno = 0;
                        retval = -1;
                        _ASSERTE(("Invalid file descriptor. File possibly closed by a different thread",0));
                }
        }
        __finally {
                /* Unlock the file */
                _unlock_fh(filedes);
        }


        /* Done */
        return(retval);
}
/*
 * WIN32_strerror with argument for late notification */

const char *
WIN32_strerror(int err)
{
    static char xbstrerror_buf[BUFSIZ];

    if (err < 0 || err >= sys_nerr)
	strncpy(xbstrerror_buf, wsastrerror(err), BUFSIZ);
    else
	strncpy(xbstrerror_buf, strerror(err), BUFSIZ);
    return xbstrerror_buf;
}

int
WIN32_Close_FD_Socket(int fd)
{
    int result = 0;

    if (closesocket(_get_osfhandle(fd)) == SOCKET_ERROR) {
	errno = WSAGetLastError();
	result = 1;
    }
    _free_osfhnd(fd);
    _osfile(fd) = 0;
    return result;
}

#if defined(__MINGW32__)	/* MinGW environment */
int
_free_osfhnd(int filehandle)
{
    if (((unsigned) filehandle < SQUID_MAXFD) &&
	(_osfile(filehandle) & FOPEN) &&
	(_osfhnd(filehandle) != (long) INVALID_HANDLE_VALUE)) {
	switch (filehandle) {
	case 0:
	    SetStdHandle(STD_INPUT_HANDLE, NULL);
	    break;
	case 1:
	    SetStdHandle(STD_OUTPUT_HANDLE, NULL);
	    break;
	case 2:
	    SetStdHandle(STD_ERROR_HANDLE, NULL);
	    break;
	}
	_osfhnd(filehandle) = (long) INVALID_HANDLE_VALUE;
	return (0);
    } else {
	errno = EBADF;		/* bad handle */
	_doserrno = 0L;		/* not an OS error */
	return -1;
    }
}
예제 #14
0
int __cdecl _commit (
    int filedes
)
{
    int retval;

    /* if filedes out of range, complain */
    _CHECK_FH_RETURN( filedes, EBADF, -1 );
    _VALIDATE_RETURN((filedes >= 0 && (unsigned)filedes < (unsigned)_nhandle), EBADF, -1);
    _VALIDATE_RETURN((_osfile(filedes) & FOPEN), EBADF, -1);

    _lock_fh(filedes);
    __try {
        if (_osfile(filedes) & FOPEN) {

            if ( !FlushFileBuffers((HANDLE)_get_osfhandle(filedes)) ) {
                retval = GetLastError();
            }
            else {
                retval = 0;     /* return success */
            }

            /* map the OS return code to C errno value and return code */
            if (retval == 0)
                goto good;

            _doserrno = retval;

        }

        errno = EBADF;
        retval = -1;

        _ASSERTE(("Invalid file descriptor. File possibly closed by a different thread",0));
good :
        ;
    }
    __finally {
        _unlock_fh(filedes);
    }
    return (retval);
}
예제 #15
0
파일: COMMIT.C 프로젝트: ngphloc/agmagic
int __cdecl _commit (
        int filedes
        )
{
        int retval;

        /* if filedes out of range, complain */
        if ( ((unsigned)filedes >= (unsigned)_nhandle) ||
             !(_osfile(filedes) & FOPEN) )
        {
                errno = EBADF;
                return (-1);
        }

        _lock_fh(filedes);

        /* if filedes open, try to commit, else fall through to bad */
        if (_osfile(filedes) & FOPEN) {

                if ( !FlushFileBuffers((HANDLE)_get_osfhandle(filedes)) ) {
                        retval = GetLastError();
                } else {
                        retval = 0;     /* return success */
                }

                /* map the OS return code to C errno value and return code */
                if (retval == 0) {
                        goto good;
                } else {
                        _doserrno = retval;
                        goto bad;
                }

        }

bad :
        errno = EBADF;
        retval = -1;
good :
        _unlock_fh(filedes);
        return (retval);
}
예제 #16
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;
        }
    });
}
예제 #17
0
파일: setmode.c 프로젝트: mysticTot/learn_c
int __cdecl _setmode_nolock(
    REG1 int fh,
    int mode
) {
    int oldmode;
    int oldtextmode;
    oldmode = _osfile(fh) & FTEXT;
    oldtextmode = _textmode(fh);

    switch (mode) {
    case _O_BINARY :
        _osfile(fh) &= ~FTEXT;
        break;

    case _O_TEXT :
        _osfile(fh) |= FTEXT;
        _textmode(fh) = __IOINFO_TM_ANSI;
        break;

    case _O_U8TEXT :
        _osfile(fh) |= FTEXT;
        _textmode(fh) = __IOINFO_TM_UTF8;
        break;

    case _O_U16TEXT:
    case _O_WTEXT :
        _osfile(fh) |= FTEXT;
        _textmode(fh) = __IOINFO_TM_UTF16LE;
        break;
    }

    if (oldmode == 0) {
        return _O_BINARY;
    }

    if (oldtextmode == __IOINFO_TM_ANSI) {
        return _O_TEXT;
    } else {
        return _O_WTEXT;
    }
}
int
WIN32_Close_FD_Socket(int fd)
{
    int result = 0;

    if (closesocket(_get_osfhandle(fd)) == SOCKET_ERROR) {
	errno = WSAGetLastError();
	result = 1;
    }
    _free_osfhnd(fd);
    _osfile(fd) = 0;
    return result;
}
예제 #19
0
extern "C" int __cdecl _close_nolock(int const fh)
{
    DWORD const close_os_handle_error = close_os_handle_nolock(fh);

    _free_osfhnd(fh);
    _osfile(fh) = 0;

    if (close_os_handle_error != 0)
    {
        __acrt_errno_map_os_error(close_os_handle_error);
        return -1;
    }

    return 0;
}
예제 #20
0
파일: dup2.c 프로젝트: flychen50/clib
int __cdecl _dup2 (
        int fh1,
        int fh2
        )
{
        int retcode;

        /* validate file handles */
        _CHECK_FH_CLEAR_OSSERR_RETURN( fh1, EBADF, -1 );
        _VALIDATE_CLEAR_OSSERR_RETURN((fh1 >= 0 && (unsigned)fh1 < (unsigned)_nhandle), EBADF, -1);
        _VALIDATE_CLEAR_OSSERR_RETURN((_osfile(fh1) & FOPEN), EBADF, -1);
        _CHECK_FH_CLEAR_OSSERR_RETURN( fh2, EBADF, -1 );
        _VALIDATE_CLEAR_OSSERR_RETURN(((unsigned)fh2 < _NHANDLE_), EBADF, -1);

        /*
         * Make sure there is an ioinfo struct corresponding to fh2.
         */
        if ( (fh2 >= _nhandle) && (extend_ioinfo_arrays(fh2) != 0) ) {
                errno = ENOMEM;
                return -1;
        }


        /* get the two file handle locks; in order to prevent deadlock,
           get the lowest handle lock first. */
        if ( fh1 < fh2 ) {
                _lock_fh(fh1);
                _lock_fh(fh2);
        }
        else if ( fh1 > fh2 ) {
                _lock_fh(fh2);
                _lock_fh(fh1);
        }

        __try {
                retcode = _dup2_nolock(fh1, fh2);
        }
        __finally {
                _unlock_fh(fh1);
                _unlock_fh(fh2);
        }

        return retcode;

}
예제 #21
0
// _dup2() makes the target file handle a duplicate of the source file handle,
// so that both handles refer to the same file.  If the target handle is open
// upon entry, it is closed so that it is not leaked.
//
// Returns 0 if successful; returns -1 and sets errno on failure.
extern "C" int __cdecl _dup2(int const source_fh, int const target_fh)
{
    _CHECK_FH_CLEAR_OSSERR_RETURN( source_fh, EBADF, -1 );
    _VALIDATE_CLEAR_OSSERR_RETURN((source_fh >= 0 && (unsigned)source_fh < (unsigned)_nhandle), EBADF, -1);
    _VALIDATE_CLEAR_OSSERR_RETURN((_osfile(source_fh) & FOPEN), EBADF, -1);
    _CHECK_FH_CLEAR_OSSERR_RETURN( target_fh, EBADF, -1 );
    _VALIDATE_CLEAR_OSSERR_RETURN(((unsigned)target_fh < _NHANDLE_), EBADF, -1);

    // Make sure there is an __crt_lowio_handle_data struct corresponding to the target_fh:
    if (target_fh >= _nhandle && __acrt_lowio_ensure_fh_exists(target_fh) != 0)
        return -1;

    // If the source and target are the same, return success (we've already
    // verified that the file handle is open, above).  This is for conformance
    // with the POSIX specification for dup2.
    if (source_fh == target_fh)
        return 0;

    // Obtain the two file handle locks.  In order to prevent deadlock, we
    // always obtain the lock for the lower-numbered file handle first:
    if (source_fh < target_fh)
    {
        __acrt_lowio_lock_fh(source_fh);
        __acrt_lowio_lock_fh(target_fh);
    }
    else if (source_fh > target_fh)
    {
        __acrt_lowio_lock_fh(target_fh);
        __acrt_lowio_lock_fh(source_fh);
    }

    int result = 0;

    __try
    {
        result = dup2_nolock(source_fh, target_fh);
    }
    __finally
    {
        // The order in which we unlock the file handles does not matter:
        __acrt_lowio_unlock_fh(source_fh);
        __acrt_lowio_unlock_fh(target_fh);
    }
    return result;
}
예제 #22
0
static Integer __cdecl common_lseek_nolock(int const fh, Integer const offset, int const origin) throw()
{
    HANDLE const os_handle = reinterpret_cast<HANDLE>(_get_osfhandle(fh));
    if (os_handle == reinterpret_cast<HANDLE>(-1))
    {
        errno = EBADF;
        _ASSERTE(("Invalid file descriptor",0));
        return -1;
    }

    Integer const new_position = common_lseek_do_seek_nolock(os_handle, offset, origin);
    if (new_position == -1)
        return -1;

    // The call succeeded, so return success:
    _osfile(fh) &= ~FEOFLAG; // Clear the Ctrl-Z flag
    return new_position;
}
예제 #23
0
파일: ISATTY.C 프로젝트: ngphloc/agmagic
int __cdecl _isatty (
        int fh
        )
{
        /* see if file handle is valid, otherwise return FALSE */
#ifndef _MAC
        if ( (unsigned)fh >= (unsigned)_nhandle )
#else  /* _MAC */
        if ((unsigned)fh >= (unsigned)_nfile)
#endif  /* _MAC */
                return 0;

        /* check file handle database to see if device bit set */
#ifndef _MAC
        return (int)(_osfile(fh) & FDEV);
#else  /* _MAC */
        return (int)(_osfile[fh] & FDEV);
#endif  /* _MAC */
}
예제 #24
0
파일: close.c 프로젝트: chunhualiu/OpenNT
int __cdecl _close (
	int fh
	)
{
	int r;				/* return value */

	/* validate file handle */
	if ( ((unsigned)fh >= (unsigned)_nhandle) ||
             !(_osfile(fh) & FOPEN) )
         {
		/* bad file handle, set errno and abort */
		errno = EBADF;
		_doserrno = 0;
		return -1;
	}

	_lock_fh(fh);			/* lock file */
        r = _close_lk(fh);
	_unlock_fh(fh); 		/* unlock the file */

        return r;
}
예제 #25
0
파일: EOF.C 프로젝트: ngphloc/agmagic
int __cdecl _eof (
        int filedes
        )
{
        long here;
        long end;
        int retval;

        if ( ((unsigned)filedes >= (unsigned)_nhandle) ||
             !(_osfile(filedes) & FOPEN) )
        {
                errno = EBADF;
                _doserrno = 0;
                return(-1);
        }

        /* Lock the file */
        _lock_fh(filedes);

        /* See if the current position equals the end of the file. */

        if ( ((here = _lseek_lk(filedes, 0L, SEEK_CUR)) == -1L) ||
             ((end = _lseek_lk(filedes, 0L, SEEK_END)) == -1L) )
                retval = -1;
        else if ( here == end )
                retval = 1;
        else {
                _lseek_lk(filedes, here, SEEK_SET);
                retval = 0;
        }

        /* Unlock the file */
        _unlock_fh(filedes);

        /* Done */
        return(retval);
}
예제 #26
0
파일: lseek.c 프로젝트: jetlive/skiaming
/* define core _lseek -- doesn't lock or validate fh */
long __cdecl _lseek_nolock (
        int fh,
        long pos,
        int mthd
        )
{
        ULONG newpos;                   /* new file position */
        ULONG dosretval;                /* o.s. return value */
        HANDLE osHandle;        /* o.s. handle value */


        /* tell o.s. to seek */

#if SEEK_SET != FILE_BEGIN || SEEK_CUR != FILE_CURRENT || SEEK_END != FILE_END
    #error Xenix and Win32 seek constants not compatible
#endif  /* SEEK_SET != FILE_BEGIN || SEEK_CUR != FILE_CURRENT || SEEK_END != FILE_END */
        if ((osHandle = (HANDLE)_get_osfhandle(fh)) == (HANDLE)-1)
        {
            errno = EBADF;
            _ASSERTE(("Invalid file descriptor",0));
            return -1;
        }

        if ((newpos = SetFilePointer(osHandle, pos, NULL, mthd)) == -1)
                dosretval = GetLastError();
        else
                dosretval = 0;

        if (dosretval) {
                /* o.s. error */
                _dosmaperr(dosretval);
                return -1;
        }

        _osfile(fh) &= ~FEOFLAG;        /* clear the ctrl-z flag on the file */
        return newpos;                  /* return */
}
예제 #27
0
// If a binary mode stream is open for reading and the target of the requested
// seek is within the stream buffer, we can simply adjust the buffer pointer to
// the new location.  This allows us to avoid flushing the buffer.  If the user
// has set a large buffer on the stream and performs frequent seeks that are
// likely to result in targets within the buffer, this is a huge performance win.
// This function handles the most common cases.
static bool __cdecl common_fseek_binary_mode_read_only_fast_track_nolock(
    __crt_stdio_stream const stream,
    __int64                  offset,
    int                      whence
    ) throw()
{
    // This fast-track path does not handle the seek-from-end case (this is not
    // nearly as commonly used as seeking from the beginning or from the current
    // position).
    if (whence == SEEK_END)
    {
        return false;
    }

    // This fast-track path is only useful if the stream is buffered.
    if (!stream.has_any_buffer())
    {
        return false;
    }

    // This fast-track path requires a stream opened only for reading.  It may
    // be possible to handle streams opened for writing or update similarly;
    // further investigation would be required.
    if (stream.has_any_of(_IOWRITE | _IOUPDATE))
    {
        return false;
    }

    // The ftell function handles a case where _cnt is negative.  It isn't clear
    // why _cnt may be negative, so if _cnt is negative, fall back to the
    // expensive path.
    if (stream->_cnt < 0)
    {
        return false;
    }

    // This fast-track path requires a binary mode file handle.  When text mode
    // or UTF transformations are enabled, the contents of the buffer do not
    // exactly match the contents of the underlying file.
    int const fh = stream.lowio_handle();
    if ((_osfile(fh) & FTEXT) != 0 || _textmode(fh) != __crt_lowio_text_mode::ansi)
    {
        return false;
    }

    // Handle the SEEK_SET case by transforming the SEEK_SET offset into a
    // SEEK_CUR offset:
    if (whence == SEEK_SET)
    {
        __int64 const lowio_position = _lseeki64_nolock(fh, 0, SEEK_CUR);
        if (lowio_position < 0)
        {
            return false;
        }

        __int64 const stdio_position = lowio_position - stream->_cnt;
        if (FAILED(LongLongSub(offset, stdio_position, &offset)))
        {
            return false;
        }
        whence = SEEK_CUR;
    }

    // Compute the maximum number of bytes that we can seek in each direction
    // within the buffer and verify that the requested offset is within that
    // range.  Note that the minimum reverse seek is a negative value.
    __int64 const minimum_reverse_seek = -(stream->_ptr - stream->_base);
    __int64 const maximum_forward_seek = stream->_cnt;
    
    bool const seek_is_within_buffer = minimum_reverse_seek <= offset && offset <= maximum_forward_seek;
    if (!seek_is_within_buffer)
    {
        return false;
    }

    stream->_ptr += offset;

    // Note that the cast here is safe:  The buffer will never be larger than
    // INT_MAX bytes in size.  The setvbuf function validates this constraint.
    stream->_cnt -= static_cast<int>(offset);
    return true;
}
예제 #28
0
파일: fdopen.c 프로젝트: chunhualiu/OpenNT
FILE * __cdecl _tfdopen (
	int filedes,
	REG2 const _TSCHAR *mode
	)
{
	REG1 FILE *stream;
	int whileflag, tbflag, cnflag;

	_ASSERTE(mode != NULL);

#if defined(_WIN32) && !defined(_POSIX_)

	_ASSERTE((unsigned)filedes < (unsigned)_nhandle);
        _ASSERTE(_osfile(filedes) & FOPEN);

	if ( ((unsigned)filedes >= (unsigned)_nhandle) ||
             !(_osfile(filedes) & FOPEN) )
		return(NULL);

#else

#ifdef	_POSIX_

	_ASSERTE((unsigned)filedes < OPEN_MAX);

	if ((unsigned)filedes >= OPEN_MAX)
		return(NULL);

#else

#if	defined(_M_MPPC) || defined(_M_M68K)

	_ASSERTE((unsigned)filedes < (unsigned)_nfile);
        _ASSERTE(_osfile[filedes] & FOPEN);

	if ( ((unsigned)filedes >= (unsigned)_nfile) ||
             !(_osfile[filedes] & FOPEN) )
		return(NULL);

#endif	/* defined(_M_MPPC) || defined(_M_M68K) */

#endif  /* _POSIX_ */

#endif	/* _WIN32 */


	/* Find a free stream; stream is returned 'locked'. */

	if ((stream = _getstream()) == NULL)
		return(NULL);

	/* First character must be 'r', 'w', or 'a'. */

	switch (*mode) {
	case _T('r'):
		stream->_flag = _IOREAD;
		break;
	case _T('w'):
	case _T('a'):
		stream->_flag = _IOWRT;
		break;
	default:
		stream = NULL;	/* error */
		goto done;
		break;
	}

	/* There can be up to three more optional characters:
	   (1) A single '+' character,
	   (2) One of 'b' and 't' and
	   (3) One of 'c' and 'n'.

	   Note that currently, the 't' and 'b' flags are syntax checked
	   but ignored.  'c' and 'n', however, are correctly supported.
	*/

	whileflag=1;
	tbflag=cnflag=0;
	stream->_flag |= _commode;

	while(*++mode && whileflag)
		switch(*mode) {

		case _T('+'):
			if (stream->_flag & _IORW)
				whileflag=0;
			else {
				stream->_flag |= _IORW;
				stream->_flag &= ~(_IOREAD | _IOWRT);
			}
			break;

		case _T('b'):
		case _T('t'):
			if (tbflag)
				whileflag=0;
			else
				tbflag=1;
			break;

		case _T('c'):
			if (cnflag)
				whileflag = 0;
			else {
				cnflag = 1;
				stream->_flag |= _IOCOMMIT;
			}
			break;

		case _T('n'):
			if (cnflag)
				whileflag = 0;
			else {
				cnflag = 1;
				stream->_flag &= ~_IOCOMMIT;
			}
			break;

		default:
			whileflag=0;
			break;
		}

#ifndef CRTDLL
	_cflush++;  /* force library pre-termination procedure */
#endif	/* CRTDLL */

	stream->_file = filedes;

#if	defined(_M_MPPC) || defined(_M_M68K)
	if ( ( ( _osfile[filedes] & FRDONLY ) && (stream->_flag & (_IORW | _IOWRT)) ) ||
	    ( ( _osfile[filedes] & FWRONLY ) && (stream->_flag & (_IORW | _IOREAD)) ) )
		{
		stream->_flag = 0;   /* stream not used */
		return(NULL);
		}
#endif

/* Common return */

done:
	_unlock_str(stream);
	return(stream);
}
예제 #29
0
파일: PIPE.C 프로젝트: ngphloc/agmagic
int __cdecl _pipe (
        int phandles[2],
        unsigned psize,
        int textmode
        )
{
        ULONG dosretval;                    /* o.s. return value */

        HANDLE ReadHandle, WriteHandle;
        SECURITY_ATTRIBUTES SecurityAttributes;

        SecurityAttributes.nLength = sizeof(SecurityAttributes);
        SecurityAttributes.lpSecurityDescriptor = NULL;

        if (textmode & _O_NOINHERIT) {
                SecurityAttributes.bInheritHandle = FALSE;
        }
        else {
                SecurityAttributes.bInheritHandle = TRUE;
        }

        if (!CreatePipe(&ReadHandle, &WriteHandle, &SecurityAttributes, psize)) {
                /* o.s. error */
                dosretval = GetLastError();
                _dosmaperr(dosretval);
                return -1;
        }

        /* now we must allocate C Runtime handles for Read and Write handles */
        if ((phandles[0] = _alloc_osfhnd()) != -1) {

                _osfile(phandles[0]) = (char)(FOPEN | FPIPE | FTEXT);

                if ((phandles[1] = _alloc_osfhnd()) != -1) {

                        _osfile(phandles[1]) = (char)(FOPEN | FPIPE | FTEXT);

                        if ( (textmode & _O_BINARY) ||
                             (((textmode & _O_TEXT) == 0) &&
                              (_fmode == _O_BINARY)) ) {
                                /* binary mode */
                                _osfile(phandles[0]) &= ~FTEXT;
                                _osfile(phandles[1]) &= ~FTEXT;
                        }

                        if ( textmode & _O_NOINHERIT ) {
                                _osfile(phandles[0]) |= FNOINHERIT;
                                _osfile(phandles[1]) |= FNOINHERIT;
                        }

                        _set_osfhnd(phandles[0], (long)ReadHandle);
                        _set_osfhnd(phandles[1], (long)WriteHandle);
                        errno = 0;

                        _unlock_fh(phandles[1]);    /* unlock handle */
                }
                else {
                        _osfile(phandles[0]) = 0;
                        errno = EMFILE;     /* too many files */
                }

                _unlock_fh(phandles[0]);    /* unlock handle */
        }
        else {
                errno = EMFILE;     /* too many files */
        }

        /* If error occurred, close Win32 handles and return -1 */
        if (errno != 0) {
                CloseHandle(ReadHandle);
                CloseHandle(WriteHandle);
                _doserrno = 0;      /* not an o.s. error */
                return -1;
        }

        return 0;
}
예제 #30
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;
}