aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2008-11-26 16:10:56 +0000
committerNick Mathewson <nickm@torproject.org>2008-11-26 16:10:56 +0000
commitbc597758dc79008226a25c0f11a8713709b94f2f (patch)
tree7398d99764d7b0af7454010b12d6adf4db1e54b1 /src
parentcfd21c58b538c7f967b41b87619b8147d17bf17d (diff)
downloadtor-bc597758dc79008226a25c0f11a8713709b94f2f.tar
tor-bc597758dc79008226a25c0f11a8713709b94f2f.tar.gz
Use fcntl for file locking when flock() is not available.
svn:r17391
Diffstat (limited to 'src')
-rw-r--r--src/common/compat.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/src/common/compat.c b/src/common/compat.c
index 5a3858ef8..df1e94b02 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -491,6 +491,10 @@ struct tor_lockfile_t {
* 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.)
*/
tor_lockfile_t *
tor_lockfile_lock(const char *filename, int blocking, int *locked_out)
@@ -506,6 +510,7 @@ tor_lockfile_lock(const char *filename, int blocking, int *locked_out)
strerror(errno));
return NULL;
}
+
#ifdef WIN32
_lseek(fd, 0, SEEK_SET);
if (_locking(fd, blocking ? _LK_LOCK : _LK_NBLCK, 1) < 0) {
@@ -516,7 +521,7 @@ tor_lockfile_lock(const char *filename, int blocking, int *locked_out)
close(fd);
return NULL;
}
-#else
+#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));
@@ -525,6 +530,21 @@ tor_lockfile_lock(const char *filename, int blocking, int *locked_out)
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
result = tor_malloc(sizeof(tor_lockfile_t));
@@ -546,11 +566,13 @@ tor_lockfile_unlock(tor_lockfile_t *lockfile)
log_warn(LD_FS,"Error unlocking \"%s\": %s", lockfile->filename,
strerror(errno));
}
-#else
+#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
close(lockfile->fd);