Merge in fixes for SASL.
[m6w6/libmemcached] / libtest / killpid.cc
1 /* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
2 *
3 * libtest
4 *
5 * Copyright (C) 2011 Data Differential, http://datadifferential.com/
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 3 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22
23 #include <libtest/common.h>
24
25 #include <cstdlib>
26 #include <cstring>
27 #include <iostream>
28 #include <sstream>
29 #include <signal.h>
30 #include <sys/types.h>
31 #include <sys/types.h>
32 #include <sys/wait.h>
33
34
35 #include <libtest/killpid.h>
36 #include <libtest/stream.h>
37
38 using namespace libtest;
39
40 bool kill_pid(pid_t pid_arg)
41 {
42 assert(pid_arg > 0);
43 if (pid_arg < 1)
44 {
45 Error << "Invalid pid:" << pid_arg;
46 return false;
47 }
48
49 if ((::kill(pid_arg, SIGTERM) == -1))
50 {
51 switch (errno)
52 {
53 case EPERM:
54 Error << "Does someone else have a process running locally for " << int(pid_arg) << "?";
55 return false;
56
57 case ESRCH:
58 Error << "Process " << int(pid_arg) << " not found.";
59 return false;
60
61 default:
62 case EINVAL:
63 Error << "kill() " << strerror(errno);
64 return false;
65 }
66 }
67
68 int status= 0;
69 if (waitpid(pid_arg, &status, 0) == -1)
70 {
71 switch (errno)
72 {
73 // Just means that the server has already gone away
74 case ECHILD:
75 {
76 return true;
77 }
78 }
79
80 Error << "Error occured while waitpid(" << strerror(errno) << ") on pid " << int(pid_arg);
81
82 return false;
83 }
84
85 return true;
86 }
87
88
89 pid_t kill_file(const std::string &filename)
90 {
91 pid_t ret= -1;
92 FILE *fp;
93
94 if (filename.empty())
95 return ret;
96
97 if ((fp= fopen(filename.c_str(), "r")))
98 {
99 char pid_buffer[1024];
100
101 char *ptr= fgets(pid_buffer, sizeof(pid_buffer), fp);
102 fclose(fp);
103
104 if (ptr)
105 {
106 pid_t pid= (pid_t)atoi(pid_buffer);
107 if (pid != 0)
108 {
109 kill_pid(pid);
110 unlink(filename.c_str()); // If this happens we may be dealing with a dead server that left its pid file.
111 }
112 }
113 }
114
115 return ret;
116 }
117
118 #define STRINGIFY(x) #x
119 #define TOSTRING(x) STRINGIFY(x)
120 #define LIBTEST_AT __FILE__ ":" TOSTRING(__LINE__)
121
122 pid_t get_pid_from_file(const std::string &filename, std::stringstream& error_message)
123 {
124 pid_t ret= -1;
125 FILE *fp;
126
127 if (filename.empty())
128 {
129 error_message << LIBTEST_AT << " empty pid file";
130 return ret;
131 }
132
133 if ((fp= fopen(filename.c_str(), "r")))
134 {
135 char pid_buffer[1024];
136
137 char *ptr= fgets(pid_buffer, sizeof(pid_buffer), fp);
138 fclose(fp);
139
140 if (ptr)
141 {
142 ret= (pid_t)atoi(pid_buffer);
143 if (ret < 1)
144 {
145 error_message << LIBTEST_AT << " Invalid pid was read from file " << filename;
146 }
147 }
148 else
149 {
150 error_message << LIBTEST_AT << " File " << filename << " was empty ";
151 }
152
153 return ret;
154 }
155 else
156 {
157 char buffer[1024];
158 char *current_directory= getcwd(buffer, sizeof(buffer));
159 error_message << "Error while opening " << current_directory << "/" << filename << " " << strerror(errno);
160 }
161
162 return ret;
163 }