/* * FEXEC1.C * * wait() and fexecv() * * This code originated from Manx's fexecv code. I claim credit only * for the major modifications I've done to it. * */ #include "shell.h" #include typedef struct FileHandle FH; typedef struct CommandLineInterface CLI; typedef struct Process PROC; static int ret_val; extern PROC *FindTask(); extern char *AllocMem(); wait() { return(ret_val); } fexecv(cmd, argv, stdin_str, stdout_str, stdout_append) char *cmd, **argv; char *stdin_str, *stdout_str; { register CLI *cli; register char **ap, *cp, *arg; PROC *pp; APTR sav_ret; BPTR sav_CIS, sav_COS; long save_stdin_buf, save_stdin_pos, save_stdin_end; long len, seg, sav_seg; long openmode; long *stk; FH *fhp, *stdin, *stdout; char buf[40]; pp = FindTask(0L); if ((cli = (CLI *)((long)pp->pr_CLI << 2)) == 0) return(-1); if ((seg = LoadIt(cmd)) == 0) return(-3); stdin = (FH *)((stdin_str)? Open(stdin_str, 1005) : pp->pr_CIS); if (!stdin) { fprintf(Cerr, "Input redirection error\n"); return(-4); } openmode = (stdout_append) ? 1005 : 1006; stdout= (FH *)((stdout_str)? Open(stdout_str, openmode) : pp->pr_COS); if (!stdout) { fprintf(Cerr, "Output redirection error\n"); if (stdin_str) Close(stdin); return(-5); } if (stdout_append) Seek(stdout, 0, 1); sav_seg = cli->cli_Module; cli->cli_Module = seg; stk = (long *)AllocMem(4 * cli->cli_DefaultStack + 8, 0); *stk = 4 * cli->cli_DefaultStack + 8; stk = (long *)((long)stk + 4 * cli->cli_DefaultStack); stk[0] = 4 * cli->cli_DefaultStack; stk[1] = ((long *)pp->pr_ReturnAddr)[1]; sav_ret = pp->pr_ReturnAddr; pp->pr_ReturnAddr = (APTR)stk; for (len = 1, ap = argv + 1; *ap; ++ap) len += strlen(*ap) + 1; cp = arg = AllocMem(len, 0); for (ap = argv + 1; *ap; ++ap) { strcpy(cp, *ap); strcat(cp, " "); cp += strlen(cp); } arg[len-1] = '\n'; cp = (char *)((long)cli->cli_CommandName << 2); movmem(cp, buf, 40); strcpy(cp + 1, cmd); cp[0] = strlen(cmd); fhp = (FH *)((long)stdin << 2); save_stdin_buf = fhp->fh_Buf; save_stdin_pos = fhp->fh_Pos; save_stdin_end = fhp->fh_End; fhp->fh_Buf = (long)AllocMem(202, 0) >> 2; strncpy(fhp->fh_Buf<<2, arg, (int)((len < 200)?len:199)); fhp->fh_Pos = 0; fhp->fh_End = (len < 200)?len:199; sav_CIS = pp->pr_CIS; sav_COS = pp->pr_COS; pp->pr_CIS = (BPTR)stdin; pp->pr_COS = (BPTR)stdout; ret_val = doexec(len, arg, (seg+1)<<2, stk); FreeMem(fhp->fh_Buf<<2, 202); fhp->fh_Buf = save_stdin_buf; fhp->fh_Pos = save_stdin_pos; fhp->fh_End = save_stdin_end; /* fhp->fh_Pos = fhp->fh_End; */ if (stdin_str) Close(stdin); if (stdout_str) Close(stdout); pp->pr_CIS = sav_CIS; pp->pr_COS = sav_COS; UnLoadSeg(cli->cli_Module); pp->pr_ReturnAddr = sav_ret; cli->cli_Module = sav_seg; FreeMem(arg, len); movmem(buf, cp, 40); return(0); } LoadIt(cmd) char *cmd; { char buf[128]; long seg; seg = LoadSeg(FindIt(cmd, "", buf)); return (seg); } char * FindIt(cmd, ext, buf) char *cmd; char *ext; char *buf; { int n; long lock = 0; APTR original; PROC *myproc = FindTask(0); char *ptr; char *p; original = myproc->pr_WindowPtr; myproc->pr_WindowPtr = (APTR)(-1); if ((p = get_var(LEVEL_SET, V_PATH)) == NULL) p = ""; for (ptr = cmd; *ptr; ++ptr) { if (*ptr == '/' || *ptr == ':') p = ""; } strcpy(buf, cmd); strcat(buf, ext); while ((lock = Lock(buf, ACCESS_READ)) == 0) { if (*p == '\0') break; for (n = 0; p[n] && p[n] != ','; ++n); strncpy(buf, p, n); strcat(buf, cmd); strcat(buf, ext); p += n + (*p != 0); } myproc->pr_WindowPtr = original; if (lock) UnLock(lock); return(buf); }