mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
common: Make sure dotlock functions set a proper ERRNO.
* common/dotlock.c (map_w32_to_errno): New. (read_lockfile): Return a proper ERRNO. (dotlock_create_unix): Do not let log functions clobber ERRNO. (dotlock_take_unix): Ditto. (dotlock_release_unix): Ditto. (dotlock_create_w32): Set proper ERRNO. (dotlock_take_w32): Ditto. (dotlock_release_w32): Ditto. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
1608629786
commit
4aceebf36f
@ -412,7 +412,8 @@ struct dotlock_handle
|
|||||||
|
|
||||||
|
|
||||||
/* A list of of all lock handles. The volatile attribute might help
|
/* A list of of all lock handles. The volatile attribute might help
|
||||||
if used in an atexit handler. */
|
if used in an atexit handler. Note that [UN]LOCK_all_lockfiles
|
||||||
|
must not change ERRNO. */
|
||||||
static volatile dotlock_t all_lockfiles;
|
static volatile dotlock_t all_lockfiles;
|
||||||
#ifdef DOTLOCK_USE_PTHREAD
|
#ifdef DOTLOCK_USE_PTHREAD
|
||||||
static pthread_mutex_t all_lockfiles_mutex = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t all_lockfiles_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
@ -434,6 +435,41 @@ static int never_lock;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_DOSISH_SYSTEM
|
||||||
|
static int
|
||||||
|
map_w32_to_errno (DWORD w32_err)
|
||||||
|
{
|
||||||
|
switch (w32_err)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case ERROR_FILE_NOT_FOUND:
|
||||||
|
return ENOENT;
|
||||||
|
|
||||||
|
case ERROR_PATH_NOT_FOUND:
|
||||||
|
return ENOENT;
|
||||||
|
|
||||||
|
case ERROR_ACCESS_DENIED:
|
||||||
|
return EPERM;
|
||||||
|
|
||||||
|
case ERROR_INVALID_HANDLE:
|
||||||
|
case ERROR_INVALID_BLOCK:
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
case ERROR_NOT_ENOUGH_MEMORY:
|
||||||
|
return ENOMEM;
|
||||||
|
|
||||||
|
case ERROR_NO_DATA:
|
||||||
|
case ERROR_BROKEN_PIPE:
|
||||||
|
return EPIPE;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return EIO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /*HAVE_DOSISH_SYSTEM*/
|
||||||
|
|
||||||
|
|
||||||
/* Entirely disable all locking. This function should be called
|
/* Entirely disable all locking. This function should be called
|
||||||
@ -514,11 +550,12 @@ read_lockfile (dotlock_t h, int *same_node )
|
|||||||
continue;
|
continue;
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
{
|
{
|
||||||
|
int e = errno;
|
||||||
my_info_1 ("error reading lockfile '%s'\n", h->lockname );
|
my_info_1 ("error reading lockfile '%s'\n", h->lockname );
|
||||||
close (fd);
|
close (fd);
|
||||||
if (buffer != buffer_space)
|
if (buffer != buffer_space)
|
||||||
xfree (buffer);
|
xfree (buffer);
|
||||||
my_set_errno (0); /* Do not return an inappropriate ERRNO. */
|
my_set_errno (e);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
p += res;
|
p += res;
|
||||||
@ -532,7 +569,7 @@ read_lockfile (dotlock_t h, int *same_node )
|
|||||||
my_info_1 ("invalid size of lockfile '%s'\n", h->lockname);
|
my_info_1 ("invalid size of lockfile '%s'\n", h->lockname);
|
||||||
if (buffer != buffer_space)
|
if (buffer != buffer_space)
|
||||||
xfree (buffer);
|
xfree (buffer);
|
||||||
my_set_errno (0); /* Better don't return an inappropriate ERRNO. */
|
my_set_errno (EINVAL);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -543,7 +580,7 @@ read_lockfile (dotlock_t h, int *same_node )
|
|||||||
my_error_2 ("invalid pid %d in lockfile '%s'\n", pid, h->lockname);
|
my_error_2 ("invalid pid %d in lockfile '%s'\n", pid, h->lockname);
|
||||||
if (buffer != buffer_space)
|
if (buffer != buffer_space)
|
||||||
xfree (buffer);
|
xfree (buffer);
|
||||||
my_set_errno (0);
|
my_set_errno (EINVAL);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -664,12 +701,14 @@ dotlock_create_unix (dotlock_t h, const char *file_to_lock)
|
|||||||
|
|
||||||
if ( fd == -1 )
|
if ( fd == -1 )
|
||||||
{
|
{
|
||||||
|
int saveerrno = errno;
|
||||||
all_lockfiles = h->next;
|
all_lockfiles = h->next;
|
||||||
UNLOCK_all_lockfiles ();
|
UNLOCK_all_lockfiles ();
|
||||||
my_error_2 (_("failed to create temporary file '%s': %s\n"),
|
my_error_2 (_("failed to create temporary file '%s': %s\n"),
|
||||||
h->tname, strerror (errno));
|
h->tname, strerror (errno));
|
||||||
xfree (h->tname);
|
xfree (h->tname);
|
||||||
xfree (h);
|
xfree (h);
|
||||||
|
my_set_errno (saveerrno);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if ( write (fd, pidstr, 11 ) != 11 )
|
if ( write (fd, pidstr, 11 ) != 11 )
|
||||||
@ -696,19 +735,25 @@ dotlock_create_unix (dotlock_t h, const char *file_to_lock)
|
|||||||
h->use_o_excl = 1;
|
h->use_o_excl = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
my_error_2 ("can't check whether hardlinks are supported for '%s': %s\n",
|
{
|
||||||
h->tname, strerror(errno));
|
int saveerrno = errno;
|
||||||
|
my_error_2 ("can't check whether hardlinks are supported for '%s': %s\n"
|
||||||
|
, h->tname, strerror (saveerrno));
|
||||||
|
my_set_errno (saveerrno);
|
||||||
|
}
|
||||||
goto write_failed;
|
goto write_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
h->lockname = xtrymalloc (strlen (file_to_lock) + 6 );
|
h->lockname = xtrymalloc (strlen (file_to_lock) + 6 );
|
||||||
if (!h->lockname)
|
if (!h->lockname)
|
||||||
{
|
{
|
||||||
|
int saveerrno = errno;
|
||||||
all_lockfiles = h->next;
|
all_lockfiles = h->next;
|
||||||
UNLOCK_all_lockfiles ();
|
UNLOCK_all_lockfiles ();
|
||||||
unlink (h->tname);
|
unlink (h->tname);
|
||||||
xfree (h->tname);
|
xfree (h->tname);
|
||||||
xfree (h);
|
xfree (h);
|
||||||
|
my_set_errno (saveerrno);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
strcpy (stpcpy (h->lockname, file_to_lock), EXTSEP_S "lock");
|
strcpy (stpcpy (h->lockname, file_to_lock), EXTSEP_S "lock");
|
||||||
@ -719,6 +764,8 @@ dotlock_create_unix (dotlock_t h, const char *file_to_lock)
|
|||||||
return h;
|
return h;
|
||||||
|
|
||||||
write_failed:
|
write_failed:
|
||||||
|
{
|
||||||
|
int saveerrno = errno;
|
||||||
all_lockfiles = h->next;
|
all_lockfiles = h->next;
|
||||||
UNLOCK_all_lockfiles ();
|
UNLOCK_all_lockfiles ();
|
||||||
my_error_2 (_("error writing to '%s': %s\n"), h->tname, strerror (errno));
|
my_error_2 (_("error writing to '%s': %s\n"), h->tname, strerror (errno));
|
||||||
@ -727,6 +774,8 @@ dotlock_create_unix (dotlock_t h, const char *file_to_lock)
|
|||||||
unlink (h->tname);
|
unlink (h->tname);
|
||||||
xfree (h->tname);
|
xfree (h->tname);
|
||||||
xfree (h);
|
xfree (h);
|
||||||
|
my_set_errno (saveerrno);
|
||||||
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#endif /*HAVE_POSIX_SYSTEM*/
|
#endif /*HAVE_POSIX_SYSTEM*/
|
||||||
@ -784,11 +833,13 @@ dotlock_create_w32 (dotlock_t h, const char *file_to_lock)
|
|||||||
}
|
}
|
||||||
if (h->lockhd == INVALID_HANDLE_VALUE)
|
if (h->lockhd == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
|
int saveerrno = map_w32_to_errno (GetLastError ());
|
||||||
all_lockfiles = h->next;
|
all_lockfiles = h->next;
|
||||||
UNLOCK_all_lockfiles ();
|
UNLOCK_all_lockfiles ();
|
||||||
my_error_2 (_("can't create '%s': %s\n"), h->lockname, w32_strerror (-1));
|
my_error_2 (_("can't create '%s': %s\n"), h->lockname, w32_strerror (-1));
|
||||||
xfree (h->lockname);
|
xfree (h->lockname);
|
||||||
xfree (h);
|
xfree (h);
|
||||||
|
my_set_errno (saveerrno);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return h;
|
return h;
|
||||||
@ -911,7 +962,7 @@ dotlock_destroy_w32 (dotlock_t h)
|
|||||||
#endif /*HAVE_DOSISH_SYSTEM*/
|
#endif /*HAVE_DOSISH_SYSTEM*/
|
||||||
|
|
||||||
|
|
||||||
/* Destroy the locck handle H and release the lock. */
|
/* Destroy the lock handle H and release the lock. */
|
||||||
void
|
void
|
||||||
dotlock_destroy (dotlock_t h)
|
dotlock_destroy (dotlock_t h)
|
||||||
{
|
{
|
||||||
@ -962,6 +1013,7 @@ dotlock_take_unix (dotlock_t h, long timeout)
|
|||||||
int ownerchanged;
|
int ownerchanged;
|
||||||
const char *maybe_dead="";
|
const char *maybe_dead="";
|
||||||
int same_node;
|
int same_node;
|
||||||
|
int saveerrno;
|
||||||
|
|
||||||
again:
|
again:
|
||||||
if (h->use_o_excl)
|
if (h->use_o_excl)
|
||||||
@ -981,8 +1033,10 @@ dotlock_take_unix (dotlock_t h, long timeout)
|
|||||||
; /* Lock held by another process. */
|
; /* Lock held by another process. */
|
||||||
else if (fd == -1)
|
else if (fd == -1)
|
||||||
{
|
{
|
||||||
|
saveerrno = errno;
|
||||||
my_error_2 ("lock not made: open(O_EXCL) of '%s' failed: %s\n",
|
my_error_2 ("lock not made: open(O_EXCL) of '%s' failed: %s\n",
|
||||||
h->lockname, strerror (errno));
|
h->lockname, strerror (saveerrno));
|
||||||
|
my_set_errno (saveerrno);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1000,10 +1054,12 @@ dotlock_take_unix (dotlock_t h, long timeout)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* Write error. */
|
/* Write error. */
|
||||||
|
saveerrno = errno;
|
||||||
my_error_2 ("lock not made: writing to '%s' failed: %s\n",
|
my_error_2 ("lock not made: writing to '%s' failed: %s\n",
|
||||||
h->lockname, strerror (errno));
|
h->lockname, strerror (errno));
|
||||||
close (fd);
|
close (fd);
|
||||||
unlink (h->lockname);
|
unlink (h->lockname);
|
||||||
|
my_set_errno (saveerrno);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1016,11 +1072,13 @@ dotlock_take_unix (dotlock_t h, long timeout)
|
|||||||
|
|
||||||
if (stat (h->tname, &sb))
|
if (stat (h->tname, &sb))
|
||||||
{
|
{
|
||||||
|
saveerrno = errno;
|
||||||
my_error_1 ("lock not made: Oops: stat of tmp file failed: %s\n",
|
my_error_1 ("lock not made: Oops: stat of tmp file failed: %s\n",
|
||||||
strerror (errno));
|
strerror (errno));
|
||||||
/* In theory this might be a severe error: It is possible
|
/* In theory this might be a severe error: It is possible
|
||||||
that link succeeded but stat failed due to changed
|
that link succeeded but stat failed due to changed
|
||||||
permissions. We can't do anything about it, though. */
|
permissions. We can't do anything about it, though. */
|
||||||
|
my_set_errno (saveerrno);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1036,7 +1094,9 @@ dotlock_take_unix (dotlock_t h, long timeout)
|
|||||||
{
|
{
|
||||||
if ( errno != ENOENT )
|
if ( errno != ENOENT )
|
||||||
{
|
{
|
||||||
|
saveerrno = errno;
|
||||||
my_info_0 ("cannot read lockfile\n");
|
my_info_0 ("cannot read lockfile\n");
|
||||||
|
my_set_errno (saveerrno);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
my_info_0 ("lockfile disappeared\n");
|
my_info_0 ("lockfile disappeared\n");
|
||||||
@ -1131,6 +1191,7 @@ dotlock_take_w32 (dotlock_t h, long timeout)
|
|||||||
{
|
{
|
||||||
my_error_2 (_("lock '%s' not made: %s\n"),
|
my_error_2 (_("lock '%s' not made: %s\n"),
|
||||||
h->lockname, w32_strerror (w32err));
|
h->lockname, w32_strerror (w32err));
|
||||||
|
my_set_errno (map_w32_to_errno (w32err));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1161,6 +1222,7 @@ dotlock_take_w32 (dotlock_t h, long timeout)
|
|||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
my_set_errno (EACCES);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif /*HAVE_DOSISH_SYSTEM*/
|
#endif /*HAVE_DOSISH_SYSTEM*/
|
||||||
@ -1200,23 +1262,29 @@ static int
|
|||||||
dotlock_release_unix (dotlock_t h)
|
dotlock_release_unix (dotlock_t h)
|
||||||
{
|
{
|
||||||
int pid, same_node;
|
int pid, same_node;
|
||||||
|
int saveerrno;
|
||||||
|
|
||||||
pid = read_lockfile (h, &same_node);
|
pid = read_lockfile (h, &same_node);
|
||||||
if ( pid == -1 )
|
if ( pid == -1 )
|
||||||
{
|
{
|
||||||
|
saveerrno = errno;
|
||||||
my_error_0 ("release_dotlock: lockfile error\n");
|
my_error_0 ("release_dotlock: lockfile error\n");
|
||||||
|
my_set_errno (saveerrno);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if ( pid != getpid() || !same_node )
|
if ( pid != getpid() || !same_node )
|
||||||
{
|
{
|
||||||
my_error_1 ("release_dotlock: not our lock (pid=%d)\n", pid);
|
my_error_1 ("release_dotlock: not our lock (pid=%d)\n", pid);
|
||||||
|
my_set_errno (EACCES);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( unlink( h->lockname ) )
|
if ( unlink( h->lockname ) )
|
||||||
{
|
{
|
||||||
|
saveerrno = errno;
|
||||||
my_error_1 ("release_dotlock: error removing lockfile '%s'\n",
|
my_error_1 ("release_dotlock: error removing lockfile '%s'\n",
|
||||||
h->lockname);
|
h->lockname);
|
||||||
|
my_set_errno (saveerrno);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/* Fixme: As an extra check we could check whether the link count is
|
/* Fixme: As an extra check we could check whether the link count is
|
||||||
@ -1236,8 +1304,10 @@ dotlock_release_w32 (dotlock_t h)
|
|||||||
memset (&ovl, 0, sizeof ovl);
|
memset (&ovl, 0, sizeof ovl);
|
||||||
if (!UnlockFileEx (h->lockhd, 0, 1, 0, &ovl))
|
if (!UnlockFileEx (h->lockhd, 0, 1, 0, &ovl))
|
||||||
{
|
{
|
||||||
|
int saveerrno = map_w32_to_errno (GetLastError ());
|
||||||
my_error_2 ("release_dotlock: error removing lockfile '%s': %s\n",
|
my_error_2 ("release_dotlock: error removing lockfile '%s': %s\n",
|
||||||
h->lockname, w32_strerror (-1));
|
h->lockname, w32_strerror (-1));
|
||||||
|
my_set_errno (saveerrno);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user