/* launch.c */ /* Copyright © 1989 by Donald T. Meyer, Stormgate Software * All Rights Reserved */ #include "rxil.h" #include /* NAME * RxilLaunch * * SYNOPSIS * result = RxilLaunch( rxi ) * * LONG result; * * struct RxilInvocation *rxi; * * FUNCTION * Launch an ARexx program by sending an invocation message * to the RexxMaster process. The RxilInvocation structure * which is allocated prior to this call via RxilCreateRxi() * contains the information neccessary to launch the program. * * INPUTS * rxi A pointer to an initialized RxilInvocation structure. * * RESULT * Zero if the launch was successful, non-zero otherwise. * * SIDES * * HISTORY * 01-Aug-89 Creation. * * BUGS * * SEE ALSO * RxilCreateRxi(), RxilDeleteRxi() */ LONG RxilLaunch( struct RxilInvocation *rxi ) { struct RexxArg *arg; struct MsgPort *rmast, *replyport; struct RexxMsg *rexxmsg; int i; int ac=0; UWORD len; /* Make call "safe" even if RxilInit() failed */ if( global_rdef == NULL ) { return( -1 ); } /* Replys can come in at either port. */ replyport = global_rdef->SecretPort ? global_rdef->SecretPort : global_rdef->PublicPort; if( rxi->State != RXIL_STATE_AVAILABLE ) { /* A command is already launched, (using this structure), * or the reply has not yet been dealt with. */ return( -1 ); } /* Allocate a packet to send to rexxmaster */ rexxmsg = CreateRexxMsg( replyport, rxi->FileExt, rxi->CommAddr ); if( rexxmsg == NULL ) { return( -1 ); } /* Allocate an argument string for the command name and args */ arg = CreateArgstring( rxi->Name, strlen( rxi->Name ) ); if( arg == NULL ) { DeleteRexxMsg( rexxmsg ); return( -1 ); } ARG0(rexxmsg) = (STRPTR)arg; if( rxi->Type == RXFUNC ) { /* This is a Function invocation. */ /* Turn the arguments into Rexx Argstrings and place in the * RexxMsg packet. */ for( i=1; i<=MAXRMARG; i++ ) { if( rxi->FuncArg[i] == NULL ) { /* Empty argument slot, consider it the last */ break; } /* We can either determine the argument length, or the client * can pre-set a count. */ len = rxi->CountArgs ? rxi->ArgLen[i] : strlen(rxi->FuncArg[i]); rexxmsg->rm_Args[i] = (STRPTR)CreateArgstring( rxi->FuncArg[i], len ); ac++; if( rexxmsg->rm_Args[i] == NULL ) { /* Unable to create this argstring. Cleanup and return * a failure code. */ for( i=0; i<=MAXRMARG; i++ ) { if( rexxmsg->rm_Args[i] != NULL ) { DeleteArgstring( (struct RexxArg *) (rexxmsg->rm_Args[i]) ); } } DeleteRexxMsg( rexxmsg ); return( -1 ); } } rexxmsg->rm_Action = RXFUNC | rxi->ActionFlags | ac; } else { /* This is a Command invocation */ rexxmsg->rm_Action = RXCOMM | rxi->ActionFlags; } /* Set up the I/O streams for the macro */ if( rxi->Parent == NULL ) { /* This is an original launch from the application */ if( rxi->Console ) { /* And there is a console spec. Use it. */ RxilOpenConsole( rxi->Console, rexxmsg ); } } else { /* This is a loopback child of a macro. Use the I/O fields * from the parent message. */ rexxmsg->rm_Stdin = rxi->Parent->rm_Stdin; rexxmsg->rm_Stdout = rxi->Parent->rm_Stdout; } Forbid(); if( ( rmast = FindPort( rxi->IHostPort ) ) != NULL ) { PutMsg( rmast, (struct message *)rexxmsg ); } Permit(); if( rmast == NULL ) { /* we could not find the REXX port, this failed! * Cleanup and return a failure code. */ for( i=0; i<=MAXRMARG; i++ ) { if( rexxmsg->rm_Args[i] != NULL ) { DeleteArgstring( (struct RexxArg *) (rexxmsg->rm_Args[i]) ); } } if( rxi->Console ) { RxilCloseConsole( rexxmsg ); } DeleteRexxMsg( rexxmsg ); return( -1 ); } /* If we make it here, we have hopefully launched. */ /* Set this so we can recognize the reply, and to let us know that * we have a command pending. */ rxi->RexxMsg = rexxmsg; rxi->State = RXIL_STATE_PENDING; if( rxi->CommAddr == global_rdef->SecretPortName ) { #if 0 if( global_rdef->Locked ) { /* Since we are locked, we should not be launching any macros * which have the secret port as their initial host address. */ return( -1 ); } #endif /* Increment the locked count. */ global_rdef->LockCount++; } if( rxi->Parent == NULL ) { /* This is a launch originated within the application. */ if( FlagIsClear( global_rdef->Flags, RXIL_NO_ABORT ) ) { /* Post the macro cancel requester */ RxilPostCancel(); } } return( 0 ); }