# HG changeset patch # User Markus Mützel # Date 1609752208 -3600 # Mon Jan 04 10:23:28 2021 +0100 # Node ID dc5f79ef15e40fd3a849e252d8aa9ed27d2ffeef # Parent 11343ca3c125682645efc2d6f46bf7270dc32180 load-path: Use unique id as key for private function map (bug #59711). * liboctave/system/lo-sysdep.cc, liboctave/system/lo-sysdep.h (oct_uid_from_fname): Add new function that returns a structure that uniquely identifies a file cross-platform. * libinterp/corefcn/load-path.cc, libinterp/corefcn/load-path.h: Use new structure as key in the private function file map. diff -r 11343ca3c125 -r dc5f79ef15e4 libinterp/corefcn/load-path.cc --- a/libinterp/corefcn/load-path.cc Thu Dec 17 20:18:51 2020 -0500 +++ b/libinterp/corefcn/load-path.cc Mon Jan 04 10:23:28 2021 +0100 @@ -1598,7 +1598,7 @@ remove_fcn_map (dir, fcn_files); - remove_private_fcn_map (sys::canonicalize_file_name (dir)); + remove_private_fcn_map (dir); remove_method_map (dir); } @@ -1617,7 +1617,7 @@ for (const auto& dir_fnlst : private_fcn_map) { os << "\n*** private functions in " - << sys::file_ops::concat (dir_fnlst.first, "private") + << sys::file_ops::concat (dir_fnlst.first.fname, "private") << ":\n\n"; print_fcn_list (os, dir_fnlst.second); @@ -1730,7 +1730,8 @@ // update (); - const_private_fcn_map_iterator q = private_fcn_map.find (dir); + const_private_fcn_map_iterator q + = private_fcn_map.find (sys::oct_uid_from_fname (dir)); if (q != private_fcn_map.end ()) { @@ -1965,7 +1966,7 @@ dir_info::fcn_file_map_type private_file_map = di.private_file_map; if (! private_file_map.empty ()) - private_fcn_map[sys::canonicalize_file_name (di.dir_name)] + private_fcn_map[sys::oct_uid_from_fname (di.dir_name)] = private_file_map; } @@ -2029,7 +2030,7 @@ dir_info::fcn_file_map_type private_file_map = ci.private_file_map; if (! private_file_map.empty ()) - private_fcn_map[sys::canonicalize_file_name (full_dir_name)] + private_fcn_map[sys::oct_uid_from_fname (full_dir_name)] = private_file_map; } } @@ -2169,7 +2170,7 @@ void load_path::package_info::remove_private_fcn_map (const std::string& dir) { - auto p = private_fcn_map.find (sys::canonicalize_file_name (dir)); + auto p = private_fcn_map.find (sys::oct_uid_from_fname (dir)); if (p != private_fcn_map.end ()) private_fcn_map.erase (p); diff -r 11343ca3c125 -r dc5f79ef15e4 libinterp/corefcn/load-path.h --- a/libinterp/corefcn/load-path.h Thu Dec 17 20:18:51 2020 -0500 +++ b/libinterp/corefcn/load-path.h Mon Jan 04 10:23:28 2021 +0100 @@ -36,6 +36,7 @@ #include #include "oct-time.h" +#include "lo-sysdep.h" #include "pathsearch.h" #include "str-vec.h" @@ -376,7 +377,7 @@ typedef fcn_map_type::iterator fcn_map_iterator; // > - typedef std::map + typedef std::map private_fcn_map_type; typedef private_fcn_map_type::const_iterator const_private_fcn_map_iterator; diff -r 11343ca3c125 -r dc5f79ef15e4 liboctave/system/lo-sysdep.cc --- a/liboctave/system/lo-sysdep.cc Thu Dec 17 20:18:51 2020 -0500 +++ b/liboctave/system/lo-sysdep.cc Mon Jan 04 10:23:28 2021 +0100 @@ -47,6 +47,8 @@ # include "lo-hash.h" # include "oct-locbuf.h" # include "unwind-prot.h" +#else +# include "file-stat.h" #endif namespace octave @@ -714,5 +716,48 @@ return orig_file_name; } + + oct_uid oct_uid_from_fname (const std::string& fname) + { + oct_uid ret; + ret.fname = fname; +#if defined (OCTAVE_USE_WINDOWS_API) + ret.dev = 0; + ret.ino1 = 0; + ret.ino2 = 0; + + std::wstring wfname = u8_to_wstring (fname); + HANDLE h_file + = CreateFileW (wfname.c_str (), GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, + nullptr); + if (h_file) + { + BY_HANDLE_FILE_INFORMATION file_information; + if (GetFileInformationByHandle (h_file, &file_information)) + { + ret.dev = file_information.dwVolumeSerialNumber; + ret.ino1 = file_information.nFileIndexHigh; + ret.ino2 = file_information.nFileIndexLow; + } + CloseHandle (h_file); + } +#else + file_stat fs (fname); + if (fs) + { + ret.dev = fs.dev (); + ret.ino1 = fs.ino (); + } + else + { + ret.dev = 0; + ret.ino1 = 0; + } + ret.ino2 = 0; +#endif + return ret; + } } } diff -r 11343ca3c125 -r dc5f79ef15e4 liboctave/system/lo-sysdep.h --- a/liboctave/system/lo-sysdep.h Thu Dec 17 20:18:51 2020 -0500 +++ b/liboctave/system/lo-sysdep.h Mon Jan 04 10:23:28 2021 +0100 @@ -80,6 +80,23 @@ extern OCTAVE_API std::string get_ASCII_filename (const std::string& long_file_name, const bool allow_locale = false); + + // structure that uniquely identifies files cross-platform + struct oct_uid + { + intmax_t dev; + intmax_t ino1; + intmax_t ino2; + std::string fname; + + bool operator < (const oct_uid &b) const + { + return (dev < b.dev || (dev == b.dev && ino1 < b.ino1) || + (dev == b.dev && ino1 == b.ino1 && ino2 < b.ino2)); + } + }; + + extern OCTAVE_API oct_uid oct_uid_from_fname (const std::string& fname); } }