diff --git a/SystemTools.cxx b/SystemTools.cxx
index 716752727e8bf25ab6957dff01f39bca3b9301b2..7743e4ed3d477ccb0659477d21a8489fd164ff19 100644
--- a/SystemTools.cxx
+++ b/SystemTools.cxx
@@ -4032,23 +4032,16 @@ std::string SystemTools::MakeCidentifier(const std::string& s)
   return str;
 }
 
-// Due to a buggy stream library on the HP and another on Mac OS X, we
-// need this very carefully written version of getline.  Returns true
+// Convenience function around std::getline which removes a trailing carriage
+// return and can truncate the buffer as needed.  Returns true
 // if any data were read before the end-of-file was reached.
 bool SystemTools::GetLineFromStream(std::istream& is, std::string& line,
                                     bool* has_newline /* = 0 */,
                                     long sizeLimit /* = -1 */)
 {
-  const int bufferSize = 1024;
-  char buffer[bufferSize];
-  bool haveData = false;
-  bool haveNewline = false;
-
   // Start with an empty line.
   line = "";
 
-  long leftToRead = sizeLimit;
-
   // Early short circuit return if stream is no good. Just return
   // false and the empty line. (Probably means caller tried to
   // create a file stream with a non-existent file name...)
@@ -4060,44 +4053,23 @@ bool SystemTools::GetLineFromStream(std::istream& is, std::string& line,
     return false;
   }
 
-  // If no characters are read from the stream, the end of file has
-  // been reached.  Clear the fail bit just before reading.
-  while (!haveNewline && leftToRead != 0 &&
-         (static_cast<void>(is.clear(is.rdstate() & ~std::ios::failbit)),
-          static_cast<void>(is.getline(buffer, bufferSize)),
-          is.gcount() > 0)) {
-    // We have read at least one byte.
-    haveData = true;
-
-    // If newline character was read the gcount includes the character
-    // but the buffer does not: the end of line has been reached.
-    size_t length = strlen(buffer);
-    if (length < static_cast<size_t>(is.gcount())) {
-      haveNewline = true;
-    }
-
+  std::getline(is, line);
+  bool haveData = !line.empty() || !is.eof();
+  if (!line.empty()) {
     // Avoid storing a carriage return character.
-    if (length > 0 && buffer[length - 1] == '\r') {
-      buffer[length - 1] = 0;
+    if (*line.rbegin() == '\r') {
+      line.resize(line.size() - 1);
     }
 
     // if we read too much then truncate the buffer
-    if (leftToRead > 0) {
-      if (static_cast<long>(length) > leftToRead) {
-        buffer[leftToRead] = 0;
-        leftToRead = 0;
-      } else {
-        leftToRead -= static_cast<long>(length);
-      }
+    if (sizeLimit >= 0 && line.size() >= static_cast<size_t>(sizeLimit)) {
+      line.resize(sizeLimit);
     }
-
-    // Append the data read to the line.
-    line.append(buffer);
   }
 
   // Return the results.
   if (has_newline) {
-    *has_newline = haveNewline;
+    *has_newline = !is.eof();
   }
   return haveData;
 }
diff --git a/SystemTools.hxx.in b/SystemTools.hxx.in
index e79e3fcf98678edabf80b6b6a385f5e3578df441..3898e3ad2fb929463c764776683b74e370c182f5 100644
--- a/SystemTools.hxx.in
+++ b/SystemTools.hxx.in
@@ -523,9 +523,8 @@ public:
   static bool GetShortPath(const std::string& path, std::string& result);
 
   /**
-   * Read line from file. Make sure to get everything. Due to a buggy stream
-   * library on the HP and another on Mac OS X, we need this very carefully
-   * written version of getline. Returns true if any data were read before the
+   * Read line from file. Make sure to read a full line and truncates it if
+   * requested via sizeLimit. Returns true if any data were read before the
    * end-of-file was reached. If the has_newline argument is specified, it will
    * be true when the line read had a newline character.
    */
diff --git a/testSystemTools.cxx b/testSystemTools.cxx
index a6d934b14fd37fccd06f825f17265627360c601c..8c928d40c67b5035f664ae4a34384ccdfd873de6 100644
--- a/testSystemTools.cxx
+++ b/testSystemTools.cxx
@@ -912,6 +912,78 @@ static bool CheckGetLineFromStream()
   return ret;
 }
 
+static bool CheckGetLineFromStreamLongLine()
+{
+  const std::string fileWithLongLine("longlines.txt");
+  std::string firstLine, secondLine;
+  // First line: large buffer, containing a carriage return for some reason.
+  firstLine.assign(2050, ' ');
+  firstLine += "\rfirst";
+  secondLine.assign(2050, 'y');
+  secondLine += "second";
+
+  // Create file with long lines.
+  {
+    kwsys::ofstream out(fileWithLongLine.c_str(), std::ios::binary);
+    if (!out) {
+      std::cerr << "Problem opening for write: " << fileWithLongLine
+                << std::endl;
+      return false;
+    }
+    out << firstLine << "\r\n\n" << secondLine << "\n";
+  }
+
+  kwsys::ifstream file(fileWithLongLine.c_str(), std::ios::binary);
+  if (!file) {
+    std::cerr << "Problem opening: " << fileWithLongLine << std::endl;
+    return false;
+  }
+
+  std::string line;
+  bool has_newline = false;
+  bool result;
+
+  // Read first line.
+  result = kwsys::SystemTools::GetLineFromStream(file, line, &has_newline, -1);
+  if (!result || line != firstLine) {
+    std::cerr << "First line does not match, expected " << firstLine.size()
+              << " characters, got " << line.size() << std::endl;
+    return false;
+  }
+  if (!has_newline) {
+    std::cerr << "Expected new line to be read from first line" << std::endl;
+    return false;
+  }
+
+  // Read empty line.
+  has_newline = false;
+  result = kwsys::SystemTools::GetLineFromStream(file, line, &has_newline, -1);
+  if (!result || !line.empty()) {
+    std::cerr << "Expected successful read with an empty line, got "
+              << line.size() << " characters" << std::endl;
+    return false;
+  }
+  if (!has_newline) {
+    std::cerr << "Expected new line to be read for an empty line" << std::endl;
+    return false;
+  }
+
+  // Read second line.
+  has_newline = false;
+  result = kwsys::SystemTools::GetLineFromStream(file, line, &has_newline, -1);
+  if (!result || line != secondLine) {
+    std::cerr << "Second line does not match, expected " << secondLine.size()
+              << " characters, got " << line.size() << std::endl;
+    return false;
+  }
+  if (!has_newline) {
+    std::cerr << "Expected new line to be read from second line" << std::endl;
+    return false;
+  }
+
+  return true;
+}
+
 int testSystemTools(int, char* [])
 {
   bool res = true;
@@ -951,6 +1023,8 @@ int testSystemTools(int, char* [])
 
   res &= CheckGetLineFromStream();
 
+  res &= CheckGetLineFromStreamLongLine();
+
   res &= CheckGetFilenameName();
 
   return res ? 0 : 1;