]> git.lyx.org Git - lyx.git/blob - src/support/syscontr.C
more changes read the ChangeLog
[lyx.git] / src / support / syscontr.C
1 #include <config.h>
2
3 #include <cerrno>
4 #include <cstdlib>
5 #include <unistd.h>
6 #include <sys/wait.h>
7 #include "syscontr.h"
8 #include "syscall.h"
9 #include "debug.h"
10
11 #ifdef __GNUG__
12 #pragma implementation
13 #endif
14
15
16 using std::endl;
17
18 //
19 // Default constructor
20 //
21
22 SystemcallsSingletoncontroller::SystemcallsSingletoncontroller() 
23 {
24        sysCalls = 0;
25 }
26
27 //
28 // Destructor
29 // 
30 // destroy structs for leaving program
31 // open question: should we stop childs here?
32 // Asger says no: I like to have my xdvi open after closing LyX. Maybe
33 // I want to print or something.
34
35 SystemcallsSingletoncontroller::~SystemcallsSingletoncontroller()
36 {
37        ControlledCalls *next;
38        while (sysCalls)
39        {
40                next = sysCalls->next;
41                delete sysCalls;
42                sysCalls = next;
43        }
44        
45 }
46
47 //
48 // Add child process information into controlled list
49 //
50
51 void 
52 SystemcallsSingletoncontroller::addCall(Systemcalls const &newcall) {
53        ControlledCalls * newCall = new ControlledCalls;
54        if (newCall == 0) // sorry, no idea
55                return;
56        newCall->next = sysCalls;
57        newCall->call = new Systemcalls(newcall);
58        sysCalls = newCall;
59 }
60
61 // 
62 // Timer-call
63 // 
64 // Check list, if there is a stopped child. If yes, call-back.
65 //
66
67 void 
68 SystemcallsSingletoncontroller::timer() {
69         lyxerr << "Tick" << endl;
70         // check each entry of our list, if it's finished
71         ControlledCalls *prev = 0;
72         for (ControlledCalls *actCall= sysCalls; actCall; actCall= actCall->next)
73         {
74                 pid_t pid= actCall->call->getpid();
75                 int stat_loc;
76                 int waitrpid = waitpid(pid, &stat_loc, WNOHANG);
77                 if (waitrpid == -1) {
78                         lyxerr << "LyX: Error waiting for child:" 
79                                << strerror(errno) << endl;
80                 } else if (WIFEXITED(stat_loc) || WIFSIGNALED(stat_loc)) {
81                         if (WIFEXITED(stat_loc)) {
82                                 // Ok, the return value goes into retval.
83                                 actCall->call->setRetValue(WEXITSTATUS(stat_loc));
84                         } else {
85                                 // Child died, so pretend it returned 1
86                                 actCall->call->setRetValue(1);
87                         }
88                         // Callback and release
89                         actCall->call->callback();
90                         if (actCall == sysCalls) {
91                                 sysCalls = actCall->next;
92                         } else {
93                                 prev->next = actCall->next;
94                         }
95                         delete actCall;
96                         actCall = prev;
97                 } else if (WIFSTOPPED(stat_loc)) {
98                         lyxerr << "LyX: Child (pid: " << pid 
99                                << ") stopped on signal "
100                                << WSTOPSIG(stat_loc) 
101                                << ". Waiting for child to finish." << endl;
102                 } else {
103                         lyxerr << "LyX: Something rotten happened while "
104                                 "waiting for child " << pid << endl;
105                 }
106                 prev = actCall;
107         }
108 }