mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-08 12:44:23 +01:00
w32: Allow Unicode filenames for dotlock
* common/dotlock.c (any8bitchar) [W32]: New. (dotlock_create_w32): Use strconcat and CreateFileW. * common/t-dotlock.c: Source include dotlock.c and modify to allow manual testing on Windows. -- GnuPG-bug-id: 5098 Signed-off-by: Werner Koch <wk@gnupg.org> (cherry picked from commit b47c355b18d9537ccc3dd3e80cc1825b018ecff7)
This commit is contained in:
parent
5c6e9b44cc
commit
d65ea29683
@ -471,6 +471,21 @@ map_w32_to_errno (DWORD w32_err)
|
|||||||
}
|
}
|
||||||
#endif /*HAVE_DOSISH_SYSTEM*/
|
#endif /*HAVE_DOSISH_SYSTEM*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_W32_SYSTEM
|
||||||
|
static int
|
||||||
|
any8bitchar (const char *string)
|
||||||
|
{
|
||||||
|
if (string)
|
||||||
|
for ( ; *string; string++)
|
||||||
|
if ((*string & 0x80))
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /*HAVE_W32_SYSTEM*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Entirely disable all locking. This function should be called
|
/* Entirely disable all locking. This function should be called
|
||||||
before any locking is done. It may be called right at startup of
|
before any locking is done. It may be called right at startup of
|
||||||
@ -794,7 +809,7 @@ dotlock_create_w32 (dotlock_t h, const char *file_to_lock)
|
|||||||
h->next = all_lockfiles;
|
h->next = all_lockfiles;
|
||||||
all_lockfiles = h;
|
all_lockfiles = h;
|
||||||
|
|
||||||
h->lockname = xtrymalloc ( strlen (file_to_lock) + 6 );
|
h->lockname = strconcat (file_to_lock, EXTSEP_S "lock", NULL);
|
||||||
if (!h->lockname)
|
if (!h->lockname)
|
||||||
{
|
{
|
||||||
all_lockfiles = h->next;
|
all_lockfiles = h->next;
|
||||||
@ -802,7 +817,6 @@ dotlock_create_w32 (dotlock_t h, const char *file_to_lock)
|
|||||||
xfree (h);
|
xfree (h);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
strcpy (stpcpy(h->lockname, file_to_lock), EXTSEP_S "lock");
|
|
||||||
|
|
||||||
/* If would be nice if we would use the FILE_FLAG_DELETE_ON_CLOSE
|
/* 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
|
along with FILE_SHARE_DELETE but that does not work due to a race
|
||||||
@ -812,25 +826,24 @@ dotlock_create_w32 (dotlock_t h, const char *file_to_lock)
|
|||||||
reasons why a lock file can't be created and thus the process
|
reasons why a lock file can't be created and thus the process
|
||||||
would not stop as expected but spin until Windows crashes. Our
|
would not stop as expected but spin until Windows crashes. Our
|
||||||
solution is to keep the lock file open; that does not harm. */
|
solution is to keep the lock file open; that does not harm. */
|
||||||
|
if (any8bitchar (h->lockname))
|
||||||
{
|
{
|
||||||
#ifdef HAVE_W32CE_SYSTEM
|
|
||||||
wchar_t *wname = utf8_to_wchar (h->lockname);
|
wchar_t *wname = utf8_to_wchar (h->lockname);
|
||||||
|
|
||||||
if (wname)
|
if (wname)
|
||||||
h->lockhd = CreateFile (wname,
|
h->lockhd = CreateFileW (wname,
|
||||||
GENERIC_READ|GENERIC_WRITE,
|
GENERIC_READ|GENERIC_WRITE,
|
||||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||||
NULL, OPEN_ALWAYS, 0, NULL);
|
NULL, OPEN_ALWAYS, 0, NULL);
|
||||||
else
|
else
|
||||||
h->lockhd = INVALID_HANDLE_VALUE;
|
h->lockhd = INVALID_HANDLE_VALUE;
|
||||||
xfree (wname);
|
xfree (wname);
|
||||||
#else
|
}
|
||||||
h->lockhd = CreateFile (h->lockname,
|
else
|
||||||
|
h->lockhd = CreateFileA (h->lockname,
|
||||||
GENERIC_READ|GENERIC_WRITE,
|
GENERIC_READ|GENERIC_WRITE,
|
||||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||||
NULL, OPEN_ALWAYS, 0, NULL);
|
NULL, OPEN_ALWAYS, 0, NULL);
|
||||||
#endif
|
|
||||||
}
|
|
||||||
if (h->lockhd == INVALID_HANDLE_VALUE)
|
if (h->lockhd == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
int saveerrno = map_w32_to_errno (GetLastError ());
|
int saveerrno = map_w32_to_errno (GetLastError ());
|
||||||
|
@ -41,22 +41,166 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#ifdef HAVE_W32_SYSTEM
|
||||||
|
# include "windows.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "dotlock.h"
|
#include "dotlock.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_W32_SYSTEM
|
||||||
|
#define DIM(v) (sizeof(v)/sizeof((v)[0]))
|
||||||
|
|
||||||
|
const char *
|
||||||
|
w32_strerror (int ec)
|
||||||
|
{
|
||||||
|
static char strerr[256];
|
||||||
|
|
||||||
|
if (ec == -1)
|
||||||
|
ec = (int)GetLastError ();
|
||||||
|
#ifdef HAVE_W32CE_SYSTEM
|
||||||
|
/* There is only a wchar_t FormatMessage. It does not make much
|
||||||
|
sense to play the conversion game; we print only the code. */
|
||||||
|
snprintf (strerr, sizeof strerr, "ec=%d", (int)GetLastError ());
|
||||||
|
#else
|
||||||
|
FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, ec,
|
||||||
|
MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
|
strerr, DIM (strerr)-1, NULL);
|
||||||
|
{
|
||||||
|
/* Strip the CR,LF - we want just the string. */
|
||||||
|
size_t n = strlen (strerr);
|
||||||
|
if (n > 2 && strerr[n-2] == '\r' && strerr[n-1] == '\n' )
|
||||||
|
strerr[n-2] = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return strerr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static wchar_t *
|
||||||
|
cp_to_wchar (const char *string, unsigned int codepage)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
size_t nbytes;
|
||||||
|
wchar_t *result;
|
||||||
|
|
||||||
|
n = MultiByteToWideChar (codepage, 0, string, -1, NULL, 0);
|
||||||
|
if (n < 0)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
nbytes = (size_t)(n+1) * sizeof(*result);
|
||||||
|
if (nbytes / sizeof(*result) != (n+1))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
result = malloc (nbytes);
|
||||||
|
if (!result)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
n = MultiByteToWideChar (codepage, 0, string, -1, result, n);
|
||||||
|
if (n < 0)
|
||||||
|
{
|
||||||
|
free (result);
|
||||||
|
result = NULL;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
wchar_t *
|
||||||
|
utf8_to_wchar (const char *string)
|
||||||
|
{
|
||||||
|
return cp_to_wchar (string, CP_UTF8);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
stpcpy(char *a,const char *b)
|
||||||
|
{
|
||||||
|
while( *b )
|
||||||
|
*a++ = *b++;
|
||||||
|
*a = 0;
|
||||||
|
|
||||||
|
return (char*)a;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
do_strconcat (const char *s1, va_list arg_ptr)
|
||||||
|
{
|
||||||
|
const char *argv[48];
|
||||||
|
size_t argc;
|
||||||
|
size_t needed;
|
||||||
|
char *buffer, *p;
|
||||||
|
|
||||||
|
argc = 0;
|
||||||
|
argv[argc++] = s1;
|
||||||
|
needed = strlen (s1);
|
||||||
|
while (((argv[argc] = va_arg (arg_ptr, const char *))))
|
||||||
|
{
|
||||||
|
needed += strlen (argv[argc]);
|
||||||
|
if (argc >= DIM (argv)-1)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
argc++;
|
||||||
|
}
|
||||||
|
needed++;
|
||||||
|
buffer = malloc (needed);
|
||||||
|
if (buffer)
|
||||||
|
{
|
||||||
|
for (p = buffer, argc=0; argv[argc]; argc++)
|
||||||
|
p = stpcpy (p, argv[argc]);
|
||||||
|
}
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Concatenate the string S1 with all the following strings up to a
|
||||||
|
NULL. Returns a malloced buffer with the new string or NULL on a
|
||||||
|
malloc error or if too many arguments are given. */
|
||||||
|
char *
|
||||||
|
strconcat (const char *s1, ...)
|
||||||
|
{
|
||||||
|
va_list arg_ptr;
|
||||||
|
char *result;
|
||||||
|
|
||||||
|
if (!s1)
|
||||||
|
result = calloc (1, 1);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
va_start (arg_ptr, s1);
|
||||||
|
result = do_strconcat (s1, arg_ptr);
|
||||||
|
va_end (arg_ptr);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endif /*HAVE_W32_SYSTEM*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "dotlock.c"
|
||||||
|
|
||||||
#define PGM "t-dotlock"
|
#define PGM "t-dotlock"
|
||||||
|
|
||||||
|
#ifndef HAVE_W32_SYSTEM
|
||||||
static volatile int ctrl_c_pending;
|
static volatile int ctrl_c_pending_flag;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
control_c_handler (int signo)
|
control_c_handler (int signo)
|
||||||
{
|
{
|
||||||
(void)signo;
|
(void)signo;
|
||||||
ctrl_c_pending = 1;
|
ctrl_c_pending_flag = 1;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
ctrl_c_pending (void)
|
||||||
|
{
|
||||||
|
#if HAVE_W32_SYSTEM
|
||||||
|
static int count;
|
||||||
|
|
||||||
|
return (++count > 9);
|
||||||
|
#else
|
||||||
|
return ctrl_c_pending_flag;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
die (const char *format, ...)
|
die (const char *format, ...)
|
||||||
@ -95,7 +239,7 @@ lock_and_unlock (const char *fname)
|
|||||||
die ("error creating lock file for '%s': %s", fname, strerror (errno));
|
die ("error creating lock file for '%s': %s", fname, strerror (errno));
|
||||||
inf ("lock created");
|
inf ("lock created");
|
||||||
|
|
||||||
while (!ctrl_c_pending)
|
while (!ctrl_c_pending ())
|
||||||
{
|
{
|
||||||
if (dotlock_take (h, -1))
|
if (dotlock_take (h, -1))
|
||||||
die ("error taking lock");
|
die ("error taking lock");
|
||||||
@ -119,8 +263,15 @@ main (int argc, char **argv)
|
|||||||
if (argc > 1)
|
if (argc > 1)
|
||||||
fname = argv[1];
|
fname = argv[1];
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
#ifdef HAVE_W32_SYSTEM
|
||||||
|
fname = "t-dotⒶlock.tmp";
|
||||||
|
#else
|
||||||
fname = "t-dotlock.tmp";
|
fname = "t-dotlock.tmp";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef HAVE_W32_SYSTEM
|
||||||
{
|
{
|
||||||
struct sigaction nact;
|
struct sigaction nact;
|
||||||
|
|
||||||
@ -128,6 +279,7 @@ main (int argc, char **argv)
|
|||||||
nact.sa_flags = 0;
|
nact.sa_flags = 0;
|
||||||
sigaction (SIGINT, &nact, NULL);
|
sigaction (SIGINT, &nact, NULL);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
dotlock_create (NULL, 0); /* Initialize (optional). */
|
dotlock_create (NULL, 0); /* Initialize (optional). */
|
||||||
|
|
||||||
@ -140,6 +292,6 @@ main (int argc, char **argv)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Local Variables:
|
Local Variables:
|
||||||
compile-command: "cc -Wall -O2 -D_FILE_OFFSET_BITS=64 -o t-dotlock t-dotlock.c dotlock.c"
|
compile-command: "cc -Wall -O2 -D_FILE_OFFSET_BITS=64 -o t-dotlock t-dotlock.c"
|
||||||
End:
|
End:
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user