Merge lp:~tangent-org/libmemcached/1.0-build Build: jenkins-Libmemcached-1.0-64
[awesomized/libmemcached] / util / pidfile.cc
index 14b28479f1eee459dd003018388b1d12bea756bc..c6c5b4401b64698c0b24e0269811b343cffff23c 100644 (file)
 #include <cstdio>
 #include <cstdlib>
 #include <cstring>
-#include <errno.h>
+#include <cerrno>
 #include <fcntl.h>
 #include <iostream>
+#include <sstream>
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <unistd.h>
+
+extern "C" {
+
+  char pid_file[1024 * 4]= { 0 };
+
+  static void remove_pidfile(void)
+  {
+    if (pid_file[0])
+    {
+      if (unlink(pid_file) == -1)
+      {
+        std::cerr << "Could not remove pidfile: " << pid_file << "(" << strerror(errno) << ")" << std::endl;
+      }
+
+      pid_file[0]= 0;
+    }
+  }
+
+}
 
 namespace datadifferential {
 namespace util {
@@ -60,45 +81,79 @@ Pidfile::Pidfile(const std::string &arg) :
 
 Pidfile::~Pidfile()
 {
-  if (not _filename.empty() and (unlink(_filename.c_str()) == -1))
+  if (not _filename.empty())
   {
-    _error_message+= "Could not remove the pid file: ";
-    _error_message+= _filename;
+    if (access(_filename.c_str(), F_OK) == -1)
+    {
+      std::stringstream error_stream;
+      error_stream << "Could not access the pid file: " << _filename << "(" << strerror(errno) << ")";
+      _error_message= error_stream.str();
+    }
+    else if (unlink(_filename.c_str()) == -1)
+    {
+      std::stringstream error_stream;
+      error_stream << "Could not remove the pid file: " << _filename << "(" << strerror(errno) << ")";
+      _error_message= error_stream.str();
+    }
   }
+  pid_file[0]= 0;
 }
 
 bool Pidfile::create()
 {
   if (_filename.empty())
+  {
     return true;
+  }
+
+  if (access(_filename.c_str(), F_OK) == 0)
+  {
+    if (unlink(_filename.c_str()) == -1)
+    {
+      std::stringstream error_stream;
+      error_stream << "Unable to remove exisiting file:" << _filename << "(" << strerror(errno) << ")";
+      _error_message= error_stream.str();
+
+      return false;
+    }
+  }
+
+  int oflags= O_CREAT|O_WRONLY|O_TRUNC;
+#ifdef HAVE_O_CLOEXEC
+  oflags= oflags | O_CLOEXEC;
+#endif
 
   int file;
-  if ((file = open(_filename.c_str(), O_CREAT|O_WRONLY|O_TRUNC, S_IRWXU|S_IRGRP|S_IROTH)) < 0)
+  if ((file = open(_filename.c_str(), oflags, S_IRWXU|S_IRGRP|S_IROTH)) < 0)
   {
-    _error_message+= "Could not open pid file for writing: "; 
-    _error_message+= _filename;
+    std::stringstream error_stream;
+    error_stream << "Could not open pid file for writing: " << _filename << "(" << strerror(errno) << ")";
+    _error_message= error_stream.str();
+    
     return false;
   }
 
   char buffer[BUFSIZ];
-
   unsigned long temp= static_cast<unsigned long>(getpid());
   int length= snprintf(buffer, sizeof(buffer), "%lu\n", temp);
-
   if (write(file, buffer, length) != length)
   { 
-    _error_message+= "Could not write pid to file: "; 
-    _error_message+= _filename;
+    std::stringstream error_stream;
+    error_stream << "Could not write pid to file: " << _filename << "(" << strerror(errno) << ")";
+    _error_message= error_stream.str();
+    close(file);
 
     return false;
   }
 
-  if (close(file < 0))
+  if (close(file) < 0)
   {
     _error_message+= "Could not close() file after writing pid to it: "; 
     _error_message+= _filename;
     return false;
   }
+  snprintf(pid_file, sizeof(pid_file), "%s", _filename.c_str());
+  atexit(remove_pidfile);
 
   return true;
 }