ChildProcess.hpp 3.36 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/******************************************************************************
 *
 * This file is part of the Castor project.
 * See http://castor.web.cern.ch/castor
 *
 * Copyright (C) 2003  CERN
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 * 
 *
 * @author Castor Dev team, castor-dev@cern.ch
 *****************************************************************************/
#pragma once

25
#include "castor/exception/Errnum.hpp"
26
#include "castor/exception/Exception.hpp"
27
28
29
30
#include <unistd.h>


namespace castor {
31
32
namespace server {

33
34
35
36
37
38
39
40
41
42
43
44
45
  /**
   * A class allowing forking of a child process, and subsequent follow up
   * of the child process. Status check, killing, return code collection.
   */
  class ChildProcess {
  public:
    /**
     * Helper functor for child to clean up unneeded parent resources 
     * after forking.
     */
    class Cleanup {
    public:
      virtual void operator() () = 0;
46
      virtual ~Cleanup() {}
47
48
49
50
    };
    /**
     * Exceptions for wrong usage.
     */
51
    class ProcessStillRunning: public castor::exception::Exception {
52
53
    public:
      ProcessStillRunning(const std::string & what = "Process still running"):
54
      castor::exception::Exception::Exception(what) {}
55
56
    };
    
57
    class ProcessNeverStarted: public castor::exception::Exception {
58
59
    public:
      ProcessNeverStarted(const std::string & what = "Process never started"):
60
      castor::exception::Exception::Exception(what) {}
61
62
    };
    
63
    class ProcessWasKilled: public castor::exception::Exception {
64
65
    public:
      ProcessWasKilled(const std::string & what = "Process was killed"):
66
      castor::exception::Exception::Exception(what) {}
67
68
69
70
    };
    
    ChildProcess(): m_started(false), m_finished(false), m_exited(false),
      m_wasKilled(false) {}
71
72
    /* Clean up leftover child processes (hopefully not useful) */
    virtual ~ChildProcess() { if (m_started && !m_finished) kill(); };
73
74
    /** start function, taking as an argument a callback for parent's
     * resources cleanup. A child process can only be fired once. */
75
    void start(Cleanup & cleanup) ;
76
    /** Check running status */
77
    bool running() ;
78
    /** Wait for completion */
79
    void wait() ;
80
    /** collect exit code */
81
    int exitCode() ;
82
    /** kill */
83
    void kill() ;
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
  private:
    pid_t m_pid;
    /** Was the process started? */
    bool m_started;
    /** As the process finished? */
    bool m_finished;
    /** Did the process exit cleanly? */
    bool m_exited;
    /** Was the process killed? */
    bool m_wasKilled;
    int m_exitCode;
    /** The function actually being run in the child process. The value returned
     * by run() will be the exit code of the process (if we get that far) */
    virtual int run() = 0;
    void parseStatus(int status);
  };
100
}}