unix/hostemu.cpp
Go to the documentation of this file.
1 /*----------------------------------------------------------------------------*/
2 /* */
3 /* Copyright (c) 2009-2010 Rexx Language Association. All rights reserved. */
4 /* */
5 /* This program and the accompanying materials are made available under */
6 /* the terms of the Common Public License v1.0 which accompanies this */
7 /* distribution. A copy is also available at the following address: */
8 /* http://www.oorexx.org/license.html */
9 /* */
10 /* Redistribution and use in source and binary forms, with or */
11 /* without modification, are permitted provided that the following */
12 /* conditions are met: */
13 /* */
14 /* Redistributions of source code must retain the above copyright */
15 /* notice, this list of conditions and the following disclaimer. */
16 /* Redistributions in binary form must reproduce the above copyright */
17 /* notice, this list of conditions and the following disclaimer in */
18 /* the documentation and/or other materials provided with the distribution. */
19 /* */
20 /* Neither the name of Rexx Language Association nor the names */
21 /* of its contributors may be used to endorse or promote products */
22 /* derived from this software without specific prior written permission. */
23 /* */
24 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
25 /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
26 /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
27 /* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
28 /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
29 /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */
30 /* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */
31 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */
32 /* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
33 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
34 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
35 /* */
36 /* Authors; */
37 /* W. David Ashley <dashley@us.ibm.com> */
38 /* */
39 /*----------------------------------------------------------------------------*/
40 
41 
42 #include <stdlib.h>
43 #include <string.h>
44 #include <stdio.h>
45 #include <sys/types.h>
46 #include <unistd.h>
47 #include <pthread.h>
48 #include <rexx.h>
49 #include <oorexxapi.h>
50 
51 #include "../../hostemu.h"
52 
53 
54 /*--------------------------------------------------------------------*/
55 /* */
56 /* Global variables */
57 /* */
58 /*--------------------------------------------------------------------*/
59 
60 // #define HOSTEMU_DEBUG
61 
64 long lCmdPtr;
65 unsigned long ulNumSym;
67 char szInline[1000];
68 long lStmtType;
69 
70 
71 /*--------------------------------------------------------------------*/
72 /* */
73 /* Local definitions */
74 /* */
75 /*--------------------------------------------------------------------*/
76 
77 typedef struct _LL
78  {
79  struct _LL * prev;
80  struct _LL * next;
81  char FileName [1024];
82  FILE * pFile;
83  } LL;
84 typedef LL * PLL;
85 
86 
87 /*--------------------------------------------------------------------*/
88 /* */
89 /* Local variables */
90 /* */
91 /*--------------------------------------------------------------------*/
92 
93 static pthread_mutex_t hmtxExecIO = PTHREAD_MUTEX_INITIALIZER;
94 static PLL pHead = NULL;
95 static PLL pTail = NULL;
96 
97 
98 /*--------------------------------------------------------------------*/
99 /* */
100 /* Local function prototypes */
101 /* */
102 /*--------------------------------------------------------------------*/
103 
104 static unsigned long ExecIO_Write_From_Stem(
105  PLL pll); /* Pointer to file linked list item */
106 static unsigned long ExecIO_Write_From_Queue(
107  PLL pll); /* Pointer to file linked list item */
108 static unsigned long ExecIO_Read_To_Stem(
109  PLL pll); /* Pointer to file linked list item */
110 static unsigned long ExecIO_Read_To_Queue(
111  PLL pll); /* Pointer to file linked list item */
112 static PLL Search_LL(
113  char * SFilename); /* Source file name */
114 static void Insert_LL(
115  PLL pll); /* Pointer to the new item */
116 static void Delete_LL(
117  PLL pll); /* Pointer to the item to be deleted */
118 static long queued(
119  void); /* No arguments */
120 static void push(
121  char * pushstr, /* String to be pushed onto queue */
122  long lOp); /* 0 = FIFO, 1 = LIFO */
123 static char * pull(
124  void); /* No arguments */
125 
126 /*--------------------------------------------------------------------*/
127 /* */
128 /* Function: FetchRexxVar() */
129 /* */
130 /* Description: Fetch contents of a REXX variable from the current */
131 /* variable pool. The caller is responsible for freeing */
132 /* the buffer pointed to by the return value via */
133 /* DosFreeMem(). */
134 /* */
135 /* Input: PSZ - name of the REXX variable to be fetched */
136 /* PRXSTRING - pointer to the return RXSTRING structure */
137 /* */
138 /* Returns: ULONG - return code from RexxVariablePool() */
139 /* */
140 /* Notes: None. */
141 /* */
142 /*--------------------------------------------------------------------*/
143 
144 unsigned long FetchRexxVar (
145  char * pszVar, /* Variable name */
146  PRXSTRING prxVar) /* REXX variable contents */
147  {
148 
149  /* local function variables */
150  SHVBLOCK RxVarBlock;
151  unsigned long ulRetc;
152  char * pszTemp;
153 
154  /* initialize the shared variable block */
155  RxVarBlock.shvnext = NULL;
156  RxVarBlock.shvname.strptr = pszVar;
157  RxVarBlock.shvname.strlength = strlen(pszVar);
158  RxVarBlock.shvnamelen = RxVarBlock.shvname.strlength;
159  RxVarBlock.shvvalue.strptr = NULL;
160  RxVarBlock.shvvalue.strlength = 0;
161  RxVarBlock.shvvaluelen = 0;
162  RxVarBlock.shvcode = RXSHV_SYFET;
163  RxVarBlock.shvret = RXSHV_OK;
164 
165  /* fetch variable from pool */
166  ulRetc = RexxVariablePool(&RxVarBlock);
167 
168  /* test return code */
169  if (ulRetc != RXSHV_OK && ulRetc != RXSHV_NEWV) {
170  prxVar -> strptr = NULL;
171  prxVar -> strlength = 0;
172  }
173  else {
174  /* allocate a new buffer for the Rexx variable pool value */
175  pszTemp = (char *) RexxAllocateMemory(RxVarBlock.shvvalue.strlength + 1);
176  if (pszTemp == NULL) {
177  /* no buffer available so return a NULL Rexx value */
178  prxVar -> strptr = NULL;
179  prxVar -> strlength = 0;
180  ulRetc = RXSHV_MEMFL;
181  }
182  else {
183  /* copy to new buffer and zero-terminate */
184  memmove(pszTemp, RxVarBlock.shvvalue.strptr,
185  RxVarBlock.shvvalue.strlength);
186  *(pszTemp + RxVarBlock.shvvalue.strlength) = '\0';
187  prxVar -> strptr = pszTemp;
188  prxVar -> strlength = RxVarBlock.shvvalue.strlength;
189  }
190  // free memory returned from RexxVariablePool API
191  RexxFreeMemory(RxVarBlock.shvvalue.strptr);
192  }
193 
194  return ulRetc;
195  }
196 
197 
198 /*--------------------------------------------------------------------*/
199 /* */
200 /* Function: SetRexxVar() */
201 /* */
202 /* Description: Sets the contents of a variable in the REXX variable */
203 /* pool. */
204 /* */
205 /* Input: PSZ - name of the REXX variable to be set */
206 /* PVOID - pointer to new contents for variable */
207 /* ULONG - buffer size of new contents */
208 /* */
209 /* Returns: ULONG - return code from RexxVariablePool() */
210 /* */
211 /* Notes: None. */
212 /* */
213 /*--------------------------------------------------------------------*/
214 
215 unsigned long SetRexxVar (
216  char * pszVar, /* Variable name to be set */
217  char * pValue, /* Ptr to new value */
218  size_t ulLen) /* Value length */
219  {
220 
221  /* local function data */
222  SHVBLOCK RxVarBlock;
223  unsigned long ulRetc;
224 
225  /* initialize RxVarBlock */
226  RxVarBlock.shvnext = NULL;
227  RxVarBlock.shvname.strptr = pszVar;
228  RxVarBlock.shvname.strlength = strlen(pszVar);
229  RxVarBlock.shvnamelen = RxVarBlock.shvname.strlength;
230  RxVarBlock.shvvalue.strptr = pValue;
231  RxVarBlock.shvvalue.strlength = ulLen;
232  RxVarBlock.shvvaluelen = ulLen;
233  RxVarBlock.shvcode = RXSHV_SYSET;
234  RxVarBlock.shvret = RXSHV_OK;
235 
236  /* set variable in pool */
237  ulRetc = RexxVariablePool(&RxVarBlock);
238 
239  /* test return code */
240  if (ulRetc == RXSHV_NEWV) {
241  ulRetc = RXSHV_OK;
242  }
243 
244  return ulRetc;
245  }
246 
247 
248 /*--------------------------------------------------------------------*/
249 /* */
250 /* Function: GrxHost() */
251 /* */
252 /* Description: Emulates the IBM host environment commands. */
253 /* */
254 /* Input: Command string */
255 /* Pointer to return flags */
256 /* Pointer to return string */
257 /* */
258 /* Returns: Return indicating success or failure */
259 /* */
260 /* References: None. */
261 /* */
262 /* Notes: */
263 /* */
264 /*--------------------------------------------------------------------*/
265 
267  unsigned short int *flags,
268  PRXSTRING retc)
269  {
270 
271  /* Local function variables */
272  unsigned long i, rc = 0;
273  PLL pll;
274 
275  #ifdef HOSTEMU_DEBUG
276  printf("HOSTEMU: Subcom called.\n");
277  #endif
278 
279  /* request the semaphore so we can get exclusive access to */
280  /* our variables */
281  pthread_mutex_lock(&hmtxExecIO);
282 
283  /* initialize the global variables */
284  memset(&ExecIO_Options, '\0', sizeof(EXECIO_OPTIONS));
286  prxCmd = command;
287  lCmdPtr = 0;
288  ulNumSym = 0;
289  *flags = RXSUBCOM_OK;
290 
291  /* parse the command */
292  if (!yyparse ()) {
293  #ifdef HOSTEMU_DEBUG
294  printf("HOSTEMU: Parse complete.\n");
295  #endif
296  if (lStmtType == HI_STMT) {
297  RexxSetHalt(getpid(), pthread_self());
298  }
299  else if (lStmtType == TE_STMT) {
300  RexxResetTrace(getpid(), pthread_self());
301  }
302  else if (lStmtType == TS_STMT) {
303  RexxSetTrace(getpid(), pthread_self());
304  }
305  else if (lStmtType == EXECIO_STMT) {
306  #ifdef HOSTEMU_DEBUG
307  printf("HOSTEMU: Executing execio statement.\n");
308  #endif
309  /* check to see if the file is already open */
311  if (pll == NULL) {
312  /* it is a new file, so open it and add to the list */
313  pll = (PLL)malloc(sizeof (LL));
314  if (pll == NULL) {
315  rc = 20;
316  *flags = RXSUBCOM_FAILURE;
317  goto return_point;
318  }
319  memset(pll, '\0', sizeof (LL));
320  strcpy(pll -> FileName, ExecIO_Options.aFilename);
321  if (ExecIO_Options.fRW) {
322  /* DISKW */
323  pll -> pFile = fopen(pll -> FileName, "w+");
324  }
325  else {
326  /* DISKR */
327  pll -> pFile = fopen(pll -> FileName, "r+");
328  }
329  if ((pll -> pFile == NULL)) {
330  /* file could be opened so return an error */
331  free(pll);
332  rc = 20;
333  *flags = RXSUBCOM_FAILURE;
334  goto return_point;
335  }
336  Insert_LL(pll);
337  }
338  /* is this a read or write operation? */
339  if (ExecIO_Options.fRW) {
340  /* DISKW */
341  /* is this a stem or queue operation? */
342  if (strlen (ExecIO_Options.aStem)) {
343  rc = ExecIO_Write_From_Stem(pll);
344  }
345  else {
346  rc = ExecIO_Write_From_Queue(pll);
347  }
348  }
349  else {
350  /* DISKR */
351  /* is this a stem or queue operation? */
352  if (strlen(ExecIO_Options.aStem)) {
353  rc = ExecIO_Read_To_Stem(pll);
354  }
355  else {
356  rc = ExecIO_Read_To_Queue(pll);
357  }
358  }
359  /* process the FINIS option */
360  if (ExecIO_Options.fFinis) {
361  fclose(pll -> pFile);
362  Delete_LL(pll);
363  }
364  /* if the return code is 20 then set the failure flag */
365  if (rc == 20) {
366  *flags = RXSUBCOM_FAILURE;
367  }
368  }
369  else { /* bad statement type */
370  *flags = RXSUBCOM_ERROR;
371  rc = 20;
372  }
373  }
374  else { /* parse failed */
375  *flags = RXSUBCOM_ERROR;
376  rc = 20;
377  }
378 
379  return_point:
380 
381  /* release our symbol table memory */
382  if (ulNumSym != 0) {
383  for (i = 0; i < ulNumSym; i++) {
384  free(pszSymbol[i]);
385  }
386  }
387 
388  pthread_mutex_unlock(&hmtxExecIO);
389 
390  sprintf(retc->strptr, "%ld", rc);
391  retc->strlength = strlen(retc->strptr);
392  #ifdef HOSTEMU_DEBUG
393  printf("HOSTEMU: Subcom return code = %u.\n", rc);
394  #endif
395  return rc;
396  }
397 
398 
399 /*--------------------------------------------------------------------*/
400 /* */
401 /* Function: ExecIO_Write_From_Stem */
402 /* */
403 /* Description: ExecIO write from a stem to a file. */
404 /* */
405 /* Input: Pointer to file linked list item */
406 /* */
407 /* Returns: Return indicating success or failure */
408 /* */
409 /* References: None. */
410 /* */
411 /* Notes: */
412 /* */
413 /* */
414 /*--------------------------------------------------------------------*/
415 
416 static unsigned long ExecIO_Write_From_Stem (
417  PLL pll) /* Pointer to file linked list item */
418  {
419 
420  /* Local function variables */
421  char * Stem; /* Stem variable name */
422  char * Index; /* Stem index value (string) */
423  RXSTRING rxVal; /* Rexx stem variable value */
424  int elements;
425 
426  /* process request */
427  if (ExecIO_Options.lRcdCnt == 0)
428  return 0;
429  Stem = (char *)malloc(strlen(ExecIO_Options.aStem) + 33);
430  if (Stem == NULL) {
431  return 20;
432  }
433  strcpy(Stem, ExecIO_Options.aStem);
434  Index = Stem + strlen(Stem);
435  if (ExecIO_Options.lRcdCnt == -1) {
436  /* process an "*" record count */
437  // get the number of elements
438  sprintf(Index, "%u", 0);
439  FetchRexxVar(Stem, &rxVal);
440  elements = atoi(rxVal.strptr);
441  RexxFreeMemory(rxVal.strptr);
442  while (ExecIO_Options.lStartRcd <= elements) {
443  sprintf(Index, "%ld", ExecIO_Options.lStartRcd);
444  FetchRexxVar(Stem, &rxVal);
445  fputs(rxVal.strptr, pll -> pFile);
446  fputs("\n", pll -> pFile);
447  RexxFreeMemory(rxVal.strptr);
449  }
450  }
451  else {
452  /* process a specific record count */
454  sprintf(Index, "%ld", ExecIO_Options.lStartRcd);
455  FetchRexxVar(Stem, &rxVal);
456  fputs(rxVal.strptr, pll -> pFile);
457  fputs("\n", pll -> pFile);
458  RexxFreeMemory(rxVal.strptr);
460  }
461  }
462  fflush (pll -> pFile);
463 
464  /* return with successful return code */
465  return 0;
466  }
467 
468 
469 /*--------------------------------------------------------------------*/
470 /* */
471 /* Function: ExecIO_Write_From_Queue */
472 /* */
473 /* Description: ExecIO write from the queue to a file. */
474 /* */
475 /* Input: Pointer to file linked list item */
476 /* */
477 /* Returns: Return indicating success or failure */
478 /* */
479 /* References: None. */
480 /* */
481 /* Notes: */
482 /* */
483 /*--------------------------------------------------------------------*/
484 
485 static unsigned long ExecIO_Write_From_Queue (
486  PLL pll) /* Pointer to file linked list item */
487  {
488 
489  /* Local function variables */
490  char * Item; /* Item pulled from the queue */
491  long items;
492 
493  /* process request */
494  if (ExecIO_Options.lRcdCnt == 0) {
495  return 0;
496  }
497  /* start at the proper place in the queue */
498  while (ExecIO_Options.lStartRcd > 1 && queued() > 0) {
499  Item = pull();
500  if (Item != NULL) {
501  RexxFreeMemory(Item);
502  }
504  }
505  if (ExecIO_Options.lRcdCnt == -1) {
506  /* process an "*" record count */
507  items = queued();
508  while (items > 0) {
509  Item = pull();
510  if (Item != NULL) {
511  fputs(Item, pll -> pFile);
512  fputs("\n", pll -> pFile);
513  RexxFreeMemory(Item);
514  }
515  else {
516  goto return_point;
517  }
518  items--;
519  }
520  }
521  else {
522  /* process a specific record count */
523  while (ExecIO_Options.lRcdCnt > 0) {
524  if (queued() == 0)
525  break;
526  Item = pull();
527  if (Item != NULL) {
528  fputs(Item, pll -> pFile);
529  fputs("\n", pll -> pFile);
530  RexxFreeMemory(Item);
531  }
532  else {
533  goto return_point;
534  }
536  }
537  }
538 
539  return_point:
540  fflush (pll -> pFile);
541 
542  /* return with successful return code */
543  return 0;
544  }
545 
546 
547 /*--------------------------------------------------------------------*/
548 /* */
549 /* Function: ExecIO_Read_To_Stem */
550 /* */
551 /* Description: ExecIO read from a file to a stem. */
552 /* */
553 /* Input: Pointer to file linked list item */
554 /* */
555 /* Returns: Return indicating success or failure */
556 /* */
557 /* References: None. */
558 /* */
559 /* Notes: */
560 /* */
561 /* */
562 /*--------------------------------------------------------------------*/
563 
564 static unsigned long ExecIO_Read_To_Stem (
565  PLL pll) /* Pointer to file linked list item */
566  {
567 
568  /* Local function variables */
569  char * Stem; /* Stem variable name */
570  char * Index; /* Stem index value (string) */
571  unsigned long ulRc = 0; /* Return code */
572 
573  /* process request */
574  if (ExecIO_Options.lRcdCnt == 0) {
575  return 0;
576  }
577  Stem = (char *)malloc(strlen(ExecIO_Options.aStem) + 33);
578  if (Stem == NULL) {
579  return 20;
580  }
581  strcpy(Stem, ExecIO_Options.aStem);
582  Index = Stem + strlen(Stem);
583  if (ExecIO_Options.lRcdCnt == -1) {
584  /* process an "*" record count */
585  while (fgets(szInline, sizeof (szInline), pll -> pFile)) {
586  if (*(szInline + strlen(szInline) - 1) == '\n')
587  *(szInline + strlen(szInline) - 1) = '\0';
588  sprintf(Index, "%ld", ExecIO_Options.lStartRcd);
589  SetRexxVar(Stem, szInline, strlen(szInline));
591  }
592  }
593  else {
594  /* process a specific record count */
595  while (ExecIO_Options.lRcdCnt > 0) {
596  if (fgets(szInline, sizeof(szInline), pll -> pFile)) {
597  if (*(szInline + strlen(szInline) - 1) == '\n') {
598  *(szInline + strlen(szInline) - 1) = '\0';
599  }
600  sprintf(Index, "%ld", ExecIO_Options.lStartRcd);
601  SetRexxVar(Stem, szInline, strlen(szInline));
603  }
604  else {
605  ulRc = 2;
606  break;
607  }
609  }
610  }
612  sprintf(szInline, "%ld", ExecIO_Options.lStartRcd);
613  sprintf(Index, "%d", 0);
614  SetRexxVar(Stem, szInline, strlen (szInline));
615  free(Stem);
616 
617  /* return with successful return code */
618  return ulRc;
619  }
620 
621 
622 /*--------------------------------------------------------------------*/
623 /* */
624 /* Function: ExecIO_Read_To_Queue */
625 /* */
626 /* Description: ExecIO read file to the current queue. */
627 /* */
628 /* Input: Pointer to file linked list item */
629 /* */
630 /* Returns: Return indicating success or failure */
631 /* */
632 /* References: None. */
633 /* */
634 /* Notes: */
635 /* */
636 /*--------------------------------------------------------------------*/
637 
638 static unsigned long ExecIO_Read_To_Queue (
639  PLL pll) /* Pointer to file linked list item */
640  {
641 
642  /* Local function variables */
643 
644  /* process request */
645  if (ExecIO_Options.lRcdCnt == 0) {
646  return 0;
647  }
648  if (ExecIO_Options.lRcdCnt == -1) {
649  /* process an "*" record count */
650  while (fgets (szInline, sizeof (szInline), pll -> pFile)) {
651  if (*(szInline + strlen (szInline) - 1) == '\n') {
652  *(szInline + strlen (szInline) - 1) = '\0';
653  }
654  if (ExecIO_Options.lDirection != 2) {
656  }
657  }
658  }
659  else {
660  /* process a specific record count */
661  while (ExecIO_Options.lRcdCnt > 0) {
662  if (fgets (szInline, sizeof (szInline), pll -> pFile)) {
663  if (*(szInline + strlen (szInline) - 1) == '\n') {
664  *(szInline + strlen (szInline) - 1) = '\0';
665  }
666  if (ExecIO_Options.lDirection != 2) {
668  }
669  }
670  else {
671  return 2;
672  }
674  }
675  }
676 
677  /* return with successful return code */
678  return 0;
679  }
680 
681 
682 /*--------------------------------------------------------------------*/
683 /* */
684 /* Function: Search_LL */
685 /* */
686 /* Description: Search the linked list of files for a match. */
687 /* */
688 /* Input: Filename */
689 /* */
690 /* Returns: Pointer to found struct or NULL if not found */
691 /* */
692 /* References: None. */
693 /* */
694 /* Notes: */
695 /* */
696 /*--------------------------------------------------------------------*/
697 
698 static PLL Search_LL (
699  char * SFilename) /* Source file name */
700  {
701 
702  /* Local function variables */
703  PLL pll = pHead;
704 
705  while (pll != NULL) {
706  if (!strcmp (SFilename, pll -> FileName)) {
707  return pll;
708  }
709  pll = pll -> next;
710  }
711  return pll;
712  }
713 
714 
715 /*--------------------------------------------------------------------*/
716 /* */
717 /* Function: Insert_LL */
718 /* */
719 /* Description: Insert a new item at the end of the list. */
720 /* */
721 /* Input: Pointer to new item struct. */
722 /* */
723 /* Returns: None. */
724 /* */
725 /* References: None. */
726 /* */
727 /* Notes: */
728 /* */
729 /*--------------------------------------------------------------------*/
730 
731 static void Insert_LL (
732  PLL pll) /* Pointer to the new item */
733  {
734 
735  if (pHead == NULL) {
736  pHead = pll;
737  }
738  else {
739  pTail -> next = pll;
740  }
741  pll -> prev = pTail;
742  pll -> next = NULL;
743  pTail = pll;
744  return;
745  }
746 
747 
748 /*--------------------------------------------------------------------*/
749 /* */
750 /* Function: Delete_LL */
751 /* */
752 /* Description: Delete an item from the list. */
753 /* */
754 /* Input: Pointer to item to be deleted. */
755 /* */
756 /* Returns: None. */
757 /* */
758 /* References: None. */
759 /* */
760 /* Notes: */
761 /* */
762 /*--------------------------------------------------------------------*/
763 
764 static void Delete_LL (
765  PLL pll) /* Pointer to the item to be deleted */
766  {
767 
768  if (pHead == pll) {
769  pHead = pll -> next;
770  }
771  if (pTail == pll) {
772  pTail = pll -> prev;
773  }
774  if (pll -> next != NULL) {
775  pll -> next -> prev = pll -> prev;
776  }
777  if (pll -> prev != NULL) {
778  pll -> prev -> next = pll -> next;
779  }
780  free(pll);
781  return;
782  }
783 
784 
785 /*--------------------------------------------------------------------*/
786 /* */
787 /* Function: queued */
788 /* */
789 /* Description: Returns the number of items in the current Rexx queue */
790 /* */
791 /* Input: None. */
792 /* */
793 /* Returns: Number of queued items */
794 /* */
795 /* References: None. */
796 /* */
797 /* Notes: */
798 /* */
799 /*--------------------------------------------------------------------*/
800 
801 static long queued (
802  void) /* No arguments */
803  {
804 
805  /* local function variables */
806  size_t elements;
807 
808  RexxQueryQueue("SESSION", &elements);
809  return (long)elements;
810  }
811 
812 
813 /*--------------------------------------------------------------------*/
814 /* */
815 /* Function: push */
816 /* */
817 /* Description: Push an item onto the current Rexx queue. */
818 /* */
819 /* Input: Pointer to the string to be pushed */
820 /* */
821 /* Returns: Number of queued items */
822 /* */
823 /* References: None. */
824 /* */
825 /* Notes: */
826 /* */
827 /*--------------------------------------------------------------------*/
828 
829 static void push (
830  char * pushstr, /* String to be pushed onto queue */
831  long lOp) /* 0 = FIFO, 1 = LIFO */
832  {
833 
834  CONSTRXSTRING rxstr;
835 
836  rxstr.strptr = pushstr;
837  rxstr.strlength = strlen(pushstr);
838  RexxAddQueue("SESSION", &rxstr, (size_t)lOp);
839  return;
840  }
841 
842 
843 /*--------------------------------------------------------------------*/
844 /* */
845 /* Function: pull */
846 /* */
847 /* Description: Pull an item off the current Rexx queue. */
848 /* */
849 /* Input: None */
850 /* */
851 /* Returns: Pointer to the pulled string */
852 /* */
853 /* References: None. */
854 /* */
855 /* Notes: */
856 /* */
857 /*--------------------------------------------------------------------*/
858 
859 static char * pull (
860  void) /* No arguments */
861  {
862 
863  /* local function variables */
864  RXSTRING result = {0, NULL};
865  RexxReturnCode rc;
866 
867  rc = RexxPullFromQueue("SESSION", &result, NULL, RXQUEUE_WAIT);
868  return result.strptr;
869  }
870 
871 
872 static void hostemu_loader(RexxThreadContext *context) {
873  RexxReturnCode rc;
874 
875  rc = RexxRegisterSubcomExe("HostEmu", (void *)GrxHost, NULL);
876  #ifdef HOSTEMU_DEBUG
877  printf("HOSTEMU: Library loaded.\n");
878  printf("HOSTEMU: RexxRegisterSubcomExe retc = %d.\n", rc);
879  #endif
880  }
881 
882 
883 static void hostemu_unloader(RexxThreadContext *context) {
884  PLL pll;
885 
886  /* close all our open files */
887  pll = pHead;
888  while (pll != NULL) {
889  fclose (pll -> pFile);
890  pll = pll -> next;
891  }
892  }
893 
894 
897  REXX_INTERPRETER_4_0_0, // anything after 4.0.0 will work
898  "HostEmu", // name of the package
899  "1.0.0", // package information
900  hostemu_loader, // load function
901  hostemu_unloader, // unload function
902  NULL, // the exported routines
903  NULL // the exported methods
904  };
905 
906 // package loading stub.
908 
RexxReturnCode RexxEntry RexxVariablePool(PSHVBLOCK pshvblock)
RexxReturnCode REXXENTRY RexxResetTrace(process_id_t procid, thread_id_t threadid)
RexxReturnCode REXXENTRY RexxSetTrace(process_id_t procid, thread_id_t threadid)
RexxReturnCode REXXENTRY RexxSetHalt(process_id_t procid, thread_id_t threadid)
#define HI_STMT
Definition: hostemu.h:70
#define TS_STMT
Definition: hostemu.h:72
int yyparse(void)
Definition: cmdparse.cpp:493
#define EXECIO_STMT
Definition: hostemu.h:69
#define SYMTABLESIZE
Definition: hostemu.h:68
#define TE_STMT
Definition: hostemu.h:71
#define REXX_INTERPRETER_4_0_0
Definition: oorexxapi.h:216
#define STANDARD_PACKAGE_HEADER
Definition: oorexxapi.h:230
RexxReturnCode REXXENTRY RexxRegisterSubcomExe(CONSTANT_STRING, REXXPFN, CONSTANT_STRING)
RexxReturnCode REXXENTRY RexxPullFromQueue(CONSTANT_STRING, PRXSTRING, RexxQueueTime *, size_t)
RexxReturnCode REXXENTRY RexxFreeMemory(void *)
RexxReturnCode REXXENTRY RexxAddQueue(CONSTANT_STRING, PCONSTRXSTRING, size_t)
CONSTANT_RXSTRING * PCONSTRXSTRING
Definition: rexx.h:186
RexxReturnCode REXXENTRY RexxQueryQueue(CONSTANT_STRING, size_t *)
void *REXXENTRY RexxAllocateMemory(size_t)
int RexxReturnCode
Definition: rexx.h:73
#define RexxEntry
Definition: rexx.h:412
#define RXSHV_NEWV
Definition: rexxapidefs.h:113
#define RXQUEUE_WAIT
Definition: rexxapidefs.h:243
#define RXSHV_SYFET
Definition: rexxapidefs.h:101
#define RXSUBCOM_OK
Definition: rexxapidefs.h:85
#define RXSUBCOM_ERROR
Definition: rexxapidefs.h:79
#define RXSHV_OK
Definition: rexxapidefs.h:112
#define RXSHV_SYSET
Definition: rexxapidefs.h:100
#define RXSUBCOM_FAILURE
Definition: rexxapidefs.h:80
#define RXSHV_MEMFL
Definition: rexxapidefs.h:117
const char * strptr
Definition: rexx.h:163
size_t strlength
Definition: rexx.h:162
long lStartRcd
Definition: hostemu.h:80
char aFilename[1024]
Definition: hostemu.h:77
long lRcdCnt
Definition: hostemu.h:75
char aStem[251]
Definition: hostemu.h:78
long lDirection
Definition: hostemu.h:81
struct _LL * prev
FILE * pFile
struct _LL * next
char FileName[1024]
size_t strlength
Definition: rexx.h:157
char * strptr
Definition: rexx.h:158
Definition: oorexxapi.h:242
size_t shvvaluelen
Definition: rexx.h:209
CONSTANT_RXSTRING shvname
Definition: rexx.h:206
unsigned char shvret
Definition: rexx.h:211
unsigned char shvcode
Definition: rexx.h:210
RXSTRING shvvalue
Definition: rexx.h:207
size_t shvnamelen
Definition: rexx.h:208
struct _SHVBLOCK * shvnext
Definition: rexx.h:205
RexxReturnCode RexxEntry GrxHost(PCONSTRXSTRING command, unsigned short int *flags, PRXSTRING retc)
OOREXX_GET_PACKAGE(hostemu)
static unsigned long ExecIO_Write_From_Stem(PLL pll)
static void hostemu_unloader(RexxThreadContext *context)
static unsigned long ExecIO_Read_To_Queue(PLL pll)
static void push(char *pushstr, long lOp)
unsigned long SetRexxVar(char *pszVar, char *pValue, size_t ulLen)
long lStmtType
struct _LL LL
char * pszSymbol[SYMTABLESIZE]
LL * PLL
static void Delete_LL(PLL pll)
long lCmdPtr
static PLL pTail
unsigned long FetchRexxVar(char *pszVar, PRXSTRING prxVar)
static char * pull(void)
RexxPackageEntry hostemu_package_entry
static PLL pHead
static PLL Search_LL(char *SFilename)
static unsigned long ExecIO_Read_To_Stem(PLL pll)
static void hostemu_loader(RexxThreadContext *context)
static void Insert_LL(PLL pll)
char szInline[1000]
unsigned long ulNumSym
static long queued(void)
static unsigned long ExecIO_Write_From_Queue(PLL pll)
EXECIO_OPTIONS ExecIO_Options
static pthread_mutex_t hmtxExecIO
PCONSTRXSTRING prxCmd