killpid.cc 4.0 KB

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