LCOV - code coverage report
Current view: top level - okssystem/src - Process.cpp (source / functions) Coverage Total Hit
Test: code.result Lines: 0.0 % 86 0
Test Date: 2026-07-12 15:23:06 Functions: 0.0 % 20 0

            Line data    Source code
       1              : // DUNE DAQ modification notice:
       2              : // This file has been modified from the original ATLAS system source for the DUNE DAQ project.
       3              : // Fork baseline commit: system-00-00-20 (2020-09-25).
       4              : // Renamed since fork: yes (from src/Process.cxx to src/Process.cpp).
       5              : 
       6              : /*
       7              :  *  Process.cxx
       8              :  *  OksSystem 
       9              :  *
      10              :  *  Created by Matthias Wiesmann on 18.01.05.
      11              :  *  Copyright 2005 CERN. All rights reserved.
      12              :  *
      13              :  */
      14              :  
      15              : #include <sys/wait.h>
      16              : #include <sys/types.h>
      17              : #include <unistd.h>
      18              : #include <sysexits.h>
      19              : 
      20              : #include <iostream>
      21              : #include <sstream>
      22              : 
      23              : #include "ers/ers.hpp"
      24              : 
      25              : #include "okssystem/exceptions.hpp"
      26              : #include "okssystem/Process.hpp"
      27              : 
      28              : 
      29              : const int OksSystem::Process::TEST_BASE_VALUE = 182;/**< Lowest value for test manager result code  */
      30              : const int OksSystem::Process::TEST_MAX_VALUE = 186; /**< Highest value for test manager result code */
      31              : 
      32              : const int OksSystem::Process::TERMINATION_WAIT = 100000; /**< Wait time before deciding a termination signal did not work (in nanoseconds) */
      33              : 
      34              : const char * const OksSystem::Process::SYS_EXITS_NAMES[] = { "command line usage error", "data format error", "cannot open input", "addressee unknown", "host name unknown", "service unavailable", "internal software error", "okssystem error", 
      35              :     "critical OS file missing", "can't create (user) output file", "input/output error", "temp failure; user is invited to retry", "remote error in protocol", "permission denied ", "configuration error" };
      36              : const char * const OksSystem::Process::TEST_EXITS_NAMES[] = { "undefined test", "test failed", "test unresolved", "test untested", "unsupported test" };
      37              : const char * const OksSystem::Process::OK_EXIT_NAME = "ok";
      38              : 
      39              : OksSystem::Process *OksSystem::Process::s_instance = 0;
      40              : 
      41              : /** Gives textual representation of exit values. 
      42              :   * This method recognises return codes from \c sysexits and the values returned by the text-manager 
      43              :   * \param return_value the integer returned by a program
      44              :   * \return a pointer to the string desribing the code, or a null pointer if the code is not recognised
      45              :   */
      46              : 
      47            0 : const char* OksSystem::Process::exit_text(int return_value) {
      48            0 :     if ( 0==return_value) return OK_EXIT_NAME;
      49            0 :     if ((return_value >= EX__BASE)  && (return_value <= EX__MAX)) return SYS_EXITS_NAMES[return_value-EX__BASE];
      50            0 :     if ((return_value >= TEST_BASE_VALUE) && (return_value <= TEST_MAX_VALUE)) return TEST_EXITS_NAMES[return_value-TEST_BASE_VALUE];
      51              :     return 0;
      52              : } // return_text
      53              : 
      54              : /** Builds a pretty string for an exit value 
      55              :   * \param return_value the integer returned by a program
      56              :   * \return if the code is recognised by \c exit_text, this text and the number between parenthesis 
      57              :   *         if not, the \c return_value converter into a string 
      58              :   */
      59              : 
      60            0 : std::string OksSystem::Process::exit_pretty(int return_value) {
      61            0 :     std::ostringstream stream;
      62            0 :     const char* text = OksSystem::Process::exit_text(return_value);
      63            0 :     if (text) {
      64            0 :         stream << text << '(' << return_value << ')';
      65              :     } else {
      66            0 :         stream << return_value ;
      67              :     }
      68            0 :     return stream.str(); 
      69            0 : } // exit_string
      70              : 
      71              : 
      72              : /** Default current process instance 
      73              :   * If needed the instance is created 
      74              :   * \return singleton instance for current process
      75              :   */
      76              : 
      77            0 : const OksSystem::Process *OksSystem::Process::instance() throw() {
      78            0 :     if (0==s_instance) {
      79            0 :         s_instance = new OksSystem::Process(); 
      80              :     } // if
      81            0 :     return s_instance;
      82              : } // instance
      83              : 
      84              : 
      85              : /** Sets the process name of the current process 
      86              :   */
      87              : 
      88            0 : void OksSystem::Process::set_name(const std::string &name) throw() {
      89            0 :     (void) instance();
      90            0 :     s_instance->m_process_name = name;
      91            0 : } // set_name
      92              : 
      93              : 
      94              : /** Constructor from current process 
      95              :  *  For the current process, the singleton factory method \c instance should be used 
      96              :  */
      97              : 
      98            0 : OksSystem::Process::Process() {
      99            0 :     m_process_id = ::getpid();
     100            0 : } // Process
     101              : 
     102              : /** Copy constructor 
     103              :   * \param other original instance 
     104              :   */
     105              : 
     106            0 : OksSystem::Process::Process(const Process &other) {
     107            0 :     m_process_id = other.m_process_id;
     108            0 :     m_process_name = other.m_process_name;
     109            0 : } // Process
     110              : 
     111              : /** Constructor for pid
     112              :   * \param id pid of the process
     113              :   */
     114              : 
     115            0 : OksSystem::Process::Process(pid_t id){
     116            0 :     m_process_id = id;
     117            0 : } // Process 
     118              : 
     119              : /** Constructor from pid and process name 
     120              :   * \param id pid of the process 
     121              :   * \param name display name of the process 
     122              :   */
     123              : 
     124            0 : OksSystem::Process::Process(pid_t id, const std::string &name) {
     125            0 :     m_process_id = id;
     126            0 :     m_process_name = name;
     127            0 : } 
     128              : 
     129              : 
     130              : /** Destructor 
     131              :   */
     132              : 
     133            0 : OksSystem::Process::~Process() throw() {
     134            0 :     m_process_id = 0;
     135            0 : } // ~Process
     136              : 
     137              : /** Cast operator - converts to process-id 
     138              :   */
     139              : 
     140            0 : OksSystem::Process::operator pid_t() const throw() {
     141            0 :     return m_process_id;
     142              : } // operator pid_t
     143              : 
     144              : 
     145              : /** Waits for a process to terminate. 
     146              :   * If the process terminates normally, the return value is the termination status of the process. 
     147              :   * If the process stops or is signaled, an SignalIssue is thrown. 
     148              :   * \return the termination status of the process 
     149              :   */
     150              : 
     151            0 : int OksSystem::Process::join(bool throw_non_zero) const {
     152            0 :     ERS_PRECONDITION(! equals(*instance())); 
     153            0 :     int status;
     154            0 :     errno = 0;
     155            0 :     pid_t pid = ::waitpid(m_process_id,&status,0); 
     156            0 :     if (pid!=m_process_id) {
     157            0 :         std::string message = "on process " + this->to_string();
     158            0 :         throw OksSystem::OksSystemCallIssue( ERS_HERE, errno, "waitpid", message.c_str() ); 
     159            0 :     } // if 
     160            0 :     if (WIFEXITED(status)) {
     161            0 :         int exit_status = WEXITSTATUS(status);
     162            0 :         if ((throw_non_zero==false) || (exit_status==0)) return exit_status;
     163            0 :         throw OksSystem::TerminationIssue(ERS_HERE, errno, exit_status);
     164              :     } // exit status
     165            0 :     if (WIFSIGNALED(status)) throw OksSystem::SignalIssue(ERS_HERE,errno,WTERMSIG(status));
     166            0 :     if (WIFSTOPPED(status)) throw OksSystem::SignalIssue(ERS_HERE,errno,WSTOPSIG(status));
     167            0 :     return WEXITSTATUS(status);
     168              : } // join
     169              : 
     170              : /** Sends a signal to the process 
     171              :   * \param signal_number number of the signal 
     172              :   */
     173              : 
     174            0 : void OksSystem::Process::signal(int signal_number) const {
     175            0 :     const int status = ::kill(m_process_id,signal_number);
     176            0 :     if (status < 0) {
     177            0 :       std::string message = "on process " + this->to_string();
     178            0 :       throw OksSystem::OksSystemCallIssue(ERS_HERE, errno, "kill", message.c_str());
     179            0 :     }
     180            0 : } // signal
     181              : 
     182              : /** Checks if the process actually exists on the host
     183              :   * \return true if the process exists 
     184              :   * \note currently the check is done by sending signal 0 to the process
     185              :   *       in case of failure, we know process does not exist 
     186              :   */
     187              : 
     188            0 : bool OksSystem::Process::exists() const {
     189            0 :     const int status = ::kill(m_process_id,0);
     190            0 :     return (status>=0);
     191              : } // exists
     192              : 
     193              : /** Checks if two process are equal 
     194              :   * \param other the process to compare this process to
     195              :   * \return true if both proceses are equal (same pid).
     196              :   */
     197              : 
     198            0 : bool OksSystem::Process::equals(const Process &other) const throw() {
     199            0 :     return m_process_id == other.m_process_id;
     200              : } // equals
     201              : 
     202              : /** Terminates a process 
     203              :   * Termination is implemented by
     204              :   * \li sending the TERM signal
     205              :   */
     206              : 
     207            0 : void OksSystem::Process::terminate() const {
     208              :   /*
     209              :     struct timespec wait_time;
     210              :     struct timespec remain_time;
     211              :     wait_time.tv_sec = 0;
     212              :     wait_time.tv_nsec = TERMINATION_WAIT;
     213              :   */
     214            0 :     if (exists()) {
     215            0 :         signal(SIGTERM);
     216              :     }
     217            0 :     return;
     218              : } 
     219              : 
     220              : /* This is a piece of crap 
     221              :     nanosleep(&wait_time,&remain_time); 
     222              :     if (exists()) {
     223              :         signal(SIGQUIT);
     224              :     } else {
     225              :         return;
     226              :     } //
     227              :     nanosleep(&wait_time,&remain_time); 
     228              :     if (exists()) {
     229              :         signal(SIGKILL);
     230              :     } // exists
     231              : } // terminate
     232              : */
     233              : /** Builds a string description of the process 
     234              :   * \return textual description
     235              :   */
     236              : 
     237            0 : std::string OksSystem::Process::to_string() const throw() {
     238            0 :     std::ostringstream stream;
     239            0 :     if (! m_process_name.empty()) {
     240            0 :         stream << m_process_name << ' ';
     241              :     } 
     242            0 :     stream << "pid: " << m_process_id;
     243            0 :     return stream.str(); 
     244            0 : } // to_string
     245              : 
     246              : /** \return the process id for the process 
     247              :   */
     248              : 
     249            0 : pid_t OksSystem::Process::process_id() const throw() { return m_process_id;} 
     250              : 
     251              : /** Streaming operator
     252              :   * \param out destination stream
     253              :   * \param proc the process to stream 
     254              :   * \see Process::to_string()
     255              :   */
     256              : 
     257            0 : std::ostream& operator<<(std::ostream& out, const OksSystem::Process &proc) {
     258            0 :     out << proc.to_string();
     259            0 :     return out;
     260              : } // operator<<
     261              : 
     262              : /** Comparison operator 
     263              :   * \param a first process to compare
     264              :   * \param b second process to compare 
     265              :   * \return true if they are equal 
     266              :   * \see OksSystem::Process::equals
     267              :   */
     268              : 
     269            0 : bool operator ==(const OksSystem::Process &a, const OksSystem::Process &b)  throw() {
     270            0 :     return a.equals(b);
     271              : } // operator ==
     272              : 
     273              : /** Comparison operator 
     274              :   * \param a first process to compare
     275              :   * \param b second process to compare 
     276              :   * \return false if they are equal 
     277              :   * \see OksSystem::Process::equals
     278              :   */
     279              : 
     280            0 : bool operator !=(const OksSystem::Process &a, const OksSystem::Process &b)  throw() {
     281            0 :     return ! a.equals(b); 
     282              : } // operator !=
     283              : 
     284              : 
        

Generated by: LCOV version 2.0-1