diff --git a/common/iobuf.c b/common/iobuf.c index a5b8d5955..e82e75d1b 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -198,6 +198,19 @@ fd_cache_strcmp (const char *a, const char *b) #endif } + +#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*/ + /* * Invalidate (i.e. close) a cached iobuf */ @@ -299,21 +312,23 @@ direct_open (const char *fname, const char *mode, int mode700) sm = FILE_SHARE_READ; } -#ifdef HAVE_W32CE_SYSTEM - { - wchar_t *wfname = utf8_to_wchar (fname); - if (wfname) - { - hfile = CreateFile (wfname, da, sm, NULL, cd, - FILE_ATTRIBUTE_NORMAL, NULL); - xfree (wfname); - } - else - hfile = INVALID_HANDLE_VALUE; - } -#else - hfile = CreateFile (fname, da, sm, NULL, cd, FILE_ATTRIBUTE_NORMAL, NULL); -#endif + /* We use the Unicode version of the function only if needed to + * avoid an extra conversion step. */ + if (any8bitchar (fname)) + { + wchar_t *wfname = utf8_to_wchar (fname); + if (wfname) + { + hfile = CreateFileW (wfname, da, sm, NULL, cd, + FILE_ATTRIBUTE_NORMAL, NULL); + xfree (wfname); + } + else + hfile = INVALID_HANDLE_VALUE; + } + else + hfile = CreateFileA (fname, da, sm, NULL, cd, FILE_ATTRIBUTE_NORMAL, NULL); + return hfile; #else /*!HAVE_W32_SYSTEM*/ diff --git a/common/sysutils.c b/common/sysutils.c index 6738da108..bfb5d7dd8 100644 --- a/common/sysutils.c +++ b/common/sysutils.c @@ -182,6 +182,18 @@ enable_core_dumps (void) #endif } +#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*/ + /* Allow the use of special "-&nnn" style file names. */ void @@ -1066,6 +1078,30 @@ gnupg_access (const char *name, int mode) #endif } +/* A wrapper around open to handle Unicode file names under Windows. */ +int +gnupg_open (const char *name, int flags, unsigned int mode) +{ +#ifdef HAVE_W32_SYSTEM + if (any8bitchar (name)) + { + wchar_t *wname; + int ret; + + wname = utf8_to_wchar (name); + if (!wname) + return -1; + ret = _wopen (wname, flags, mode); + xfree (wname); + return ret; + } + else + return open (name, flags, mode); +#else + return open (name, flags, mode); +#endif +} + /* Try to set an envvar. Print only a notice on error. */ #ifndef HAVE_W32_SYSTEM diff --git a/common/sysutils.h b/common/sysutils.h index 12b45e47c..d088fe29f 100644 --- a/common/sysutils.h +++ b/common/sysutils.h @@ -74,6 +74,7 @@ int gnupg_setenv (const char *name, const char *value, int overwrite); int gnupg_unsetenv (const char *name); char *gnupg_getcwd (void); gpg_err_code_t gnupg_access (const char *name, int mode); +int gnupg_open (const char *name, int flags, unsigned int mode); gpg_error_t gnupg_chuid (const char *user, int silent); char *gnupg_get_socket_name (int fd); int gnupg_fd_valid (int fd); diff --git a/dirmngr/crlcache.c b/dirmngr/crlcache.c index 131a0bd8d..54caf4136 100644 --- a/dirmngr/crlcache.c +++ b/dirmngr/crlcache.c @@ -1142,7 +1142,7 @@ lock_db_file (crl_cache_t cache, crl_cache_entry_t entry) xfree (fname); return NULL; } - fd = open (fname, O_RDONLY | O_BINARY); + fd = gnupg_open (fname, O_RDONLY | O_BINARY, 0); if (fd == -1) { log_error (_("error opening cache file '%s': %s\n"), @@ -2226,7 +2226,7 @@ crl_cache_insert (ctrl_t ctrl, const char *url, ksba_reader_t reader) } } - fd_cdb = open (fname, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644); + fd_cdb = gnupg_open (fname, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644); if (fd_cdb == -1) { err = gpg_error_from_errno (errno); diff --git a/g10/gpg.c b/g10/gpg.c index 412867b91..1b1d18969 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -1407,10 +1407,10 @@ open_info_file (const char *fname, int for_write, int binary) do { if (for_write) - fd = open (fname, O_CREAT | O_TRUNC | O_WRONLY | binary, - S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); + fd = gnupg_open (fname, O_CREAT | O_TRUNC | O_WRONLY | binary, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); else - fd = open (fname, O_RDONLY | binary); + fd = gnupg_open (fname, O_RDONLY | binary, 0); } while (fd == -1 && errno == EINTR); /* } */ diff --git a/g10/tdbio.c b/g10/tdbio.c index fdb90ec53..193f80dc2 100644 --- a/g10/tdbio.c +++ b/g10/tdbio.c @@ -753,7 +753,7 @@ tdbio_set_dbname (ctrl_t ctrl, const char *new_dbname, log_fatal (_("can't create '%s': %s\n"), fname, strerror (errno)); es_fclose (fp); - db_fd = open (db_name, O_RDWR | MY_O_BINARY); + db_fd = gnupg_open (db_name, O_RDWR | MY_O_BINARY, 0); if (db_fd == -1) log_fatal (_("can't open '%s': %s\n"), db_name, strerror (errno)); @@ -813,7 +813,7 @@ open_db () (int)prevrc, (int)GetLastError ()); } #else /*!HAVE_W32CE_SYSTEM*/ - db_fd = open (db_name, O_RDWR | MY_O_BINARY ); + db_fd = gnupg_open (db_name, O_RDWR | MY_O_BINARY, 0); if (db_fd == -1 && (errno == EACCES #ifdef EROFS || errno == EROFS @@ -821,7 +821,7 @@ open_db () ) ) { /* Take care of read-only trustdbs. */ - db_fd = open (db_name, O_RDONLY | MY_O_BINARY ); + db_fd = gnupg_open (db_name, O_RDONLY | MY_O_BINARY, 0); if (db_fd != -1 && !opt.quiet) log_info (_("Note: trustdb not writable\n")); } diff --git a/sm/gpgsm.c b/sm/gpgsm.c index ef5f801c8..e461f99fe 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -2324,7 +2324,7 @@ open_read (const char *filename) fd = check_special_filename (filename, 0, 0); if (fd != -1) return fd; - fd = open (filename, O_RDONLY | O_BINARY); + fd = gnupg_open (filename, O_RDONLY | O_BINARY, 0); if (fd == -1) { log_error (_("can't open '%s': %s\n"), filename, strerror (errno)); diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index 5efe6e50a..26f213666 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -2226,8 +2226,9 @@ change_options_program (gc_component_id_t component, *dest_filenamep = dest_filename; *orig_filenamep = orig_filename; - /* Use open() so that we can use O_EXCL. */ - fd = open (src_filename, O_CREAT | O_EXCL | O_WRONLY, 0644); + /* Use open() so that we can use O_EXCL. + * FIXME: gpgrt has an x flag for quite some time now - use that. */ + fd = gnupg_open (src_filename, O_CREAT | O_EXCL | O_WRONLY, 0644); if (fd < 0) return -1; src_file = gpgrt_fdopen (fd, "w");