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.