/* -*-C-*-
*******************************************************************************
*
* File:         perldos.c
* RCS:          $Header: $
* Description:  
* Author:       Darryl Okahata
* Created:      Sun Oct 16 02:51:36 1994
* Modified:     Sun Oct 16 02:52:07 1994 (darrylo@home) darrylo@hostigos
* Language:     C
* Package:      N/A
* Status:       Experimental
*
* (C) Copyright 1994, Darryl Okahata, all rights reserved.
*
*******************************************************************************
*/


#include "EXTERN.h"
#include "perl.h"

#include <stdio.h>
#include <ctype.h>
#include <dos.h>
#include <process.h>
#include <fcntl.h>

#include "dpmi.h"		/* sets DOS_EXTENDER, if appropriate */

extern Malloc_t malloc(MEM_SIZE nbytes);


/*
 * The following code is based on the do_exec and do_aexec functions
 * in file doio.c
 */
#if 1

bool
do_aspawn(really,mark,sp)
SV *really;
register SV **mark;
register SV **sp;
{
    register char **a;
    char *tmps, *cmd;
    int status = 0;

    if (sp > mark) {
	New(401,Argv, sp - mark + 1, char*);
	a = Argv;
	while (++mark <= sp) {
	    if (*mark)
		*a++ = SvPVx(*mark, na);
	    else
		*a++ = "";
	}
	*a = Nullch;
	if (*Argv[0] != '/')	/* will execvp use PATH? */
	    TAINT_ENV();	/* testing IFS here is overkill, probably */
	if (really && *(tmps = SvPV(really, na))) {
	    cmd = msdos32_fix_cmd(tmps);
	    status = spawnvp(P_WAIT,cmd,Argv);
	    free(cmd);
	} else {
	    cmd = msdos32_fix_cmd(Argv[0]);
	    status = spawnvp(P_WAIT,cmd,Argv);
	    free(cmd);
	}
    }
    do_execfree();
    return (status * 256);
}
#else
int
do_aspawn(really,arglast)
STR *really;
int *arglast;
{
    register STR **st = stack->ary_array;
    register int sp = arglast[1];
    register int items = arglast[2] - sp;
    register char **a;
    char **argv;
    char *tmps;
    int status;

    if (items) {
	New(1101,argv, items+1, char*);
	a = argv;
	for (st += ++sp; items > 0; items--,st++) {
	    if (*st)
		*a++ = str_get(*st);
	    else
		*a++ = "";
	}
	*a = Nullch;
	if (really && *(tmps = str_get(really)))
	    status = spawnvp(P_WAIT,tmps,argv);
	else
	    status = spawnvp(P_WAIT,argv[0],argv);
	Safefree(argv);
    }
    return (status * 256);
}
#endif


int
do_spawn(cmd)
char *cmd;
{
    register char **a;
    register char *s;
    char **argv;
    char flags[10];
    int status = -1;
    char *shell, *cmd2, *fixed_cmd;

    /* save an extra exec if possible */
    if ((shell = getenv("COMSPEC")) == 0)
	shell = "\\command.com";

    /* see if there are shell metacharacters in it */
    if (strchr(cmd, '>') || strchr(cmd, '<') || strchr(cmd, '|')) {
	int	status;

    doshell:
	status = spawnl(P_WAIT,shell,shell,"/c",cmd,(char*)0);
	if (status != -1) {
	    status *= 256;
	}
	return (status);
    }

    New(1102,argv, strlen(cmd) / 2 + 2, char*);

    New(1103,cmd2, strlen(cmd) + 1, char);
    strcpy(cmd2, cmd);
    a = argv;
    for (s = cmd2; *s;) {
	while (*s && isspace(*s)) s++;
	if (*s)
	    *(a++) = s;
	while (*s && !isspace(*s)) s++;
	if (*s)
	    *s++ = '\0';
    }
    *a = Nullch;
    if (argv[0]) {
	fixed_cmd = msdos32_fix_cmd(argv[0]);
	if ((status = spawnvp(P_WAIT,fixed_cmd,argv)) == -1) {
	    free(fixed_cmd);
	    Safefree(argv);
	    Safefree(cmd2);
	    goto doshell;
	}
	free(fixed_cmd);
    }
    Safefree(cmd2);
    Safefree(argv);
    if (status != -1) {
	status *= 256;
    }
    return status;
}
