|
rllib
1
|
00001 /*************************************************************************** 00002 rlpcontrol.cpp - description 00003 ------------------- 00004 begin : Wed Dec 11 2002 00005 copyright : (C) 2002 by Rainer Lehrig 00006 email : lehrig@t-online.de 00007 ***************************************************************************/ 00008 00009 /*************************************************************************** 00010 * * 00011 * This library is free software; you can redistribute it and/or modify * 00012 * it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as * 00013 * published by the Free Software Foundation * 00014 * * 00015 ***************************************************************************/ 00016 #include "rlpcontrol.h" 00017 #include "rlcutil.h" 00018 #include <stdio.h> 00019 #include <stdlib.h> 00020 #include <string.h> 00021 #ifdef RLWIN32 00022 #include <windows.h> 00023 #include <winuser.h> 00024 //#define USE_WINKILL 00025 #endif 00026 #ifdef RLUNIX 00027 #include <unistd.h> 00028 #include <sys/types.h> 00029 #include <sys/wait.h> 00030 #include <signal.h> 00031 #endif 00032 #ifdef __VMS 00033 #include <unistd.h> 00034 #include <descrip.h> 00035 #include <starlet.h> 00036 #include <ssdef.h> 00037 #include <lib$routines.h> 00038 #include <jpidef.h> 00039 #endif 00040 00041 #ifdef RLWIN32 00042 static UINT rlSIGTERM = 0; 00043 #endif 00044 00045 rlPcontrol::rlPcontrol() 00046 { 00047 m_pid = -1; 00048 startup_command = process_name = NULL; 00049 next = NULL; 00050 #ifdef __VMS 00051 m_input = m_output = m_error = NULL; 00052 prio = 4; // normal user priority 00053 #endif 00054 #ifdef RLWIN32 00055 m_dwProcessId = -1; 00056 prio = 1; // normal user priority 00057 if(rlSIGTERM == 0) rlSIGTERM = RegisterWindowMessage("rlSIGTERM"); 00058 #endif 00059 #ifdef RLUNIX 00060 prio = 0; 00061 #endif 00062 } 00063 00064 rlPcontrol::~rlPcontrol() 00065 { 00066 if(startup_command != NULL) delete [] startup_command; 00067 if(next != NULL) delete next; 00068 #ifdef RLWIN32 00069 if(m_pid != -1) CloseHandle((HANDLE) m_pid); 00070 #endif 00071 #ifdef __VMS 00072 if(m_input != NULL) delete [] m_input; 00073 if(m_output != NULL) delete [] m_output; 00074 if(m_error != NULL) delete [] m_error; 00075 #endif 00076 } 00077 00078 const char *rlPcontrol::startupCommand() 00079 { 00080 return startup_command; 00081 } 00082 00083 const char *rlPcontrol::processName() 00084 { 00085 return process_name; 00086 } 00087 00088 rlTime *rlPcontrol::processTime() 00089 { 00090 return &process_time; 00091 } 00092 00093 void rlPcontrol::setPID(long _pid) 00094 { 00095 if(_pid <= 0) 00096 { 00097 m_pid = -1; 00098 return; 00099 } 00100 #ifdef RLWIN32 00101 if(m_pid != -1) CloseHandle((HANDLE) m_pid); 00102 m_dwProcessId = _pid; 00103 m_pid = (long) OpenProcess(PROCESS_ALL_ACCESS,TRUE,m_dwProcessId); 00104 #else 00105 m_pid = _pid; 00106 #endif 00107 } 00108 00109 long rlPcontrol::pid() 00110 { 00111 #ifdef RLWIN32 00112 if(m_dwProcessId == -1) return 0; 00113 if(m_dwProcessId == 0) return 0; 00114 return m_dwProcessId; 00115 #else 00116 if(m_pid == -1) return 0; 00117 if(m_pid == 0) return 0; 00118 return m_pid; 00119 #endif 00120 } 00121 00122 void rlPcontrol::setStartupCommand(const char *command, const char *processname) 00123 { 00124 if(startup_command != NULL) delete [] startup_command; 00125 startup_command = new char[strlen(command)+1]; 00126 strcpy(startup_command,command); 00127 00128 if(process_name != NULL) delete [] process_name; 00129 process_name = new char[strlen(processname)+1]; 00130 strcpy(process_name,processname); 00131 } 00132 00133 int rlPcontrol::rlstrlen(const char *str) 00134 { 00135 if(str == NULL) return -1; 00136 else return strlen(str); 00137 } 00138 00139 int rlPcontrol::start() 00140 { 00141 if(startup_command == NULL) return -1; 00142 if(isAlive()) return -1; 00143 process_time.getLocalTime(); 00144 00145 #ifdef RLUNIX 00146 if((m_pid = ::fork()) == 0) 00147 { 00148 rlexec(startup_command); 00149 ::exit(0); 00150 } 00151 // printf("start pid=%ld\n",m_pid); 00152 return 0; 00153 #endif 00154 00155 #ifdef __VMS 00156 int ret; 00157 struct dsc$descriptor_s image,prcnam,input,output,error,*inputptr,*outputptr,*errorptr; 00158 00159 image.dsc$w_length = rlstrlen(startup_command); 00160 image.dsc$b_dtype = DSC$K_DTYPE_T; 00161 image.dsc$b_class = DSC$K_CLASS_S; 00162 image.dsc$a_pointer = startup_command; 00163 00164 prcnam.dsc$w_length = rlstrlen(process_name); 00165 prcnam.dsc$b_dtype = DSC$K_DTYPE_T; 00166 prcnam.dsc$b_class = DSC$K_CLASS_S; 00167 prcnam.dsc$a_pointer = process_name; 00168 00169 input.dsc$w_length = rlstrlen(m_input); 00170 input.dsc$b_dtype = DSC$K_DTYPE_T; 00171 input.dsc$b_class = DSC$K_CLASS_S; 00172 input.dsc$a_pointer = m_input; 00173 00174 output.dsc$w_length = rlstrlen(m_output); 00175 output.dsc$b_dtype = DSC$K_DTYPE_T; 00176 output.dsc$b_class = DSC$K_CLASS_S; 00177 output.dsc$a_pointer = m_output; 00178 00179 error.dsc$w_length = rlstrlen(m_error); 00180 error.dsc$b_dtype = DSC$K_DTYPE_T; 00181 error.dsc$b_class = DSC$K_CLASS_S; 00182 error.dsc$a_pointer = m_error; 00183 00184 inputptr = outputptr = errorptr = 0; 00185 if( input.dsc$w_length > 0) inputptr = &input; 00186 if(output.dsc$w_length > 0) outputptr = &output; 00187 if( error.dsc$w_length > 0) errorptr = &error; 00188 00189 if( inputptr != 0 && inputptr->dsc$a_pointer == NULL) inputptr = 0; 00190 if(outputptr != 0 && outputptr->dsc$a_pointer == NULL) outputptr = 0; 00191 if( errorptr != 0 && errorptr->dsc$a_pointer == NULL) errorptr = 0; 00192 00193 /* 00194 printf("sys$creprc(\n"); 00195 printf(" image=%s\n",image.dsc$a_pointer); 00196 printf(" inputptr=%s\n" ,inputptr->dsc$a_pointer); 00197 printf(" outputptr=%s\n",outputptr->dsc$a_pointer); 00198 printf(" errorptr=%s\n" ,errorptr->dsc$a_pointer); 00199 printf(" prcnam=%s\n",prcnam.dsc$a_pointer); 00200 printf(" priority=%d\n",prio); 00201 printf(")\n"); 00202 */ 00203 ret = sys$creprc(&m_pid,&image,inputptr,outputptr,errorptr,0,0,&prcnam,prio,0,0,0,0,0); 00204 if(ret != SS$_NORMAL) return -1; 00205 return 0; 00206 #endif 00207 00208 #ifdef RLWIN32 00209 STARTUPINFO si = {sizeof(si)}; 00210 PROCESS_INFORMATION pi; 00211 DWORD dwCreationFlags; 00212 00213 if(m_pid != -1) CloseHandle((HANDLE) m_pid); 00214 dwCreationFlags = CREATE_NO_WINDOW; 00215 if (prio == 0) dwCreationFlags |= IDLE_PRIORITY_CLASS; 00216 else if(prio == 1) dwCreationFlags |= NORMAL_PRIORITY_CLASS; 00217 else if(prio == 2) dwCreationFlags |= HIGH_PRIORITY_CLASS; 00218 else if(prio == 3) dwCreationFlags |= REALTIME_PRIORITY_CLASS; 00219 int ret = (int) CreateProcess( NULL, startup_command 00220 , NULL, NULL 00221 , FALSE, dwCreationFlags 00222 , NULL, NULL 00223 , &si, &pi); 00224 m_pid = (int) pi.hProcess; 00225 m_dwProcessId = pi.dwProcessId; 00226 CloseHandle(pi.hThread); 00227 return ret; 00228 #endif 00229 } 00230 00231 int rlPcontrol::sigterm() 00232 { 00233 if(m_pid == -1) return -1; 00234 if(m_pid == 0) return -1; 00235 00236 #ifdef RLUNIX 00237 kill(m_pid,SIGTERM); 00238 //printf("kill pid=%ld\n",m_pid); 00239 #endif 00240 00241 #ifdef __VMS 00242 kill(m_pid,SIGTERM); 00243 #endif 00244 00245 #ifdef RLWIN32 00246 #ifdef USE_WINKILL 00247 // does anybody know HOWTO send SIGTERM under windows ? 00248 // for the moment i just kill the process 00249 TerminateProcess((HANDLE) m_pid, 0); 00250 WaitForSingleObject((HANDLE) m_pid, 60000); 00251 CloseHandle((HANDLE) m_pid); 00252 #else 00253 // broadcast rlSIGTERM 00254 // Other prozesses haveto: 00255 // UINT RegisterWindowMessage("rlSIGTERM"); 00256 // and evaluate their pid from the message 00257 if(rlSIGTERM != 0) 00258 { 00259 PostMessage(HWND_BROADCAST,rlSIGTERM,-1,m_dwProcessId); 00260 /* 00261 BroadcastSystemMessage( 00262 BSF_IGNORECURRENTTASK, // do not send message to this process 00263 BSM_ALLCOMPONENTS, // BSM_APPLICATIONS, // broadcast only to applications 00264 rlSIGTERM, // PM_MYMSG, // registered private message 00265 -1, // message-specific value 00266 m_dwProcessId); // message-specific value 00267 */ 00268 } 00269 #endif 00270 #endif 00271 00272 m_pid = -1; 00273 return 0; 00274 } 00275 00276 int rlPcontrol::sigkill() 00277 { 00278 if(m_pid == -1) return -1; 00279 if(m_pid == 0) return -1; 00280 00281 #ifdef RLUNIX 00282 kill(m_pid,SIGKILL); 00283 //printf("kill pid=%ld\n",m_pid); 00284 #endif 00285 00286 #ifdef __VMS 00287 kill(m_pid,SIGKILL); 00288 #endif 00289 00290 #ifdef RLWIN32 00291 TerminateProcess((HANDLE) m_pid, 0); 00292 WaitForSingleObject((HANDLE) m_pid, 60000); 00293 CloseHandle((HANDLE) m_pid); 00294 #endif 00295 00296 m_pid = -1; 00297 return 0; 00298 } 00299 00300 int rlPcontrol::isAlive() 00301 { 00302 #ifdef __VMS 00303 long ret,code,mypid; 00304 00305 if(m_pid == -1) return 0; 00306 mypid = m_pid; 00307 code = JPI$_STATE; 00308 ret = lib$getjpi(&code,&mypid,0,0,0,0); 00309 if(ret != SS$_NORMAL) 00310 { 00311 //printf("lib$getjpi terminated abnormal\n"); 00312 return 0; 00313 } 00314 if(mypid == m_pid) return 1; 00315 return 0; 00316 #endif 00317 00318 #ifdef RLUNIX 00319 int ret,status; 00320 00321 if(m_pid == -1) return 0; 00322 ret = waitpid(m_pid, &status, WNOHANG); 00323 //printf("isAlive pid=%ld\n",m_pid); 00324 if(ret == 0) return 1; 00325 return 0; 00326 #endif 00327 00328 #ifdef RLWIN32 00329 long status; 00330 00331 if(m_pid == -1) return 0; 00332 if(GetExitCodeProcess((HANDLE) m_pid, (unsigned long *) &status) != 0) // success 00333 { 00334 if(status == STILL_ACTIVE) return 1; 00335 else return 0; 00336 } 00337 return 0; // failure 00338 #endif 00339 } 00340 00341 rlPcontrol *rlPcontrol::getNext() 00342 { 00343 return next; 00344 } 00345 00346 rlPcontrol *rlPcontrol::addNew() 00347 { 00348 rlPcontrol *item; 00349 00350 item = this; 00351 while(item->next != NULL) item = item->next; 00352 item->next = new rlPcontrol(); 00353 return item->next; 00354 } 00355 00356 #ifdef __VMS 00357 void rlPcontrol::setInput(const char *input) 00358 { 00359 if(m_input != NULL) delete [] m_input; 00360 m_input = new char [strlen(input)+1]; 00361 strcpy(m_input,input); 00362 } 00363 00364 void rlPcontrol::setOutput(const char *output) 00365 { 00366 if(m_output != NULL) delete [] m_output; 00367 m_output = new char [strlen(output)+1]; 00368 strcpy(m_output,output); 00369 } 00370 00371 void rlPcontrol::setError(const char *error) 00372 { 00373 if(m_error != NULL) delete [] m_error; 00374 m_error = new char [strlen(error)+1]; 00375 strcpy(m_error,error); 00376 } 00377 #endif 00378 00379 void rlPcontrol::setPriority(int pri) 00380 { 00381 #ifdef __VMS 00382 if(pri < 0) pri = 0; 00383 if(pri > 15) pri = 15; 00384 #endif 00385 #ifdef RLWIN32 00386 if(pri < 0) pri = 0; 00387 if(pri > 3) pri = 3; 00388 #endif 00389 prio = pri; 00390 } 00391 00392 int rlPcontrol::priority() 00393 { 00394 return prio; 00395 } 00396
1.7.5.1