/* -------------- runbackground.c --------------- SUMMARY: A Workbench Disk can be used to autostart an application through the use of the startup script and close the startup CLI. Users have commented that it is not possible to start a process going from the startup script and then cause the initial CLI to go away. Here is the solution to that problem, named appropriately: RUNBACKGROUND which starts and runs a background task. This does indeed allow you to create a startup script that will set up your workbench running any programs you might wish, removing the initial CLI in the process. Your s/startup-sequence can contain lines such as the following: RUNBACKGROUND -3 clock RUNBACKGROUND utilities/calculator RUNBACKGROUND -5 utilities/notepad where RUNBACKGROUND is the command and the second parameter is the filename which may be preceded by a flag-variable that specifies an optional delay time. The delay can be from 0 to 9, for the number of seconds that the startup script should sleep while allowing the background task to load and start. I've put that in to minimize thrashing of the disk as it tries to load several projects at once. LIMITATIONS: The program that you run cannot require any input from an interactive CLI that starts it. Additionally, you cannot specify any file redirection in the command line since this program provides the redirection for you already. If you need to use redirection for your command, you can modify the source code where shown, thus allowing the redirection to become one of the parameters passed through to your program. RUNBACKGROUND does pass your command line parameters to the program you wish to start, but limits the total length of your command string to 227 (255 minus the 28 characters for "RUN >NIL: NIL: < NIL: " following it.) LINKING INFORMATION: (Amiga/Lattice C) use -v option for pass 2 (lc2 -v filename.q) to disable stack checking code installation. (stack checking code sometimes is incorrect). FROM lib:Astartup.obj runbackground.o TO runbackground LIBRARY lib:amiga.lib, lib:lc.lib **************************** NOTE: ******************************** If you use Lstartup.obj, it won't let the startup CLI go away. This is because the source code for Lstartup.asm either opens its own window or uses an existing CLI window (Open("*",....)), so that it has some guaranteed place to put the output. Astartup.obj does not do this. ********************************************************************* Hope this helps. robp. */ /* runbackground.c */ /* Author: Rob Peck. 5/9/86 */ #include "exec/types.h" #include "exec/memory.h" #include "libraries/dosextens.h" extern struct FileHandle *Open(); extern struct FileLock *Lock(); main(argc, argv) int argc; char *argv[]; { LONG success, delaywillbe; UBYTE commandstring[255]; char *test, *filename; LONG fromparm; struct FileInfoBlock *fib; struct FileHandle *nilfh; /* NOTE: will hang around until next reset */ struct FileLock *lock; fib = NULL; /* No file info block so far. */ delaywillbe = 1; if(argc < 2 ) { usage: printf("Usage: RUNBACKGROUND [ -] []\n"); printf(" where optional loaddelay is 0-9,\n"); printf(" specified in seconds for the CLI\n"); printf(" to sleep, waiting for task to load\n"); printf(" (minimizes inter-task disk-thrashing)\n"); if(fib) FreeMem(fib, sizeof(struct FileInfoBlock)); exit(0); } /* See if there is a delay parameter present */ test = argv[1]; if(*test++ == '-') { filename = argv[2]; /* argv[1] is delay so argv[2] is file */ fromparm = 3; /* Copy parms from 3 to end */ if(*test >= '0' && *test <= '9') { delaywillbe = 1 + (50 * (*test - '0')); } if (argc < 3) goto usage; /* Only a delay, and no filename!! */ argc--; /* one less parm to copy */ } else { filename = argv[1]; fromparm = 2; /* Copy parms from 2 to end */ } /* Now see if the file exists! If not, it can crash the background * CLI and take the system along with it. */ lock = Lock(filename,ACCESS_READ); if(!lock) { test = filename; if(*test == '?') goto usage; else { printf("%ls: Command not found\n",filename); goto usage; } } else { /* If file exists, it better be a file and not a directory */ /* Unfortunately, it is difficult to tell if it is an executable * file. If not executable, we'll still get blown out of the * water, but that is up to the user to do it right! */ fib = (struct FileInfoBlock *) AllocMem(sizeof(struct FileInfoBlock),MEMF_CLEAR); if(!fib) { UnLock(lock); printf("Ran out of memory!\n"); exit(0); } else { success = Examine(lock,fib); if(fib->fib_DirEntryType > 0) /* its a directory!! */ { printf("%ls is a directory, not a file!\n",filename); goto usage; } } FreeMem(fib, sizeof(struct FileInfoBlock)); UnLock(lock); } nilfh = Open("NIL:",MODE_NEWFILE); /* will always succeed */ strcpy( &commandstring[0], "RUN >NIL: somewhere" or "NIL: 0) /* Rebuild parameter string for passing it on */ { strcat( &commandstring[0], " "); /* add a blank */ strcat( &commandstring[0], argv[fromparm++]); } success = Execute( &commandstring[0] , nilfh, nilfh); /* The full command passed to Execute now looks like this: * * "RUN >NIL: NIL: