This C/370™ program creates
a REXX environment and runs a REXX program:
#pragma strings(readonly)
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
typedef int EXTF();
#pragma linkage(EXTF,OS)
int main(int argc, char **argv) {
extern char **environ; /* access environ variables */
EXTF *irxjcl; /* pointer to IRXJCL routine */
EXTF *bpxwrbld; /* pointer to BPXWRBLD routine */
char *penvb; /* addr of REXX environment */
int i,j; /* temps */
long rcinit; /* return code */
int **environlp; /* ptr to env length pointers */
int *environl; /* ptr to env lengths */
char rxwork[16000]; /* OE MVS env work area */
char *execname="execname"; /* name of exec up to 8 chars */
char *execparm="exec parameter string"; /* parm to exec */
struct s_rxparm { /* parm to IRXJCL */
short len; /* halfword length of parm */
char name[8]; /* area to hold exec name */
char space; /* one space */
char text[253]; /* big area for exec parm */
} *rxparm;
/* if stdin or stdout are not open you might want to open file */
/* descriptors 0 and 1 here */
/* if no environ, probably tso or batch - make one */
if (environ==NULL) {
environ=(char **)malloc(8); /* create one */
environ[0]="PATH=."; /* set PATH to cwd */
environ[1]=NULL; /* env terminator */
};
/* need to build the environment in the same format as expected by */
/* the exec() callable service. See */
/* Assembler Callable Services for UNIX System Services. */
/* the environ array must always end with a NULL element */
for (i=0;environ[i]!=NULL;i++); /* count vars */
environlp=(int **)malloc(i*4+4); /* get array for len ptrs */
environl=(int *)malloc(i*4+4); /* get words for len vals */
for (j=0;j<i;j++) {
environlp[j]=&environl[j]; /* point to len */
environl[j]=strlen(environ[j])+1; /* set len word */
};
environlp[j]=NULL; /* null entry at end */
environl[j]=0;
/* load routines */
irxjcl=(EXTF *)fetch("IRXJCL ");
bpxwrbld=(EXTF *)fetch("BPXWRBLD ");
/* build the REXX environment */
rcinit=bpxwrbld(rxwork,
argc,argv,
i,environlp,environ,
&penvb);
if (rcinit!=0) {
printf("environment create failed rc=%d\n",rcinit);
return 255;
};
/* if you need to add subcommands or functions to the environment, */
/* or create a new environment inheriting the current one, this is */
/* the place to do it. The user field in the environment is used */
/* by the z/OS UNIX REXX support and must be preserved. */
/* run exec */
rxparm=(struct s_rxparm *)malloc(strlen(execname)+
strlen(execparm)+
sizeof(struct s_rxparm));
memset(rxparm->name,' ',sizeof(rxparm->name));
memcpy(rxparm->name,execname,strlen(execname));
rxparm->space=' ';
memcpy(rxparm->text,execparm,i=strlen(execparm));
rxparm->len=sizeof(rxparm->name)+sizeof(rxparm->space)+i;
return irxjcl(rxparm);
}