#include #include #include UBYTE *AllocMem(); BPTR LoadSeg(); struct MsgPort *CreateProc(); /* Launch(rport, name, argv, argc, pri, win, stack) -- launch a program. * * Launch builds a startup message, loads a program, and launches it. * * Arguments: * rport -- reply port to receive startup message back when the program * finishes. * name -- File name for the program to load. * argv -- list of filenames to pass to loaded program. * argc -- length of argument list. * pri -- priority of the new process. * win -- ToolWindow for the new process, or NULL. * stack -- Stack size for the new process. * * argv[0] should be the same as the program. pri should normally be 0. * stack should normally be at least 4K. */ struct WBStartup * Launch(rport, name, argv, argc, pri, win, stack) struct MsgPort *rport; char *name; char **argv; int argc; long pri; char *win; ULONG stack; { ULONG flock; struct WBStartup *msg; char *s, *namep; int i; if(!rport) return 0; /* Get some space to work in -- the startup message */ msg = (struct WBStartup *) AllocMem(sizeof(struct WBStartup), MEMF_PUBLIC|MEMF_CLEAR); if(!msg) return 0; /* Now load the program */ msg->sm_Segment = LoadSeg(name); if(!msg->sm_Segment) { FreeStartup(msg); return 0; } /* Allocate and link in the window description */ if(win) { msg->sm_ToolWindow = (char *)AllocMem(strlen(win)+1, MEMF_PUBLIC); if(!msg->sm_ToolWindow) { FreeStartup(msg); return 0; } strcpy(msg->sm_ToolWindow, win); } else msg->sm_ToolWindow = 0; /* Allocate the arg list */ msg->sm_ArgList = (struct WBArg *) AllocMem(sizeof(struct WBArg) * argc, MEMF_PUBLIC | MEMF_CLEAR); if(!msg->sm_ArgList) { FreeStartup(msg); return 0; } /* Empty out all args, just in case this aborts, so cleanup * can clean it up */ msg->sm_NumArgs = argc; for(i = 0; i < argc; i++) { msg->sm_ArgList[i].wa_Lock = 0; msg->sm_ArgList[i].wa_Name = 0; } /* Get lock and name for wbargs */ for(i = 0; i < argc; i++) { flock = Lock(argv[i]); if(!flock) { FreeStartup(msg); return 0; } msg->sm_ArgList[i].wa_Lock = ParentDir(flock); UnLock(flock); if(!msg->sm_ArgList[i].wa_Lock) { FreeStartup(msg); return 0; } /* Get the tail end of the file name. I could also do an Examine * on the lock, but didn't want to bother allocating a File Info * Block that wouldn't fit under the tracking via the startup * message. */ namep = argv[i]; for(s = argv[i]; *s; s++) if(*s=='/' || *s==':') namep = s+1; msg->sm_ArgList[i].wa_Name = (char *)AllocMem(strlen(namep)+1, MEMF_PUBLIC); if(!msg->sm_ArgList[i].wa_Name) { FreeStartup(msg); return 0; } strcpy(msg->sm_ArgList[i].wa_Name, namep); } /* Create the process. It is now running, but will wait for the * startup message. */ msg->sm_Process = CreateProc(msg->sm_ArgList[0].wa_Name, pri, msg->sm_Segment, stack); if(!msg->sm_Process) { FreeStartup(msg); return 0; } /* Initialise the message part of the startup message, and pass it to * the process. At this point it will actually start ding work */ msg->sm_Message.mn_ReplyPort = rport; msg->sm_Message.mn_Length = sizeof(struct WBStartup); msg->sm_Message.mn_Node.ln_Type = NT_MESSAGE; PutMsg(msg->sm_Process, msg); /* return message. Not very useful, but it's as meaningful a response as * any. */ return msg; }