summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS5
-rw-r--r--src/argparse.c2
-rw-r--r--src/gpg-error.def.in2
-rw-r--r--src/gpg-error.h.in3
-rw-r--r--src/gpg-error.vers2
-rw-r--r--src/gpgrt-int.h3
-rw-r--r--src/spawn-w32.c6
-rw-r--r--src/sysutils.c43
-rw-r--r--src/visibility.c6
-rw-r--r--src/visibility.h5
-rw-r--r--tests/t-stringutils.c16
11 files changed, 90 insertions, 3 deletions
diff --git a/NEWS b/NEWS
index f470109..531994e 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,11 @@ Noteworthy changes in version 1.40 (unreleased) [C30/A30/R1]
-----------------------------------------------
+ * Interface changes relative to the 1.39 release:
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ gpgrt_access NEW.
+
+
Noteworthy changes in version 1.39 (2020-08-24) [C30/A30/R0]
-----------------------------------------------
diff --git a/src/argparse.c b/src/argparse.c
index 308a7dc..0415909 100644
--- a/src/argparse.c
+++ b/src/argparse.c
@@ -1467,7 +1467,7 @@ try_versioned_conffile (const char *configname)
endp = dash + strlen (dash) - 1;
while (endp > dash)
{
- if (!access (name, R_OK))
+ if (!_gpgrt_access (name, R_OK))
{
return name;
}
diff --git a/src/gpg-error.def.in b/src/gpg-error.def.in
index 888d9a4..769be1b 100644
--- a/src/gpg-error.def.in
+++ b/src/gpg-error.def.in
@@ -240,4 +240,6 @@ EXPORTS
gpgrt_fcancel @182
+ gpgrt_access @183
+
;; end of file with public symbols for Windows.
diff --git a/src/gpg-error.h.in b/src/gpg-error.h.in
index 925ef51..d2c3b8d 100644
--- a/src/gpg-error.h.in
+++ b/src/gpg-error.h.in
@@ -495,6 +495,9 @@ gpg_err_code_t gpgrt_chdir (const char *name);
/* Return the current WD as a malloced string. */
char *gpgrt_getcwd (void);
+/* A wrapper around access to handle UTF-8 on Windows. */
+gpg_err_code_t gpgrt_access (const char *fname, int mode);
+
diff --git a/src/gpg-error.vers b/src/gpg-error.vers
index e67a16f..aaea22a 100644
--- a/src/gpg-error.vers
+++ b/src/gpg-error.vers
@@ -206,6 +206,8 @@ GPG_ERROR_1.0 {
gpgrt_fnameconcat;
gpgrt_absfnameconcat;
+ gpgrt_access;
+
local:
*;
};
diff --git a/src/gpgrt-int.h b/src/gpgrt-int.h
index 58b156f..fde5ee4 100644
--- a/src/gpgrt-int.h
+++ b/src/gpgrt-int.h
@@ -794,6 +794,9 @@ gpg_err_code_t _gpgrt_chdir (const char *name);
/* Return the current WD as a malloced string. */
char *_gpgrt_getcwd (void);
+/* Wrapper for Windows to allow utf8 file names. */
+gpg_err_code_t _gpgrt_access (const char *fname, int mode);
+
/* Return the home directory of user NAME. */
char *_gpgrt_getpwdir (const char *name);
diff --git a/src/spawn-w32.c b/src/spawn-w32.c
index 12ebe40..3ede1f2 100644
--- a/src/spawn-w32.c
+++ b/src/spawn-w32.c
@@ -826,12 +826,14 @@ _gpgrt_spawn_process_detached (const char *pgmname, const char *argv[],
int cr_flags;
char *cmdline;
int ret;
+ gpg_err_code_t ec;
/* We don't use ENVP. */
(void)envp;
- if (access (pgmname, X_OK))
- return _gpg_err_code_from_syserror ();
+ ec = _gpgrt_access (pgmname, X_OK);
+ if (ec)
+ return ec;
/* Prepare security attributes. */
memset (&sec_attr, 0, sizeof sec_attr );
diff --git a/src/sysutils.c b/src/sysutils.c
index 36daaec..8005a51 100644
--- a/src/sysutils.c
+++ b/src/sysutils.c
@@ -39,6 +39,19 @@
#include "gpgrt-int.h"
+#ifdef HAVE_W32_SYSTEM
+/* Return true if STRING has any 8 bit character. */
+static int
+any8bitchar (const char *string)
+{
+ if (string)
+ for ( ; *string; string++)
+ if ((*string & 0x80))
+ return 1;
+ return 0;
+}
+#endif /*HAVE_W32_SYSTEM*/
+
/* Return true if FD is valid. */
int
@@ -395,6 +408,36 @@ _gpgrt_getcwd (void)
}
+/* Wrapper around access to handle file name encoding under Windows.
+ * Returns 0 if FNAME can be accessed in MODE or an error code. */
+gpg_err_code_t
+_gpgrt_access (const char *fname, int mode)
+{
+ gpg_err_code_t ec;
+
+#ifdef HAVE_W32_SYSTEM
+ if (any8bitchar (fname))
+ {
+ wchar_t *wfname;
+
+ wfname = _gpgrt_utf8_to_wchar (fname);
+ if (!wfname)
+ ec = _gpg_err_code_from_syserror ();
+ else
+ {
+ ec = _waccess (wfname, mode)? _gpg_err_code_from_syserror () : 0;
+ _gpgrt_free_wchar (wfname);
+ }
+ }
+ else
+#endif /*HAVE_W32_SYSTEM*/
+ ec = access (fname, mode)? _gpg_err_code_from_syserror () : 0;
+
+ return ec;
+}
+
+
+
/* Get the standard home directory for user NAME. If NAME is NULL the
* directory for the current user is returned. Caller must release
* the returned string. */
diff --git a/src/visibility.c b/src/visibility.c
index 85caef3..03a6c45 100644
--- a/src/visibility.c
+++ b/src/visibility.c
@@ -847,6 +847,12 @@ gpgrt_getcwd (void)
return _gpgrt_getcwd ();
}
+gpg_err_code_t
+gpgrt_access (const char *fname, int mode)
+{
+ return _gpgrt_access (fname, mode);
+}
+
gpgrt_b64state_t
diff --git a/src/visibility.h b/src/visibility.h
index 3b12acf..f9218b5 100644
--- a/src/visibility.h
+++ b/src/visibility.h
@@ -164,6 +164,7 @@ MARK_VISIBLE (gpgrt_setenv)
MARK_VISIBLE (gpgrt_mkdir)
MARK_VISIBLE (gpgrt_chdir)
MARK_VISIBLE (gpgrt_getcwd)
+MARK_VISIBLE (gpgrt_access);
MARK_VISIBLE (gpgrt_b64dec_start)
MARK_VISIBLE (gpgrt_b64dec_proc)
@@ -224,6 +225,7 @@ MARK_VISIBLE (gpgrt_fnameconcat);
MARK_VISIBLE (gpgrt_absfnameconcat);
+
#undef MARK_VISIBLE
#else /*!_GPGRT_INCL_BY_VISIBILITY_C*/
@@ -347,6 +349,7 @@ MARK_VISIBLE (gpgrt_absfnameconcat);
#define gpgrt_mkdir _gpgrt_USE_UNDERSCORED_FUNCTION
#define gpgrt_chdir _gpgrt_USE_UNDERSCORED_FUNCTION
#define gpgrt_getcwd _gpgrt_USE_UNDERSCORED_FUNCTION
+#define gpgrt_access _gpgrt_USE_UNDERSCORED_FUNCTION
#define gpgrt_set_syscall_clamp _gpgrt_USE_UNDERSCORED_FUNCTION
#define gpgrt_get_syscall_clamp _gpgrt_USE_UNDERSCORED_FUNCTION
@@ -404,6 +407,8 @@ MARK_VISIBLE (gpgrt_absfnameconcat);
#define gpgrt_set_confdir _gpgrt_USE_UNDERSCORED_FUNCTION
#define gpgrt_cmp_version _gpgrt_USE_UNDERSCORED_FUNCTION
+#define gpgrt_fnameconcat _gpgrt_USE_UNDERSCORED_FUNCTION
+#define gpgrt_absfnameconcat _gpgrt_USE_UNDERSCORED_FUNCTION
/* Windows specific functions. */
#define gpgrt_w32_reg_query_string _gpgrt_USE_UNDERSCORED_FUNCTION
diff --git a/tests/t-stringutils.c b/tests/t-stringutils.c
index a7351e5..8879e1a 100644
--- a/tests/t-stringutils.c
+++ b/tests/t-stringutils.c
@@ -325,6 +325,21 @@ check_absfnameconcat (void)
}
+static void
+check_access (void)
+{
+ char *cwd = mygetcwd ();
+
+ if (gpgrt_access (cwd, F_OK))
+ fail ("gpgrt_access(%s) failed: %s\n",
+ cwd, gpg_strerror (gpg_error_from_syserror ()));
+ else
+ show ("gpgrt_access(%s) succeeded\n", cwd);
+
+ xfree (cwd);
+}
+
+
int
main (int argc, char **argv)
{
@@ -373,6 +388,7 @@ main (int argc, char **argv)
check_fnameconcat ();
check_absfnameconcat ();
+ check_access ();
show ("testing string utilities finished\n");
return !!errorcount;