diff options
-rw-r--r-- | NEWS | 5 | ||||
-rw-r--r-- | src/argparse.c | 2 | ||||
-rw-r--r-- | src/gpg-error.def.in | 2 | ||||
-rw-r--r-- | src/gpg-error.h.in | 3 | ||||
-rw-r--r-- | src/gpg-error.vers | 2 | ||||
-rw-r--r-- | src/gpgrt-int.h | 3 | ||||
-rw-r--r-- | src/spawn-w32.c | 6 | ||||
-rw-r--r-- | src/sysutils.c | 43 | ||||
-rw-r--r-- | src/visibility.c | 6 | ||||
-rw-r--r-- | src/visibility.h | 5 | ||||
-rw-r--r-- | tests/t-stringutils.c | 16 |
11 files changed, 90 insertions, 3 deletions
@@ -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; |