windows/SysInterpreterInstance.cpp
Go to the documentation of this file.
1 /*----------------------------------------------------------------------------*/
2 /* */
3 /* Copyright (c) 1995, 2004 IBM Corporation. All rights reserved. */
4 /* Copyright (c) 2005-2009 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.ibm.com/developerworks/oss/CPLv1.0.htm */
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 /* Implementation of the SysInterpreterInstance class */
40 /* */
41 /******************************************************************************/
42 
43 #include "RexxCore.h"
44 #include "InterpreterInstance.hpp"
45 #include "ListClass.hpp"
46 #include "SystemInterpreter.hpp"
47 #include "RexxActivation.hpp"
48 
49 #include <stdio.h>
50 #include <fcntl.h>
51 #include <io.h>
52 
53 
54 BOOL __stdcall WinConsoleCtrlHandler(DWORD dwCtrlType)
55 /******************************************************************************/
56 /* Arguments: Report record, registration record, context record, */
57 /* dispatcher context */
58 /* */
59 /* DESCRIPTION : For Control Break conditions issue a halt to activation */
60 /* Control-C or control-Break is pressed. */
61 /* */
62 /* Returned: Action code */
63 /******************************************************************************/
64 {
65  // check to condition for all threads of this process */
66 
67  if ((dwCtrlType == CTRL_CLOSE_EVENT) || (dwCtrlType == CTRL_SHUTDOWN_EVENT))
68  {
69  return false; /* send to system */
70  }
71 
72  /* if RXCTRLBREAK=NO then ignore SIGBREAK exception */
73  if (dwCtrlType == CTRL_BREAK_EVENT || dwCtrlType == CTRL_LOGOFF_EVENT)
74  {
75  char envp[65];
76  if (GetEnvironmentVariable("RXCTRLBREAK", envp, sizeof(envp)) > 0 && strcmp("NO",envp) == 0)
77  {
78  return true; /* ignore signal */
79  }
80  }
81 
82  if (dwCtrlType == CTRL_LOGOFF_EVENT)
83  {
84  return false; /* send to system */
85  }
86 
87  // we need to do something about this one, let the system interpreter handle
88  return SystemInterpreter::processSignal(dwCtrlType);
89 }
90 
91 /**
92  * Initialize the interpreter instance.
93  *
94  * @param i Our interpreter instance container.
95  * @param options The options used to initialize us. We can add additional
96  * platform-specific options if we wish.
97  */
99 {
100  externalTraceEnabled = false; // off by default
101  const int bufferSize = 20; // was 8 but better to increase because now supports an optional :<depth>
102  TCHAR rxTraceBuf[bufferSize];
103 
104  externalTraceOption = NULL;
105  /* scan current environment, */
106  // value syntax: ON or <traceOption>[:<depth>]
107  // ON is equivalent to ?R
108  // Example of possible values : on i i:10 ?r ?r:10
109  DWORD charcount = GetEnvironmentVariable("RXTRACE", rxTraceBuf, bufferSize);
110  if (charcount != 0 && charcount < bufferSize )
111  {
113  if (externalTraceOption != NULL)
114  {
115  strcpy(externalTraceOption, rxTraceBuf);
116  externalTraceEnabled = true; // turn on tracing of top-level activations for this instance
117  }
118  }
119 
120  /* Because of using the stand-alone runtime library or when using different compilers,
121  the std-streams of the calling program and the REXX.DLL might be located at different
122  addresses and therefore _file might be -1. If so, std-streams are reassigned to the
123  file standard handles returned by the system */
124  if ((_fileno(stdin) < 0) && (GetFileType(GetStdHandle(STD_INPUT_HANDLE)) != FILE_TYPE_UNKNOWN))
125  {
126  *stdin = *_fdopen(_open_osfhandle((intptr_t)GetStdHandle(STD_INPUT_HANDLE),_O_RDONLY), "r");
127  }
128  if ((_fileno(stdout) < 0) && (GetFileType(GetStdHandle(STD_OUTPUT_HANDLE)) != FILE_TYPE_UNKNOWN))
129  {
130  *stdout = *_fdopen(_open_osfhandle((intptr_t)GetStdHandle(STD_OUTPUT_HANDLE),_O_APPEND), "a");
131  }
132  if ((_fileno(stderr) < 0) && (GetFileType(GetStdHandle(STD_ERROR_HANDLE)) != FILE_TYPE_UNKNOWN))
133  {
134  *stderr = *_fdopen(_open_osfhandle((intptr_t)GetStdHandle(STD_ERROR_HANDLE),_O_APPEND), "a");
135  }
136  // enable trapping for CTRL_C exceptions
137  SetConsoleCtrlHandler(&WinConsoleCtrlHandler, true);
138  instance = i;
139 
140  // add our default search extension
141  addSearchExtension(".REX");
142 }
143 
144 
145 /**
146  * Terminate the interpreter instance.
147  */
149 {
150  SetConsoleCtrlHandler(&WinConsoleCtrlHandler, false);
152 }
153 
154 
155 /**
156  * Append a system default extension to the extension search order.
157  *
158  * @param name The name to add.
159  */
160 void SysInterpreterInstance::addSearchExtension(const char *name)
161 {
162  // if the extension is not already in the extension list, add it
163  RexxString *ext = new_string(name);
165  {
167  }
168 }
169 
171 /******************************************************************************/
172 /* Function: Do system specific program setup */
173 /******************************************************************************/
174 {
175  // trace this activation if turned on externally when the instance was started
177  {
179  }
180 }
181 
182 
183 SysSearchPath::SysSearchPath(const char *parentDir, const char *extensionPath)
184 {
185  char temp[4]; // this is just a temp buffer to check component sizes
186 
187  size_t pathSize = GetEnvironmentVariable("PATH", temp, sizeof(temp));
188  size_t rexxPathSize = GetEnvironmentVariable("REXX_PATH", temp, sizeof(temp));
189  size_t parentSize = parentDir == NULL ? 0 : strlen(parentDir);
190  size_t extensionSize = extensionPath == NULL ? 0 : strlen(extensionPath);
191 
192 
193  // enough room for separators and a terminating null
194  path = (char *)SystemInterpreter::allocateResultMemory(pathSize + rexxPathSize + parentSize + extensionSize + 16);
195  *path = '\0'; // add a null character so strcat can work
196  if (parentDir != NULL)
197  {
198  strcpy(path, parentDir);
199  strcat(path, ";");
200  }
201 
202  // add on the current directory
203  strcat(path, ".;");
204 
205  if (extensionPath != NULL)
206  {
207  strcat(path, extensionPath);
208  if (path[strlen(path) - 1] != ';')
209  {
210  strcat(path, ";");
211  }
212  }
213 
214  // add on the Rexx path, then the normal path
215  GetEnvironmentVariable("REXX_PATH", path + strlen(path), (DWORD)pathSize + 1);
216  if (path[strlen(path) - 1] != ';')
217  {
218  strcat(path, ";");
219  }
220 
221  GetEnvironmentVariable("PATH", path + strlen(path), (DWORD)pathSize + 1);
222  if (path[strlen(path) - 1] != ';')
223  {
224  strcat(path, ";");
225  }
226 }
227 
228 
229 /**
230  * Deconstructor for releasing storage used by the constructed path.
231  */
233 {
235 }
#define TheFalseObject
Definition: RexxCore.h:195
RexxString * new_string(const char *s, stringsize_t l)
void enableExternalTrace(const char *option)
RexxObject * append(RexxObject *)
Definition: ListClass.cpp:538
RexxObject * hasItem(RexxObject *)
Definition: ListClass.cpp:994
void addSearchExtension(const char *name)
void initialize(InterpreterInstance *i, RexxOption *options)
void setupProgram(RexxActivation *activation)
SysSearchPath(const char *parent, const char *extension)
static bool processSignal(DWORD dwCtrlType)
static void * allocateResultMemory(size_t)
static void releaseResultMemory(void *)
BOOL __stdcall WinConsoleCtrlHandler(DWORD dwCtrlType)
INT_PTR intptr_t