Mercurial > octave
changeset 26843:f07542e3a9b9
Fix "exist" for drive letters and UNC shares on Windows (bug #55824).
* sysdep.[h,cc] (drive_or_unc_share): New function.
* variables.cc (symbol_exist): Use this function.
author | Markus Mützel <markus.muetzel@gmx.de> |
---|---|
date | Tue, 05 Mar 2019 22:24:00 +0100 |
parents | 05d492bb8ab8 |
children | d8712d26d086 |
files | libinterp/corefcn/sysdep.cc libinterp/corefcn/sysdep.h libinterp/corefcn/variables.cc |
diffstat | 3 files changed, 58 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/corefcn/sysdep.cc Tue Mar 05 22:04:24 2019 +0100 +++ b/libinterp/corefcn/sysdep.cc Tue Mar 05 22:24:00 2019 +0100 @@ -320,6 +320,57 @@ #endif } + // Return TRUE if NAME refers to an existing drive letter or UNC share + + bool drive_or_unc_share (const std::string& name) + { +#if defined (OCTAVE_USE_WINDOWS_API) + size_t len = name.length (); + bool candidate = false; + if (len > 1 && isalpha(name[0]) && name[1]==':' + && (len == 2 || name[2] == '\\')) + candidate = true; + if (len > 4 && name[0] == '\\' && name[1] == '\\') + { + // It starts with two slashes. Find the next slash. + size_t next_slash = name.find ("\\", 3); + if (next_slash != -1 && len > next_slash+1) + { + // Check if it ends with the share + size_t last_slash = name.find ("\\", next_slash+1); + if (last_slash == -1 || + (len > next_slash+2 && last_slash == len-1)) + candidate = true; + } + } + + if (candidate) + { + // Open a handle to the file. + std::wstring wname = octave::sys::u8_to_wstring (name); + HANDLE h = + CreateFileW (wname.c_str (), FILE_READ_ATTRIBUTES, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, + nullptr); + if (h != INVALID_HANDLE_VALUE) + { + CloseHandle (h); + return true; + } + } + + return false; + +#else + + octave_unused_parameter (name); + + return false; + +#endif + } + void sysdep_init (void) { // Use a function from libgomp to force loading of OpenMP library.
--- a/libinterp/corefcn/sysdep.h Tue Mar 05 22:04:24 2019 +0100 +++ b/libinterp/corefcn/sysdep.h Tue Mar 05 22:24:00 2019 +0100 @@ -52,6 +52,8 @@ extern OCTINTERP_API bool same_file_internal (const std::string&, const std::string&); + + extern OCTINTERP_API bool drive_or_unc_share (const std::string&); } #if defined (OCTAVE_USE_DEPRECATED_FUNCTIONS)
--- a/libinterp/corefcn/variables.cc Tue Mar 05 22:04:24 2019 +0100 +++ b/libinterp/corefcn/variables.cc Tue Mar 05 22:24:00 2019 +0100 @@ -63,6 +63,7 @@ #include "parse.h" #include "syminfo.h" #include "symtab.h" +#include "sysdep.h" #include "unwind-prot.h" #include "utils.h" #include "variables.h" @@ -270,6 +271,10 @@ if (file_name.empty ()) file_name = name; + // "stat" doesn't work on UNC shares and drive letters. + if ((search_any || search_file) && octave::drive_or_unc_share (file_name)) + return 7; + octave::sys::file_stat fs (file_name); if (fs)