Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EnableLogCleaner doesn't work #786

Open
ml232528 opened this issue Jan 24, 2022 · 6 comments
Open

EnableLogCleaner doesn't work #786

ml232528 opened this issue Jan 24, 2022 · 6 comments
Labels

Comments

@ml232528
Copy link

glog v0.5.0
EnableLogCleaner doesn't work because opendir only supports English paths.
Need to call setlocale (lc_all, ""); Can be used correctly。

@sergiud
Copy link
Collaborator

sergiud commented Jan 24, 2022

Could you please provide a minimal example that shows the problem?

@Arfrever
Copy link

Arfrever commented Jan 24, 2022

glog/src/logging.cc

Lines 62 to 66 in b0174b3

#ifdef GLOG_OS_WINDOWS
#include "windows/dirent.h"
#else
#include <dirent.h> // for automatic removal of old logs
#endif

if ((dir = opendir(log_directory.c_str()))) {

On Unix systems, opendir function should just pass raw bytes to kernel, without being affected by locale.
For Windows, glog defines custom version of opendir function:

glog/src/windows/dirent.h

Lines 672 to 726 in b0174b3

/*
* Open directory stream using plain old C-string.
*/
static DIR*
opendir(
const char *dirname)
{
struct DIR *dirp;
/* Must have directory name */
if (dirname == NULL || dirname[0] == '\0') {
dirent_set_errno (ENOENT);
return NULL;
}
/* Allocate memory for DIR structure */
dirp = (DIR*) malloc (sizeof (struct DIR));
if (!dirp) {
return NULL;
}
{
int error;
wchar_t wname[PATH_MAX + 1];
size_t n;
/* Convert directory name to wide-character string */
error = dirent_mbstowcs_s(
&n, wname, PATH_MAX + 1, dirname, PATH_MAX + 1);
if (error) {
/*
* Cannot convert file name to wide-character string. This
* occurs if the string contains invalid multi-byte sequences or
* the output buffer is too small to contain the resulting
* string.
*/
goto exit_free;
}
/* Open directory stream using wide-character name */
dirp->wdirp = _wopendir (wname);
if (!dirp->wdirp) {
goto exit_free;
}
}
/* Success */
return dirp;
/* Failure */
exit_free:
free (dirp);
return NULL;
}

According to documentation, Windows version of mbstowcs_s function (called by dirent_mbstowcs_s function) supposedly uses current locale.

@ml232528: Do you use Windows?

setlocale (LC_ALL, ""), or rather setlocale (LC_CTYPE, "") if it is sufficient and working on Windows, should be probably in Windows-specific block of code somewhere:

#ifdef GLOG_OS_WINDOWS
  setlocale(LC_CTYPE, "");
#endif

@sergiud
Copy link
Collaborator

sergiud commented Feb 14, 2022

@ml232528 It is not clear what kind of resolution do you expect here. Could you please also respond to @Arfrever's questions?

@Arfrever
Copy link

If that setlocale (LC_CTYPE, "") was to be added somewhere, probably appropriate place would be glog_internal_namespace_::InitGoogleLoggingUtilities (which is called by google::InitGoogleLogging).

I do not use Windows, so here is untested patch:

--- src/utilities.cc
+++ src/utilities.cc
@@ -57,6 +57,9 @@
 #ifdef __ANDROID__
 #include <android/log.h>
 #endif
+#ifdef GLOG_OS_WINDOWS
+# include <clocale>  // For setlocale()
+#endif
 
 #include "base/googleinit.h"
 
@@ -364,6 +367,11 @@
 void InitGoogleLoggingUtilities(const char* argv0) {
   CHECK(!IsGoogleLoggingInitialized())
       << "You called InitGoogleLogging() twice!";
+
+#ifdef GLOG_OS_WINDOWS
+  setlocale(LC_CTYPE, "");
+#endif
+
   const char* slash = strrchr(argv0, '/');
 #ifdef GLOG_OS_WINDOWS
   if (!slash)  slash = strrchr(argv0, '\\');

@ml232528
Copy link
Author

ml232528 commented Feb 18, 2022

It is recommended to replace mbstowcs with multibytetowidechar and use the flag CP_ ACP,Example:

std::wstring As_WStringFromString(std::string const &s) {
	auto len = ::MultiByteToWideChar(CP_ACP, 0, s.c_str(), s.size(), NULL, 0);
	std::unique_ptr<WCHAR[]> result(new WCHAR[len + 1]);
	::MultiByteToWideChar(CP_ACP, 0, s.c_str(), s.size(), result.get(), len + 1);
	result.get()[len] = 0;
	return std::wstring(result.get());
}


std::string As_StringFromWstring(std::wstring const &s) {
	auto len = WideCharToMultiByte(CP_ACP, 0, s.c_str(), s.size(), nullptr, 0, nullptr, nullptr);
	std::unique_ptr<char[]> result(new char[len + 1]);
	WideCharToMultiByte(CP_ACP, 0, s.c_str(), s.size(), result.get(), len + 1, nullptr, nullptr);
	result.get()[len] = 0;
	return std::string(result.get());
}

std::string As_Utf8FromWstring(std::wstring const &s) {
	auto len = WideCharToMultiByte(CP_UTF8, 0, s.c_str(), s.size(), nullptr, 0, nullptr, nullptr);
	std::unique_ptr<char[]> result(new char[len + 1]);
	WideCharToMultiByte(CP_UTF8, 0, s.c_str(), s.size(), result.get(), len + 1, nullptr, nullptr);
	result.get()[len] = 0;
	return std::string(result.get());
}

@Arfrever
Copy link

Maybe you could create pull-request for glog?
(You would need to firstly sign Google's Contributor License Agreement if not done already.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants