callrexx2.c
Go to the documentation of this file.
1 /*----------------------------------------------------------------------------*/
2 /* */
3 /* Copyright (c) 1995, 2004 IBM Corporation. All rights reserved. */
4 /* Copyright (c) 2005-2014 Rexx Language Association. All rights reserved. */
5 /* */
6 /* This program and the accompanying materials are made available under */
7 /* the terms of the Common Public License v1.0 which accompanies this */
8 /* distribution. A copy is also available at the following address: */
9 /* http://www.oorexx.org/license.html */
10 /* */
11 /* Redistribution and use in source and binary forms, with or */
12 /* without modification, are permitted provided that the following */
13 /* conditions are met: */
14 /* */
15 /* Redistributions of source code must retain the above copyright */
16 /* notice, this list of conditions and the following disclaimer. */
17 /* Redistributions in binary form must reproduce the above copyright */
18 /* notice, this list of conditions and the following disclaimer in */
19 /* the documentation and/or other materials provided with the distribution. */
20 /* */
21 /* Neither the name of Rexx Language Association nor the names */
22 /* of its contributors may be used to endorse or promote products */
23 /* derived from this software without specific prior written permission. */
24 /* */
25 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
26 /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
27 /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
28 /* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
29 /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
30 /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */
31 /* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */
32 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */
33 /* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
34 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
35 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
36 /* */
37 /*----------------------------------------------------------------------------*/
38 /*********************************************************************/
39 /* */
40 /* File Name: CALLREXX2.C */
41 /* */
42 /* ----------------------------------------------------------------- */
43 /* */
44 /* Description: Samples of how to invoke the Open Object Rexx*/
45 /* interpreter. It loads the Rexx library at */
46 /* runtime. */
47 /* */
48 /* Entry Points: main - main entry point */
49 /* */
50 /* Input: None */
51 /* */
52 /* Output: returns from the Open Object Rexx programs */
53 /* */
54 /*********************************************************************/
55 
56 #include <stdlib.h>
57 #include <stdio.h>
58 #include <string.h>
59 #include <dlfcn.h>
60 #include <sys/stat.h>
61 #include <errno.h>
62 
63 #include "rexx.h"
64 
65 char *pcharTemp;
66 
67 int main(int argc, char **argv)
68 {
69  CONSTRXSTRING arg[4]; /* argument string for Rexx */
70  RXSTRING rexxretval; /* return value from Rexx */
71  RXSTRING instore[2]; /* in storage parms */
72  PFNREXXSTART FuncAddress;
73  void *pLibHandle = NULL; /* Library handle */
74  RexxReturnCode rc = 0; /* return code from Rexx */
75  short rexxrc = 0; /* return code from function */
76  const char *pszLibraryName = "librexx.so"; /* define the library name */
77  char returnBuffer[100];
78 
79  char val;
80  const char *str1 = "Arg number one"; /* text to swap */
81  const char *str2 = "Arg number two"; /* text to swap */
82  const char *str3 = "Arg number three"; /* text to swap */
83  const char *str4 = "Arg number four"; /* text to swap */
84 
85  const char *sync_tst = "call time 'Reset';" \
86  "object1 = .example~new;" \
87  "object2 = .example~new;" \
88  "object3 = .example~new;" \
89  "a.1 = object1~start('REPEAT', 4 , 'Object 1 running');" \
90  "say a.1~result;" \
91  "say 'The result method waits until the START message has completed:';" \
92  "a.2 = object2~start('REPEAT', 2, 'Object 2 running');" \
93  "a.3 = object3~start('REPEAT', 2, 'Object 3 running');" \
94  "say a.2~result;" \
95  "say a.3~result;" \
96  "say 'main ended';" \
97  "say 'Elapsed time: ' time('E');" \
98  "exit;" \
99  "::REQUIRES 'example.rex'";
100 
101  if (!(pLibHandle = dlopen(pszLibraryName, RTLD_LAZY )))
102  { /* Load and resolve symbols immediately */
103  fprintf(stderr, " *** Unable to load library %s !\nError message: %s\n",
104  pszLibraryName, dlerror());
105  return 99;
106  }
107 
108  if(!(FuncAddress = (PFNREXXSTART) dlsym(pLibHandle, "RexxStart")))
109  {
110  rc = 1; /* could not resolve */
111  fprintf(stderr, " *** Unable to load function %s !\nError message: %s\n",
112  "RexxStart", dlerror());
113  return 99;
114  }
115 
116 
117  /* By setting the strlength of the Rexx output to zero, the */
118  /* interpreter allocates memory. */
119  /* We can provide a buffer for the interpreter to use instead. */
120  /* If the returned value does not fit into the buffer, */
121  /* Open Object Rexx creates a new one. */
122 
123  system("clear");
124 
125  rexxretval.strptr = NULL; /* initialize return-pointer to empty */
126  rexxretval.strlength = 0; /* initialize return-length to zero */
127 
128  printf("This is an easy sample of how to invoke the Rexx interpreter. \n");
129  printf("The Rexx commandfile which is started is named: startrx1.rex\n");
130 
131  printf("Press Enter to continue\n");
132  scanf("%c", &val);
133 
134 
135  /* This is the interpreter invocation. ------------------------------ */
136 
137  rc = (*FuncAddress)(
138  0, /* number of arguments */
139  NULL, /* array of arguments */
140  "startrx1.rex", /* name of Rexx file */
141  NULL, /* No INSTORE used */
142  "ksh", /* Command env. name */
143  RXCOMMAND, /* Code for how invoked */
144  NULL, /* No EXITs on this call */
145  &rexxrc, /* Rexx program output */
146  &rexxretval ); /* Rexx program output */
147 
148  printf("CALLREXX2 - Back from REXXSTART: Return Code: %d\n", rc);
149  printf("CALLREXX2 - RESULT-LENGTH: %d\n", rexxretval.strlength);
150  printf("CALLREXX2 - RESULT-Value: %s\n", rexxretval.strptr);
151 
152  if (rexxretval.strptr != NULL)
153  {
154  RexxFreeMemory(rexxretval.strptr);
155  }
156 
157  printf("Press Enter to continue\n");
158  scanf("%c", &val);
159 
160  system("clear");
161 
162  printf("In this case a previously defined Resultstring is \n");
163  printf("delivered to Open Object Rexx, which is large enough to \n");
164  printf("hold the Return Value of the Rexx commandfile.\n");
165 
166  printf("Press Enter to continue\n");
167  scanf("%c", &val);
168 
169  rexxretval.strptr = returnBuffer;
170  rexxretval.strlength = sizeof(returnBuffer);
171 
172  rc = (*FuncAddress)(
173  0, /* number of arguments */
174  NULL, /* array of arguments */
175  "startrx1.rex", /* name of Rexx file */
176  NULL, /* No INSTORE used */
177  "ksh", /* Command env. name */
178  RXCOMMAND, /* Code for how invoked */
179  NULL, /* No EXITs on this call */
180  &rexxrc, /* Rexx program output */
181  &rexxretval ); /* Rexx program output */
182 
183  printf("CALLREXX2 - Back from REXXSTART: Return Code: %d\n", rc);
184  printf("rexxretval.strptr contains %s\n", rexxretval.strptr);
185  printf("CALLREXX2 - RESULT-LENGTH: %d\n", rexxretval.strlength);
186  printf("CALLREXX2 - RESULT-Value: %s\n", rexxretval.strptr);
187  /* if Rexx needed to allocate a new buffer, release that one */
188  if (rexxretval.strptr != returnBuffer)
189  {
190  RexxFreeMemory(rexxretval.strptr);
191  }
192 
193  printf("Press Enter to continue\n");
194  scanf("%c", &val);
195 
196  system("clear");
197 
198  printf("In this case a previously defined Resultstring is \n");
199  printf("delivered to Open Object Rexx, which is too small to\n");
200  printf("hold the Return Value of the Rexx commandfile.\n");
201  printf("Rexx reallocates the buffer which needs to be freed.\n");
202  printf("in the calling program\n");
203 
204  printf("Press Enter to continue\n");
205  scanf("%c", &val);
206 
207  rexxretval.strptr = (char *)returnBuffer;
208  rexxretval.strlength = 2;
209 
210  printf("The length of the Resultstring is %d\n", rexxretval.strlength);
211 
212  rc = (*FuncAddress)(
213  0, /* number of arguments */
214  NULL, /* array of arguments */
215  "startrx1.rex", /* name of Rexx file */
216  NULL, /* No INSTORE used */
217  "ksh", /* Command env. name */
218  RXCOMMAND, /* Code for how invoked */
219  NULL, /* No EXITs on this call */
220  &rexxrc, /* Rexx program output */
221  &rexxretval ); /* Rexx program output */
222 
223  printf("CALLREXX2 - Back from REXXSTART: Return Code: %d\n", rc);
224  printf("The ResultString contains %s after call\n", rexxretval.strptr);
225  printf("The length is now %d\n", rexxretval.strlength);
226 
227  /* if Rexx needed to allocate a new buffer, release that one */
228  if (rexxretval.strptr != returnBuffer)
229  {
230  RexxFreeMemory(rexxretval.strptr);
231  }
232 
233  printf("Press Enter to continue\n");
234  scanf("%c", &val);
235 
236  system("clear");
237 
238  rexxretval.strptr = NULL; /* initialize return-pointer to empty */
239  rexxretval.strlength = 0; /* initialize return-length to zero */
240 
241  printf("This is a sample with 4 arguments delivered to \n");
242  printf("REXXSTART\n");
243  printf("The Rexx commandfile which is started is named: startrx2.rex\n");
244 
245  printf("Press Enter to continue\n");
246  scanf("%c", &val);
247 
248  MAKERXSTRING(arg[0], str1, strlen(str1)); /* create input argument 1 */
249  MAKERXSTRING(arg[1], str2, strlen(str2)); /* create input argument 2 */
250  MAKERXSTRING(arg[2], str3, strlen(str3)); /* create input argument 3 */
251  MAKERXSTRING(arg[3], str4, strlen(str4)); /* create input argument 4 */
252 
253  rc = (*FuncAddress)(
254  4, /* number of arguments */
255  arg, /* array of arguments */
256  "startrx2.rex", /* name of Rexx file */
257  NULL, /* No INSTORE used */
258  "ksh", /* Command env. name */
259  RXCOMMAND, /* Code for how invoked */
260  NULL, /* No EXITs on this call */
261  &rexxrc, /* Rexx program output */
262  &rexxretval ); /* Rexx program output */
263 
264  printf("CALLREXX2 - Back from REXXSTART: Return Code: %d\n", rc);
265  printf("CALLREXX2 - RESULT-LENGTH: %d\n", rexxretval.strlength);
266  printf("CALLREXX2 - RESULT-Value: %s\n", rexxretval.strptr);
267 
268  RexxFreeMemory(rexxretval.strptr);
269 
270  printf("Press Enter to continue\n");
271  scanf("%c", &val);
272 
273  system("clear");
274 
275  printf("This is a sample with 2 arguments delivered to \n");
276  printf("REXXSTART\n");
277  printf("The Rexx commandfile which is started is named: startrx2.rex\n");
278 
279  printf("Press Enter to continue\n");
280  scanf("%c", &val);
281 
282  rexxretval.strptr = NULL; /* initialize return-pointer to empty */
283  rexxretval.strlength = 0; /* initialize return-length to zero */
284 
285  rc = (*FuncAddress)(
286  2, /* number of arguments */
287  arg, /* array of arguments */
288  "startrx2.rex", /* name of Rexx file */
289  NULL, /* No INSTORE used */
290  "ksh", /* Command env. name */
291  RXCOMMAND, /* Code for how invoked */
292  NULL, /* No EXITs on this call */
293  &rexxrc, /* Rexx program output */
294  &rexxretval ); /* Rexx program output */
295 
296  printf("CALLREXX2 - Back from REXXSTART: Return Code: %d\n", rc);
297  printf("CALLREXX2 - RESULT-LENGTH: %d\n", rexxretval.strlength);
298  printf("CALLREXX2 - RESULT-Value: %s\n", rexxretval.strptr);
299 
300  RexxFreeMemory(rexxretval.strptr);
301 
302  printf("Press Enter to continue\n");
303  scanf("%c", &val);
304 
305  system("clear");
306 
307  printf("This is a sample where the directory listing of the \n");
308  printf("actual directory is returned by the Rexx program. The \n");
309  printf("returned ResultString is displayed\n");
310  printf("The Rexx commandfile which is started is named: startrx3.rex\n");
311 
312  printf("Press Enter to continue\n");
313  scanf("%c", &val);
314 
315  rexxretval.strptr = NULL; /* initialize return-pointer to empty */
316  rexxretval.strlength = 0; /* initialize return-length to zero */
317 
318  rc = (*FuncAddress)(
319  0, /* number of arguments */
320  NULL, /* array of arguments */
321  "startrx3.rex", /* name of Rexx file */
322  NULL, /* No INSTORE used */
323  "ksh", /* Command env. name */
324  RXCOMMAND, /* Code for how invoked */
325  NULL, /* No EXITs on this call */
326  &rexxrc, /* Rexx program output */
327  &rexxretval ); /* Rexx program output */
328 
329  printf("CALLREXX2 - Back from REXXSTART: Return Code: %d\n", rc);
330  printf("CALLREXX2 - RESULT-LENGTH: %d\n", rexxretval.strlength);
331  printf("CALLREXX2 - RESULT-Value: %s\n", rexxretval.strptr);
332 
333  RexxFreeMemory(rexxretval.strptr);
334 
335  printf("Press Enter to continue\n");
336  scanf("%c", &val);
337 
338  system("clear");
339 
340  printf("This is a sample where the instore parameter [0] is \n");
341  printf("tested. Instore parameter [0] is loaded with \n");
342  printf("a small Open Object Rexx script showing the concurrency feature.\n");
343 
344  printf("Press Enter to continue\n");
345  scanf("%c", &val);
346 
347  instore[0].strptr = (const char *)sync_tst;
348  instore[0].strlength = strlen(instore[0].strptr);
349  instore[1].strptr = NULL;
350  instore[1].strlength = 0;
351 
352  rexxretval.strptr = NULL; /* initialize return-pointer to empty */
353  rexxretval.strlength = 0; /* initialize return-length to zero */
354 
355  rc = (*FuncAddress)(
356  0, /* number of arguments */
357  NULL, /* array of arguments */
358  NULL, /* no name for Rexx file */
359  instore, /* INSTORE used */
360  "ksh", /* Command env. name */
361  RXCOMMAND, /* Code for how invoked */
362  NULL, /* No EXITs on this call */
363  &rexxrc, /* Rexx program output */
364  &rexxretval ); /* Rexx program output */
365 
366  printf("CALLREXX2 - Back from REXXSTART: Return Code: %d\n", rc);
367  printf("CALLREXX2 - RESULT-LENGTH: %d\n", rexxretval.strlength);
368  printf("CALLREXX2 - RESULT-Value: %s\n", rexxretval.strptr);
369 
370  RexxFreeMemory(rexxretval.strptr);
371 
372  printf("Press Enter to continue\n");
373  scanf("%c", &val);
374 
375  system("clear");
376 
377  printf("Now instore[1] is loaded with the content of instore[0]. \n");
378  printf("It can be used on subsequent calls. instore[0] is set to NULL \n");
379 
380  printf("Press Enter to continue\n");
381  scanf("%c", &val);
382 
383  instore[0].strptr = NULL;
384  instore[0].strlength = 0;
385 
386  rexxretval.strptr = NULL; /* initialize return-pointer to empty */
387  rexxretval.strlength = 0; /* initialize return-length to zero */
388 
389  rc = (*FuncAddress)(
390  0, /* number of arguments */
391  NULL, /* array of arguments */
392  NULL, /* no name for Rexx file */
393  instore, /* INSTORE used */
394  "ksh", /* Command env. name */
395  RXCOMMAND, /* Code for how invoked */
396  NULL, /* No EXITs on this call */
397  &rexxrc, /* Rexx program output */
398  &rexxretval ); /* Rexx program output */
399 
400  printf("CALLREXX2 - Back from REXXSTART: Return Code: %d\n", rc);
401  printf("CALLREXX2 - RESULT-LENGTH: %d\n", rexxretval.strlength);
402  printf("CALLREXX2 - RESULT-Value: %s\n", rexxretval.strptr);
403 
404  RexxFreeMemory(rexxretval.strptr);
405 
406  free(instore[1].strptr);
407 
408  printf("Press Enter to continue\n");
409  scanf("%c", &val);
410 
411  system("clear");
412 
413  printf("This is a sample to show how to use the Rexx MacroSpace facility. \n");
414  printf("First of all load_macro.rex is called to load \n");
415  printf("the Rexx script macros.rex into Macrospace. The Macrospace- \n");
416  printf("name is upload.rex. \n");
417 
418  printf("Press Enter to continue\n");
419  scanf("%c", &val);
420 
421  rexxretval.strptr = NULL; /* initialize return-pointer to empty */
422  rexxretval.strlength = 0; /* initialize return-length to zero */
423 
424  rc = (*FuncAddress)(
425  0, /* number of arguments */
426  NULL, /* array of arguments */
427  "load_macro.rex", /* name for Rexx macrospacefile*/
428  NULL, /* INSTORE not used */
429  "ksh", /* Command env. name */
430  RXCOMMAND, /* Code for how invoked */
431  NULL, /* No EXITs on this call */
432  &rexxrc, /* Rexx program output */
433  &rexxretval ); /* Rexx program output */
434 
435  printf("CALLREXX2 - Back from REXXSTART: Return Code: %d\n", rc);
436  printf("CALLREXX2 - RESULT-LENGTH: %d\n", rexxretval.strlength);
437  printf("CALLREXX2 - RESULT-Value: %s\n", rexxretval.strptr);
438 
439  RexxFreeMemory(rexxretval.strptr);
440 
441  printf("Press Enter to continue\n");
442  scanf("%c", &val);
443 
444  system("clear");
445 
446  printf("Now the Open Object Rexx script macros.rex (named upload.rex) has been loaded\n");
447  printf("into Macrospace. It is now used in the name option of\n");
448  printf("the REXXSTART command. \n");
449  printf("It is very important that instore paramenter [0] and [1] are\n");
450  printf("initialized to NULL rsp. 0 and used as REXXSTART parameters\n");
451 
452  printf("Press Enter to continue\n");
453  scanf("%c", &val);
454 
455  rexxretval.strptr = NULL; /* initialize return-pointer to empty */
456  rexxretval.strlength = 0; /* initialize return-length to zero */
457 
458  instore[1].strptr = NULL;
459  instore[1].strlength = 0;
460  instore[0].strptr = NULL;
461  instore[0].strlength = 0;
462 
463  rc = (*FuncAddress)(
464  0, /* number of arguments */
465  NULL, /* array of arguments */
466  "upload.rex", /* name for Rexx macrospacefile */
467  instore, /* INSTORE used */
468  "ksh", /* Command env. name */
469  RXCOMMAND, /* Code for how invoked */
470  NULL, /* No EXITs on this call */
471  &rexxrc, /* Rexx program output */
472  &rexxretval ); /* Rexx program output */
473 
474  printf("CALLREXX2 - Back from REXXSTART: Return Code: %d\n", rc);
475  printf("CALLREXX2 - RESULT-LENGTH: %d\n", rexxretval.strlength);
476  printf("CALLREXX2 - RESULT-Value: %s\n", rexxretval.strptr);
477 
478  RexxFreeMemory(rexxretval.strptr);
479 
480  free(rexxretval.strptr);
481 
482  printf("Press Enter to continue\n");
483  scanf("%c", &val);
484 
485  system("clear");
486 
487  printf("Finally del_macro.rex is called to delete macros.rex (named upload.rex)\n");
488  printf("out of the Open Object Rexx Macrospace.\n");
489 
490  printf("Press Enter to continue\n");
491  scanf("%c", &val);
492 
493  rc = (*FuncAddress)(
494  0, /* number of arguments */
495  NULL, /* array of arguments */
496  "del_macro.rex", /* name for Rexx macrospacefile */
497  NULL, /* INSTORE not used */
498  "ksh", /* Command env. name */
499  RXCOMMAND, /* Code for how invoked */
500  NULL, /* No EXITs on this call */
501  &rexxrc, /* Rexx program output */
502  &rexxretval ); /* Rexx program output */
503 
504  printf("CALLREXX2 - Back from REXXSTART: Return Code: %d\n", rc);
505  printf("CALLREXX2 - RESULT-LENGTH: %d\n", rexxretval.strlength);
506  printf("CALLREXX2 - RESULT-Value: %s\n", rexxretval.strptr);
507 
508  RexxFreeMemory(rexxretval.strptr);
509 
510  printf("Press Enter to continue\n");
511  scanf("%c", &val);
512 
513  system("clear");
514  return 0;
515 }
516 
int main(int argc, char **argv)
Definition: callrexx2.c:67
char * pcharTemp
Definition: callrexx2.c:65
RexxReturnCode(REXXENTRY * PFNREXXSTART)(size_t, PCONSTRXSTRING, CONSTANT_STRING, PRXSTRING, CONSTANT_STRING, int, PRXSYSEXIT, short *, PRXSTRING)
Definition: rexx.h:462
RexxReturnCode REXXENTRY RexxFreeMemory(void *)
#define MAKERXSTRING(r, p, l)
Definition: rexx.h:182
int RexxReturnCode
Definition: rexx.h:73
#define RXCOMMAND
Definition: rexxapidefs.h:64
size_t strlength
Definition: rexx.h:157
char * strptr
Definition: rexx.h:158