Updated FSF's address.
[gnupg.git] / jnlib / dotlock.c
index 7240faf..89edb7b 100644 (file)
@@ -1,5 +1,6 @@
 /* dotlock.c - dotfile locking
- *     Copyright (C) 1998,2000,2001,2003 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 2000, 2001, 2003, 2004, 
+ *               2005 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -15,7 +16,8 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
  */
 
 #include <config.h>
 #include "libjnlib-config.h"
 #include "dotlock.h"
 
+#if !defined(DIRSEP_C) && !defined(EXTSEP_C) \
+    && !defined(DIRSEP_S) && !defined(EXTSEP_S)
+#ifdef HAVE_DOSISH_SYSTEM
+#define DIRSEP_C '\\'
+#define EXTSEP_C '.'
+#define DIRSEP_S "\\"
+#define EXTSEP_S "."
+#else
+#define DIRSEP_C '/'
+#define EXTSEP_C '.'
+#define DIRSEP_S "/"
+#define EXTSEP_S "."
+#endif
+#endif
+
+
 struct dotlock_handle {
     struct dotlock_handle *next;
     char *tname;    /* name of lockfile template */
@@ -133,9 +151,9 @@ create_dotlock( const char *file_to_lock )
        dirpart = file_to_lock;
     }
 
-  #ifdef _REENTRANT
+#ifdef _REENTRANT
     /* fixme: aquire mutex on all_lockfiles */
-  #endif
+#endif
     h->next = all_lockfiles;
     all_lockfiles = h;
 
@@ -186,15 +204,54 @@ create_dotlock( const char *file_to_lock )
        return NULL;
     }
 
-  #ifdef _REENTRANT
+ifdef _REENTRANT
     /* release mutex */
-  #endif
+endif
 #endif /* !HAVE_DOSISH_SYSTEM */
     h->lockname = jnlib_xmalloc( strlen(file_to_lock) + 6 );
     strcpy(stpcpy(h->lockname, file_to_lock), EXTSEP_S "lock");
     return h;
 }
 
+
+void
+destroy_dotlock ( DOTLOCK h )
+{
+#if !defined (HAVE_DOSISH_SYSTEM)
+    if ( h )
+      {
+        DOTLOCK hprev, htmp;
+
+        /* First remove the handle from our global list of all locks. */
+        for (hprev=NULL, htmp=all_lockfiles; htmp; hprev=htmp, htmp=htmp->next)
+          if (htmp == h)
+            {
+              if (hprev)
+                hprev->next = htmp->next;
+              else
+                all_lockfiles = htmp->next;
+              h->next = NULL;
+              break;
+            }
+
+        /* Second destroy the lock. */
+       if (!h->disable)
+          {
+           if (h->locked && h->lockname)
+              unlink (h->lockname);
+            if (h->tname)
+              unlink (h->tname);
+           jnlib_free (h->tname);
+           jnlib_free (h->lockname);
+          }
+       jnlib_free(h);
+
+      }
+#endif
+}
+
+
+
 static int
 maybe_deadlock( DOTLOCK h )
 {
@@ -315,6 +372,13 @@ release_dotlock( DOTLOCK h )
 #else
     int pid;
 
+    /* To avoid atexit race conditions we first check whether there
+       are any locks left.  It might happen that another atexit
+       handler tries to release the lock while the atexit handler of
+       this module already ran and thus H is undefined.  */
+    if(!all_lockfiles)
+        return 0;
+
     if( h->disable ) {
        return 0;
     }
@@ -398,22 +462,16 @@ void
 dotlock_remove_lockfiles()
 {
 #ifndef HAVE_DOSISH_SYSTEM
-    DOTLOCK h, h2;
-
-    h = all_lockfiles;
-    all_lockfiles = NULL;
-
-    while( h ) {
-       h2 = h->next;
-        if (!h->disable ) {
-          if( h->locked )
-           unlink( h->lockname );
-          unlink(h->tname);
-          jnlib_free(h->tname);
-          jnlib_free(h->lockname);
-        }
-       jnlib_free(h);
-       h = h2;
+  DOTLOCK h, h2;
+  
+  h = all_lockfiles;
+  all_lockfiles = NULL;
+    
+  while ( h )
+    {
+      h2 = h->next;
+      destroy_dotlock (h);
+      h = h2;
     }
 #endif
 }