]> err.no Git - dpkg/commitdiff
libdpkg: Refactor the database locking into a general file locking
authorGuillem Jover <guillem@debian.org>
Tue, 25 Mar 2008 02:37:45 +0000 (04:37 +0200)
committerGuillem Jover <guillem@debian.org>
Tue, 25 Mar 2008 02:44:37 +0000 (04:44 +0200)
Make the lockdatabase functions use the lock_files ones instead.

Based on a patch by Ian Jackson <ian@davenant.greenend.org.uk>.

ChangeLog
lib/dpkg.h
lib/lock.c

index 233db45ab4e07ad6958735899d88af64c8b853db..18da5cf6db5fad49f9ed4cbe775111b2e8c12e3f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2008-03-25  Ian Jackson  <ian@davenant.greenend.org.uk>,
+            Guillem Jover  <guillem@debian.org>
+
+       * lib/dpkg.h (lock_file): New function prototype.
+       (unlock_file): Likewise.
+       * lib/lock.c (cu_unlockdb): Rename to ...
+       (cu_unlock_file): ... here. Rename dblockfd to lockfd, and take it
+       from argv.
+       (unlock_file): New function.
+       (lock_file): Likewise.
+       (dblockfd): Move variable to ...
+       (lockdatabase): ... here. Call lock_file instead of doing the
+       actual file locking.
+       (unlockdatabase): Call unlock_file, instead if doing the actual
+       pop_cleanup.
+
 2008-03-24  Ian Jackson  <ian@davenant.greenend.org.uk>
 
        * lib/dpkg.h (error_printer): New function pointer type.
index 4a53d92e3330dce3e8afc68479c3205f645398e0..45967432a047357062bfd173c426d1d3d667f5a4 100644 (file)
@@ -214,6 +214,12 @@ void cu_closepipe(int argc, void **argv);
 void cu_closedir(int argc, void **argv);
 void cu_closefd(int argc, void **argv);
 
+/*** lock.c ***/
+
+void lock_file(int *lockfd, const char *filename,
+               const char *emsg, const char *emsg_eagain);
+void unlock_file(void);
+
 /*** from mlib.c ***/
 
 void setcloexec(int fd, const char* fn);
index 06fb413eac271d28c324afe99da9638f5e5a4cf0..5d8e3c0cb8bd3876775d2ed03aed3c6f3be3477e 100644 (file)
 #include <dpkg.h>
 #include <dpkg-db.h>
 
-static int dblockfd= -1;
-
-static void cu_unlockdb(int argc, void **argv) {
+static void
+cu_unlock_file(int argc, void **argv)
+{
+  int lockfd = *(int*)argv[0];
   struct flock fl;
-  assert(dblockfd >= 0);
+
+  assert(lockfd >= 0);
   fl.l_type= F_UNLCK;
   fl.l_whence= SEEK_SET;
   fl.l_start= 0;
   fl.l_len= 0;
-  if (fcntl(dblockfd,F_SETLK,&fl) == -1)
+  if (fcntl(lockfd, F_SETLK, &fl) == -1)
     ohshite(_("unable to unlock dpkg status database"));
 }
 
+void
+unlock_file(void)
+{
+  pop_cleanup(ehflag_normaltidy); /* Calls cu_unlock_file. */
+}
+
+/* lockfd must be allocated statically as its addresses is passed to
+ * a cleanup handler. */
+void
+lock_file(int *lockfd, const char *filename,
+          const char *emsg, const char *emsg_eagain)
+{
+  struct flock fl;
+
+  setcloexec(*lockfd, filename);
+
+  fl.l_type = F_WRLCK;
+  fl.l_whence = SEEK_SET;
+  fl.l_start = 0;
+  fl.l_len = 0;
+
+  if (fcntl(*lockfd, emsg_eagain ? F_SETLK : F_SETLKW, &fl) == -1) {
+    if (emsg_eagain && (errno == EACCES || errno == EAGAIN))
+      ohshit(emsg_eagain);
+    ohshite(emsg);
+  }
+
+  push_cleanup(cu_unlock_file, ~0, NULL, 0, 1, lockfd);
+}
+
 void unlockdatabase(const char *admindir) {
-  pop_cleanup(ehflag_normaltidy); /* calls cu_unlockdb */
+  unlock_file();
 }
 
 void lockdatabase(const char *admindir) {
+  static int dblockfd = -1;
   int n;
-  struct flock fl;
   char *dblockfile= NULL;
   
     n= strlen(admindir);
@@ -66,16 +98,10 @@ void lockdatabase(const char *admindir) {
       ohshite(_("unable to open/create status database lockfile"));
     }
   }
-  fl.l_type= F_WRLCK;
-  fl.l_whence= SEEK_SET;
-  fl.l_start= 0;
-  fl.l_len= 0;
-  if (fcntl(dblockfd,F_SETLK,&fl) == -1) {
-    if (errno == EACCES || errno == EAGAIN)
-      ohshit(_("status database area is locked by another process"));
-    ohshite(_("unable to lock dpkg status database"));
-  }
-  setcloexec(dblockfd, dblockfile);
+
+  lock_file(&dblockfd, dblockfile,
+            _("unable to lock dpkg status database"),
+            _("status database area is locked by another process"));
+
   free(dblockfile);
-  push_cleanup(cu_unlockdb,~0, NULL,0, 0);
 }