Switch to side-by-side view

--- a/src/utils/pathut.cpp
+++ b/src/utils/pathut.cpp
@@ -26,7 +26,11 @@
 #include <sys/param.h>
 #include <pwd.h>
 #include <math.h>
+#include <errno.h>
 #include <sys/types.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+
 // Let's include all files where statfs can be defined and hope for no
 // conflict...
 #ifdef HAVE_SYS_MOUNT_H 
@@ -452,6 +456,96 @@
     return true;
 }
 
+
+Pidfile::~Pidfile()
+{
+    if (m_fd >= 0)
+	::close(m_fd);
+    m_fd = -1;
+}
+
+pid_t Pidfile::read_pid()
+{
+    int fd = ::open(m_path.c_str(), O_RDONLY);
+    if (fd == -1)
+	return (pid_t)-1;
+
+    char buf[16];
+    int error;
+    int i = read(fd, buf, sizeof(buf) - 1);
+    error = errno;
+    ::close(fd);
+    if (i <= 0)
+	return (pid_t)-1;
+    buf[i] = '\0';
+    char *endptr;
+    pid_t pid = strtol(buf, &endptr, 10);
+    if (endptr != &buf[i])
+	return (pid_t)-1;
+    return pid;
+}
+
+int Pidfile::flopen()
+{
+    const char *path = m_path.c_str();
+    int operation = LOCK_EX | LOCK_NB;
+    if ((m_fd = ::open(path, O_RDWR|O_CREAT, 0644)) == -1) {
+	m_reason = "Open failed";
+	return -1;
+    }
+    if (flock(m_fd, operation) == -1) {
+	int serrno = errno;
+	(void)::close(m_fd);
+	errno = serrno;
+	m_reason = "flock failed";
+	return -1;
+    }
+    if (ftruncate(m_fd, 0) != 0) {
+	/* can't happen [tm] */
+	int serrno = errno;
+	(void)::close(m_fd);
+	errno = serrno;
+	m_reason = "ftruncate failed";
+	return -1;
+    }
+    return 0;
+}
+
+pid_t Pidfile::open()
+{
+    if (flopen() < 0) {
+	return read_pid();
+    }
+    return (pid_t)0;
+}
+
+int Pidfile::write_pid()
+{
+    /* truncate to allow multiple calls */
+    if (ftruncate(m_fd, 0) == -1) {
+	m_reason = "ftruncate failed";
+	return -1;
+    }
+    char pidstr[20];
+    sprintf(pidstr, "%u", int(getpid()));
+    lseek(m_fd, 0, 0);
+    if (::write(m_fd, pidstr, strlen(pidstr)) != (ssize_t)strlen(pidstr)) {
+	m_reason = "write failed";
+	return -1;
+    }
+    return 0;
+}
+
+int Pidfile::close()
+{
+    return ::close(m_fd);
+}
+
+int Pidfile::remove()
+{
+    return unlink(m_path.c_str());
+}
+
 #else // TEST_PATHUT
 
 #include <iostream>
@@ -522,7 +616,7 @@
     }
 #endif
 
-#if 1
+#if 0
     if (argc != 1) {
 	fprintf(stderr, "Usage: fsocc: trpathut <path>\n");
 	exit(1);
@@ -537,6 +631,21 @@
   }
   printf("pc %d, megabytes %ld\n", pc, blocks);
 #endif
+
+#if 1
+  Pidfile pidfile("/tmp/pathutpidfile");
+  pid_t pid;
+  if ((pid = pidfile.open()) != 0) {
+      cerr << "open failed. reason: " << pidfile.getreason() << 
+	  " return " << pid << endl;
+      exit(1);
+  }
+  pidfile.write_pid();
+  sleep(10);
+  pidfile.close();
+  pidfile.remove();
+#endif
+
     return 0;
 }