Windows: fix fl_system() and fl_execvp() (STR 3438)

Use correct conversions to Windows "wide character" encoding and
use the appropriate wide character functions.
This commit is contained in:
Albrecht Schlosser
2021-05-26 21:52:58 +02:00
parent 12c0509806
commit e4a972c3f3
+12 -32
View File
@@ -68,7 +68,7 @@ extern "C" {
} }
/* /*
Convert a UTF-8 string to Windows wide character encoding (UTF-16). Convert UTF-8 string to Windows wide character encoding (UTF-16).
This helper function is used throughout this file to convert UTF-8 This helper function is used throughout this file to convert UTF-8
strings to Windows specific UTF-16 encoding for filenames, paths, or strings to Windows specific UTF-16 encoding for filenames, paths, or
@@ -86,15 +86,14 @@ extern "C" {
'wbuf' is NULL a new buffer is allocated with realloc(). Hence the pointer 'wbuf' is NULL a new buffer is allocated with realloc(). Hence the pointer
'wbuf' can be shared among multiple calls to this function if it has been 'wbuf' can be shared among multiple calls to this function if it has been
initialized with NULL (or malloc or realloc) before the first call. initialized with NULL (or malloc or realloc) before the first call.
Ideally every call to this function has its own static pointer though.
The return value is either the old value of 'wbuf' (if the string fits) The return value is either the old value of 'wbuf' (if the string fits)
or a pointer at the (re)allocated buffer. or a pointer to the (re)allocated buffer.
Pseudo doxygen docs (static function intentionally not documented): Pseudo doxygen docs (static function intentionally not documented):
param[in] utf8 input string (UTF-8) param[in] utf8 input string (UTF-8)
param[in,out] wbuf in: pointer to output string buffer param[in,out] wbuf in: pointer to output string buffer or NULL
out: new string (the pointer may be changed) out: new string (the pointer may be changed)
param[in] lg optional: input string length (default = -1) param[in] lg optional: input string length (default = -1)
@@ -227,43 +226,24 @@ FILE *Fl_WinAPI_System_Driver::fopen(const char *fnam, const char *mode) {
} }
int Fl_WinAPI_System_Driver::system(const char *cmd) { int Fl_WinAPI_System_Driver::system(const char *cmd) {
# ifdef __MINGW32__
return ::system(fl_utf2mbcs(cmd));
# else
return _wsystem(utf8_to_wchar(cmd, wbuf)); return _wsystem(utf8_to_wchar(cmd, wbuf));
# endif
} }
int Fl_WinAPI_System_Driver::execvp(const char *file, char *const *argv) { int Fl_WinAPI_System_Driver::execvp(const char *file, char *const *argv) {
# ifdef __MINGW32__ int n = 0;
return _execvp(fl_utf2mbcs(file), argv); while (argv[n]) n++; // count args
# else wchar_t **ar = (wchar_t **)calloc(sizeof(wchar_t *), n + 1);
wchar_t **ar; // convert arguments first; trailing NULL provided by calloc()
for (int i = 0; i < n; i++)
ar[i] = utf8_to_wchar(argv[i], ar[i]); // alloc and assign
// convert executable file and execute it ...
utf8_to_wchar(file, wbuf); utf8_to_wchar(file, wbuf);
int i = 0, n = 0;
while (argv[i]) {i++; n++;}
ar = (wchar_t **)malloc(sizeof(wchar_t *) * (n + 1));
i = 0;
while (i <= n) {
unsigned wn;
unsigned len = (unsigned)strlen(argv[i]);
wn = fl_utf8toUtf16(argv[i], len, NULL, 0) + 1; // Query length
ar[i] = (wchar_t *)malloc(sizeof(wchar_t) * wn);
wn = fl_utf8toUtf16(argv[i], len, (unsigned short *)ar[i], wn); // Convert string
ar[i][wn] = 0;
i++;
}
ar[n] = NULL;
_wexecvp(wbuf, ar); // STR #3040 _wexecvp(wbuf, ar); // STR #3040
i = 0; // clean up (reached only if _wexecvp() failed)
while (i < n) { for (int i = 0; i < n; i++)
free(ar[i]); free(ar[i]);
i++;
}
free(ar); free(ar);
return -1; // STR #3040 return -1; // STR #3040
#endif
} }
int Fl_WinAPI_System_Driver::chmod(const char *fnam, int mode) { int Fl_WinAPI_System_Driver::chmod(const char *fnam, int mode) {