summaryrefslogtreecommitdiffstats
path: root/jnlib/dotlock.c
diff options
context:
space:
mode:
Diffstat (limited to 'jnlib/dotlock.c')
-rw-r--r--jnlib/dotlock.c83
1 files changed, 62 insertions, 21 deletions
diff --git a/jnlib/dotlock.c b/jnlib/dotlock.c
index a50a0ee99..b7f892717 100644
--- a/jnlib/dotlock.c
+++ b/jnlib/dotlock.c
@@ -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.
*
@@ -149,9 +150,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;
@@ -202,15 +203,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 )
{
@@ -331,6 +371,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;
}
@@ -414,22 +461,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
}