[svn] GnuPG - r4992 - in branches/STABLE-BRANCH-1-4: . g10 util
svn author wk
cvs at cvs.gnupg.org
Tue May 5 17:32:17 CEST 2009
Author: wk
Date: 2009-05-05 17:32:16 +0200 (Tue, 05 May 2009)
New Revision: 4992
Modified:
branches/STABLE-BRANCH-1-4/NEWS
branches/STABLE-BRANCH-1-4/g10/ChangeLog
branches/STABLE-BRANCH-1-4/util/ChangeLog
branches/STABLE-BRANCH-1-4/util/dotlock.c
Log:
Improve dotlocking.
Implement locking for W32.
Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog
===================================================================
--- branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-05-05 11:44:56 UTC (rev 4991)
+++ branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-05-05 15:32:16 UTC (rev 4992)
@@ -1,12 +1,12 @@
2009-05-05 Werner Koch <wk at g10code.com>
- * keygen.c (output_control_s): s/create/creation/.
+ * keygen.c (read_parameter_file): Add keyword "Creation-Date".
+ (output_control_s): s/create/creation/.
(enum para_name): Add pCREATIONDATE, pKEYCREATIONDATE. Remove
pCREATETIME.
(generate_keypair): Do not set old pCREATETIME.
(parse_creation_string): New.
(proc_parameter_file): Set pCREATIONDATE.
- (read_parameter_file): Add keyword "Creation-Date".
(do_generate_keypair): Remove arg TIMESTAMP. Set it using
pKEYCREATIONDATE.
(get_parameter_u32): Set a default pKEYCREATIONDATE.
Modified: branches/STABLE-BRANCH-1-4/util/ChangeLog
===================================================================
--- branches/STABLE-BRANCH-1-4/util/ChangeLog 2009-05-05 11:44:56 UTC (rev 4991)
+++ branches/STABLE-BRANCH-1-4/util/ChangeLog 2009-05-05 15:32:16 UTC (rev 4992)
@@ -1,5 +1,8 @@
2009-05-05 Werner Koch <wk at g10code.com>
+ * dotlock.c: Merged changes from GnuPG-2. Better detection of
+ stale lockfiles and actual locking support on W32. Fixes bug#1028.
+
* miscutil.c (isotime2seconds): New.
2009-04-05 David Shaw <dshaw at jabberwocky.com>
Modified: branches/STABLE-BRANCH-1-4/NEWS
===================================================================
--- branches/STABLE-BRANCH-1-4/NEWS 2009-05-05 11:44:56 UTC (rev 4991)
+++ branches/STABLE-BRANCH-1-4/NEWS 2009-05-05 15:32:16 UTC (rev 4992)
@@ -4,7 +4,9 @@
* The algorithm to compute the SIG_ID status has been changed to
match the one from 2.0.10.
+ * Improved file locking. Implemented it for W32.
+
Noteworthy changes in version 1.4.9 (2008-03-26)
------------------------------------------------
Modified: branches/STABLE-BRANCH-1-4/util/dotlock.c
===================================================================
--- branches/STABLE-BRANCH-1-4/util/dotlock.c 2009-05-05 11:44:56 UTC (rev 4991)
+++ branches/STABLE-BRANCH-1-4/util/dotlock.c 2009-05-05 15:32:16 UTC (rev 4992)
@@ -1,6 +1,6 @@
/* dotlock.c - dotfile locking
* Copyright (C) 1998, 1999, 2000, 2001, 2004,
- * 2005 Free Software Foundation, Inc.
+ * 2005, 2009 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -25,8 +25,11 @@
#include <ctype.h>
#include <errno.h>
#include <unistd.h>
-#if !defined (HAVE_DOSISH_SYSTEM)
-#include <sys/utsname.h>
+#ifdef HAVE_DOSISH_SYSTEM
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+#else
+# include <sys/utsname.h>
#endif
#include <sys/types.h>
#ifndef _WIN32
@@ -38,25 +41,50 @@
#include "types.h"
#include "util.h"
#include "memory.h"
+#include "i18n.h"
+
+/* The object describing a lock. */
struct dotlock_handle {
struct dotlock_handle *next;
char *tname; /* name of lockfile template */
char *lockname; /* name of the real lockfile */
int locked; /* lock status */
int disable; /* locking */
+#ifdef HAVE_DOSISH_SYSTEM
+ HANDLE lockhd; /* The W32 handle of the lock file. */
+#else
+ size_t nodename_off; /* Offset in TNAME to the nodename part. */
+ size_t nodename_len; /* Length of the nodename part. */
+#endif
};
+/* A list of of all lock handles. */
static volatile DOTLOCK all_lockfiles;
+
+/* If this has the value true all locking is disabled. */
static int never_lock;
+
+#ifdef _REENTRANT
+ /* fixme: acquire mutex on all_lockfiles */
+# define lock_all_lockfiles(h) do { } while (0)
+# define unlock_all_lockfiles(h) do { } while (0)
+#else
+# define lock_all_lockfiles(h) do { } while (0)
+# define unlock_all_lockfiles(h) do { } while (0)
+#endif
+
+
+
void
disable_dotlock(void)
{
- never_lock = 1;
+ never_lock = 1;
}
+
/****************
* Create a lockfile with the given name and return an object of
* type DOTLOCK which may be used later to actually do the lock.
@@ -78,14 +106,16 @@
{
static int initialized;
DOTLOCK h;
-#if !defined (HAVE_DOSISH_SYSTEM)
+#ifndef HAVE_DOSISH_SYSTEM
int fd = -1;
char pidstr[16];
struct utsname utsbuf;
const char *nodename;
const char *dirpart;
int dirpartlen;
-#endif
+ size_t tnamelen;
+ int n;
+#endif /*!HAVE_DOSISH_SYSTEM*/
if( !initialized ) {
atexit( remove_lockfiles );
@@ -97,18 +127,15 @@
h = xmalloc_clear( sizeof *h );
if( never_lock ) {
h->disable = 1;
-#ifdef _REENTRANT
- /* fixme: aquire mutex on all_lockfiles */
-#endif
+ lock_all_lockfiles (h);
h->next = all_lockfiles;
all_lockfiles = h;
return h;
}
-#if !defined (HAVE_DOSISH_SYSTEM)
- sprintf( pidstr, "%10d\n", (int)getpid() );
- /* fixme: add the hostname to the second line (FQDN or IP addr?) */
+#ifndef HAVE_DOSISH_SYSTEM
+ snprintf (pidstr, sizeof pidstr, "%10d\n", (int)getpid() );
/* create a temporary file */
if( uname( &utsbuf ) )
@@ -116,14 +143,14 @@
else
nodename = utsbuf.nodename;
-#ifdef __riscos__
+# ifdef __riscos__
{
char *iter = (char *) nodename;
for (; iter[0]; iter++)
if (iter[0] == '.')
iter[0] = '/';
}
-#endif /* __riscos__ */
+# endif /* __riscos__ */
if( !(dirpart = strrchr( file_to_lock, DIRSEP_C )) ) {
dirpart = EXTSEP_S;
@@ -134,25 +161,27 @@
dirpart = file_to_lock;
}
-#ifdef _REENTRANT
- /* fixme: aquire mutex on all_lockfiles */
-#endif
+ lock_all_lockfiles (h);
h->next = all_lockfiles;
all_lockfiles = h;
- h->tname = xmalloc( dirpartlen + 6+30+ strlen(nodename) + 11 );
-#ifndef __riscos__
- sprintf( h->tname, "%.*s/.#lk%p.%s.%d",
- dirpartlen, dirpart, (void *)h, nodename, (int)getpid() );
-#else /* __riscos__ */
- sprintf( h->tname, "%.*s.lk%p/%s/%d",
- dirpartlen, dirpart, (void *)h, nodename, (int)getpid() );
-#endif /* __riscos__ */
+ tnamelen = dirpartlen + 6+30+ strlen(nodename) + 10;
+ h->tname = xmalloc (tnamelen + 1);
+ h->nodename_len = strlen (nodename);
+# ifndef __riscos__
+ snprintf (h->tname, tnamelen, "%.*s/.#lk%p.%n%s.%d",
+ dirpartlen, dirpart, (void *)h, &n, nodename, (int)getpid ());
+# else /* __riscos__ */
+ snprintf (h->tname, tnamelen, "%.*s.lk%p/%n%s/%d",
+ dirpartlen, dirpart, (void *)h, &n, nodename, (int)getpid ());
+# endif /* __riscos__ */
+ h->nodename_off = n;
+
do {
errno = 0;
- fd = open( h->tname, O_WRONLY|O_CREAT|O_EXCL,
- S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR );
+ fd = open (h->tname, O_WRONLY|O_CREAT|O_EXCL,
+ S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR);
} while( fd == -1 && errno == EINTR );
if( fd == -1 ) {
all_lockfiles = h->next;
@@ -162,78 +191,110 @@
xfree(h);
return NULL;
}
- if( write(fd, pidstr, 11 ) != 11 ) {
- all_lockfiles = h->next;
-#ifdef _REENTRANT
- /* release mutex */
-#endif
- log_fatal( "error writing to `%s': %s\n", h->tname, strerror(errno) );
- close(fd);
- unlink(h->tname);
- xfree(h->tname);
- xfree(h);
- return NULL;
- }
- if( close(fd) ) {
- all_lockfiles = h->next;
-#ifdef _REENTRANT
- /* release mutex */
-#endif
- log_error( "error closing `%s': %s\n", h->tname, strerror(errno));
- unlink(h->tname);
- xfree(h->tname);
- xfree(h);
- return NULL;
- }
+ if (write (fd, pidstr, 11) != 11)
+ goto write_failed;
+ if (write (fd, nodename, strlen (nodename)) != strlen (nodename))
+ goto write_failed;
+ if (write (fd, "\n", 1 ) != 1)
+ goto write_failed;
+ if (close (fd))
+ goto write_failed;
-#ifdef _REENTRANT
- /* release mutex */
-#endif
-#endif
+ unlock_all_lockfiles (h);
h->lockname = xmalloc( strlen(file_to_lock) + 6 );
strcpy(stpcpy(h->lockname, file_to_lock), EXTSEP_S "lock");
return h;
+
+ write_failed:
+ all_lockfiles = h->next;
+ unlock_all_lockfiles (h);
+ log_error ("error writing to `%s': %s\n", h->tname, strerror(errno));
+ close (fd);
+ unlink (h->tname);
+ xfree (h->tname);
+ xfree (h);
+ return NULL;
+
+#else /* HAVE_DOSISH_SYSTEM */
+
+ /* The Windows version does not need a temporary file but uses the
+ plain lock file along with record locking. We create this file
+ here so that we later do only need to do the file locking. For
+ error reporting it is useful to keep the name of the file in the
+ handle. */
+ h->next = all_lockfiles;
+ all_lockfiles = h;
+
+ h->lockname = xmalloc ( strlen (file_to_lock) + 6 );
+ strcpy (stpcpy(h->lockname, file_to_lock), EXTSEP_S "lock");
+
+ /* If would be nice if we would use the FILE_FLAG_DELETE_ON_CLOSE
+ along with FILE_SHARE_DELETE but that does not work due to a race
+ condition: Despite the OPEN_ALWAYS flag CreateFile may return an
+ error and we can't reliable create/open the lock file unless we
+ would wait here until it works - however there are other valid
+ reasons why a lock file can't be created and thus the process
+ would not stop as expected but spin until Windows crashes. Our
+ solution is to keep the lock file open; that does not harm. */
+ h->lockhd = CreateFile (h->lockname,
+ GENERIC_READ|GENERIC_WRITE,
+ FILE_SHARE_READ|FILE_SHARE_WRITE,
+ NULL, OPEN_ALWAYS, 0, NULL);
+ if (h->lockhd == INVALID_HANDLE_VALUE)
+ {
+ log_error (_("can't create `%s': %s\n"), h->lockname, w32_strerror (-1));
+ all_lockfiles = h->next;
+ xfree (h->lockname);
+ xfree (h);
+ return NULL;
+ }
+ return h;
+
+#endif /* HAVE_DOSISH_SYSTEM */
}
void
destroy_dotlock ( DOTLOCK h )
{
-#if !defined (HAVE_DOSISH_SYSTEM)
- if ( h )
- {
- DOTLOCK hprev, htmp;
+ 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;
- }
+ if (!h)
+ return;
- /* Second destroy the lock. */
- if (!h->disable)
- {
- if (h->locked && h->lockname)
- unlink (h->lockname);
- if (h->tname)
- unlink (h->tname);
- xfree (h->tname);
- xfree (h->lockname);
- }
- xfree(h);
+ /* 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)
+ {
+#ifdef HAVE_DOSISH_SYSTEM
+ if (h->locked)
+ UnlockFile (h->lockhd, 0, 0, 1, 0);
+ CloseHandle (h->lockhd);
+#else
+ if (h->locked && h->lockname)
+ unlink (h->lockname);
+ if (h->tname)
+ unlink (h->tname);
+ xfree (h->tname);
#endif
+ xfree (h->lockname);
+ }
+ xfree(h);
}
+
#ifndef HAVE_DOSISH_SYSTEM
-
static int
maybe_deadlock( DOTLOCK h )
{
@@ -245,44 +306,101 @@
}
return 0;
}
+#endif /* !HAVE_DOSISH_SYSTEM */
-/****************
- * Read the lock file and return the pid, returns -1 on error.
- */
+
+/* Read the lock file and return the pid, returns -1 on error. True
+ will be stored in the integer at address SAME_NODE if the lock file
+ has been created on the same node. */
+#ifndef HAVE_DOSISH_SYSTEM
static int
-read_lockfile( const char *name )
+read_lockfile (DOTLOCK h, int *same_node )
{
- int fd, pid;
- char pidstr[16];
+ char buffer_space[10+1+70+1]; /* 70 is just an estimated value; node
+ names are usually shorter. */
+ int fd;
+ int pid = -1;
+ char *buffer, *p;
+ size_t expected_len;
+ int res, nread;
+
+ *same_node = 0;
+ expected_len = 10 + 1 + h->nodename_len + 1;
+ if ( expected_len >= sizeof buffer_space)
+ buffer = xmalloc (expected_len);
+ else
+ buffer = buffer_space;
- if( (fd = open(name, O_RDONLY)) == -1 ) {
- int e = errno;
- log_debug("error opening lockfile `%s': %s\n", name, strerror(errno) );
- errno = e;
- return -1;
+ if ( (fd = open (h->lockname, O_RDONLY)) == -1 )
+ {
+ int e = errno;
+ log_info ("error opening lockfile `%s': %s\n",
+ h->lockname, strerror(errno) );
+ if (buffer != buffer_space)
+ xfree (buffer);
+ errno = e; /* Need to return ERRNO here. */
+ return -1;
}
- if( read(fd, pidstr, 10 ) != 10 ) { /* Read 10 digits w/o newline */
- log_debug("error reading lockfile `%s'", name );
- close(fd);
- errno = 0;
- return -1;
+
+ p = buffer;
+ nread = 0;
+ do
+ {
+ res = read (fd, p, expected_len - nread);
+ if (res == -1 && errno == EINTR)
+ continue;
+ if (res < 0)
+ {
+ log_info ("error reading lockfile `%s'", h->lockname );
+ close (fd);
+ if (buffer != buffer_space)
+ xfree (buffer);
+ errno = 0; /* Do not return an inappropriate ERRNO. */
+ return -1;
+ }
+ p += res;
+ nread += res;
}
- pidstr[10] = 0; /* terminate pid string */
- close(fd);
- pid = atoi(pidstr);
+ while (res && nread != expected_len);
+ close (fd);
+
+ if (nread < 11)
+ {
+ log_info ("invalid size of lockfile `%s'", h->lockname );
+ if (buffer != buffer_space)
+ xfree (buffer);
+ errno = 0; /* Better don't return an inappropriate ERRNO. */
+ return -1;
+ }
+
+ if (buffer[10] != '\n'
+ || (buffer[10] = 0, pid = atoi (buffer)) == -1
#ifndef __riscos__
- if( !pid || pid == -1 ) {
+ || !pid
#else /* __riscos__ */
- if( (!pid && riscos_getpid()) || pid == -1 ) {
+ || (!pid && riscos_getpid())
#endif /* __riscos__ */
- log_error("invalid pid %d in lockfile `%s'", pid, name );
- errno = 0;
- return -1;
+ )
+ {
+ log_error ("invalid pid %d in lockfile `%s'", pid, h->lockname );
+ if (buffer != buffer_space)
+ xfree (buffer);
+ errno = 0;
+ return -1;
}
- return pid;
+
+ if (nread == expected_len
+ && !memcmp (h->tname+h->nodename_off, buffer+11, h->nodename_len)
+ && buffer[11+h->nodename_len] == '\n')
+ *same_node = 1;
+
+ if (buffer != buffer_space)
+ xfree (buffer);
+ return pid;
}
#endif /* !HAVE_DOSISH_SYSTEM */
+
/****************
* Do a lock on H. A TIMEOUT of 0 returns immediately,
* -1 waits forever (hopefully not), other
@@ -292,90 +410,129 @@
int
make_dotlock( DOTLOCK h, long timeout )
{
-#if defined (HAVE_DOSISH_SYSTEM)
+ int backoff=0;
+#ifndef HAVE_DOSISH_SYSTEM
+ int pid;
+ const char *maybe_dead="";
+ int same_node;
+#endif
+
+ if (h->disable)
return 0;
-#else
- int pid;
- const char *maybe_dead="";
- int backoff=0;
- if( h->disable ) {
- return 0;
- }
-
- if( h->locked ) {
+ if (h->locked)
+ {
#ifndef __riscos__
- log_debug("oops, `%s' is already locked\n", h->lockname );
+ log_debug ("oops, `%s' is already locked\n", h->lockname);
#endif /* !__riscos__ */
- return 0;
+ return 0;
}
-
- for(;;) {
-#ifndef __riscos__
- if( !link(h->tname, h->lockname) ) {
- /* fixme: better use stat to check the link count */
- h->locked = 1;
- return 0; /* okay */
+
+ for (;;)
+ {
+#ifndef HAVE_DOSISH_SYSTEM
+# ifndef __riscos__
+ if( !link(h->tname, h->lockname) )
+ {
+ /* fixme: better use stat to check the link count */
+ h->locked = 1;
+ return 0; /* okay */
}
- if( errno != EEXIST ) {
- log_error( "lock not made: link() failed: %s\n", strerror(errno) );
- return -1;
+ if (errno != EEXIST)
+ {
+ log_error ("lock not made: link() failed: %s\n", strerror(errno));
+ return -1;
}
-#else /* __riscos__ */
- if( !riscos_renamefile(h->tname, h->lockname) ) {
- h->locked = 1;
- return 0; /* okay */
+# else /* __riscos__ */
+ if ( !riscos_renamefile(h->tname, h->lockname) )
+ {
+ h->locked = 1;
+ return 0; /* okay */
}
- if( errno != EEXIST ) {
- log_error( "lock not made: rename() failed: %s\n", strerror(errno) );
- return -1;
+ if (errno != EEXIST)
+ {
+ log_error ("lock not made: rename() failed: %s\n", strerror(errno));
+ return -1;
}
-#endif /* __riscos__ */
- if( (pid = read_lockfile(h->lockname)) == -1 ) {
- if( errno != ENOENT ) {
- log_info("cannot read lockfile\n");
- return -1;
+# endif /* __riscos__ */
+
+ if ((pid = read_lockfile (h, &same_node)) == -1 )
+ {
+ if (errno != ENOENT)
+ {
+ log_info ("cannot read lockfile\n");
+ return -1;
}
- log_info( "lockfile disappeared\n");
- continue;
+ log_info ("lockfile disappeared\n");
+ continue;
}
- else if( pid == getpid() ) {
- log_info( "Oops: lock already held by us\n");
- h->locked = 1;
- return 0; /* okay */
+ else if (pid == getpid ())
+ {
+ log_info ("Oops: lock already held by us\n");
+ h->locked = 1;
+ return 0; /* okay */
}
- else if( kill(pid, 0) && errno == ESRCH ) {
-#ifndef __riscos__
- maybe_dead = " - probably dead";
-#if 0 /* we should not do this without checking the permissions */
- /* and the hostname */
- log_info( "removing stale lockfile (created by %d)", pid );
-#endif
-#else /* __riscos__ */
- /* we are *pretty* sure that the other task is dead and therefore
- we remove the other lock file */
- maybe_dead = " - probably dead - removing lock";
- unlink(h->lockname);
-#endif /* __riscos__ */
+ else if (same_node && kill(pid, 0) && errno == ESRCH)
+ {
+# ifndef __riscos__
+ log_info (_("removing stale lockfile (created by %d)\n"), pid );
+ unlink (h->lockname);
+ continue;
+# else /* __riscos__ */
+ /* We are *pretty* sure that the other task is dead and
+ therefore we remove the other lock file. */
+ maybe_dead = " - probably dead - removing lock";
+ unlink (h->lockname);
+# endif /* __riscos__ */
}
- if( timeout == -1 ) {
- struct timeval tv;
- log_info( "waiting for lock (held by %d%s) %s...\n",
- pid, maybe_dead, maybe_deadlock(h)? "(deadlock?) ":"");
+ if (timeout == -1)
+ {
+ struct timeval tv;
- /* can't use sleep, cause signals may be blocked */
+ log_info ("waiting for lock (held by %d%s) %s...\n",
+ pid, maybe_dead, maybe_deadlock(h)? "(deadlock?) ":"");
+
+
+ /* We can't use sleep, because signals may be blocked. */
tv.tv_sec = 1 + backoff;
tv.tv_usec = 0;
- select(0, NULL, NULL, NULL, &tv);
- if( backoff < 10 )
- backoff++ ;
+ select (0, NULL, NULL, NULL, &tv);
+ if (backoff < 10)
+ backoff++ ;
}
- else
- return -1;
+ else
+ return -1;
+
+#else /*HAVE_DOSISH_SYSTEM*/
+ int w32err;
+
+ if (LockFile (h->lockhd, 0, 0, 1, 0))
+ {
+ h->locked = 1;
+ return 0; /* okay */
+ }
+ w32err = GetLastError ();
+ if (w32err != ERROR_LOCK_VIOLATION)
+ {
+ log_error (_("lock `%s' not made: %s\n"),
+ h->lockname, w32_strerror (w32err));
+ return -1;
+ }
+
+ if (timeout == -1)
+ {
+ /* Wait until lock has been released. */
+ log_info (_("waiting for lock %s...\n"), h->lockname);
+ Sleep ((1 + backoff)*1000);
+ if ( backoff < 10 )
+ backoff++ ;
+ }
+ else
+ return -1;
+#endif /*HAVE_DOSISH_SYSTEM*/
}
- /*not reached */
-#endif
+ /*NOTREACHED */
}
@@ -384,56 +541,71 @@
* Returns: 0 := success
*/
int
-release_dotlock( DOTLOCK h )
+release_dotlock (DOTLOCK h)
{
-#if defined (HAVE_DOSISH_SYSTEM)
+#ifndef HAVE_DOSISH_SYSTEM
+ int pid, same_node;
+#endif
+
+ /* 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;
-#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;
- if( h->disable )
- return 0;
-
- if( !h->locked ) {
- log_debug("oops, `%s' is not locked\n", h->lockname );
- return 0;
+ if (!h->locked)
+ {
+ log_debug("oops, `%s' is not locked\n", h->lockname );
+ return 0;
}
- pid = read_lockfile( h->lockname );
- if( pid == -1 ) {
- log_error( "release_dotlock: lockfile error\n");
- return -1;
+#ifndef HAVE_DOSISH_SYSTEM
+ pid = read_lockfile (h, &same_node);
+ if (pid == -1)
+ {
+ log_error ("release_dotlock: lockfile error\n");
+ return -1;
}
- if( pid != getpid() ) {
- log_error( "release_dotlock: not our lock (pid=%d)\n", pid);
- return -1;
+ if (pid != getpid () || !same_node)
+ {
+ log_error ("release_dotlock: not our lock (pid=%d)\n", pid);
+ return -1;
}
-#ifndef __riscos__
- if( unlink( h->lockname ) ) {
- log_error( "release_dotlock: error removing lockfile `%s'",
- h->lockname);
- return -1;
+# ifndef __riscos__
+ if (unlink (h->lockname))
+ {
+ log_error ("release_dotlock: error removing lockfile `%s'",
+ h->lockname);
+ return -1;
}
-#else /* __riscos__ */
- if( riscos_renamefile(h->lockname, h->tname) ) {
- log_error( "release_dotlock: error renaming lockfile `%s' to `%s'",
- h->lockname, h->tname);
- return -1;
+# else /* __riscos__ */
+ if( riscos_renamefile(h->lockname, h->tname) )
+ {
+ log_error( "release_dotlock: error renaming lockfile `%s' to `%s'",
+ h->lockname, h->tname);
+ return -1;
}
-#endif /* __riscos__ */
- /* fixme: check that the link count is now 1 */
- h->locked = 0;
- return 0;
-#endif
+# endif /* __riscos__ */
+
+#else /*HAVE_DOSISH_SYSTEM*/
+
+ if (!UnlockFile (h->lockhd, 0, 0, 1, 0))
+ {
+ log_error ("release_dotlock: error removing lockfile `%s': %s\n",
+ h->lockname, w32_strerror (-1));
+ return -1;
+ }
+#endif /*HAVE_DOSISH_SYSTEM*/
+
+ h->locked = 0;
+ return 0;
}
+
void
remove_lockfiles()
{
More information about the Gnupg-commits
mailing list