Update talk to 60923971

Review URL: https://webrtc-codereview.appspot.com/7909004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@5475 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/talk/base/linux.cc b/talk/base/linux.cc
index 644ec45..16666f8 100644
--- a/talk/base/linux.cc
+++ b/talk/base/linux.cc
@@ -250,6 +250,89 @@
   return true;
 }
 
+#if !defined(GOOGLE_CHROME_BUILD) && !defined(CHROMIUM_BUILD)
+static bool ExpectLineFromStream(FileStream* stream,
+                                 std::string* out) {
+  StreamResult res = stream->ReadLine(out);
+  if (res != SR_SUCCESS) {
+    if (res != SR_EOS) {
+      LOG(LS_ERROR) << "Error when reading from stream";
+    } else {
+      LOG(LS_ERROR) << "Incorrect number of lines in stream";
+    }
+    return false;
+  }
+  return true;
+}
+
+static void ExpectEofFromStream(FileStream* stream) {
+  std::string unused;
+  StreamResult res = stream->ReadLine(&unused);
+  if (res == SR_SUCCESS) {
+    LOG(LS_WARNING) << "Ignoring unexpected extra lines from stream";
+  } else if (res != SR_EOS) {
+    LOG(LS_WARNING) << "Error when checking for extra lines from stream";
+  }
+}
+
+// For caching the lsb_release output (reading it invokes a sub-process and
+// hence is somewhat expensive).
+static std::string lsb_release_string;
+static CriticalSection lsb_release_string_critsec;
+
+std::string ReadLinuxLsbRelease() {
+  CritScope cs(&lsb_release_string_critsec);
+  if (!lsb_release_string.empty()) {
+    // Have cached result from previous call.
+    return lsb_release_string;
+  }
+  // No cached result. Run lsb_release and parse output.
+  POpenStream lsb_release_output;
+  if (!lsb_release_output.Open("lsb_release -idrcs", "r", NULL)) {
+    LOG_ERR(LS_ERROR) << "Can't run lsb_release";
+    return lsb_release_string;  // empty
+  }
+  // Read in the command's output and build the string.
+  std::ostringstream sstr;
+  std::string line;
+  int wait_status;
+
+  if (!ExpectLineFromStream(&lsb_release_output, &line)) {
+    return lsb_release_string;  // empty
+  }
+  sstr << "DISTRIB_ID=" << line;
+
+  if (!ExpectLineFromStream(&lsb_release_output, &line)) {
+    return lsb_release_string;  // empty
+  }
+  sstr << " DISTRIB_DESCRIPTION=\"" << line << '"';
+
+  if (!ExpectLineFromStream(&lsb_release_output, &line)) {
+    return lsb_release_string;  // empty
+  }
+  sstr << " DISTRIB_RELEASE=" << line;
+
+  if (!ExpectLineFromStream(&lsb_release_output, &line)) {
+    return lsb_release_string;  // empty
+  }
+  sstr << " DISTRIB_CODENAME=" << line;
+
+  // Should not be anything left.
+  ExpectEofFromStream(&lsb_release_output);
+
+  lsb_release_output.Close();
+  wait_status = lsb_release_output.GetWaitStatus();
+  if (wait_status == -1 ||
+      !WIFEXITED(wait_status) ||
+      WEXITSTATUS(wait_status) != 0) {
+    LOG(LS_WARNING) << "Unexpected exit status from lsb_release";
+  }
+
+  lsb_release_string = sstr.str();
+
+  return lsb_release_string;
+}
+#endif
 
 std::string ReadLinuxUname() {
   struct utsname buf;