Add StrError and replace posix_strerror_r calls
author <shinichiro.hamaji@gmail.com> <>
Thu, 31 Oct 2013 05:39:43 +0000 (05:39 +0000)
committer <shinichiro.hamaji@gmail.com> <>
Thu, 31 Oct 2013 05:39:43 +0000 (05:39 +0000)
For now, we do not remove the declaration of posix_strerror_r,
but we might remove it in future.

git-svn-id: https://google-glog.googlecode.com/svn/trunk@139 eb4d4688-79bd-11dd-afb4-1d65580434c0

src/glog/logging.h.in
src/googletest.h
src/logging.cc
src/logging_unittest.cc
src/windows/glog/logging.h

index 8f9ca98a85dd4dce325b2bba14ae7a0965699008..e8e3e7a135aae0086cee6c48253de8f063389e9d 100644 (file)
@@ -1528,8 +1528,12 @@ extern GOOGLE_GLOG_DLL_DECL void SetLogger(LogSeverity level, Logger* logger);
 // be set to an empty string, if this function failed. This means, in most
 // cases, you do not need to check the error code and you can directly
 // use the value of "buf". It will never have an undefined value.
+// DEPRECATED: Use StrError(int) instead.
 GOOGLE_GLOG_DLL_DECL int posix_strerror_r(int err, char *buf, size_t len);
 
+// A thread-safe replacement for strerror(). Returns a string describing the
+// given POSIX error code.
+GOOGLE_GLOG_DLL_DECL std::string StrError(int err);
 
 // A class for which we define operator<<, which does nothing.
 class GOOGLE_GLOG_DLL_DECL NullStream : public LogMessage::LogStream {
index 21e4f643f8783fb17a1987805ce8ed6798701e73..2525bc33a0ad83d7136b9a51cbb3d0da283dd6f7 100644 (file)
@@ -450,19 +450,11 @@ static inline string Munge(const string& filename) {
     // Remove 0x prefix produced by %p. VC++ doesn't put the prefix.
     StringReplace(&line, " 0x", " ");
 
-    char errmsg_buf[100];
-    posix_strerror_r(0, errmsg_buf, sizeof(errmsg_buf));
-    if (*errmsg_buf == '\0') {
-      // MacOSX 10.4 and FreeBSD return empty string for errno=0.
-      // In such case, the we need to remove an extra space.
-      StringReplace(&line, "__SUCCESS__ ", "");
-    } else {
-      StringReplace(&line, "__SUCCESS__", errmsg_buf);
-    }
-    StringReplace(&line, "__ENOENT__", strerror(ENOENT));
-    StringReplace(&line, "__EINTR__", strerror(EINTR));
-    StringReplace(&line, "__ENXIO__", strerror(ENXIO));
-    StringReplace(&line, "__ENOEXEC__", strerror(ENOEXEC));
+    StringReplace(&line, "__SUCCESS__", StrError(0));
+    StringReplace(&line, "__ENOENT__", StrError(ENOENT));
+    StringReplace(&line, "__EINTR__", StrError(EINTR));
+    StringReplace(&line, "__ENXIO__", StrError(ENXIO));
+    StringReplace(&line, "__ENOEXEC__", StrError(ENOEXEC));
     result += line + "\n";
   }
   fclose(fp);
index e5eae459d722095f8cf82ef325a73f2a3fc251db..81d966fe5dd609719342416728035fce8091e42b 100644 (file)
@@ -1580,9 +1580,8 @@ ErrnoLogMessage::ErrnoLogMessage(const char* file, int line,
 ErrnoLogMessage::~ErrnoLogMessage() {
   // Don't access errno directly because it may have been altered
   // while streaming the message.
-  char buf[100];
-  posix_strerror_r(preserved_errno(), buf, sizeof(buf));
-  stream() << ": " << buf << " [" << preserved_errno() << "]";
+  stream() << ": " << StrError(preserved_errno()) << " ["
+           << preserved_errno() << "]";
 }
 
 void FlushLogFiles(LogSeverity min_severity) {
@@ -1711,13 +1710,11 @@ static bool SendEmailInternal(const char*dest, const char *subject,
       bool ok = pclose(pipe) != -1;
       if ( !ok ) {
         if ( use_logging ) {
-          char buf[100];
-          posix_strerror_r(errno, buf, sizeof(buf));
-          LOG(ERROR) << "Problems sending mail to " << dest << ": " << buf;
+          LOG(ERROR) << "Problems sending mail to " << dest << ": "
+                     << StrError(errno);
         } else {
-          char buf[100];
-          posix_strerror_r(errno, buf, sizeof(buf));
-          fprintf(stderr, "Problems sending mail to %s: %s\n", dest, buf);
+          fprintf(stderr, "Problems sending mail to %s: %s\n",
+                  dest, StrError(errno).c_str());
         }
       }
       return ok;
@@ -1991,6 +1988,15 @@ int posix_strerror_r(int err, char *buf, size_t len) {
   }
 }
 
+string StrError(int err) {
+  char buf[100];
+  int rc = posix_strerror_r(err, buf, sizeof(buf));
+  if ((rc < 0) || (buf[0] == '\000')) {
+    snprintf(buf, sizeof(buf), "Error number %d", err);
+  }
+  return buf;
+}
+
 LogMessageFatal::LogMessageFatal(const char* file, int line) :
     LogMessage(file, line, GLOG_FATAL) {}
 
index d7e95cf7cdc4011d94a2068a8939944c11914c67..fa6afce12cebfe77dcd904ab5af06b7edd09bac2 100644 (file)
@@ -1058,8 +1058,9 @@ TEST(Strerror, logging) {
   CHECK_STREQ(buf, "");
   CHECK_EQ(posix_strerror_r(errcode, buf, buf_size), 0);
   CHECK_STREQ(buf, msg);
-  free(msg);
   delete[] buf;
+  CHECK_EQ(msg, StrError(errcode));
+  free(msg);
 }
 
 // Simple routines to look at the sizes of generated code for LOG(FATAL) and
index eb4a4c5b70360652cc39a0fd59d1685078646cf3..bab8c612500d25928b4f0cd59987a2e0b3aadfa0 100755 (executable)
@@ -1532,8 +1532,12 @@ extern GOOGLE_GLOG_DLL_DECL void SetLogger(LogSeverity level, Logger* logger);
 // be set to an empty string, if this function failed. This means, in most
 // cases, you do not need to check the error code and you can directly
 // use the value of "buf". It will never have an undefined value.
+// DEPRECATED: Use StrError(int) instead.
 GOOGLE_GLOG_DLL_DECL int posix_strerror_r(int err, char *buf, size_t len);
 
+// A thread-safe replacement for strerror(). Returns a string describing the
+// given POSIX error code.
+GOOGLE_GLOG_DLL_DECL std::string StrError(int err);
 
 // A class for which we define operator<<, which does nothing.
 class GOOGLE_GLOG_DLL_DECL NullStream : public LogMessage::LogStream {