[tor-commits] [tor/master] Move lockfile code into lib/fs

nickm at torproject.org nickm at torproject.org
Thu Jun 28 19:21:00 UTC 2018


commit aa3edfd2053bb418907f204e171ae8f7e78c30eb
Author: Nick Mathewson <nickm at torproject.org>
Date:   Thu Jun 28 11:33:50 2018 -0400

    Move lockfile code into lib/fs
---
 src/common/compat.c   | 111 ----------------------------------------
 src/common/compat.h   |   4 --
 src/lib/fs/include.am |   2 +
 src/lib/fs/lockfile.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/lib/fs/lockfile.h |  14 +++++
 src/or/main.c         |   1 +
 6 files changed, 155 insertions(+), 115 deletions(-)

diff --git a/src/common/compat.c b/src/common/compat.c
index 9fd966798..1199fdae9 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -131,116 +131,6 @@ SecureZeroMemory(PVOID ptr, SIZE_T cnt)
 #include "lib/net/address.h"
 #include "lib/sandbox/sandbox.h"
 
-/** Represents a lockfile on which we hold the lock. */
-struct tor_lockfile_t {
-  /** Name of the file */
-  char *filename;
-  /** File descriptor used to hold the file open */
-  int fd;
-};
-
-/** Try to get a lock on the lockfile <b>filename</b>, creating it as
- * necessary.  If someone else has the lock and <b>blocking</b> is true,
- * wait until the lock is available.  Otherwise return immediately whether
- * we succeeded or not.
- *
- * Set *<b>locked_out</b> to true if somebody else had the lock, and to false
- * otherwise.
- *
- * Return a <b>tor_lockfile_t</b> on success, NULL on failure.
- *
- * (Implementation note: because we need to fall back to fcntl on some
- *  platforms, these locks are per-process, not per-thread.  If you want
- *  to do in-process locking, use tor_mutex_t like a normal person.
- *  On Windows, when <b>blocking</b> is true, the maximum time that
- *  is actually waited is 10 seconds, after which NULL is returned
- *  and <b>locked_out</b> is set to 1.)
- */
-tor_lockfile_t *
-tor_lockfile_lock(const char *filename, int blocking, int *locked_out)
-{
-  tor_lockfile_t *result;
-  int fd;
-  *locked_out = 0;
-
-  log_info(LD_FS, "Locking \"%s\"", filename);
-  fd = tor_open_cloexec(filename, O_RDWR|O_CREAT|O_TRUNC, 0600);
-  if (fd < 0) {
-    log_warn(LD_FS,"Couldn't open \"%s\" for locking: %s", filename,
-             strerror(errno));
-    return NULL;
-  }
-
-#ifdef _WIN32
-  _lseek(fd, 0, SEEK_SET);
-  if (_locking(fd, blocking ? _LK_LOCK : _LK_NBLCK, 1) < 0) {
-    if (errno != EACCES && errno != EDEADLOCK)
-      log_warn(LD_FS,"Couldn't lock \"%s\": %s", filename, strerror(errno));
-    else
-      *locked_out = 1;
-    close(fd);
-    return NULL;
-  }
-#elif defined(HAVE_FLOCK)
-  if (flock(fd, LOCK_EX|(blocking ? 0 : LOCK_NB)) < 0) {
-    if (errno != EWOULDBLOCK)
-      log_warn(LD_FS,"Couldn't lock \"%s\": %s", filename, strerror(errno));
-    else
-      *locked_out = 1;
-    close(fd);
-    return NULL;
-  }
-#else
-  {
-    struct flock lock;
-    memset(&lock, 0, sizeof(lock));
-    lock.l_type = F_WRLCK;
-    lock.l_whence = SEEK_SET;
-    if (fcntl(fd, blocking ? F_SETLKW : F_SETLK, &lock) < 0) {
-      if (errno != EACCES && errno != EAGAIN)
-        log_warn(LD_FS, "Couldn't lock \"%s\": %s", filename, strerror(errno));
-      else
-        *locked_out = 1;
-      close(fd);
-      return NULL;
-    }
-  }
-#endif /* defined(_WIN32) || ... */
-
-  result = tor_malloc(sizeof(tor_lockfile_t));
-  result->filename = tor_strdup(filename);
-  result->fd = fd;
-  return result;
-}
-
-/** Release the lock held as <b>lockfile</b>. */
-void
-tor_lockfile_unlock(tor_lockfile_t *lockfile)
-{
-  tor_assert(lockfile);
-
-  log_info(LD_FS, "Unlocking \"%s\"", lockfile->filename);
-#ifdef _WIN32
-  _lseek(lockfile->fd, 0, SEEK_SET);
-  if (_locking(lockfile->fd, _LK_UNLCK, 1) < 0) {
-    log_warn(LD_FS,"Error unlocking \"%s\": %s", lockfile->filename,
-             strerror(errno));
-  }
-#elif defined(HAVE_FLOCK)
-  if (flock(lockfile->fd, LOCK_UN) < 0) {
-    log_warn(LD_FS, "Error unlocking \"%s\": %s", lockfile->filename,
-             strerror(errno));
-  }
-#else
-  /* Closing the lockfile is sufficient. */
-#endif /* defined(_WIN32) || ... */
-
-  close(lockfile->fd);
-  lockfile->fd = -1;
-  tor_free(lockfile->filename);
-  tor_free(lockfile);
-}
-
 /** Number of extra file descriptors to keep in reserve beyond those that we
  * tell Tor it's allowed to use. */
 #define ULIMIT_BUFFER 32 /* keep 32 extra fd's beyond ConnLimit_ */
@@ -550,7 +440,6 @@ compute_num_cpus(void)
   return num_cpus;
 }
 
-
 /** Called before we make any calls to network-related functions.
  * (Some operating systems require their network libraries to be
  * initialized.) */
diff --git a/src/common/compat.h b/src/common/compat.h
index 018caab24..e455dc8ef 100644
--- a/src/common/compat.h
+++ b/src/common/compat.h
@@ -108,10 +108,6 @@
 #endif /* !defined(timercmp) */
 
 /* ===== File compatibility */
-typedef struct tor_lockfile_t tor_lockfile_t;
-tor_lockfile_t *tor_lockfile_lock(const char *filename, int blocking,
-                                  int *locked_out);
-void tor_lockfile_unlock(tor_lockfile_t *lockfile);
 
 /* ===== Net compatibility */
 
diff --git a/src/lib/fs/include.am b/src/lib/fs/include.am
index dcfd0b201..0256c0f2f 100644
--- a/src/lib/fs/include.am
+++ b/src/lib/fs/include.am
@@ -9,6 +9,7 @@ src_lib_libtor_fs_a_SOURCES =			\
 	src/lib/fs/conffile.c			\
 	src/lib/fs/dir.c			\
 	src/lib/fs/files.c			\
+	src/lib/fs/lockfile.c			\
 	src/lib/fs/mmap.c			\
 	src/lib/fs/path.c			\
 	src/lib/fs/storagedir.c			\
@@ -23,6 +24,7 @@ noinst_HEADERS +=					\
 	src/lib/fs/conffile.h				\
 	src/lib/fs/dir.h				\
 	src/lib/fs/files.h				\
+	src/lib/fs/lockfile.h				\
 	src/lib/fs/mmap.h				\
 	src/lib/fs/path.h				\
 	src/lib/fs/storagedir.h				\
diff --git a/src/lib/fs/lockfile.c b/src/lib/fs/lockfile.c
new file mode 100644
index 000000000..3fc9cd426
--- /dev/null
+++ b/src/lib/fs/lockfile.c
@@ -0,0 +1,138 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "orconfig.h"
+#include "lib/fs/files.h"
+#include "lib/fs/lockfile.h"
+#include "lib/log/torlog.h"
+#include "lib/log/util_bug.h"
+#include "lib/malloc/util_malloc.h"
+
+#ifdef HAVE_SYS_FILE_H
+#include <sys/file.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef _WIN32
+#include <windows.h>
+#include <sys/locking.h>
+#endif
+
+#include <errno.h>
+#include <string.h>
+
+/** Represents a lockfile on which we hold the lock. */
+struct tor_lockfile_t {
+  /** Name of the file */
+  char *filename;
+  /** File descriptor used to hold the file open */
+  int fd;
+};
+
+/** Try to get a lock on the lockfile <b>filename</b>, creating it as
+ * necessary.  If someone else has the lock and <b>blocking</b> is true,
+ * wait until the lock is available.  Otherwise return immediately whether
+ * we succeeded or not.
+ *
+ * Set *<b>locked_out</b> to true if somebody else had the lock, and to false
+ * otherwise.
+ *
+ * Return a <b>tor_lockfile_t</b> on success, NULL on failure.
+ *
+ * (Implementation note: because we need to fall back to fcntl on some
+ *  platforms, these locks are per-process, not per-thread.  If you want
+ *  to do in-process locking, use tor_mutex_t like a normal person.
+ *  On Windows, when <b>blocking</b> is true, the maximum time that
+ *  is actually waited is 10 seconds, after which NULL is returned
+ *  and <b>locked_out</b> is set to 1.)
+ */
+tor_lockfile_t *
+tor_lockfile_lock(const char *filename, int blocking, int *locked_out)
+{
+  tor_lockfile_t *result;
+  int fd;
+  *locked_out = 0;
+
+  log_info(LD_FS, "Locking \"%s\"", filename);
+  fd = tor_open_cloexec(filename, O_RDWR|O_CREAT|O_TRUNC, 0600);
+  if (fd < 0) {
+    log_warn(LD_FS,"Couldn't open \"%s\" for locking: %s", filename,
+             strerror(errno));
+    return NULL;
+  }
+
+#ifdef _WIN32
+  _lseek(fd, 0, SEEK_SET);
+  if (_locking(fd, blocking ? _LK_LOCK : _LK_NBLCK, 1) < 0) {
+    if (errno != EACCES && errno != EDEADLOCK)
+      log_warn(LD_FS,"Couldn't lock \"%s\": %s", filename, strerror(errno));
+    else
+      *locked_out = 1;
+    close(fd);
+    return NULL;
+  }
+#elif defined(HAVE_FLOCK)
+  if (flock(fd, LOCK_EX|(blocking ? 0 : LOCK_NB)) < 0) {
+    if (errno != EWOULDBLOCK)
+      log_warn(LD_FS,"Couldn't lock \"%s\": %s", filename, strerror(errno));
+    else
+      *locked_out = 1;
+    close(fd);
+    return NULL;
+  }
+#else
+  {
+    struct flock lock;
+    memset(&lock, 0, sizeof(lock));
+    lock.l_type = F_WRLCK;
+    lock.l_whence = SEEK_SET;
+    if (fcntl(fd, blocking ? F_SETLKW : F_SETLK, &lock) < 0) {
+      if (errno != EACCES && errno != EAGAIN)
+        log_warn(LD_FS, "Couldn't lock \"%s\": %s", filename, strerror(errno));
+      else
+        *locked_out = 1;
+      close(fd);
+      return NULL;
+    }
+  }
+#endif /* defined(_WIN32) || ... */
+
+  result = tor_malloc(sizeof(tor_lockfile_t));
+  result->filename = tor_strdup(filename);
+  result->fd = fd;
+  return result;
+}
+
+/** Release the lock held as <b>lockfile</b>. */
+void
+tor_lockfile_unlock(tor_lockfile_t *lockfile)
+{
+  tor_assert(lockfile);
+
+  log_info(LD_FS, "Unlocking \"%s\"", lockfile->filename);
+#ifdef _WIN32
+  _lseek(lockfile->fd, 0, SEEK_SET);
+  if (_locking(lockfile->fd, _LK_UNLCK, 1) < 0) {
+    log_warn(LD_FS,"Error unlocking \"%s\": %s", lockfile->filename,
+             strerror(errno));
+  }
+#elif defined(HAVE_FLOCK)
+  if (flock(lockfile->fd, LOCK_UN) < 0) {
+    log_warn(LD_FS, "Error unlocking \"%s\": %s", lockfile->filename,
+             strerror(errno));
+  }
+#else
+  /* Closing the lockfile is sufficient. */
+#endif /* defined(_WIN32) || ... */
+
+  close(lockfile->fd);
+  lockfile->fd = -1;
+  tor_free(lockfile->filename);
+  tor_free(lockfile);
+}
diff --git a/src/lib/fs/lockfile.h b/src/lib/fs/lockfile.h
new file mode 100644
index 000000000..1c5bb023b
--- /dev/null
+++ b/src/lib/fs/lockfile.h
@@ -0,0 +1,14 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef TOR_LOCKFILE_H
+#define TOR_LOCKFILE_H
+
+typedef struct tor_lockfile_t tor_lockfile_t;
+tor_lockfile_t *tor_lockfile_lock(const char *filename, int blocking,
+                                  int *locked_out);
+void tor_lockfile_unlock(tor_lockfile_t *lockfile);
+
+#endif
diff --git a/src/or/main.c b/src/or/main.c
index 50e51915b..0ba38658a 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -112,6 +112,7 @@
 #include "or/ext_orport.h"
 #include "lib/memarea/memarea.h"
 #include "lib/sandbox/sandbox.h"
+#include "lib/fs/lockfile.h"
 
 #include <event2/event.h>
 





More information about the tor-commits mailing list