mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +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*/
|
||||
|
||||
|
||||
#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
|
||||
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;
|
||||
all_lockfiles = h;
|
||||
|
||||
h->lockname = xtrymalloc ( strlen (file_to_lock) + 6 );
|
||||
h->lockname = strconcat (file_to_lock, EXTSEP_S "lock", NULL);
|
||||
if (!h->lockname)
|
||||
{
|
||||
all_lockfiles = h->next;
|
||||
@ -802,7 +817,6 @@ dotlock_create_w32 (dotlock_t h, const char *file_to_lock)
|
||||
xfree (h);
|
||||
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
|
||||
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
|
||||
would not stop as expected but spin until Windows crashes. Our
|
||||
solution is to keep the lock file open; that does not harm. */
|
||||
{
|
||||
#ifdef HAVE_W32CE_SYSTEM
|
||||
wchar_t *wname = utf8_to_wchar (h->lockname);
|
||||
if (any8bitchar (h->lockname))
|
||||
{
|
||||
wchar_t *wname = utf8_to_wchar (h->lockname);
|
||||
|
||||
if (wname)
|
||||
h->lockhd = CreateFile (wname,
|
||||
GENERIC_READ|GENERIC_WRITE,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
NULL, OPEN_ALWAYS, 0, NULL);
|
||||
else
|
||||
h->lockhd = INVALID_HANDLE_VALUE;
|
||||
xfree (wname);
|
||||
#else
|
||||
h->lockhd = CreateFile (h->lockname,
|
||||
GENERIC_READ|GENERIC_WRITE,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
NULL, OPEN_ALWAYS, 0, NULL);
|
||||
#endif
|
||||
}
|
||||
if (wname)
|
||||
h->lockhd = CreateFileW (wname,
|
||||
GENERIC_READ|GENERIC_WRITE,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
NULL, OPEN_ALWAYS, 0, NULL);
|
||||
else
|
||||
h->lockhd = INVALID_HANDLE_VALUE;
|
||||
xfree (wname);
|
||||
}
|
||||
else
|
||||
h->lockhd = CreateFileA (h->lockname,
|
||||
GENERIC_READ|GENERIC_WRITE,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
NULL, OPEN_ALWAYS, 0, NULL);
|
||||
if (h->lockhd == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
int saveerrno = map_w32_to_errno (GetLastError ());
|
||||
|
@ -41,22 +41,166 @@
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
# include "windows.h"
|
||||
#endif
|
||||
|
||||
#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"
|
||||
|
||||
|
||||
static volatile int ctrl_c_pending;
|
||||
|
||||
#ifndef HAVE_W32_SYSTEM
|
||||
static volatile int ctrl_c_pending_flag;
|
||||
static void
|
||||
control_c_handler (int 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
|
||||
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));
|
||||
inf ("lock created");
|
||||
|
||||
while (!ctrl_c_pending)
|
||||
while (!ctrl_c_pending ())
|
||||
{
|
||||
if (dotlock_take (h, -1))
|
||||
die ("error taking lock");
|
||||
@ -119,8 +263,15 @@ main (int argc, char **argv)
|
||||
if (argc > 1)
|
||||
fname = argv[1];
|
||||
else
|
||||
fname = "t-dotlock.tmp";
|
||||
{
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
fname = "t-dotⒶlock.tmp";
|
||||
#else
|
||||
fname = "t-dotlock.tmp";
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef HAVE_W32_SYSTEM
|
||||
{
|
||||
struct sigaction nact;
|
||||
|
||||
@ -128,6 +279,7 @@ main (int argc, char **argv)
|
||||
nact.sa_flags = 0;
|
||||
sigaction (SIGINT, &nact, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
dotlock_create (NULL, 0); /* Initialize (optional). */
|
||||
|
||||
@ -140,6 +292,6 @@ main (int argc, char **argv)
|
||||
|
||||
/*
|
||||
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:
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user