Example #1
0
/* 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;
}
Example #2
0
/* 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;
}
Example #3
0
File: dup.c Project: 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;
}
Example #4
0
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);
}
Example #5
0
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;

}
Example #6
0
File: eof.c Project: 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);
}
Example #7
0
void __cdecl _wperror (
        const wchar_t *wmessage
        )
{
        int fh = 2;
        size_t size = 0;
        char *amessage;
        const char *sysmessage;

        /* convert WCS string into ASCII string */

        if ( wmessage && *wmessage )
        {
            _ERRCHECK_EINVAL_ERANGE(wcstombs_s( &size, NULL, 0, wmessage, INT_MAX));

            if ( size==0 || (amessage = (char *)_calloc_crt(size, sizeof(char))) == NULL )
                return;

            if ( _ERRCHECK_EINVAL_ERANGE(wcstombs_s(NULL, amessage, size, wmessage, _TRUNCATE)) != 0)
            {
                _free_crt(amessage);
                return;
            }
        }
        else
            amessage = NULL;

        _lock_fh( fh );         /* acquire file handle lock */
        __try {

        if ( amessage )
        {
                _write_nolock(fh,(char *)amessage,(unsigned)strlen(amessage));
                _write_nolock(fh,": ",2);
        }

        _free_crt(amessage);    /* note: freeing NULL is legal and benign */

        sysmessage = _get_sys_err_msg( errno );
        _write_nolock(fh, sysmessage,(unsigned)strlen(sysmessage));
        _write_nolock(fh,"\n",1);

        }
        __finally {
            _unlock_fh( fh );   /* release file handle lock */
        }
}
Example #8
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);
}
Example #9
0
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);
}
Example #10
0
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;
}
void __cdecl _wperror (
        REG1 const wchar_t *wmessage
        )
{
        REG2 int fh = 2;
        int size;
        char *amessage;

        /* convert WCS string into ASCII string */

        size = wcslen(wmessage) + 1;

        if (NULL == (amessage = (char *)_malloc_crt(size * sizeof(char))))
            return;

        if (0 == (wcstombs(amessage, wmessage, size)))
        {
            _free_crt (amessage);
            return;
        }

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

        if (amessage && *amessage)
        {
                _write_lk(fh,(char *)amessage,strlen(amessage));
                _write_lk(fh,": ",2);
        }

        _free_crt(amessage);

        amessage = _sys_err_msg( errno );
        _write_lk(fh,(char *)amessage,strlen(amessage));
        _write_lk(fh,"\n",1);

        _unlock_fh(fh);         /* release file handle lock */
}
Example #12
0
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);
}
Example #13
0
int __cdecl _dup (
        int fh
        )
{
        ULONG dosretval;                /* o.s. return value */
        int newfh;                      /* variable for new file handle */
        char fileinfo;                  /* _osfile info for file */
        long new_osfhandle;

        /* validate file handle */
        if ( ((unsigned)fh >= (unsigned)_nhandle) ||
             !(_osfile(fh) & FOPEN) )
        {
                errno = EBADF;
                _doserrno = 0;  /* no o.s. error */
                return -1;
        }

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

        /* create duplicate handle */

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

        /*
         * 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;
        }

        _unlock_fh(newfh);

        _unlock_fh(fh);                 /* unlock file handle */

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

        /*
         * copy the _osfile value, with the FNOINHERIT bit cleared
         */
        _osfile(newfh) = fileinfo & ~FNOINHERIT;

        return newfh;
}
Example #14
0
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;
}
Example #15
0
File: dup.c Project: 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;
}
Example #16
0
FILE * __cdecl _tpopen (
        const _TSCHAR *cmdstring,
        const _TSCHAR *type
        )
{

        int phdls[2];             /* I/O handles for pipe */
        int ph_open[2];           /* flags, set if correspond phdls is open */
        int i1;                   /* index into phdls[] */
        int i2;                   /* index into phdls[] */

        int tm = 0;               /* flag indicating text or binary mode */

        int stdhdl;               /* either STDIN or STDOUT */
        HANDLE osfhndsv1;         /* used to save _osfhnd(stdhdl) */
        long osfhndsv2;           /* used to save _osfhnd(phdls[i2]) */
        char osfilesv1;           /* used to save _osfile(stdhdl) */
        char osfilesv2;           /* used to save _osfile(phdls[i2]) */

        HANDLE oldhnd;            /* used to hold OS file handle values... */
        HANDLE newhnd;            /* ...in calls to DuplicateHandle API */

        FILE *pstream;            /* stream to be associated with pipe */

        HANDLE prochnd;           /* handle for current process */

        _TSCHAR *cmdexe;                  /* pathname for the command processor */
        int childhnd;             /* handle for child process (cmd.exe) */

        IDpair *locidpair;        /* pointer to IDpair table entry */


        /* first check for errors in the arguments
         */
        if ( (cmdstring == NULL) || (type == NULL) || ((*type != 'w') &&
             (*type != _T('r'))) )
                goto error1;

        /* do the _pipe(). note that neither of the resulting handles will
         * be inheritable.
         */

        if ( *(type + 1) == _T('t') )
                tm = _O_TEXT;
        else if ( *(type + 1) == _T('b') )
                tm = _O_BINARY;

        tm |= _O_NOINHERIT;

        if ( _pipe( phdls, PSIZE, tm ) == -1 )
                goto error1;

        /* test *type and set stdhdl, i1 and i2 accordingly.
         */
        if ( *type == _T('w') ) {
                stdhdl = STDIN;
                i1 = 0;
                i2 = 1;
        }
        else {
                stdhdl = STDOUT;
                i1 = 1;
                i2 = 0;
        }

        /* the pipe now exists. the following steps must be carried out before
         * the child process (cmd.exe) may be spawned:
         *
         *      1. save a non-inheritable dup of stdhdl
         *
         *      2. force stdhdl to be a dup of ph[i1]. close both ph[i1] and
         *         the original OS handle underlying stdhdl
         *
         *      3. associate a stdio-level stream with ph[i2].
         */

        /* set flags to indicate pipe handles are open. note, these are only
         * used for error recovery.
         */
        ph_open[ 0 ] = ph_open[ 1 ] = 1;


        /* get the process handle, it will be needed in some API calls
         */
        prochnd = GetCurrentProcess();

        /* MULTI-THREAD: ASSERT LOCK ON STDHDL HERE!!!!
         */
        _lock_fh( stdhdl );

        /* save a non-inheritable copy of stdhdl for later restoration.
         */

        oldhnd = (HANDLE)_osfhnd( stdhdl );

        if ( (oldhnd == INVALID_HANDLE_VALUE) ||
             !DuplicateHandle( prochnd,
                               oldhnd,
                               prochnd,
                               &osfhndsv1,
                               0L,
                               FALSE,                   /* non-inheritable */
                               DUPLICATE_SAME_ACCESS )
        ) {
                goto error2;
        }

        osfilesv1 = _osfile( stdhdl );

        /* force stdhdl to an inheritable dup of phdls[i1] (i.e., force
         * STDIN to the pipe read handle or STDOUT to the pipe write handle)
         * and close phdls[i1] (so there won't be a stray open handle on the
         * pipe after a _pclose). also, clear ph_open[i1] flag so that error
         * recovery won't try to close it again.
         */

        if ( !DuplicateHandle( prochnd,
                               (HANDLE)_osfhnd( phdls[i1] ),
                               prochnd,
                               &newhnd,
                               0L,
                               TRUE,                    /* inheritable */
                               DUPLICATE_SAME_ACCESS )
        ) {
                goto error3;
        }

        (void)CloseHandle( (HANDLE)_osfhnd(stdhdl) );
        _free_osfhnd( stdhdl );

        _set_osfhnd( stdhdl, (long)newhnd );
        _osfile( stdhdl ) = _osfile( phdls[i1] );

        (void)_close( phdls[i1] );
        ph_open[ i1 ] = 0;


        /* associate a stream with phdls[i2]. note that if there are no
         * errors, pstream is the return value to the caller.
         */
        if ( (pstream = _tfdopen( phdls[i2], type )) == NULL )
                goto error4;

        /* MULTI-THREAD: ASSERT LOCK ON IDPAIRS HERE!!!!
         */
        _mlock( _POPEN_LOCK );

        /* next, set locidpair to a free entry in the idpairs table.
         */
        if ( (locidpair = idtab( NULL )) == NULL )
                goto error5;


        /* temporarily change the osfhnd and osfile entries so that
         * the child doesn't get any entries for phdls[i2].
         */
        osfhndsv2 = _osfhnd( phdls[i2] );
        _osfhnd( phdls[i2] ) = (long)INVALID_HANDLE_VALUE;
        osfilesv2 = _osfile( phdls[i2] );
        _osfile( phdls[i2] ) = 0;

        /* spawn the child copy of cmd.exe. the algorithm is adapted from
         * SYSTEM.C, and behaves the same way.
         */
        if ( ((cmdexe = _tgetenv(_T("COMSPEC"))) == NULL) ||
             (((childhnd = _tspawnl( _P_NOWAIT,
                                    cmdexe,
                                    cmdexe,
                                    _T("/c"),
                                    cmdstring,
                                    NULL ))
             == -1) && ((errno == ENOENT) || (errno == EACCES))) ) {
                /*
                 * either COMSPEC wasn't defined, or the spawn failed because
                 * cmdexe wasn't found or was inaccessible. in either case, try to
                 * spawn "cmd.exe" (Windows NT) or "command.com" (Windows 95) instead
                 * Note that spawnlp is used here so that the path is searched.
                 */
                cmdexe = ( _osver & 0x8000 ) ? _T("command.com") : _T("cmd.exe");
                childhnd = _tspawnlp( _P_NOWAIT,
                                     cmdexe,
                                     cmdexe,
                                     _T("/c"),
                                     cmdstring,
                                     NULL);
        }

        _osfhnd( phdls[i2] ) = osfhndsv2;
        _osfile( phdls[i2] ) = osfilesv2;

        /* check if the last (perhaps only) spawn attempt was successful
         */
        if ( childhnd == -1 )
                goto error6;

        /* restore stdhdl for the current process, set value of *locidpair,
         * close osfhndsv1 (note that CloseHandle must be used instead of close)
         * and return pstream to the caller
         */

        (void)DuplicateHandle( prochnd,
                               osfhndsv1,
                               prochnd,
                               &newhnd,
                               0L,
                               TRUE,                    /* inheritable */
                               DUPLICATE_CLOSE_SOURCE | /* close osfhndsv1 */
                               DUPLICATE_SAME_ACCESS );

        (void)CloseHandle( (HANDLE)_osfhnd(stdhdl) );
        _free_osfhnd( stdhdl );

        _set_osfhnd( stdhdl, (long)newhnd );
        _osfile(stdhdl) = osfilesv1;

        /* MULTI-THREAD: RELEASE LOCK ON STDHDL HERE!!!!
         */
        _unlock_fh( stdhdl );

        locidpair->prochnd = childhnd;
        locidpair->stream = pstream;

        /* MULTI-THREAD: RELEASE LOCK ON IDPAIRS HERE!!!!
         */
        _munlock( _POPEN_LOCK );

        /* all successful calls to _popen return to the caller via this return
         * statement!
         */
        return( pstream );

        /**
         * error handling code. all detected errors end up here, entering
         * via a goto one of the labels. note that the logic is currently
         * a straight fall-thru scheme (e.g., if entered at error5, the
         * code for error5, error4,...,error1 is all executed).
         **********************************************************************/

        error6: /* make sure locidpair is reusable
                 */
                locidpair->stream = NULL;

        error5: /* close pstream (also, clear ph_open[i2] since the stream
                 * close will also close the pipe handle)
                 */
                (void)fclose( pstream );
                ph_open[ i2 ] = 0;

                /* MULTI-THREAD: RELEASE LOCK ON IDPAIRS HERE!!!!
                 */
                _munlock(_POPEN_LOCK);

        error4: /* restore stdhdl
                 */

                (void)DuplicateHandle( prochnd,
                                       osfhndsv1,
                                       prochnd,
                                       &newhnd,
                                       0L,
                                       TRUE,
                                       DUPLICATE_SAME_ACCESS );

                (void)CloseHandle( (HANDLE)_osfhnd(stdhdl) );
                _free_osfhnd( stdhdl );

                _set_osfhnd( stdhdl, (long)newhnd );
                _osfile( stdhdl ) = osfilesv1;

                /* MULTI-THREAD: RELEASE LOCK ON STDHDL HERE!!!!
                 */
                _unlock_fh( stdhdl );

        error3: /* close osfhndsv1
                 */

                CloseHandle( osfhndsv1 );

        error2: /* close handles on pipe (if they are still open)
                 */
                if ( ph_open[i1] )
                        _close( phdls[i1] );
                if ( ph_open[i2] )
                        _close( phdls[i2] );

        error1: /* return NULL to the caller indicating failure
                 */
                return( NULL );
}
Example #17
0
int __cdecl _dup2 (
	int fh1,
	int fh2
	)
{
	ULONG dosretval;		/* o.s. return code */

	/* validate file handles */
	if ( ((unsigned)fh1 >= (unsigned)_nhandle) ||
	     !(_osfile(fh1) & FOPEN) ||
	     ((unsigned)fh2 >= _NHANDLE_) ) {
		/* handle out of range */
		errno = EBADF;
		_doserrno = 0;	/* not an OS error */
		return -1;
	}

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


#if     defined(_MT) && !defined(DLL_FOR_WIN32S)
	/* 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);
	}

	/*
	 * 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, release locks and 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).
		 */
		_unlock_fh(fh1);
	        _unlock_fh(fh2);
		errno = EBADF;
		_doserrno = 0;	/* not an OS error */
		return -1;
	}
#endif

        /* 
         * 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.
                 */
                _unlock_fh(fh1);
                _unlock_fh(fh2);
                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_lk as we
                 * already own lock
		 */
		(void) _close_lk(fh2);


	/* Duplicate source file onto target file */

        {
        long new_osfhandle;

	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);
	        _unlock_fh(fh1);
	        _unlock_fh(fh2);
	        return -1;
        }

	/* copy _osfile information */
	_osfile(fh2) = _osfile(fh1);

	/* unlock file handles */
	_unlock_fh(fh1);
	_unlock_fh(fh2);

	return 0;
}