/* RunBack.c version 5 */ /* Author: Rob Peck. 5/9/86 */ /* Re-written by Greg Searle 7/14/89 */ /* Modified by Doug Keller 8/12/89 */ /* Command format: RUNBACK [[-]delay [priority]] command [argumentss...] * * delay is an integer number of seconds to wait for the task to * load. This may be used to eliminate "disk thrashing" when * loading many tasks in sequence. May be preceded with a dash. * * priority sets the task's priority. Recommended between -5 and * 5, but may theoretically be between -127 and 127. Don't precede * with a dash unless you wish the priority to be negative. * * Modifed 8/14/89 by Doug Keller. v6.0 Used Lattice C v5.02 * with registerized parameters, no stack checking, short ints, * forced prototyping, and global optimizing. * * * Modified 7/3/89 by Greg Searle. version 5. Major Cleanup. * Removed crash situation when program tries to input * input or output to the CLI. * * Oh my! What a little cleaning up a re-coding will do! This had a whole lot * of wrong turns and tangled code. Now it works like a dream. Even runs * DPaint. * * Doesn't need to check if command exists anymore. * Doesn't need to search path. AmigaDOS does this automatically. * * Added priority setting. * * Parameter checking improved. Knows when it sees a number. * Treats everything after its own parameters as arguments. * * Removed obsolete comments. */ /* Modified 5/21/88 by Dan Barrett. version 4. * * [path searching removed in version 5.] * * A few "#ifdef AZTEC_C" lines had to be added. It seems that * Aztec C parses the command line differently from the way Lattice * does with respect to arguments in quotes. When I compiled this * program with Aztec, all the quotes in quoted arguments were * disappearing. I re-insert them around any argument that has a * space character (' ') in it. */ /*#define DEBUG /* Uncomment this line for debugging. */ #include #include #include #include #include #include #include #include #include #include #include /* protos */ void main (int , char **); void Usage(void); int IsInteger (char *); /* */ void main (int argc, char *argv[]) { LONG loaddelay = 0, fromparm = 1, priority = 0, oldpriority, priorityset = FALSE, SetTaskPri(); UBYTE commandstring[255], name[255]; /*struct FileHandle *nilfh;*/ /* Don't free this. It is passed on to the task. */ BPTR nilfh; struct TaskCB *task, *FindTask(); if (argc < 2 || argv[1][0] == '?') Usage(); /********* * Check for Delay and Priority parameters. * *********/ if (IsInteger (argv[1])) { /* Load Delay. */ fromparm = 2; loaddelay = 50 * atol (argv[1]); if (loaddelay < 0) loaddelay = -loaddelay; if (argc < 3) Usage(); /* Only a delay, and no filename! */ strcpy(name, argv[2]); if (IsInteger (argv[2])) { /* Task priority. */ fromparm = 3; priority = atol (argv[2]); priorityset = TRUE; if (argc < 4) Usage(); /* Still no filename! */ strcpy(name, argv[3]); } } else { strcpy(name, argv[1]); } nilfh = Open ("NIL:" ,MODE_NEWFILE); /* will always succeed */ /********* * Rebuild parameter string * *********/ strcpy (commandstring, "RUN "); while (fromparm < argc) { strcat (commandstring, " "); /* add a blank */ strcat (commandstring, argv[fromparm++]); } /* while */ /********* * Run the program * *********/ /* Priority is set by temporarily setting the priority * of the current CLI. The new task takes on this * priority. */ #ifdef DEBUG printf("%s\n", commandstring); printf("Delay %ld Priority %ld\n", loaddelay, priority); #else task = FindTask (NULL); if (priorityset) oldpriority = SetTaskPri (task, priority); Execute (commandstring, nilfh, nilfh); if (priorityset) SetTaskPri (task, oldpriority); printf("Started %s as a background task, with a priority of %ld\n", name, priority); #endif /* The full command passed to Execute now looks like this: * * "RUN FILENAME PARAMETER(s)" * * There is no need to put re-direction in here, as it defaults to the * file handle passed on to the Execute() call. Redirection only * confuses things, and was one of the reason for past crashes. */ /* RunBack won't check if the file exists, and won't say anything to the * user about its actions. */ /* Execute, in this case, returns IMMEDIATELY. The process * that is loading the code that is to be run as a background * process is working to get everything in and started. */ /* Now, to minimize thrashing between tasks, lets put this task to * sleep so that the each task actually gets a chance to load. */ Delay (loaddelay); } /* main() */ int IsInteger (char *s) /* Return TRUE if string is an integer. */ { if (*s == '-') ++s; while (*s) if (*s < '0' || *(s++) > '9') return (FALSE); return (TRUE); } void Usage() /* Called from many places. */ { printf("Runback V6.0\n"); printf("Usage: RUNBACK [[-]delay [priority]] command [arguments...]\n\n"); exit(0); }