summaryrefslogtreecommitdiffstats
path: root/common/t-dotlock.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2020-10-20 13:38:11 +0200
committerWerner Koch <wk@gnupg.org>2020-10-20 13:38:11 +0200
commitb47c355b18d9537ccc3dd3e80cc1825b018ecff7 (patch)
tree2ca24c9657c4897b67c812a5b6b0249f9d0b6046 /common/t-dotlock.c
parentReplace most of the remaining stdio calls by estream calls. (diff)
downloadgnupg2-b47c355b18d9537ccc3dd3e80cc1825b018ecff7.tar.xz
gnupg2-b47c355b18d9537ccc3dd3e80cc1825b018ecff7.zip
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>
Diffstat (limited to '')
-rw-r--r--common/t-dotlock.c164
1 files changed, 158 insertions, 6 deletions
diff --git a/common/t-dotlock.c b/common/t-dotlock.c
index f7aee09d3..e2d22f66d 100644
--- a/common/t-dotlock.c
+++ b/common/t-dotlock.c
@@ -41,21 +41,165 @@
#include <errno.h>
#include <signal.h>
#include <unistd.h>
+#ifdef HAVE_W32_SYSTEM
+# include "windows.h"
+#endif
#include "dotlock.h"
-#define PGM "t-dotlock"
+#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*/
-static volatile int ctrl_c_pending;
+#include "dotlock.c"
+
+#define PGM "t-dotlock"
+#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
@@ -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:
*/