source: box/trunk/lib/server/ServerControl.cpp @ 2506

Revision 2506, 3.7 KB checked in by martin, 3 years ago (diff)

Fixes for gcc 4.4.

Line 
1#include "Box.h"
2
3#include <errno.h>
4#include <stdio.h>
5
6#ifdef HAVE_SYS_TYPES_H
7        #include <sys/types.h>
8#endif
9
10#ifdef HAVE_SYS_WAIT_H
11        #include <sys/wait.h>
12#endif
13
14#ifdef HAVE_SIGNAL_H
15        #include <signal.h>
16#endif
17
18#include "ServerControl.h"
19#include "Test.h"
20
21#ifdef WIN32
22
23#include "WinNamedPipeStream.h"
24#include "IOStreamGetLine.h"
25#include "BoxPortsAndFiles.h"
26
27static std::string sPipeName;
28
29void SetNamedPipeName(const std::string& rPipeName)
30{
31        sPipeName = rPipeName;
32}
33
34bool SendCommands(const std::string& rCmd)
35{
36        WinNamedPipeStream connection;
37
38        try
39        {
40                connection.Connect(sPipeName);
41        }
42        catch(...)
43        {
44                BOX_ERROR("Failed to connect to daemon control socket");
45                return false;
46        }
47
48        // For receiving data
49        IOStreamGetLine getLine(connection);
50       
51        // Wait for the configuration summary
52        std::string configSummary;
53        if(!getLine.GetLine(configSummary))
54        {
55                BOX_ERROR("Failed to receive configuration summary from daemon");
56                return false;
57        }
58
59        // Was the connection rejected by the server?
60        if(getLine.IsEOF())
61        {
62                BOX_ERROR("Server rejected the connection");
63                return false;
64        }
65
66        // Decode it
67        int autoBackup, updateStoreInterval, minimumFileAge, maxUploadWait;
68        if(::sscanf(configSummary.c_str(), "bbackupd: %d %d %d %d", 
69                        &autoBackup, &updateStoreInterval, 
70                        &minimumFileAge, &maxUploadWait) != 4)
71        {
72                BOX_ERROR("Config summary didn't decode");
73                return false;
74        }
75
76        std::string cmds;
77        bool expectResponse;
78
79        if (rCmd != "")
80        {
81                cmds = rCmd;
82                cmds += "\nquit\n";
83                expectResponse = true;
84        }
85        else
86        {
87                cmds = "quit\n";
88                expectResponse = false;
89        }
90       
91        connection.Write(cmds.c_str(), cmds.size());
92       
93        // Read the response
94        std::string line;
95        bool statusOk = !expectResponse;
96
97        while (expectResponse && !getLine.IsEOF() && getLine.GetLine(line))
98        {
99                // Is this an OK or error line?
100                if (line == "ok")
101                {
102                        statusOk = true;
103                }
104                else if (line == "error")
105                {
106                        BOX_ERROR(rCmd);
107                        break;
108                }
109                else
110                {
111                        BOX_WARNING("Unexpected response to command '" <<
112                                rCmd << "': " << line)
113                }
114        }
115       
116        return statusOk;
117}
118
119bool HUPServer(int pid)
120{
121        return SendCommands("reload");
122}
123
124bool KillServerInternal(int pid)
125{
126        HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, false, pid);
127        if (hProcess == NULL)
128        {
129                BOX_ERROR("Failed to open process " << pid << ": " <<
130                        GetErrorMessage(GetLastError()));
131                return false;
132        }
133
134        if (!TerminateProcess(hProcess, 1))
135        {
136                BOX_ERROR("Failed to terminate process " << pid << ": " <<
137                        GetErrorMessage(GetLastError()));
138                CloseHandle(hProcess);
139                return false;
140        }
141
142        CloseHandle(hProcess);
143        return true;
144}
145
146#else // !WIN32
147
148bool HUPServer(int pid)
149{
150        if(pid == 0) return false;
151        return ::kill(pid, SIGHUP) == 0;
152}
153
154bool KillServerInternal(int pid)
155{
156        if(pid == 0 || pid == -1) return false;
157        bool killed = (::kill(pid, SIGTERM) == 0);
158        if (!killed)
159        {
160                BOX_LOG_SYS_ERROR("Failed to kill process " << pid);
161        }
162        TEST_THAT(killed);
163        return killed;
164}
165
166#endif // WIN32
167
168bool KillServer(int pid, bool WaitForProcess)
169{
170        if (!KillServerInternal(pid))
171        {
172                return false;
173        }
174
175        #ifdef HAVE_WAITPID
176        if (WaitForProcess)
177        {
178                int status, result;
179
180                result = waitpid(pid, &status, 0);
181                if (result != pid)
182                {
183                        BOX_LOG_SYS_ERROR("waitpid failed");
184                }
185                TEST_THAT(result == pid);
186
187                TEST_THAT(WIFEXITED(status));
188                if (WIFEXITED(status))
189                {
190                        if (WEXITSTATUS(status) != 0)
191                        {
192                                BOX_WARNING("process exited with code " <<
193                                        WEXITSTATUS(status));
194                        }
195                        TEST_THAT(WEXITSTATUS(status) == 0);
196                }
197        }
198        #endif
199
200        for (int i = 0; i < 30; i++)
201        {
202                if (i == 0) 
203                {
204                        printf("Waiting for server to die (pid %d): ", pid);
205                }
206
207                printf(".");
208                fflush(stdout);
209
210                if (!ServerIsAlive(pid)) break;
211                ::sleep(1);
212                if (!ServerIsAlive(pid)) break;
213        }
214
215        if (!ServerIsAlive(pid))
216        {
217                printf(" done.\n");
218        }
219        else
220        {
221                printf(" failed!\n");
222        }
223
224        fflush(stdout);
225
226        return !ServerIsAlive(pid);
227}
228
Note: See TracBrowser for help on using the repository browser.