26#if defined (HAVE_CONFIG_H)
34#if defined (OCTAVE_USE_WINDOWS_API)
52#if defined (OCTAVE_USE_WINDOWS_API)
65#if defined (OCTAVE_USE_WINDOWS_API)
74 SECURITY_ATTRIBUTES sa {};
75 sa.nLength =
sizeof (sa);
76 sa.bInheritHandle = TRUE;
77 sa.lpSecurityDescriptor =
nullptr;
79 if (! CreatePipe (&h_read, &h_write, &sa, 0))
80 return GetLastError ();
83 SetHandleInformation (h_read, HANDLE_FLAG_INHERIT, 0);
86 std::wstring wcmd_str {L
"cmd.exe /C \""};
88 wcmd_str.append (L
"\"");
91 si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
92 si.wShowWindow = SW_HIDE;
93 si.hStdOutput = h_write;
94 si.hStdError = h_write;
95 si.hStdInput = GetStdHandle (STD_INPUT_HANDLE);
96 PROCESS_INFORMATION pi {};
98 BOOL ok = CreateProcessW (
nullptr, &wcmd_str[0],
nullptr,
nullptr, TRUE,
99 CREATE_NEW_CONSOLE,
nullptr,
nullptr, &si, &pi);
101 CloseHandle (h_write);
105 CloseHandle (h_read);
106 return GetLastError ();
112 while (ReadFile (h_read, buffer,
sizeof (buffer)-1, &bytes_read,
nullptr)
115 buffer[bytes_read] =
'\0';
119 WaitForSingleObject (pi.hProcess, INFINITE);
122 GetExitCodeProcess (pi.hProcess, &ret);
124 CloseHandle (pi.hProcess);
125 CloseHandle (pi.hThread);
126 CloseHandle (h_read);
131 return ::system (cmd_str.c_str ());
140#if defined (OCTAVE_USE_WINDOWS_API)
141 wchar_t *tmp = _wgetcwd (
nullptr, 0);
144 (*current_liboctave_error_handler) (
"unable to find current directory");
146 std::wstring tmp_wstr (tmp);
161 (*current_liboctave_error_handler) (
"unable to find current directory");
173 std::string path = sys::file_ops::tilde_expand (path_arg);
175#if defined (OCTAVE_USE_WINDOWS_API)
176 if (path.length () == 2 && path[1] ==
':')
189#if defined (OCTAVE_USE_WINDOWS_API)
190 _WIN32_FIND_DATAW ffd;
192 std::string path_name (
dirname);
193 if (path_name.empty ())
196 if (path_name.back () ==
'\\' || path_name.back () ==
'/')
197 path_name.push_back (
'*');
199 path_name.append (R
"(\*)");
203 HANDLE hFind = FindFirstFileW (wpath_name.c_str (), &ffd);
204 if (INVALID_HANDLE_VALUE == hFind)
206 DWORD errCode = GetLastError ();
207 char *errorText =
nullptr;
208 FormatMessageA (FORMAT_MESSAGE_FROM_SYSTEM |
209 FORMAT_MESSAGE_ALLOCATE_BUFFER |
210 FORMAT_MESSAGE_IGNORE_INSERTS,
212 MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
213 reinterpret_cast<char *
> (&errorText), 0,
nullptr);
214 if (errorText !=
nullptr)
216 msg = std::string (errorText);
217 LocalFree (errorText);
222 std::list<std::string> dirlist_str;
225 while (FindNextFileW (hFind, &ffd) != 0);
241 dirlist = dir.
read ();
249#if defined (OCTAVE_USE_WINDOWS_API)
252check_fseek_ftell_workaround_needed (
bool set_nonbuffered_mode)
275 std::string tmpname = sys::tempnam (
"",
"oct-");
277 if (tmpname.empty ())
279 (*current_liboctave_warning_handler)
280 (
"fseek/ftell bug check failed (tmp name creation)!");
284 std::FILE *
fptr = std::fopen (tmpname.c_str (),
"wb");
288 (*current_liboctave_warning_handler)
289 (
"fseek/ftell bug check failed (opening tmp file for writing)!");
293 fprintf (
fptr,
"%s",
"foo\nbar\nbaz\n");
297 fptr = std::fopen (tmpname.c_str (),
"rt");
301 (*current_liboctave_warning_handler)
302 (
"fseek/ftell bug check failed (opening tmp file for reading)!");
309 sys::unlink (tmpname);
312 if (set_nonbuffered_mode)
313 ::setvbuf (
fptr,
nullptr, _IONBF, 0);
317 int c = fgetc (
fptr);
321 (*current_liboctave_warning_handler)
322 (
"fseek/ftell bug check failed (skipping first line)!");
336 int c = fgetc (
fptr);
340 (*current_liboctave_warning_handler)
341 (
"fseek/ftell bug check failed (reading second line)!");
348 buf1[i++] =
static_cast<char> (c);
358 int c = fgetc (
fptr);
362 (*current_liboctave_warning_handler)
363 (
"fseek/ftell bug check failed (reading after repositioning)!");
370 buf2[i++] =
static_cast<char> (c);
374 return strcmp (buf1, buf2);
378get_formatted_last_error ()
380 std::string msg =
"";
382 DWORD last_error = GetLastError ();
384 wchar_t *error_text =
nullptr;
385 FormatMessageW (FORMAT_MESSAGE_FROM_SYSTEM |
386 FORMAT_MESSAGE_ALLOCATE_BUFFER |
387 FORMAT_MESSAGE_IGNORE_INSERTS,
389 MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
390 reinterpret_cast<wchar_t *
> (&error_text), 0,
nullptr);
392 if (error_text !=
nullptr)
395 LocalFree (error_text);
398 msg =
"Unknown error.";
409#if defined (OCTAVE_USE_WINDOWS_API)
412 DWORD f_attr = GetFileAttributesW (w_fn.c_str ());
414 return ((f_attr != INVALID_FILE_ATTRIBUTES)
415 && (is_dir || ! (f_attr & FILE_ATTRIBUTE_DIRECTORY)));
420 return (fs && (is_dir || ! fs.
is_dir ()));
426file_exists (
const std::string& filename,
bool is_dir, std::string& msg)
430#if defined (OCTAVE_USE_WINDOWS_API)
433 DWORD f_attr = GetFileAttributesW (w_fn.c_str ());
435 if (f_attr == INVALID_FILE_ATTRIBUTES)
436 msg = get_formatted_last_error ();
438 return ((f_attr != INVALID_FILE_ATTRIBUTES)
439 && (is_dir || ! (f_attr & FILE_ATTRIBUTE_DIRECTORY)));
447 return (fs && (is_dir || ! fs.
is_dir ()));
456#if defined (OCTAVE_USE_WINDOWS_API)
459 DWORD f_attr = GetFileAttributesW (w_dn.c_str ());
461 return ((f_attr != INVALID_FILE_ATTRIBUTES)
462 && (f_attr & FILE_ATTRIBUTE_DIRECTORY));
467 return (fs && fs.
is_dir ());
476#if defined (OCTAVE_USE_WINDOWS_API)
479 DWORD f_attr = GetFileAttributesW (w_dn.c_str ());
481 if (f_attr == INVALID_FILE_ATTRIBUTES)
482 msg = get_formatted_last_error ();
484 return ((f_attr != INVALID_FILE_ATTRIBUTES)
485 && (f_attr & FILE_ATTRIBUTE_DIRECTORY));
493 return (fs && fs.
is_dir ());
501same_file (
const std::string& file1,
const std::string& file2)
503#if defined (OCTAVE_USE_WINDOWS_API)
510 std::wstring file1w = sys::u8_to_wstring (file1);
511 std::wstring file2w = sys::u8_to_wstring (file2);
512 const wchar_t *f1 = file1w.c_str ();
513 const wchar_t *f2 = file2w.c_str ();
515 bool f1_is_dir = GetFileAttributesW (f1) & FILE_ATTRIBUTE_DIRECTORY;
516 bool f2_is_dir = GetFileAttributesW (f2) & FILE_ATTRIBUTE_DIRECTORY;
521 DWORD share = FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE;
524 = CreateFileW (f1, 0, share, 0, OPEN_EXISTING,
525 f1_is_dir ? FILE_FLAG_BACKUP_SEMANTICS : 0, 0);
527 if (hfile1 != INVALID_HANDLE_VALUE)
530 = CreateFileW (f2, 0, share, 0, OPEN_EXISTING,
531 f2_is_dir ? FILE_FLAG_BACKUP_SEMANTICS : 0, 0);
533 if (hfile2 != INVALID_HANDLE_VALUE)
535 BY_HANDLE_FILE_INFORMATION hfi1;
536 BY_HANDLE_FILE_INFORMATION hfi2;
538 if (GetFileInformationByHandle (hfile1, &hfi1)
539 && GetFileInformationByHandle (hfile2, &hfi2))
541 retval = (hfi1.dwVolumeSerialNumber == hfi2.dwVolumeSerialNumber
542 && hfi1.nFileIndexHigh == hfi2.nFileIndexHigh
543 && hfi1.nFileIndexLow == hfi2.nFileIndexLow
544 && hfi1.nFileSizeHigh == hfi2.nFileSizeHigh
545 && hfi1.nFileSizeLow == hfi2.nFileSizeLow
546 && hfi1.ftLastWriteTime.dwLowDateTime
547 == hfi2.ftLastWriteTime.dwLowDateTime
548 && hfi1.ftLastWriteTime.dwHighDateTime
549 == hfi2.ftLastWriteTime.dwHighDateTime);
552 CloseHandle (hfile2);
555 CloseHandle (hfile1);
564 sys::file_stat fs_file1 (file1);
565 sys::file_stat fs_file2 (file2);
567 return (fs_file1 && fs_file2
568 && fs_file1.ino () == fs_file2.ino ()
569 && fs_file1.dev () == fs_file2.dev ());
575fopen (
const std::string& filename,
const std::string& mode)
577#if defined (OCTAVE_USE_WINDOWS_API)
582 std::FILE *
fptr = _wfopen (wfilename.c_str (), wmode.c_str ());
584 static bool fseek_ftell_bug_workaround_needed =
false;
585 static bool fseek_ftell_bug_checked =
false;
587 if (! fseek_ftell_bug_checked && mode.find (
't') != std::string::npos)
623 if (check_fseek_ftell_workaround_needed (
false))
625 if (check_fseek_ftell_workaround_needed (
true))
626 (*current_liboctave_warning_handler)
627 (
"fseek/ftell may fail for files opened in text mode");
629 fseek_ftell_bug_workaround_needed =
true;
632 fseek_ftell_bug_checked =
true;
635 if (fseek_ftell_bug_workaround_needed
636 && mode.find (
't') != std::string::npos)
637 ::setvbuf (
fptr,
nullptr, _IONBF, 0);
642 return std::fopen (filename.c_str (), mode.c_str ());
647fopen_tmp (
const std::string& name,
const std::string& mode)
649#if defined (OCTAVE_USE_WINDOWS_API)
653 std::string tmp_mode = mode +
"D";
655 return std::fopen (name.c_str (), tmp_mode.c_str ());
659 std::FILE *
fptr = std::fopen (name.c_str (), mode.c_str ());
671fstream (
const std::string& filename,
const std::ios::openmode mode)
673#if defined (OCTAVE_USE_WINDOWS_API)
677 return std::fstream (wfilename.c_str (), mode);
680 return std::fstream (filename.c_str (), mode);
685ifstream (
const std::string& filename,
const std::ios::openmode mode)
687#if defined (OCTAVE_USE_WINDOWS_API)
691 return std::ifstream (wfilename.c_str (), mode);
694 return std::ifstream (filename.c_str (), mode);
699ofstream (
const std::string& filename,
const std::ios::openmode mode)
701#if defined (OCTAVE_USE_WINDOWS_API)
705 return std::ofstream (wfilename.c_str (), mode);
708 return std::ofstream (filename.c_str (), mode);
718#if defined (OCTAVE_USE_WINDOWS_API)
724 if (name.find (
'=') != std::string::npos)
725 (*current_liboctave_error_handler)
726 (
"putenv: name (%s) must not contain '='", name.c_str());
728 std::string new_env = name +
"=" + value;
732 int len = (new_wenv.length () + 1) *
sizeof (
wchar_t);
734 wchar_t *new_item =
static_cast<wchar_t *
> (std::malloc (
len));
736 wcscpy (new_item, new_wenv.c_str());
738 if (_wputenv (new_item) < 0)
739 (*current_liboctave_error_handler)
740 (
"putenv (%s) failed", new_env.c_str());
746 (
"setenv (%s, %s) failed with error %d", name.c_str (), value.c_str (),
754#if defined (OCTAVE_USE_WINDOWS_API)
756 wchar_t *
env = _wgetenv (wname.c_str ());
759 char *
env = ::getenv (name.c_str ());
767#if defined (OCTAVE_USE_WINDOWS_API)
772 return (SetEnvironmentVariableW (wname.c_str (),
nullptr) ? 0 : -1);
781#if defined (OCTAVE_USE_WINDOWS_API)
783 wchar_t *
env = _wgetenv (wname.c_str ());
785 char *
env = ::getenv (name.c_str ());
794 size_t srclen = utf8_string.length ();
795 const uint8_t *src =
reinterpret_cast<const uint8_t *
> (utf8_string.c_str ());
801 return std::wstring ();
805 retval.resize (length /
sizeof (
wchar_t));
806 std::memcpy (retval.data (), wchar, length);
807 free (
static_cast<void *
> (wchar));
816 size_t srclen = wchar_string.length () *
sizeof (wchar_t);
817 const char *src =
reinterpret_cast<const char *
> (wchar_string.c_str ());
820 char *mbchar =
reinterpret_cast<char *
>
823 std::string retval =
"";
824 if (mbchar !=
nullptr)
826 retval = std::string (mbchar, length);
827 free (
static_cast<void *
> (mbchar));
880 const bool allow_locale)
882#if defined (OCTAVE_USE_WINDOWS_API)
892 std::string::const_iterator first_non_ASCII
893 = std::find_if (orig_file_name.begin (), orig_file_name.end (),
894 [](
char c) { return (c < 0 || c >= 128); });
896 if (first_non_ASCII == orig_file_name.end ())
897 return orig_file_name;
906 const uint8_t *name_u8 =
reinterpret_cast<const uint8_t *
>
907 (orig_file_name.c_str ());
908 std::size_t length = 0;
911 orig_file_name.length () + 1, &length);
914 std::string file_name_locale (name_locale, length);
916 return file_name_locale;
923 std::wstring w_orig_file_name_str =
u8_to_wstring (orig_file_name);
924 const wchar_t *w_orig_file_name = w_orig_file_name_str.c_str ();
927 wchar_t w_full_file_name[_MAX_PATH];
928 if (_wfullpath (w_full_file_name, w_orig_file_name, _MAX_PATH) ==
nullptr)
929 return orig_file_name;
931 std::wstring w_full_file_name_str = w_full_file_name;
935 long length = GetShortPathNameW (w_full_file_name,
nullptr, 0);
943 GetShortPathNameW (w_full_file_name, w_short_file_name, length);
945 std::wstring w_short_file_name_str
946 = std::wstring (w_short_file_name, length);
948 if (w_short_file_name_str.compare (0, length-1, w_full_file_name_str) != 0)
951 std::string short_file_name
954 = std::find_if (short_file_name.begin (),
955 short_file_name.end (),
956 [](
char c) { return (c < 0 || c >= 128); });
957 if (first_non_ASCII == short_file_name.end ())
958 return short_file_name;
965 std::wstring::iterator w_first_non_ASCII
966 = std::find_if (w_full_file_name_str.begin (), w_full_file_name_str.end (),
967 [](
wchar_t c) { return (c < 0 || c >= 128); });
968 std::wstring tmp_substr
969 = std::wstring (w_full_file_name_str.begin (), w_first_non_ASCII);
972 = tmp_substr.find_last_of (
u8_to_wstring (file_ops::dir_sep_chars ()));
980 std::string oct_ascii_dir = par_dir +
".oct_ascii";
983 if (test_dir.empty ())
986 int status = sys::mkdir (oct_ascii_dir, 0777, msg);
989 return orig_file_name;
992 SetFileAttributesA (oct_ascii_dir.c_str (), FILE_ATTRIBUTE_HIDDEN);
996 std::string filename_hash
997 = (oct_ascii_dir + file_ops::dir_sep_str ()
998 + crypto::hash (
"SHA1", orig_file_name));
1004 if (! abs_filename_hash.empty ())
1005 sys::unlink (filename_hash);
1009 std::wstring w_filename_hash (filename_hash.begin (),
1010 filename_hash.end ());
1012 if (CreateHardLinkW (w_filename_hash.c_str (), w_orig_file_name,
nullptr))
1013 return filename_hash;
1017 octave_unused_parameter (allow_locale);
1021 return orig_file_name;
1024OCTAVE_END_NAMESPACE(sys)
1025OCTAVE_END_NAMESPACE(octave)
std::string error() const
std::string error() const
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
std::string canonicalize_file_name(const std::string &name)
std::string dirname(const std::string &path)
int octave_fseeko_wrapper(FILE *fp, off_t offset, int whence)
off_t octave_ftello_wrapper(FILE *fp)
OCTAVE_NORETURN liboctave_error_handler current_liboctave_error_handler
const char * octave_locale_charset_wrapper(void)
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
FloatComplex(* fptr)(const FloatComplex &, float, int, octave_idx_type &)
bool strcmp(const T &str_a, const T &str_b)
Octave string utility functions.
int system(const std::string &cmd_str)
std::FILE * fopen(const std::string &filename, const std::string &mode)
bool dir_exists(const std::string &dirname)
std::FILE * fopen_tmp(const std::string &name, const std::string &mode)
std::string u8_from_wstring(const std::wstring &wchar_string)
std::string get_ASCII_filename(const std::string &orig_file_name, const bool allow_locale)
std::string getenv_wrapper(const std::string &name)
bool file_exists(const std::string &filename, bool is_dir)
bool isenv_wrapper(const std::string &name)
std::ofstream ofstream(const std::string &filename, const std::ios::openmode mode)
int chdir(const std::string &path_arg)
std::ifstream ifstream(const std::string &filename, const std::ios::openmode mode)
std::wstring u8_to_wstring(const std::string &utf8_string)
void putenv_wrapper(const std::string &name, const std::string &value)
bool get_dirlist(const std::string &dirname, string_vector &dirlist, std::string &msg)
bool same_file(const std::string &file1, const std::string &file2)
int unsetenv_wrapper(const std::string &name)
int octave_setenv_wrapper(const char *envname, const char *envval, int overwrite)
char * octave_u8_conv_to_encoding_strict(const char *tocode, const uint8_t *src, size_t srclen, size_t *lengthp)
char * octave_u8_conv_to_encoding(const char *tocode, const uint8_t *src, size_t srclen, size_t *lengthp)
uint8_t * octave_u8_conv_from_encoding(const char *fromcode, const char *src, size_t srclen, size_t *lengthp)
char * octave_getcwd_wrapper(char *nm, size_t len)
int octave_unlink_wrapper(const char *nm)
int octave_chdir_wrapper(const char *nm)
int octave_unsetenv_wrapper(const char *name)