rllib  1
rlpcontrol.cpp
Go to the documentation of this file.
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 
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines