rllib  1
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  si.cb = sizeof(si);
211  PROCESS_INFORMATION pi;
212  DWORD dwCreationFlags;
213 
214  if(m_pid != -1) CloseHandle((HANDLE) m_pid);
215  dwCreationFlags = CREATE_NO_WINDOW;
216  if (prio == 0) dwCreationFlags |= IDLE_PRIORITY_CLASS;
217  else if(prio == 1) dwCreationFlags |= NORMAL_PRIORITY_CLASS;
218  else if(prio == 2) dwCreationFlags |= HIGH_PRIORITY_CLASS;
219  else if(prio == 3) dwCreationFlags |= REALTIME_PRIORITY_CLASS;
220  int ret = (int) CreateProcess( NULL, startup_command
221  , NULL, NULL
222  , FALSE, dwCreationFlags
223  , NULL, NULL
224  , &si, &pi);
225  m_pid = (int) pi.hProcess;
226  m_dwProcessId = pi.dwProcessId;
227  CloseHandle(pi.hThread);
228  return ret;
229 #endif
230 }
231 
233 {
234  if(m_pid == -1) return -1;
235  if(m_pid == 0) return -1;
236 
237 #ifdef RLUNIX
238  kill(m_pid,SIGTERM);
239  //printf("kill pid=%ld\n",m_pid);
240 #endif
241 
242 #ifdef __VMS
243  kill(m_pid,SIGTERM);
244 #endif
245 
246 #ifdef RLWIN32
247 #ifdef USE_WINKILL
248  // does anybody know HOWTO send SIGTERM under windows ?
249  // for the moment i just kill the process
250  TerminateProcess((HANDLE) m_pid, 0);
251  WaitForSingleObject((HANDLE) m_pid, 60000);
252  CloseHandle((HANDLE) m_pid);
253 #else
254  // broadcast rlSIGTERM
255  // Other prozesses haveto:
256  // UINT RegisterWindowMessage("rlSIGTERM");
257  // and evaluate their pid from the message
258  if(rlSIGTERM != 0)
259  {
260  PostMessage(HWND_BROADCAST,rlSIGTERM,-1,m_dwProcessId);
261  /*
262  BroadcastSystemMessage(
263  BSF_IGNORECURRENTTASK, // do not send message to this process
264  BSM_ALLCOMPONENTS, // BSM_APPLICATIONS, // broadcast only to applications
265  rlSIGTERM, // PM_MYMSG, // registered private message
266  -1, // message-specific value
267  m_dwProcessId); // message-specific value
268  */
269  }
270 #endif
271 #endif
272 
273  m_pid = -1;
274  return 0;
275 }
276 
278 {
279  if(m_pid == -1) return -1;
280  if(m_pid == 0) return -1;
281 
282 #ifdef RLUNIX
283  kill(m_pid,SIGKILL);
284  //printf("kill pid=%ld\n",m_pid);
285 #endif
286 
287 #ifdef __VMS
288  kill(m_pid,SIGKILL);
289 #endif
290 
291 #ifdef RLWIN32
292  TerminateProcess((HANDLE) m_pid, 0);
293  WaitForSingleObject((HANDLE) m_pid, 60000);
294  CloseHandle((HANDLE) m_pid);
295 #endif
296 
297  m_pid = -1;
298  return 0;
299 }
300 
302 {
303 #ifdef __VMS
304  long ret,code,mypid;
305 
306  if(m_pid == -1) return 0;
307  mypid = m_pid;
308  code = JPI$_STATE;
309  ret = lib$getjpi(&code,&mypid,0,0,0,0);
310  if(ret != SS$_NORMAL)
311  {
312  //printf("lib$getjpi terminated abnormal\n");
313  return 0;
314  }
315  if(mypid == m_pid) return 1;
316  return 0;
317 #endif
318 
319 #ifdef RLUNIX
320  int ret,status;
321 
322  if(m_pid == -1) return 0;
323  ret = waitpid(m_pid, &status, WNOHANG);
324  //printf("isAlive pid=%ld\n",m_pid);
325  if(ret == 0) return 1;
326  return 0;
327 #endif
328 
329 #ifdef RLWIN32
330  long status;
331 
332  if(m_pid == -1) return 0;
333  if(GetExitCodeProcess((HANDLE) m_pid, (unsigned long *) &status) != 0) // success
334  {
335  if(status == STILL_ACTIVE) return 1;
336  else return 0;
337  }
338  return 0; // failure
339 #endif
340 }
341 
343 {
344  return next;
345 }
346 
348 {
349  rlPcontrol *item;
350 
351  item = this;
352  while(item->next != NULL) item = item->next;
353  item->next = new rlPcontrol();
354  return item->next;
355 }
356 
357 #ifdef __VMS
358 void rlPcontrol::setInput(const char *input)
359 {
360  if(m_input != NULL) delete [] m_input;
361  m_input = new char [strlen(input)+1];
362  strcpy(m_input,input);
363 }
364 
365 void rlPcontrol::setOutput(const char *output)
366 {
367  if(m_output != NULL) delete [] m_output;
368  m_output = new char [strlen(output)+1];
369  strcpy(m_output,output);
370 }
371 
372 void rlPcontrol::setError(const char *error)
373 {
374  if(m_error != NULL) delete [] m_error;
375  m_error = new char [strlen(error)+1];
376  strcpy(m_error,error);
377 }
378 #endif
379 
381 {
382 #ifdef __VMS
383  if(pri < 0) pri = 0;
384  if(pri > 15) pri = 15;
385 #endif
386 #ifdef RLWIN32
387  if(pri < 0) pri = 0;
388  if(pri > 3) pri = 3;
389 #endif
390  prio = pri;
391 }
392 
394 {
395  return prio;
396 }
397 
void getLocalTime()
Definition: rltime.cpp:342
static UINT rlSIGTERM
Definition: rlpcontrol.cpp:42
int isAlive()
Definition: rlpcontrol.cpp:301
virtual ~rlPcontrol()
Definition: rlpcontrol.cpp:64
const char * startupCommand()
Definition: rlpcontrol.cpp:78
void setOutput(const char *output)
Definition: rlpcontrol.cpp:365
void setError(const char *error)
Definition: rlpcontrol.cpp:372
rlPcontrol * getNext()
Definition: rlpcontrol.cpp:342
void setInput(const char *input)
Definition: rlpcontrol.cpp:358
int rlexec(const char *command)
Definition: rlcutil.cpp:113
char * process_name
Definition: rlpcontrol.h:125
int rlstrlen(const char *str)
Definition: rlpcontrol.cpp:133
int sigkill()
Definition: rlpcontrol.cpp:277
void setPID(long pid)
Definition: rlpcontrol.cpp:93
long m_dwProcessId
Definition: rlpcontrol.h:132
rlTime process_time
Definition: rlpcontrol.h:136
int sigterm()
Definition: rlpcontrol.cpp:232
long pid()
Definition: rlpcontrol.cpp:109
void setPriority(int priority)
Definition: rlpcontrol.cpp:380
int priority()
Definition: rlpcontrol.cpp:393
char * startup_command
Definition: rlpcontrol.h:125
rlPcontrol * next
Definition: rlpcontrol.h:137
char * m_error
Definition: rlpcontrol.h:128
char * m_input
Definition: rlpcontrol.h:128
const char * processName()
Definition: rlpcontrol.cpp:83
long m_pid
Definition: rlpcontrol.h:135
rlTime * processTime()
Definition: rlpcontrol.cpp:88
void setStartupCommand(const char *command, const char *process_name)
Definition: rlpcontrol.cpp:122
rlPcontrol * addNew()
Definition: rlpcontrol.cpp:347
Definition: rltime.h:25
char * m_output
Definition: rlpcontrol.h:128