4 * This file is part of LyX, the document processor.
5 * Licence details can be found in the file COPYING.
7 * \author Asger Alstrup
9 * Interface cleaned up by
10 * \author Angus Leeming
12 * Full author contact details are available in file CREDITS.
14 * An instance of Class Forkedcall represents a single child process.
16 * Class Forkedcall uses fork() and execvp() to lauch the child process.
18 * Once launched, control is returned immediately to the parent process
19 * but a Signal can be emitted upon completion of the child.
21 * The child process is not killed when the Forkedcall instance goes out of
22 * scope, but it can be killed by an explicit invocation of the kill() member
29 #include <boost/shared_ptr.hpp>
30 #include <boost/signal.hpp>
32 #include <sys/types.h>
34 // pid_t isn't defined by the stdlibs that ship with MSVC.
35 #if defined (_WIN32) && defined(_MSC_VER)
56 virtual ~ForkedProcess() {}
58 virtual boost::shared_ptr<ForkedProcess> clone() const = 0;
60 /** A SignalType signal is can be emitted once the forked process
61 * has finished. It passes:
62 * the PID of the child and;
63 * the return value from the child.
65 * We use a signal rather than simply a callback function so that
66 * we can return easily to C++ methods, rather than just globally
67 * accessible functions.
69 typedef boost::signal<void(pid_t, int)> SignalType;
71 /** The signal is connected in the calling routine to the desired
72 * slot. We pass a shared_ptr rather than a reference to the signal
73 * because it is eminently possible for the instance of the calling
74 * class (and hence the signal) to be destructed before the forked
77 * It doesn't matter if the slot disappears, SigC takes care of that.
79 typedef boost::shared_ptr<SignalType> SignalTypePtr;
81 /** Invoking the following methods makes sense only if the command
82 * is running asynchronously!
85 /** gets the PID of the child process.
88 pid_t pid() const { return pid_; }
95 /** Set the return value of the child process.
98 void setRetValue(int r) { retval_ = r; }
100 /// Returns the identifying command (for display in the GUI perhaps).
101 std::string const & command() const { return command_; }
103 /// is the process running ?
104 bool running() const;
106 /** Kill child prematurely.
107 * First, a SIGHUP is sent to the child.
108 * If that does not end the child process within "tolerance"
109 * seconds, the SIGKILL signal is sent to the child.
110 * When the child is dead, the callback is called.
112 void kill(int tolerance = 5);
115 /** Spawn the child process.
116 * Returns returncode from child.
118 int run(Starttype type);
120 /// Callback function
121 SignalTypePtr signal_;
123 /// identifying command (for display in the GUI perhaps).
124 std::string command_;
126 /// Process ID of child
129 /// Return value from child
132 /// generate child in background
133 virtual int generateChild() = 0;
135 /// Wait for child process to finish. Updates returncode from child.
140 class Forkedcall : public ForkedProcess {
143 virtual boost::shared_ptr<ForkedProcess> clone() const {
144 return boost::shared_ptr<ForkedProcess>(new Forkedcall(*this));
147 /** Start the child process.
149 * The command "what" is passed to execvp() for execution.
151 * There are two startscript commands available. They differ in that
152 * the second receives a signal that is executed on completion of
153 * the command. This makes sense only for a command executed
154 * in the background, ie DontWait.
156 * The other startscript command can be executed either blocking
157 * or non-blocking, but no signal will be emitted on finishing.
159 int startscript(Starttype, std::string const & what);
162 int startscript(std::string const & what, SignalTypePtr);
166 virtual int generateChild();
169 } // namespace support
172 #endif // FORKEDCALL_H