/* * FEXEC1.C * * (C)CopyRight 1987 Matthew Dillon, All rights reserved. * * 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 CommandLineInterface CLI; typedef struct FileHandle FH; static int ret_val; 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) { fhprintf(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) { fhprintf(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) /* length of command line */ len += strlen(*ap) + 1; cp = arg = malloc(len + 1); for (ap = argv + 1; *ap; ++ap) { strcpy(cp, *ap); strcat(cp, " "); cp += strlen(cp); } if (len > 199) /* BCPL parameter limit */ len = 199; arg[len-1] = '\n'; /* for BCPL */ arg[len] = 0; /* for C */ 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; bmov(arg, fhp->fh_Buf<<2, len); fhp->fh_Pos = 0; fhp->fh_End = len; sav_CIS = pp->pr_CIS; sav_COS = pp->pr_COS; pp->pr_CIS = (BPTR)stdin; pp->pr_COS = (BPTR)stdout; /* * pr_Result2 must be NULL or RUN/NEWCLI think the command line is * somewhere other than in the file handle. The cli_Interactive * field gets cleared sometimes (how???), and for some reason, signal * 31 is set sometimes and might cause inproper operation of RUN. */ pp->pr_Result2 = NULL; cli->cli_Interactive = -1; SetSignal(0L, 0x80000000); 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; 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; free(arg); movmem(buf, cp, 40); return(0); } LoadIt(cmd) char *cmd; { long seg; mountrequest(0); if ((seg = LoadSeg(cmd)) == NULL) { register long lock; char buf[128]; if (lock = FindIt(cmd, "", buf)) { register long pardir = ParentDir(lock); if (pardir) { register long oldir = CurrentDir(pardir); seg = LoadSeg(cmd); CurrentDir(oldir); UnLock(pardir); } UnLock(lock); } } mountrequest(1); return(seg); } /* * Find a specific command (cmd) with extension (ext). Returns * a lock if found, else NULL. Searches both the symbolic path and * the CLI path. The symbolic path is searched first. */ long FindIt(cmd, ext, buf) char *cmd; char *ext; char *buf; { register long lock = 0; register char *p; PROC *myproc = FindTask(0); strcpy(buf, cmd); strcat(buf, ext); if (rindex(buf, ':') || rindex(buf, '/')) return(Lock(buf, ACCESS_READ)); if ((p = get_var(LEVEL_SET, V_PATH)) == NULL) p = ""; #ifdef DEBUG if (SDebug) printf ("FindIt: try: %s\n", buf); #endif while ((lock = Lock(buf, ACCESS_READ)) == 0 || !isfile(lock)) { register short n; if (lock) UnLock(lock); if (*p == '\0') { buf[0] = 0; break; } for (n = 0; p[n] && p[n] != ','; ++n); strncpy(buf, p, n); buf[n] = 0; strcat(buf, cmd); strcat(buf, ext); p += n + (*p != 0); #ifdef DEBUG if (SDebug) printf ("FindIt: try: %s\n", buf); #endif } #ifdef DEBUG if (SDebug) puts ("FindIt 1"); #endif if (lock) return(lock); /* * Search the CLI path by CurrentDir'ing each lock and * attempting to lock the name */ #ifdef DEBUG if (SDebug) puts("SEARCH CLI"); #endif strcpy(buf, cmd); strcat(buf, ext); if (myproc->pr_CLI) { long oldir; long dupdir; register LOCK *dirlock = (LOCK *)(((CLI *)(myproc->pr_CLI << 2))->cli_CommandDir << 2); for (; dirlock; dirlock = (LOCK *)(dirlock->fl_Link << 2)) { oldir = CurrentDir(((long *)dirlock)[1]); lock = Lock(buf, ACCESS_READ); CurrentDir(oldir); if (lock) break; } } #ifdef DEBUG if (SDebug) puts("FindIt done"); #endif return(lock); } static isfile(lock) long lock; { register FIB *fib = (FIB *)malloc(sizeof(FIB)); register int result = 0; if (fib) { if (Examine(lock, fib)) result = fib->fib_DirEntryType; free(fib); } return(result < 0); /* is it a file? */ }