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