windows/hostemu.cpp
Go to the documentation of this file.
1 /*----------------------------------------------------------------------------*/
2 /* */
3 /* Copyright (c) 2009-2016 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 /* https://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 <windows.h>
47 #include <rexx.h>
48 #include <oorexxapi.h>
49 
50 #include "../../hostemu.h"
51 
52 
53 /*--------------------------------------------------------------------*/
54 /* */
55 /* Global variables */
56 /* */
57 /*--------------------------------------------------------------------*/
58 
59 // #define HOSTEMU_DEBUG
60 
63 long lCmdPtr;
64 unsigned long ulNumSym;
66 char szInline[100000];
67 long lStmtType;
68 
69 
70 /*--------------------------------------------------------------------*/
71 /* */
72 /* Local definitions */
73 /* */
74 /*--------------------------------------------------------------------*/
75 
76 typedef struct _LL
77  {
78  struct _LL * prev;
79  struct _LL * next;
80  char FileName [1024];
81  FILE * pFile;
82  } LL;
83 typedef LL * PLL;
84 
85 
86 /*--------------------------------------------------------------------*/
87 /* */
88 /* Local variables */
89 /* */
90 /*--------------------------------------------------------------------*/
91 
92 static HANDLE htmxExecIO = NULL;
93 static PLL pHead = NULL;
94 static PLL pTail = NULL;
95 
96 
97 /*--------------------------------------------------------------------*/
98 /* */
99 /* Local function prototypes */
100 /* */
101 /*--------------------------------------------------------------------*/
102 
103 static unsigned long ExecIO_Write_From_Stem(
104  PLL pll); /* Pointer to file linked list item */
105 static unsigned long ExecIO_Write_From_Queue(
106  PLL pll); /* Pointer to file linked list item */
107 static unsigned long ExecIO_Read_To_Stem(
108  PLL pll); /* Pointer to file linked list item */
109 static unsigned long ExecIO_Read_To_Queue(
110  PLL pll); /* Pointer to file linked list item */
111 static PLL Search_LL(
112  char * SFilename); /* Source file name */
113 static void Insert_LL(
114  PLL pll); /* Pointer to the new item */
115 static void Delete_LL(
116  PLL pll); /* Pointer to the item to be deleted */
117 static long queued(
118  void); /* No arguments */
119 static void push(
120  char * pushstr, /* String to be pushed onto queue */
121  long lOp); /* 0 = FIFO, 1 = LIFO */
122 static char * pull(
123  void); /* No arguments */
124 
125 /*--------------------------------------------------------------------*/
126 /* */
127 /* Function: FetchRexxVar() */
128 /* */
129 /* Description: Fetch contents of a REXX variable from the current */
130 /* variable pool. The caller is responsible for freeing */
131 /* the buffer pointed to by the return value via */
132 /* DosFreeMem(). */
133 /* */
134 /* Input: PSZ - name of the REXX variable to be fetched */
135 /* PRXSTRING - pointer to the return RXSTRING structure */
136 /* */
137 /* Returns: ULONG - return code from RexxVariablePool() */
138 /* */
139 /* Notes: None. */
140 /* */
141 /*--------------------------------------------------------------------*/
142 
143 unsigned long FetchRexxVar (
144  char * pszVar, /* Variable name */
145  PRXSTRING prxVar) /* REXX variable contents */
146  {
147 
148  /* local function variables */
149  SHVBLOCK RxVarBlock;
150  unsigned long ulRetc;
151  char * pszTemp;
152 
153  /* initialize the shared variable block */
154  RxVarBlock.shvnext = NULL;
155  RxVarBlock.shvname.strptr = pszVar;
156  RxVarBlock.shvname.strlength = strlen(pszVar);
157  RxVarBlock.shvnamelen = RxVarBlock.shvname.strlength;
158  RxVarBlock.shvvalue.strptr = NULL;
159  RxVarBlock.shvvalue.strlength = 0;
160  RxVarBlock.shvvaluelen = 0;
161  RxVarBlock.shvcode = RXSHV_SYFET;
162  RxVarBlock.shvret = RXSHV_OK;
163 
164  /* fetch variable from pool */
165  ulRetc = RexxVariablePool(&RxVarBlock);
166 
167  /* test return code */
168  if (ulRetc != RXSHV_OK && ulRetc != RXSHV_NEWV) {
169  prxVar -> strptr = NULL;
170  prxVar -> strlength = 0;
171  }
172  else {
173  /* allocate a new buffer for the Rexx variable pool value */
174  pszTemp = (char *) RexxAllocateMemory(RxVarBlock.shvvalue.strlength + 1);
175  if (pszTemp == NULL) {
176  /* no buffer available so return a NULL Rexx value */
177  prxVar -> strptr = NULL;
178  prxVar -> strlength = 0;
179  ulRetc = RXSHV_MEMFL;
180  }
181  else {
182  /* copy to new buffer and zero-terminate */
183  memmove(pszTemp, RxVarBlock.shvvalue.strptr,
184  RxVarBlock.shvvalue.strlength);
185  *(pszTemp + RxVarBlock.shvvalue.strlength) = '\0';
186  prxVar -> strptr = pszTemp;
187  prxVar -> strlength = RxVarBlock.shvvalue.strlength;
188  }
189  // free memory returned from RexxVariablePool API
190  RexxFreeMemory(RxVarBlock.shvvalue.strptr);
191  }
192 
193  return ulRetc;
194  }
195 
196 
197 /*--------------------------------------------------------------------*/
198 /* */
199 /* Function: SetRexxVar() */
200 /* */
201 /* Description: Sets the contents of a variable in the REXX variable */
202 /* pool. */
203 /* */
204 /* Input: PSZ - name of the REXX variable to be set */
205 /* PVOID - pointer to new contents for variable */
206 /* ULONG - buffer size of new contents */
207 /* */
208 /* Returns: ULONG - return code from RexxVariablePool() */
209 /* */
210 /* Notes: None. */
211 /* */
212 /*--------------------------------------------------------------------*/
213 
214 unsigned long SetRexxVar (
215  char * pszVar, /* Variable name to be set */
216  char * pValue, /* Ptr to new value */
217  size_t ulLen) /* Value length */
218  {
219 
220  /* local function data */
221  SHVBLOCK RxVarBlock;
222  unsigned long ulRetc;
223 
224  /* initialize RxVarBlock */
225  RxVarBlock.shvnext = NULL;
226  RxVarBlock.shvname.strptr = pszVar;
227  RxVarBlock.shvname.strlength = strlen(pszVar);
228  RxVarBlock.shvnamelen = RxVarBlock.shvname.strlength;
229  RxVarBlock.shvvalue.strptr = pValue;
230  RxVarBlock.shvvalue.strlength = ulLen;
231  RxVarBlock.shvvaluelen = ulLen;
232  RxVarBlock.shvcode = RXSHV_SYSET;
233  RxVarBlock.shvret = RXSHV_OK;
234 
235  /* set variable in pool */
236  ulRetc = RexxVariablePool(&RxVarBlock);
237 
238  /* test return code */
239  if (ulRetc == RXSHV_NEWV) {
240  ulRetc = RXSHV_OK;
241  }
242 
243  return ulRetc;
244  }
245 
246 
247 /*--------------------------------------------------------------------*/
248 /* */
249 /* Function: GrxHost() */
250 /* */
251 /* Description: Emulates the IBM host environment commands. */
252 /* */
253 /* Input: Command string */
254 /* Pointer to return flags */
255 /* Pointer to return string */
256 /* */
257 /* Returns: Return indicating success or failure */
258 /* */
259 /* References: None. */
260 /* */
261 /* Notes: */
262 /* */
263 /*--------------------------------------------------------------------*/
264 
266  unsigned short int *flags,
267  PRXSTRING retc)
268  {
269 
270  /* Local function variables */
271  unsigned long i, rc = 0;
272  PLL pll;
273 
274  #ifdef HOSTEMU_DEBUG
275  printf("HOSTEMU: Subcom called.\n");
276  #endif
277 
278  /* request the semaphore so we can get exclusive access to */
279  /* our variables */
280  WaitForSingleObject(htmxExecIO, INFINITE);
281 
282  /* initialize the global variables */
283  memset(&ExecIO_Options, '\0', sizeof(EXECIO_OPTIONS));
285  ExecIO_Options.fFinis = false;
287 
288  prxCmd = command;
289  lCmdPtr = 0;
290  ulNumSym = 0;
291  *flags = RXSUBCOM_OK;
292 
293  /* parse the command */
294  if (!yyparse ()) {
295  #ifdef HOSTEMU_DEBUG
296  printf("HOSTEMU: Parse complete, lStartRcd=%d, lRcdCnt=%d, lDirection=%d, fRW=%d, fFinis=%d\n",
299  #endif
300  if (lStmtType == HI_STMT) {
301  RexxSetHalt(GetCurrentProcessId(), GetCurrentThreadId());
302  }
303  else if (lStmtType == TE_STMT) {
304  RexxResetTrace(GetCurrentProcessId(), GetCurrentThreadId());
305  }
306  else if (lStmtType == TS_STMT) {
307  RexxSetTrace(GetCurrentProcessId(), GetCurrentThreadId());
308  }
309  else if (lStmtType == EXECIO_STMT) {
310  #ifdef HOSTEMU_DEBUG
311  printf("HOSTEMU: Executing execio statement.\n");
312  #endif
313  /* check to see if the file is already open */
315  if (pll == NULL) {
316  /* it is a new file, so open it and add to the list */
317  pll = (PLL)malloc(sizeof (LL));
318  if (pll == NULL) {
320  *flags = RXSUBCOM_FAILURE;
321  goto return_point;
322  }
323  memset(pll, '\0', sizeof (LL));
324  strcpy(pll -> FileName, ExecIO_Options.aFilename);
325 
326  /* try to open an existing file */
327  pll -> pFile = fopen(pll -> FileName, "r+");
328 
329  /* read only files can not be opened in read / write mode (r+) */
330  if ( pll -> pFile == NULL && ! ExecIO_Options.fRW ) {
331  pll -> pFile = fopen(pll -> FileName, "r");
332  }
333  if (pll -> pFile == NULL) {
334  /* no existing file, so open a new file */
335  pll -> pFile = fopen(pll -> FileName, "w+");
336  }
337  if (pll -> pFile == NULL) {
338  /* nothing could be opened so return an error */
339  free(pll);
340  rc = ERR_EXECIO_BAD_PLIST; // Bad PLIST
341  *flags = RXSUBCOM_FAILURE;
342  goto return_point;
343  }
344  Insert_LL(pll);
345  }
346  /* is this a read or write operation? */
347  if (ExecIO_Options.fRW) {
348  /* DISKW */
349  /* is this a stem or queue operation? */
350  if (strlen (ExecIO_Options.aStem)) {
351  rc = ExecIO_Write_From_Stem(pll);
352  }
353  else {
354  rc = ExecIO_Write_From_Queue(pll);
355  }
356  }
357  else {
358  /* DISKR */
359  /* is this a stem or queue operation? */
360  // also send any STEM. name SKIP request to Read_To_Queue()
361  // as Read_To_Stem() won't handle SKIP
362  if (strlen(ExecIO_Options.aStem) && (ExecIO_Options.lDirection != 2)) {
363  rc = ExecIO_Read_To_Stem(pll);
364  }
365  else {
366  rc = ExecIO_Read_To_Queue(pll);
367  }
368  }
369  /* process the FINIS option */
370  if (ExecIO_Options.fFinis) {
371  fclose(pll -> pFile);
372  Delete_LL(pll);
373  }
374  /* if the return code is 20 then set the failure flag */
375  if (rc == ERR_EXECIO_BAD_PLIST) {
376  *flags = RXSUBCOM_FAILURE;
377  }
378  }
379  else { /* bad statement type */
380  // should never happen, as parsing is restricted to the four known commands
381  *flags = RXSUBCOM_FAILURE;
382  rc = ERR_EXECIO_BAD_PLIST; // Bad PLIST
383  }
384  }
385  else { /* parse failed */
386  // we don't know whether parse failed due to an invalid command (which would be a failure)
387  // or due to e. g. a misformed EXECIO command (which would be an error)
388  *flags = RXSUBCOM_ERROR;
389  rc = ERR_EXECIO_BAD_PLIST; // Bad PLIST
390  }
391 
392  return_point:
393 
394  /* release our symbol table memory */
395  if (ulNumSym != 0) {
396  for (i = 0; i < ulNumSym; i++) {
397  free(pszSymbol[i]);
398  }
399  }
400 
401  ReleaseMutex(htmxExecIO);
402 
403  sprintf(retc->strptr, "%u", rc);
404  retc->strlength = strlen(retc->strptr);
405  #ifdef HOSTEMU_DEBUG
406  printf("HOSTEMU: Subcom return code = %u.\n", rc);
407  #endif
408  return rc;
409  }
410 
411 
412 /*--------------------------------------------------------------------*/
413 /* */
414 /* Function: ExecIO_Write_From_Stem */
415 /* */
416 /* Description: ExecIO write from a stem to a file. */
417 /* */
418 /* Input: Pointer to file linked list item */
419 /* */
420 /* Returns: Return indicating success or failure */
421 /* */
422 /* References: None. */
423 /* */
424 /* Notes: */
425 /* */
426 /* */
427 /*--------------------------------------------------------------------*/
428 
429 static unsigned long ExecIO_Write_From_Stem (
430  PLL pll) /* Pointer to file linked list item */
431  {
432 
433  /* Local function variables */
434  char * Stem; /* Stem variable name */
435  char * Index; /* Stem index value (string) */
436  RXSTRING rxVal; /* Rexx stem variable value */
437  int elements;
438 
439  /* process request */
440  if (ExecIO_Options.lRcdCnt == 0)
441  return 0;
442  Stem = (char *)malloc(strlen(ExecIO_Options.aStem) + 33);
443  if (Stem == NULL) {
444  return ERR_EXECIO_NO_STORAGE; // Insufficient free storage to load EXECIO
445  }
446  strcpy(Stem, ExecIO_Options.aStem);
447  Index = Stem + strlen(Stem);
448  if (ExecIO_Options.lRcdCnt == -1) {
449  /* process an "*" record count */
450  // get the number of elements
451  sprintf(Index, "%u", 0);
452  if (FetchRexxVar(Stem, &rxVal))
453  {
454  return ERR_EXECIO_VAR_INVALID; // Variable name supplied on STEM or VAR option was not valid
455  }
456  elements = atoi(rxVal.strptr);
457  RexxFreeMemory(rxVal.strptr);
458  while (ExecIO_Options.lStartRcd <= elements) {
459  sprintf(Index, "%d", ExecIO_Options.lStartRcd);
460  if (FetchRexxVar(Stem, &rxVal))
461  {
462  return ERR_EXECIO_VAR_INVALID; // Variable name supplied on STEM or VAR option was not valid
463  }
464  fputs(rxVal.strptr, pll -> pFile);
465  fputs("\n", pll -> pFile);
466  RexxFreeMemory(rxVal.strptr);
468  }
469  }
470  else {
471  /* process a specific record count */
473  sprintf(Index, "%u", ExecIO_Options.lStartRcd);
474  if (FetchRexxVar(Stem, &rxVal))
475  {
476  return ERR_EXECIO_VAR_INVALID; // Variable name supplied on STEM or VAR option was not valid
477  }
478  fputs(rxVal.strptr, pll -> pFile);
479  fputs("\n", pll -> pFile);
480  RexxFreeMemory(rxVal.strptr);
482  }
483  }
484  fflush (pll -> pFile);
485 
486  /* return with successful return code */
487  return 0;
488  }
489 
490 
491 /*--------------------------------------------------------------------*/
492 /* */
493 /* Function: ExecIO_Write_From_Queue */
494 /* */
495 /* Description: ExecIO write from the queue to a file. */
496 /* */
497 /* Input: Pointer to file linked list item */
498 /* */
499 /* Returns: Return indicating success or failure */
500 /* */
501 /* References: None. */
502 /* */
503 /* Notes: */
504 /* */
505 /*--------------------------------------------------------------------*/
506 
507 static unsigned long ExecIO_Write_From_Queue (
508  PLL pll) /* Pointer to file linked list item */
509  {
510 
511  /* Local function variables */
512  char * Item; /* Item pulled from the queue */
513  long items;
514 
515  /* process request */
516  if (ExecIO_Options.lRcdCnt == 0) {
517  return 0;
518  }
519  /* start at the proper place in the queue */
520  while (ExecIO_Options.lStartRcd > 1 && queued() > 0) {
521  Item = pull();
522  if (Item != NULL) {
523  RexxFreeMemory(Item);
524  }
526  }
527  if (ExecIO_Options.lRcdCnt == -1) {
528  /* process an "*" record count */
529  items = queued();
530  while (items > 0) {
531  Item = pull();
532  if (Item != NULL) {
533  fputs(Item, pll -> pFile);
534  fputs("\n", pll -> pFile);
535  RexxFreeMemory(Item);
536  }
537  else {
538  goto return_point;
539  }
540  items--;
541  }
542  }
543  else {
544  /* process a specific record count */
545  while (ExecIO_Options.lRcdCnt > 0) {
546  if (queued() == 0)
547  break;
548  Item = pull();
549  if (Item != NULL) {
550  fputs(Item, pll -> pFile);
551  fputs("\n", pll -> pFile);
552  RexxFreeMemory(Item);
553  }
554  else {
555  goto return_point;
556  }
558  }
559  }
560 
561  return_point:
562  fflush (pll -> pFile);
563 
564  /* return with successful return code */
565  return 0;
566  }
567 
568 
569 /*--------------------------------------------------------------------*/
570 /* */
571 /* Function: ExecIO_Read_To_Stem */
572 /* */
573 /* Description: ExecIO read from a file to a stem. */
574 /* */
575 /* Input: Pointer to file linked list item */
576 /* */
577 /* Returns: Return indicating success or failure */
578 /* */
579 /* References: None. */
580 /* */
581 /* Notes: */
582 /* */
583 /* */
584 /*--------------------------------------------------------------------*/
585 
586 static unsigned long ExecIO_Read_To_Stem (
587  PLL pll) /* Pointer to file linked list item */
588  {
589 
590  /* Local function variables */
591  char * Stem; /* Stem variable name */
592  char * Index; /* Stem index value (string) */
593  unsigned long ulRc = 0; /* Return code */
594  int i;
595 
596  /* process request */
597  Stem = (char *)malloc(strlen(ExecIO_Options.aStem) + 33);
598  if (Stem == NULL) {
599  return ERR_EXECIO_NO_STORAGE; // Insufficient free storage to load EXECIO
600  }
601 
602  // skip until we reach line number 'StartRcd'
603  for (i = 1; i < ExecIO_Options.lStartRcd; i++)
604  {
605  fgets(szInline, sizeof(szInline), pll -> pFile);
606  }
607 
608  strcpy(Stem, ExecIO_Options.aStem);
609  Index = Stem + strlen(Stem);
610  i = 0;
611 
612  if (ExecIO_Options.lRcdCnt == -1) {
613  /* process an "*" record count */
614  while (fgets(szInline, sizeof (szInline), pll -> pFile)) {
615  if (*(szInline + strlen(szInline) - 1) == '\n')
616  *(szInline + strlen(szInline) - 1) = '\0';
617  i++;
618  sprintf(Index, "%d", i);
619  if (SetRexxVar(Stem, szInline, strlen(szInline)))
620  {
621  return ERR_EXECIO_VAR_INVALID; // Variable name supplied on STEM or VAR option was not valid
622  }
623  }
624  }
625  else {
626  /* process a specific record count */
627  while (ExecIO_Options.lRcdCnt > 0) {
628  if (fgets(szInline, sizeof(szInline), pll -> pFile)) {
629  if (*(szInline + strlen(szInline) - 1) == '\n') {
630  *(szInline + strlen(szInline) - 1) = '\0';
631  }
632  i++;
633  sprintf(Index, "%d", i);
634  if (SetRexxVar(Stem, szInline, strlen(szInline)))
635  {
636  return ERR_EXECIO_VAR_INVALID; // Variable name supplied on STEM or VAR option was not valid
637  }
638  }
639  else {
640  ulRc = ERR_EXECIO_EOF; // EOF before specified number of lines were read
641  break;
642  }
644  }
645  }
646  sprintf(szInline, "%d", i);
647  sprintf(Index, "%d", 0);
648  if (SetRexxVar(Stem, szInline, strlen(szInline)))
649  {
650  return ERR_EXECIO_VAR_INVALID; // Variable name supplied on STEM or VAR option was not valid
651  }
652  free(Stem);
653 
654  /* return with successful return code */
655  return ulRc;
656  }
657 
658 
659 /*--------------------------------------------------------------------*/
660 /* */
661 /* Function: ExecIO_Read_To_Queue */
662 /* */
663 /* Description: ExecIO read file to the current queue. */
664 /* */
665 /* Input: Pointer to file linked list item */
666 /* */
667 /* Returns: Return indicating success or failure */
668 /* */
669 /* References: None. */
670 /* */
671 /* Notes: */
672 /* */
673 /*--------------------------------------------------------------------*/
674 
675 static unsigned long ExecIO_Read_To_Queue (
676  PLL pll) /* Pointer to file linked list item */
677  {
678 
679  /* Local function variables */
680  int i;
681 
682  /* process request */
683 
684  // skip until we reach line number 'StartRcd'
685  for (i = 1; i < ExecIO_Options.lStartRcd; i++)
686  {
687  fgets(szInline, sizeof(szInline), pll -> pFile);
688  }
689 
690  if (ExecIO_Options.lRcdCnt == -1) {
691  /* process an "*" record count */
692  while (fgets (szInline, sizeof (szInline), pll -> pFile)) {
693  if (*(szInline + strlen (szInline) - 1) == '\n') {
694  *(szInline + strlen (szInline) - 1) = '\0';
695  }
696  if (ExecIO_Options.lDirection != 2) {
698  }
699  }
700  }
701  else {
702  /* process a specific record count */
703  while (ExecIO_Options.lRcdCnt > 0) {
704  if (fgets (szInline, sizeof (szInline), pll -> pFile)) {
705  if (*(szInline + strlen (szInline) - 1) == '\n') {
706  *(szInline + strlen (szInline) - 1) = '\0';
707  }
708  if (ExecIO_Options.lDirection != 2) {
710  }
711  }
712  else {
713  return ERR_EXECIO_EOF; // EOF before specified number of lines were read
714  }
716  }
717  }
718 
719  /* return with successful return code */
720  return 0;
721  }
722 
723 
724 /*--------------------------------------------------------------------*/
725 /* */
726 /* Function: Search_LL */
727 /* */
728 /* Description: Search the linked list of files for a match. */
729 /* */
730 /* Input: Filename */
731 /* */
732 /* Returns: Pointer to found struct or NULL if not found */
733 /* */
734 /* References: None. */
735 /* */
736 /* Notes: */
737 /* */
738 /*--------------------------------------------------------------------*/
739 
740 static PLL Search_LL (
741  char * SFilename) /* Source file name */
742  {
743 
744  /* Local function variables */
745  PLL pll = pHead;
746 
747  while (pll != NULL) {
748  if (!strcmp (SFilename, pll -> FileName)) {
749  return pll;
750  }
751  pll = pll -> next;
752  }
753  return pll;
754  }
755 
756 
757 /*--------------------------------------------------------------------*/
758 /* */
759 /* Function: Insert_LL */
760 /* */
761 /* Description: Insert a new item at the end of the list. */
762 /* */
763 /* Input: Pointer to new item struct. */
764 /* */
765 /* Returns: None. */
766 /* */
767 /* References: None. */
768 /* */
769 /* Notes: */
770 /* */
771 /*--------------------------------------------------------------------*/
772 
773 static void Insert_LL (
774  PLL pll) /* Pointer to the new item */
775  {
776 
777  if (pHead == NULL) {
778  pHead = pll;
779  }
780  else {
781  pTail -> next = pll;
782  }
783  pll -> prev = pTail;
784  pll -> next = NULL;
785  pTail = pll;
786  return;
787  }
788 
789 
790 /*--------------------------------------------------------------------*/
791 /* */
792 /* Function: Delete_LL */
793 /* */
794 /* Description: Delete an item from the list. */
795 /* */
796 /* Input: Pointer to item to be deleted. */
797 /* */
798 /* Returns: None. */
799 /* */
800 /* References: None. */
801 /* */
802 /* Notes: */
803 /* */
804 /*--------------------------------------------------------------------*/
805 
806 static void Delete_LL (
807  PLL pll) /* Pointer to the item to be deleted */
808  {
809 
810  if (pHead == pll) {
811  pHead = pll -> next;
812  }
813  if (pTail == pll) {
814  pTail = pll -> prev;
815  }
816  if (pll -> next != NULL) {
817  pll -> next -> prev = pll -> prev;
818  }
819  if (pll -> prev != NULL) {
820  pll -> prev -> next = pll -> next;
821  }
822  free(pll);
823  return;
824  }
825 
826 
827 /*--------------------------------------------------------------------*/
828 /* */
829 /* Function: queued */
830 /* */
831 /* Description: Returns the number of items in the current Rexx queue */
832 /* */
833 /* Input: None. */
834 /* */
835 /* Returns: Number of queued items */
836 /* */
837 /* References: None. */
838 /* */
839 /* Notes: */
840 /* */
841 /*--------------------------------------------------------------------*/
842 
843 static long queued (
844  void) /* No arguments */
845  {
846 
847  /* local function variables */
848  size_t elements;
849 
850  RexxQueryQueue("SESSION", &elements);
851  return (long)elements;
852  }
853 
854 
855 /*--------------------------------------------------------------------*/
856 /* */
857 /* Function: push */
858 /* */
859 /* Description: Push an item onto the current Rexx queue. */
860 /* */
861 /* Input: Pointer to the string to be pushed */
862 /* */
863 /* Returns: Number of queued items */
864 /* */
865 /* References: None. */
866 /* */
867 /* Notes: */
868 /* */
869 /*--------------------------------------------------------------------*/
870 
871 static void push (
872  char * pushstr, /* String to be pushed onto queue */
873  long lOp) /* 0 = FIFO, 1 = LIFO */
874  {
875 
876  CONSTRXSTRING rxstr;
877 
878  rxstr.strptr = pushstr;
879  rxstr.strlength = strlen(pushstr);
880  RexxAddQueue("SESSION", &rxstr, (size_t)lOp);
881  return;
882  }
883 
884 
885 /*--------------------------------------------------------------------*/
886 /* */
887 /* Function: pull */
888 /* */
889 /* Description: Pull an item off the current Rexx queue. */
890 /* */
891 /* Input: None */
892 /* */
893 /* Returns: Pointer to the pulled string */
894 /* */
895 /* References: None. */
896 /* */
897 /* Notes: */
898 /* */
899 /*--------------------------------------------------------------------*/
900 
901 static char * pull (
902  void) /* No arguments */
903  {
904 
905  /* local function variables */
906  RXSTRING result = {0, NULL};
907  RexxReturnCode rc;
908 
909  rc = RexxPullFromQueue("SESSION", &result, NULL, RXQUEUE_WAIT);
910  return result.strptr;
911  }
912 
913 
915  RexxReturnCode rc;
916 
917  rc = RexxRegisterSubcomExe("HostEmu", (REXXPFN)GrxHost, NULL);
918  htmxExecIO = CreateMutex(NULL, false, NULL);
919  #ifdef HOSTEMU_DEBUG
920  printf("HOSTEMU: Library loaded.\n");
921  printf("HOSTEMU: RexxRegisterSubcomExe retc = %d.\n", rc);
922  printf("HOSTEMU: CreateMutex htmxExecIO = %d.\n", htmxExecIO);
923  #endif
924  }
925 
926 
928  PLL pll;
929 
930  /* close all our open files */
931  pll = pHead;
932  while (pll != NULL) {
933  fclose (pll -> pFile);
934  pll = pll -> next;
935  }
936  }
937 
938 
941  REXX_INTERPRETER_4_0_0, // anything after 4.0.0 will work
942  "HostEmu", // name of the package
943  "1.0.1", // package information
944  hostemu_loader, // load function
945  hostemu_unloader, // unload function
946  NULL, // the exported routines
947  NULL // the exported methods
948  };
949 
950 // package loading stub.
952 
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:93
#define ERR_EXECIO_VAR_INVALID
Definition: hostemu.h:89
#define TS_STMT
Definition: hostemu.h:95
int yyparse(void)
Definition: cmdparse.cpp:1203
#define ERR_EXECIO_NO_STORAGE
Definition: hostemu.h:88
#define EXECIO_STMT
Definition: hostemu.h:92
#define SYMTABLESIZE
Definition: hostemu.h:91
#define TE_STMT
Definition: hostemu.h:94
#define ERR_EXECIO_EOF
Definition: hostemu.h:86
#define ERR_EXECIO_BAD_PLIST
Definition: hostemu.h:87
#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:235
#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:103
char aFilename[1024]
Definition: hostemu.h:100
long lRcdCnt
Definition: hostemu.h:98
char aStem[251]
Definition: hostemu.h:101
long lDirection
Definition: hostemu.h:104
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
void * REXXPFN
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 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 HANDLE htmxExecIO
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 void RexxEntry hostemu_unloader(RexxThreadContext *context)
static PLL pHead
static PLL Search_LL(char *SFilename)
static unsigned long ExecIO_Read_To_Stem(PLL pll)
static void RexxEntry hostemu_loader(RexxThreadContext *context)
static void Insert_LL(PLL pll)
unsigned long ulNumSym
static long queued(void)
static unsigned long ExecIO_Write_From_Queue(PLL pll)
char szInline[100000]
EXECIO_OPTIONS ExecIO_Options
PCONSTRXSTRING prxCmd