rllib  1
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros
rlpcontrol.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  rlpcontrol.cpp - description
3  -------------------
4  begin : Wed Dec 11 2002
5  copyright : (C) 2002 by R. Lehrig
6  email : lehrig@t-online.de
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This library is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
13  * published by the Free Software Foundation *
14  * *
15  ***************************************************************************/
16 #include "rlpcontrol.h"
17 #include "rlcutil.h"
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #ifdef RLWIN32
22 #include <windows.h>
23 #include <winuser.h>
24 //#define USE_WINKILL
25 #endif
26 #ifdef RLUNIX
27 #include <unistd.h>
28 #include <sys/types.h>
29 #include <sys/wait.h>
30 #include <signal.h>
31 #endif
32 #ifdef __VMS
33 #include <unistd.h>
34 #include <descrip.h>
35 #include <starlet.h>
36 #include <ssdef.h>
37 #include <lib$routines.h>
38 #include <jpidef.h>
39 #endif
40 
41 #ifdef RLWIN32
42 static UINT rlSIGTERM = 0;
43 #endif
44 
46 {
47  m_pid = -1;
49  next = NULL;
50 #ifdef __VMS
51  m_input = m_output = m_error = NULL;
52  prio = 4; // normal user priority
53 #endif
54 #ifdef RLWIN32
55  m_dwProcessId = -1;
56  prio = 1; // normal user priority
57  if(rlSIGTERM == 0) rlSIGTERM = RegisterWindowMessage("rlSIGTERM");
58 #endif
59 #ifdef RLUNIX
60  prio = 0;
61 #endif
62 }
63 
65 {
66  if(startup_command != NULL) delete [] startup_command;
67  if(next != NULL) delete next;
68 #ifdef RLWIN32
69  if(m_pid != -1) CloseHandle((HANDLE) m_pid);
70 #endif
71 #ifdef __VMS
72  if(m_input != NULL) delete [] m_input;
73  if(m_output != NULL) delete [] m_output;
74  if(m_error != NULL) delete [] m_error;
75 #endif
76 }
77 
79 {
80  return startup_command;
81 }
82 
84 {
85  return process_name;
86 }
87 
89 {
90  return &process_time;
91 }
92 
93 void rlPcontrol::setPID(long _pid)
94 {
95  if(_pid <= 0)
96  {
97  m_pid = -1;
98  return;
99  }
100 #ifdef RLWIN32
101  if(m_pid != -1) CloseHandle((HANDLE) m_pid);
102  m_dwProcessId = _pid;
103  m_pid = (long) OpenProcess(PROCESS_ALL_ACCESS,TRUE,m_dwProcessId);
104 #else
105  m_pid = _pid;
106 #endif
107 }
108 
110 {
111 #ifdef RLWIN32
112  if(m_dwProcessId == -1) return 0;
113  if(m_dwProcessId == 0) return 0;
114  return m_dwProcessId;
115 #else
116  if(m_pid == -1) return 0;
117  if(m_pid == 0) return 0;
118  return m_pid;
119 #endif
120 }
121 
122 void rlPcontrol::setStartupCommand(const char *command, const char *processname)
123 {
124  if(startup_command != NULL) delete [] startup_command;
125  startup_command = new char[strlen(command)+1];
126  strcpy(startup_command,command);
127 
128  if(process_name != NULL) delete [] process_name;
129  process_name = new char[strlen(processname)+1];
130  strcpy(process_name,processname);
131 }
132 
133 int rlPcontrol::rlstrlen(const char *str)
134 {
135  if(str == NULL) return -1;
136  else return strlen(str);
137 }
138 
140 {
141  if(startup_command == NULL) return -1;
142  if(isAlive()) return -1;
144 
145 #ifdef RLUNIX
146  if((m_pid = ::fork()) == 0)
147  {
149  ::exit(0);
150  }
151  // printf("start pid=%ld\n",m_pid);
152  return 0;
153 #endif
154 
155 #ifdef __VMS
156  int ret;
157  struct dsc$descriptor_s image,prcnam,input,output,error,*inputptr,*outputptr,*errorptr;
158 
159  image.dsc$w_length = rlstrlen(startup_command);
160  image.dsc$b_dtype = DSC$K_DTYPE_T;
161  image.dsc$b_class = DSC$K_CLASS_S;
162  image.dsc$a_pointer = startup_command;
163 
164  prcnam.dsc$w_length = rlstrlen(process_name);
165  prcnam.dsc$b_dtype = DSC$K_DTYPE_T;
166  prcnam.dsc$b_class = DSC$K_CLASS_S;
167  prcnam.dsc$a_pointer = process_name;
168 
169  input.dsc$w_length = rlstrlen(m_input);
170  input.dsc$b_dtype = DSC$K_DTYPE_T;
171  input.dsc$b_class = DSC$K_CLASS_S;
172  input.dsc$a_pointer = m_input;
173 
174  output.dsc$w_length = rlstrlen(m_output);
175  output.dsc$b_dtype = DSC$K_DTYPE_T;
176  output.dsc$b_class = DSC$K_CLASS_S;
177  output.dsc$a_pointer = m_output;
178 
179  error.dsc$w_length = rlstrlen(m_error);
180  error.dsc$b_dtype = DSC$K_DTYPE_T;
181  error.dsc$b_class = DSC$K_CLASS_S;
182  error.dsc$a_pointer = m_error;
183 
184  inputptr = outputptr = errorptr = 0;
185  if( input.dsc$w_length > 0) inputptr = &input;
186  if(output.dsc$w_length > 0) outputptr = &output;
187  if( error.dsc$w_length > 0) errorptr = &error;
188 
189  if( inputptr != 0 && inputptr->dsc$a_pointer == NULL) inputptr = 0;
190  if(outputptr != 0 && outputptr->dsc$a_pointer == NULL) outputptr = 0;
191  if( errorptr != 0 && errorptr->dsc$a_pointer == NULL) errorptr = 0;
192 
193  /*
194  printf("sys$creprc(\n");
195  printf(" image=%s\n",image.dsc$a_pointer);
196  printf(" inputptr=%s\n" ,inputptr->dsc$a_pointer);
197  printf(" outputptr=%s\n",outputptr->dsc$a_pointer);
198  printf(" errorptr=%s\n" ,errorptr->dsc$a_pointer);
199  printf(" prcnam=%s\n",prcnam.dsc$a_pointer);
200  printf(" priority=%d\n",prio);
201  printf(")\n");
202  */
203  ret = sys$creprc(&m_pid,&image,inputptr,outputptr,errorptr,0,0,&prcnam,prio,0,0,0,0,0);
204  if(ret != SS$_NORMAL) return -1;
205  return 0;
206 #endif
207 
208 #ifdef RLWIN32
209  STARTUPINFO si = {sizeof(si)};
210  PROCESS_INFORMATION pi;
211  DWORD dwCreationFlags;
212 
213  if(m_pid != -1) CloseHandle((HANDLE) m_pid);
214  dwCreationFlags = CREATE_NO_WINDOW;
215  if (prio == 0) dwCreationFlags |= IDLE_PRIORITY_CLASS;
216  else if(prio == 1) dwCreationFlags |= NORMAL_PRIORITY_CLASS;
217  else if(prio == 2) dwCreationFlags |= HIGH_PRIORITY_CLASS;
218  else if(prio == 3) dwCreationFlags |= REALTIME_PRIORITY_CLASS;
219  int ret = (int) CreateProcess( NULL, startup_command
220  , NULL, NULL
221  , FALSE, dwCreationFlags
222  , NULL, NULL
223  , &si, &pi);
224  m_pid = (int) pi.hProcess;
225  m_dwProcessId = pi.dwProcessId;
226  CloseHandle(pi.hThread);
227  return ret;
228 #endif
229 }
230 
232 {
233  if(m_pid == -1) return -1;
234  if(m_pid == 0) return -1;
235 
236 #ifdef RLUNIX
237  kill(m_pid,SIGTERM);
238  //printf("kill pid=%ld\n",m_pid);
239 #endif
240 
241 #ifdef __VMS
242  kill(m_pid,SIGTERM);
243 #endif
244 
245 #ifdef RLWIN32
246 #ifdef USE_WINKILL
247  // does anybody know HOWTO send SIGTERM under windows ?
248  // for the moment i just kill the process
249  TerminateProcess((HANDLE) m_pid, 0);
250  WaitForSingleObject((HANDLE) m_pid, 60000);
251  CloseHandle((HANDLE) m_pid);
252 #else
253  // broadcast rlSIGTERM
254  // Other prozesses haveto:
255  // UINT RegisterWindowMessage("rlSIGTERM");
256  // and evaluate their pid from the message
257  if(rlSIGTERM != 0)
258  {
259  PostMessage(HWND_BROADCAST,rlSIGTERM,-1,m_dwProcessId);
260  /*
261  BroadcastSystemMessage(
262  BSF_IGNORECURRENTTASK, // do not send message to this process
263  BSM_ALLCOMPONENTS, // BSM_APPLICATIONS, // broadcast only to applications
264  rlSIGTERM, // PM_MYMSG, // registered private message
265  -1, // message-specific value
266  m_dwProcessId); // message-specific value
267  */
268  }
269 #endif
270 #endif
271 
272  m_pid = -1;
273  return 0;
274 }
275 
277 {
278  if(m_pid == -1) return -1;
279  if(m_pid == 0) return -1;
280 
281 #ifdef RLUNIX
282  kill(m_pid,SIGKILL);
283  //printf("kill pid=%ld\n",m_pid);
284 #endif
285 
286 #ifdef __VMS
287  kill(m_pid,SIGKILL);
288 #endif
289 
290 #ifdef RLWIN32
291  TerminateProcess((HANDLE) m_pid, 0);
292  WaitForSingleObject((HANDLE) m_pid, 60000);
293  CloseHandle((HANDLE) m_pid);
294 #endif
295 
296  m_pid = -1;
297  return 0;
298 }
299 
301 {
302 #ifdef __VMS
303  long ret,code,mypid;
304 
305  if(m_pid == -1) return 0;
306  mypid = m_pid;
307  code = JPI$_STATE;
308  ret = lib$getjpi(&code,&mypid,0,0,0,0);
309  if(ret != SS$_NORMAL)
310  {
311  //printf("lib$getjpi terminated abnormal\n");
312  return 0;
313  }
314  if(mypid == m_pid) return 1;
315  return 0;
316 #endif
317 
318 #ifdef RLUNIX
319  int ret,status;
320 
321  if(m_pid == -1) return 0;
322  ret = waitpid(m_pid, &status, WNOHANG);
323  //printf("isAlive pid=%ld\n",m_pid);
324  if(ret == 0) return 1;
325  return 0;
326 #endif
327 
328 #ifdef RLWIN32
329  long status;
330 
331  if(m_pid == -1) return 0;
332  if(GetExitCodeProcess((HANDLE) m_pid, (unsigned long *) &status) != 0) // success
333  {
334  if(status == STILL_ACTIVE) return 1;
335  else return 0;
336  }
337  return 0; // failure
338 #endif
339 }
340 
342 {
343  return next;
344 }
345 
347 {
348  rlPcontrol *item;
349 
350  item = this;
351  while(item->next != NULL) item = item->next;
352  item->next = new rlPcontrol();
353  return item->next;
354 }
355 
356 #ifdef __VMS
357 void rlPcontrol::setInput(const char *input)
358 {
359  if(m_input != NULL) delete [] m_input;
360  m_input = new char [strlen(input)+1];
361  strcpy(m_input,input);
362 }
363 
364 void rlPcontrol::setOutput(const char *output)
365 {
366  if(m_output != NULL) delete [] m_output;
367  m_output = new char [strlen(output)+1];
368  strcpy(m_output,output);
369 }
370 
371 void rlPcontrol::setError(const char *error)
372 {
373  if(m_error != NULL) delete [] m_error;
374  m_error = new char [strlen(error)+1];
375  strcpy(m_error,error);
376 }
377 #endif
378 
380 {
381 #ifdef __VMS
382  if(pri < 0) pri = 0;
383  if(pri > 15) pri = 15;
384 #endif
385 #ifdef RLWIN32
386  if(pri < 0) pri = 0;
387  if(pri > 3) pri = 3;
388 #endif
389  prio = pri;
390 }
391 
393 {
394  return prio;
395 }
396