?? popen.c
字號:
_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 );
}
#ifndef _UNICODE
/***
*int _pclose(pstream) - wait on a child command and close the stream on the
* associated pipe
*
*Purpose:
* Closes pstream then waits on the associated child command. The
* argument, pstream, must be the return value from a previous call to
* _popen. _pclose first looks up the process handle of child command
* started by that _popen and does a cwait on it. Then, it closes pstream
* and returns the exit status of the child command to the caller.
*
*Entry:
* FILE *pstream - file stream returned by a previous call to _popen
*
*Exit:
* If successful, _pclose returns the exit status of the child command.
* The format of the return value is that same as for cwait, except that
* the low order and high order bytes are swapped.
*
* If an error occurs, -1 is returned.
*
*Exceptions:
*
*******************************************************************************/
int __cdecl _pclose (
FILE *pstream
)
{
IDpair *locidpair; /* pointer to entry in idpairs table */
int termstat; /* termination status word */
int retval = -1; /* return value (to caller) */
/* MULTI-THREAD: LOCK IDPAIRS HERE!!!!
*/
_mlock(_POPEN_LOCK);
if ( (pstream == NULL) || ((locidpair = idtab(pstream)) == NULL) )
/* invalid pstream, exit with retval == -1
*/
goto done;
/* close pstream
*/
(void)fclose(pstream);
/* wait on the child (copy of the command processor) and all of its
* children.
*/
if ( (_cwait(&termstat, locidpair->prochnd, _WAIT_GRANDCHILD) != -1) ||
(errno == EINTR) )
retval = termstat;
/* Mark the IDpairtable entry as free (note: prochnd was closed by the
* preceding call to _cwait).
*/
locidpair->stream = NULL;
locidpair->prochnd = 0;
/* only return path!
*/
done:
/* MULTI-THREAD: RELEASE LOCK ON IDPAIRS HERE!!!!
*/
_munlock(_POPEN_LOCK);
return(retval);
}
#endif /* _UNICODE */
/***
* static IDpair * idtab(FILE *pstream) - find an idpairs table entry
*
*Purpose:
* Find an entry in the idpairs table. This function finds the entry the
* idpairs table entry corresponding to pstream. In the case where pstream
* is NULL, the entry being searched for is any free entry. In this case,
* idtab will create the idpairs table if it doesn't exist, or expand it (by
* exactly one entry) if there are no free entries.
*
* [MTHREAD NOTE: This routine assumes that the caller has acquired the
* idpairs table lock.]
*
*Entry:
* FILE *pstream - stream corresponding to table entry to be found (if NULL
* then find any free table entry)
*
*Exit:
* if successful, returns a pointer to the idpairs table entry. otherwise,
* returns NULL.
*
*Exceptions:
*
*******************************************************************************/
static IDpair * __cdecl idtab (
FILE *pstream
)
{
IDpair * pairptr; /* ptr to entry */
IDpair * newptr; /* ptr to newly malloc'd memory */
/* search the table. if table is empty, appropriate action should
* fall out automatically.
*/
for ( pairptr = __idpairs ; pairptr < (__idpairs+__idtabsiz) ; pairptr++ )
if ( pairptr->stream == pstream )
break;
/* if we found an entry, return it.
*/
if ( pairptr < (__idpairs + __idtabsiz) )
return(pairptr);
/* did not find an entry in the table. if pstream was NULL, then try
* creating/expanding the table. otherwise, return NULL. note that
* when the table is created or expanded, exactly one new entry is
* produced. this must not be changed unless code is added to mark
* the extra entries as being free (i.e., set their stream fields to
* to NULL).
*/
if ( (pstream != NULL) || ((newptr = (IDpair *)_realloc_crt((void *)__idpairs,
(__idtabsiz + 1)*sizeof(IDpair))) == NULL) )
/* either pstream was non-NULL or the attempt to create/expand
* the table failed. in either case, return a NULL to indicate
* failure.
*/
return( NULL );
__idpairs = newptr; /* new table ptr */
pairptr = newptr + __idtabsiz; /* first new entry */
__idtabsiz++; /* new table size */
return( pairptr );
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -