]> git.lyx.org Git - lyx.git/blob - src/support/syscontr.C
change to use ostreams instead of string when writing files. fiddling with insettext...
[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         lyxerr << "Tick" << endl;
68         // check each entry of our list, if it's finished
69         ControlledCalls *prev = 0;
70         for (ControlledCalls *actCall= sysCalls; actCall; actCall= actCall->next)
71         {
72                 pid_t pid= actCall->call->getpid();
73                 int stat_loc;
74                 int waitrpid = waitpid(pid, &stat_loc, WNOHANG);
75                 if (waitrpid == -1) {
76                         lyxerr << "LyX: Error waiting for child:" 
77                                << strerror(errno) << endl;
78                 } else if (WIFEXITED(stat_loc) || WIFSIGNALED(stat_loc)) {
79                         if (WIFEXITED(stat_loc)) {
80                                 // Ok, the return value goes into retval.
81                                 actCall->call->setRetValue(WEXITSTATUS(stat_loc));
82                         } else {
83                                 // Child died, so pretend it returned 1
84                                 actCall->call->setRetValue(1);
85                         }
86                         // Callback and release
87                         actCall->call->callback();
88                         if (actCall == sysCalls) {
89                                 sysCalls = actCall->next;
90                         } else {
91                                 prev->next = actCall->next;
92                         }
93                         delete actCall;
94                         actCall = prev;
95                 } else if (WIFSTOPPED(stat_loc)) {
96                         lyxerr << "LyX: Child (pid: " << pid 
97                                << ") stopped on signal "
98                                << WSTOPSIG(stat_loc) 
99                                << ". Waiting for child to finish." << endl;
100                 } else {
101                         lyxerr << "LyX: Something rotten happened while "
102                                 "waiting for child " << pid << endl;
103                 }
104                 prev = actCall;
105         }
106 }