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