Update license for libtest.
[awesomized/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 <signal.h>
29 #include <sys/types.h>
30 #include <sys/types.h>
31 #include <sys/wait.h>
32
33
34 #include <libtest/killpid.h>
35 #include <libtest/stream.h>
36
37 using namespace libtest;
38
39 bool kill_pid(pid_t pid_arg)
40 {
41 assert(pid_arg > 0);
42 if (pid_arg < 1)
43 {
44 Error << "Invalid pid:" << pid_arg;
45 return false;
46 }
47
48 if ((::kill(pid_arg, SIGTERM) == -1))
49 {
50 switch (errno)
51 {
52 case EPERM:
53 Error << "Does someone else have a process running locally for " << int(pid_arg) << "?";
54 return false;
55
56 case ESRCH:
57 Error << "Process " << int(pid_arg) << " not found.";
58 return false;
59
60 default:
61 case EINVAL:
62 Error << "kill() " << strerror(errno);
63 return false;
64 }
65 }
66
67 int status= 0;
68 if (waitpid(pid_arg, &status, 0) == -1)
69 {
70 switch (errno)
71 {
72 // Just means that the server has already gone away
73 case ECHILD:
74 {
75 return true;
76 }
77 }
78
79 Error << "Error occured while waitpid(" << strerror(errno) << ") on pid " << int(pid_arg);
80
81 return false;
82 }
83
84 return true;
85 }
86
87
88 pid_t kill_file(const std::string &filename)
89 {
90 pid_t ret= -1;
91 FILE *fp;
92
93 if (filename.empty())
94 return ret;
95
96 if ((fp= fopen(filename.c_str(), "r")))
97 {
98 char pid_buffer[1024];
99
100 char *ptr= fgets(pid_buffer, sizeof(pid_buffer), fp);
101 fclose(fp);
102
103 if (ptr)
104 {
105 pid_t pid= (pid_t)atoi(pid_buffer);
106 if (pid != 0)
107 {
108 kill_pid(pid);
109 unlink(filename.c_str()); // If this happens we may be dealing with a dead server that left its pid file.
110 }
111 }
112 }
113
114 return ret;
115 }
116
117 pid_t get_pid_from_file(const std::string &filename)
118 {
119 pid_t ret= -1;
120 FILE *fp;
121
122 if (filename.empty())
123 {
124 Error << "empty pid file";
125 return ret;
126 }
127
128 if ((fp= fopen(filename.c_str(), "r")))
129 {
130 char pid_buffer[1024];
131
132 char *ptr= fgets(pid_buffer, sizeof(pid_buffer), fp);
133 fclose(fp);
134
135 if (ptr)
136 {
137 ret= (pid_t)atoi(pid_buffer);
138 if (ret <= 0)
139 {
140 return ret;
141 }
142 }
143 }
144
145 return ret;
146 }