#include #include #include #include #include #include #include struct __execblock { unsigned short envseg; void far * cmdtail; void far * fcb1; void far * fcb2; }; int __cdecl __dosexec( char *name, void *blk ); unsigned char __dogetrt( void ); #pragma aux __dogetrt = \ "mov ah, 0x4D" \ "int 0x21" \ value [al] \ modify [ax]; static const char *__searchexe( const char *path ) { static char exename[ _MAX_PATH ]; if( access( path, 0 ) == 0 ) return( __retsfn( path ) ); if( strchr( path + strlen( path ) - 4, '.' ) != NULL ) return( path ); /* Check for explicit ext */ strcpy( exename, path ); strcat( exename, ".COM" ); if( access( exename, 0 ) == 0 ) return( __retsfn( exename ) ); strcpy( exename, path ); strcat( exename, ".EXE" ); if( access( exename, 0 ) == 0 ) return( __retsfn( exename ) ); strcpy( exename, path ); strcat( exename, ".BAT" ); if( access( exename, 0 ) == 0 ) return( __retsfn( exename ) ); return( __retsfn( path ) ); } int spawnve( int mode, char *path, char **argv, char **envp ) { struct __execblock exb; struct fcb tmpfcb, tmpfcb2; char buf[ 128 ], cmdline[ 126 ]; char *p, *c, *name; int len = 0, retval, i, isbat = 0; if( mode == P_NOWAIT ) { errno = ENOEXEC; return( -1 ); } if( strstr( ( name = ( char * )__searchexe( path ) ), ".BAT" ) != NULL ) { strcpy( cmdline, "/c " ); strcat( cmdline, name ); isbat = 1; if( ( p = getenv( "COMSPEC" ) ) == NULL ) { errno = ENOENT; return( -1 ); } } for( i = 1; *argv[ i ]; i++ ) { if( ( len = strlen( cmdline ) ) != 0 ) strcat( cmdline, " " ); if( ( len += strlen( argv[ i ] ) + 1 ) > 126 ) { errno = E2BIG; return( -1 ); } if( ( c = strchr( argv[ i ], ' ' ) ) != NULL ) strcat( cmdline, "\"" ); strcat( cmdline, argv[ i ] ); if( c != NULL ) strcat( cmdline, "\"" ); } buf[ 0 ] = len; strcpy( &buf[ 1 ], cmdline ); strcpy( &buf[ buf[ 0 ] + 1 ], "\xd" ); exb.envseg = FP_SEG( envp ); exb.cmdtail = ( void far * )MK_FP( FP_SEG( buf ), FP_OFF( buf ) ); if( ( p = parsfnm( cmdline, &tmpfcb, 1 ) ) != NULL ) parsfnm( p, &tmpfcb2, 1 ); exb.fcb1 = ( void far * )&tmpfcb; exb.fcb2 = ( void far * )&tmpfcb2; if( ( retval = __dosexec( ( isbat ) ? p : name, &exb ) ) < 0 ) { errno = - retval; return( -1 ); } retval = __dogetrt(); if( mode == P_OVERLAY ) exit( retval ); return( retval ); }