All pastes #271237 Raw Edit

Something

public text v1 · immutable
·published 2006-12-08 03:06 UTC
rendered paste body
#include <dos.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>

/*
 * fflushall() isn't necessary before calling child because FILE streams are
 * always unbuffered
 * This function is a clone of the function of the same name in DeSmet C and
 * is provided as a more direct interface to the AH=4Bh call to call a child
 * process.
 */

struct __execblock {
    unsigned short  envseg;
    void far *      cmdtail;
    void far *      fcb1;
    void far *      fcb2;
};

int __dodexec( const char *path, struct __execblock far *xb );
#pragma aux __dodexec = \
    "mov ax, 0x4B00"    \
    "int 0x21"          \
    "jnc finish"        \
    "mov _doserrno, ax" \
    "mov ax, 0xFFFF"    \
    "finish:"           \
    parm [dx] [es bx]      \
    value [ax]          \
    modify [ax bx dx];

unsigned char __dogetrt( void );
#pragma aux __dogetrt = \
    "mov ah, 0x4D"      \
    "int 0x21"          \
    value [al]          \
    modify [ax];

int _exec( const char *path, const char *cmdline )
{
    char fullcmdline[ 128 ];
    char far *envp;
    int i, j;
    unsigned seg;
    struct __execblock xb = { 0, NULL, NULL, NULL };

    if( _dos_allocmem( 1024 / 16, &seg ) ) return( -1 );
    envp = MK_FP( seg, 0 );
    xb.envseg = seg;

    for( i = 0; environ[ i ] != NULL; i++ ) {
        for( j = 0; environ[ i ][ j ] != '\0'; j++ ) {
            if( FP_SEG( envp ) >= 1022 ) /* Allow for two extra null bytes */
                break;
            *envp = environ[ i ][ j ];
            envp++;
        }
        *envp = '\0';
        envp++;
        if( FP_SEG( envp ) >= 1023 ) break;
    }
    *envp = '\0';
    xb.cmdtail = ( char far * )fullcmdline;
    
    fullcmdline[ 0 ] = strlen( cmdline );
    fullcmdline[ fullcmdline[ 0 ] ] = '\r';
    strncpy( &fullcmdline[ 1 ], cmdline, 126 );

    if( __dodexec( path, &xb ) < 0 ) {
        _dos_freemem( xb.envseg );

        return( -1 );
    }

    _dos_freemem( xb.envseg );

    return( __dogetrt() );
}