![]() Chapter Contents |
![]() Previous |
![]() Next |
| execshv |
These examples
demonstrate the SUBCOM interface
to CMS and TSO. In the first example, three subcommands are accepted: ECHO
repeats operands, SETRC sets a return code, and EXEC invokes a TSO CLIST or
CMS EXEC. The program can be executed either interactively or noninteractively
depending on the value of the
interact
option in
execinit
.
#include <exec.h>
#include <ctype.h>
#include <lcstring.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
main(int argc, char **argv)
{
/* If 0, next input expected from EXEC. If nonzero, next input */
/* expected from terminal. */
int interact;
char *input, *cmdname, *operands;
int maxrc = 0;
int thisrc;
char msgbuff[120];
int result;
interact = (argc > 1 && tolower(*argv[1]) == 'i');
/* If first argument starts with 'i', use interactive mode. */
result = execinit("EXAMPLE", interact);
if (result != 0) exit(EXIT_FAILURE);
/* Check for failure of execinit */
for(;;) {
operands = input = execget();
/* Obtain next input line. */
if (!input)
break;
cmdname = execid(&operands);
/* Obtain command name. If error in execid, expect */
/* CLIST/EXEC input next. */
if (!cmdname) {
interact = 1;
continue;
}
strupr(cmdname); /* Upper case command name */
if (!*cmdname) /* Check for null input. */
continue;
/* If execid did an EXEC for us, note and continue. */
else if (strcmp(cmdname, "*EXEC") == 0) {
interact = 0;
continue;
}
/* If we just switched from EXEC to the terminal, note this. */
else if (strcmp(cmdname, "*ENDEXEC") == 0) {
interact = 1;
thisrc = atoi(operands);
/* Extract EXEC return code. Remember it might be missing.*/
if (operands)
sprintf(msgbuff, "EXEC return code %d", thisrc);
else
strcpy(msgbuff, "EXEC return code unavailable");
/* Inform user of return code. */
result = execmsg("EXAM001I", msgbuff);
if (result != 0 && errno == EINTR) break;
/* Check for unexpected signal */
}
/* Terminate if END received. */
else if (strcmp(cmdname, "END") == 0)
break;
else if (strcmp(cmdname, "EXEC") == 0) {
/* Call EXEC for EXEC subcommand and expect input from it.*/
thisrc = execcall(input);
interact = 0;
if (thisrc != 0) {
sprintf(msgbuff,"EXEC failed with return code %d",thisrc);
result = execmsg("EXAM005E",msgbuff);
if (result != 0 && errno == EINTR) break;
/* just quit after OpenEdition signal */
}
}
/* If command is ECHO, repeat its operands. */
else if (strcmp(cmdname, "ECHO") == 0) {
result = execmsg(0, operands);
if (result != 0 && errno == EINTR) break;
thisrc = 0;
}
/* If command is SETRC, set return code as requested. */
else if (strcmp(cmdname, "SETRC") == 0) {
char *number_end;
thisrc = strtol(operands, &number_end, 10);
if (!number_end) {
sprintf(msgbuff, "Invalid return code: %s",operands);
result = execmsg("EXAM002E", msgbuff);
if (result != 0 && errno == EINTR) break;
thisrc = 12;
}
else {
sprintf(msgbuff, "Return code set to %d", thisrc);
execmsg("EXAM003I", msgbuff);
if (result != 0 && errno == EINTR) break;
}
}
/* If unknown command name, try to EXEC it. */
else {
errno = 0; /* Make sure errno is clear */
thisrc = execcall(input);
if (thisrc != 0 && errno == EINTR) break;
interact = 0;
}
maxrc = execrc(thisrc); /* Inform EXEC of return code.*/
if (maxrc < 0 && errno == EINTR) break;
}
sprintf(msgbuff, "Maximum return code was %d", maxrc);
execmsg("EXAM004I", msgbuff); /* Announce max return code. */
execend(); /* Cancel SUBCOM connection. */
return maxrc; /* Return max return code. */
}
| CLIST Example for SUBCOM Processing |
CONTROL NOCAPS WRITE SUBCOM EXAMPLE: starting. /* Issue the echo subcommand a few times. */ ECHO This is the first subcommand. ECHO Your userid is &SYSUID.. SETRC 0 /* Try the SETRC subcommand. */ WRITE SUBCOM EXAMPLE: return code is now &LASTCC SETRC 8 /* Set the return code to 8 */ WRITE SUBCOM EXAMPLE: return code is now &LASTCC SETRC 0 /* and back to 0 */ WRITE /* Experiment with 'execmsg' by changing current */ /* message handling. The PCF-II X facility is used to */ /* direct PROFILE requests to TSO. */ X PROFILE MSGID /* Request message ID display. */ WRITE PROFILE MSGID (complete message) SETRC 0 WRITE X PROFILE NOMSGID /* Request message ID suppression. */ WRITE PROFILE NOMSGID (just the text) SETRC 0 WRITE CONTROL NOMSG WRITE CONTROL NOMSG (no message) SETRC 0 WRITE CONTROL MSG WRITE SET SYSOUTTRAP = 5 (trap messages within CLIST) SET SYSOUTTRAP = 5 SETRC 0 SET I = 1 WRITE Output produced by SETRC subcommand: DO WHILE & I < = & SYSOUTLINE /* Write output of SETRC subcommand. */ SET MSG = & STR(& & SYSOUTLINE& I) WRITE & MSG SET I = & I + 1 END SET SYSOUTTRAP = 0 WRITE /* Tell the example program to invoke another CLIST, */ /* this one called SUBSUB. When it finishes, display */ /* its return code. SUBSUB returns the sum of its */ /* arguments as its return code. */ %SUBSUB 12 2 WRITE SUBCOM EXAMPLE: subsub returned & LASTCC. END /* Invoked by SUBCOM CLIST */ PROC 2 VAL1 VAL2 CONTROL NOCAPS WRITE SUBSUB EXAMPLE: Received arguments & VAL1 and & VAL2 EXIT CODE(& VAL1+& VAL2)
| TSO REXX Example for SUBCOM Processing |
address example /* REXX SUBCOM example */
/* Issue the echo subcommand a few times. */
"echo This is the first subcommand."
"echo Your userid is " sysvar("SYSUID")
"setrc 0" /* try the SETRC subcommand */
say "SUBCOMR EXAMPLE: return code is now " RC
"setrc 8" /* Set the return code to 8 */
say "SUBCOMR EXAMPLE: return code is now " RC
"setrc 0" /* and back to 0 */
say " "
/* Put an echo subcommand on the stack for execution after the EXEC */
/* completes. */
queue 'echo This line is written after the EXEC is completed.'
/* Experiment with "execmsg" by changing current message handling. */
address tso "profile msgid"
say "PROFILE MSGID (complete message)"
"setrc 0"
say " "
address tso "profile nomsgid"
say "PROFILE NOMSGID (just the text)"
"setrc 0"
say " "
save = msg("OFF")
say "MSG(OFF) (no message)"
"setrc 0"
say " "
save = msg(save)
/* Tell the example program to invoke a CLIST named SUBSUB. When */
/* it finishes, display its return code. SUBSUB returns the sum */
/* of its arguments as its return code. */
"%subsub 12 2"
say "SUBCOMR EXAMPLE: subsub returned " RC
/* Now invoke a REXX EXEC named SUBSUBR, which performs the same */
/* function as the SUBSUB CLIST. Note that the negative return */
/* code produced by this call to subsubr will be flagged as an */
/* error by REXX. */
"%subsubr 5 -23"
say "SUBCOMR EXAMPLE: subsubr returned " RC
The following is the SUBSUBR EXEC invoked by the previous example.
/* REXX EXEC invoked by SUBCOMR EXEC */ parse arg val1 val2 . say "SUBSUBR EXAMPLE: Received arguments " VAL1 " and " VAL2 exit val1+val2
| CMS EXEC Example for SUBCOM Processing |
/* REXX */
say 'SUBCOM EXAMPLE: starting.'
/* Issue the echo subcommand a few times. */
'echo This is the first subcommand.'
'echo Your userid is' userid()'.'
'setrc 0' /* Try the setrc subcommand. */
say 'SUBCOM EXAMPLE: return code is now' rc
/* REXX variable 'rc' */
'setrc 8' /* Set the return code to 8. */
say 'SUBCOM EXAMPLE: return code is now' rc
/* REXX variable 'rc' */
'setrc 0' /* And back to 0. */
say ''
/* Experiment with 'execmsg' by changing the current EMSG setting. */
/* The subcommand 'setrc 0' will cause a message (or part of a */
/* message or nothing) to be sent. Note that the REXX 'address' */
/* statement is used to change the subcommand environment to CMS. */
address COMMAND 'CP SET EMSG ON' /* Display both ID and text. */
say 'SET EMSG ON (complete message)'
'setrc 0'
say ''
address COMMAND 'CP SET EMSG CODE' /* Display just the ID. */
say 'SET EMSG CODE (just the id)'
'setrc 0'
say ''
address COMMAND 'CP SET EMSG TEXT' /* Display just the text. */
say 'SET EMSG TEXT (just the text)'
'setrc 0'
say ''
address COMMAND 'CP SET EMSG OFF' /* Don't display anything. */
say 'SET EMSG OFF (no message)'
'setrc 0'
say ''
address COMMAND 'CP SET EMSG ON' /* Back to normal. */
/* Finally, tell SUBCOM C to invoke another macro, this one called */
/* 'SUBSUB'. When it finishes, display the return code. SUBSUB */
/* returns the number of arguments it got as the return code. */
'exec subsub arg1 arg2'
say 'SUBCOM EXAMPLE: subsub was passed' rc 'arguments.'
trace ?r
'end'
exit 0
/* invoked by SUBCOM EXAMPLE */
arg args
say 'SUBSUB EXAMPLE: Got' words(args) 'arguments.'
return words(args)
![]() Chapter Contents |
![]() Previous |
![]() Next |
![]() Top of Page |
Copyright © 2001 by SAS Institute Inc., Cary, NC, USA. All rights reserved.