]> git.lyx.org Git - lyx.git/blob - src/support/forkedcall.h
Sigh, commit the right version of the Makefile. I was sure I had carefully
[lyx.git] / src / support / forkedcall.h
1 // -*- C++ -*-
2 /**
3  *  \file forkedcall.h
4  *  Copyright 2002 the LyX Team
5  *  Read the file COPYING
6  *
7  * \author Asger Alstrup
8  *
9  * Interface cleaned up by
10  * \author Angus Leeming <a.leeming@ic.ac.uk>
11  *
12  * An instance of Class Forkedcall represents a single child process.
13  *
14  * Class Forkedcall uses fork() and execvp() to lauch the child process.
15  *
16  * Once launched, control is returned immediately to the parent process
17  * but a Signal can be emitted upon completion of the child.
18  *
19  * The child process is not killed when the Forkedcall instance goes out of
20  * scope, but it can be killed by an explicit invocation of the kill() member
21  * function.
22  */
23
24 #ifndef FORKEDCALL_H
25 #define FORKEDCALL_H
26
27 #ifdef __GNUG__
28 #pragma interface
29 #endif
30
31 #include "LString.h"
32
33 #include <boost/shared_ptr.hpp>
34
35 #include <sigc++/signal_system.h>
36
37 #include <sys/types.h>
38
39 class Forkedcall {
40 public:
41         ///
42         enum Starttype {
43                 ///
44                 Wait,
45                 ///
46                 DontWait
47         };
48
49         ///
50         Forkedcall();
51
52         /** Start the child process.
53          *
54          *  The command "what" is passed to fork() for execution.
55          *
56          *  There are two startscript commands available. They differ in that
57          *  the second receives a signal that is executed on completion of
58          *  the command. This makes sense only for a command executed
59          *  in the background, ie DontWait.
60          *
61          *  The other startscript command can be executed either blocking
62          *  or non-blocking, but no signal will be emitted on finishing.
63          */
64         int startscript(Starttype, string const & what);
65
66         /** A SignalType signal is can be emitted once the forked process
67          *  has finished. It passes:
68          *  the commandline string;
69          *  the PID of the child and;
70          *  the return value from the child.
71          *
72          *  We use a signal rather than simply a callback function so that
73          *  we can return easily to C++ methods, rather than just globally
74          *  accessible functions.
75          */
76         typedef SigC::Signal3<void, string const &, pid_t, int> SignalType;
77
78         /** The signal is connected in the calling routine to the desired
79          *  slot. We pass a shared_ptr rather than a reference to the signal
80          *  because it is eminently possible for the instance of the calling
81          *  class (and hence the signal) to be destructed before the forked
82          *  call is complete.
83          *
84          *  It doesn't matter if the slot disappears, SigC takes care of that.
85          */
86         typedef boost::shared_ptr<SignalType> SignalTypePtr;
87
88         ///
89         int startscript(string const & what, SignalTypePtr);
90
91         /** Invoking the following methods makes sense only if the command
92          *  is running asynchronously!
93          */
94
95         /** gets the PID of the child process.
96          *  Used by the timer.
97          */
98         pid_t pid() const { return pid_; }
99
100         /** Emit the signal.
101          *  Used by the timer.
102          */
103         void emitSignal();
104
105         /** Set the return value of the child process.
106          *  Used by the timer.
107          */
108         void setRetValue(int r) { retval_ = r; }
109
110         /** Kill child prematurely.
111          *  First, a SIGHUP is sent to the child.
112          *  If that does not end the child process within "tolerance"
113          *  seconds, the SIGKILL signal is sent to the child.
114          *  When the child is dead, the callback is called.
115          */
116         void kill(int tolerance = 5);
117         ///
118         string const & command() const { return command_; }
119
120 private:
121         /// Callback function
122         SignalTypePtr signal_;
123
124         /// Commmand line
125         string command_;
126
127         /// Process ID of child
128         pid_t pid_;
129
130         /// Return value from child
131         int retval_;
132
133         ///
134         pid_t generateChild();
135
136         /// Wait for child process to finish. Updates returncode from child.
137         int waitForChild();
138 };
139
140 #endif // FORKEDCALL_H