Add a function to check if an argument list is too long.
authorRafael Espindola <rafael.espindola@gmail.com>
Thu, 11 Apr 2013 14:06:34 +0000 (14:06 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Thu, 11 Apr 2013 14:06:34 +0000 (14:06 +0000)
This will be used in clang to decide if it should create an @file or not. It
will be tested on the clang side.

Patch by Nathan Froyd.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179285 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Support/Program.h
lib/Support/Unix/Program.inc
lib/Support/Windows/Program.inc

index bf650112f2802b9ba292e405754eac6936e9ca87..fb177de97b4092b24707f843525feabac263fd56 100644 (file)
@@ -14,6 +14,7 @@
 #ifndef LLVM_SUPPORT_PROGRAM_H
 #define LLVM_SUPPORT_PROGRAM_H
 
+#include "llvm/ADT/ArrayRef.h"
 #include "llvm/Support/Path.h"
 
 namespace llvm {
@@ -140,6 +141,10 @@ namespace sys {
     /// @}
 
   };
+
+  // Return true if the given arguments fit within system-specific
+  // argument length limits.
+  bool argumentsFitWithinSystemLimits(ArrayRef<const char*> Args);
 }
 }
 
index 117151c91d8bb5d2a333df682523d30378e242cb..aa03d48438ec749cc129f8ed5cde92290e07e72e 100644 (file)
@@ -32,6 +32,9 @@
 #if HAVE_FCNTL_H
 #include <fcntl.h>
 #endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
 #ifdef HAVE_POSIX_SPAWN
 #include <spawn.h>
 #if !defined(__APPLE__)
@@ -409,4 +412,25 @@ error_code Program::ChangeStderrToBinary(){
   return make_error_code(errc::success);
 }
 
+bool llvm::sys::argumentsFitWithinSystemLimits(ArrayRef<const char*> Args) {
+  static long ArgMax = sysconf(_SC_ARG_MAX);
+
+  // System says no practical limit.
+  if (ArgMax == -1)
+    return true;
+
+  // Conservatively account for space required by environment variables.
+  ArgMax /= 2;
+
+  size_t ArgLength = 0;
+  for (ArrayRef<const char*>::iterator I = Args.begin(), E = Args.end();
+       I != E; ++I) {
+    ArgLength += strlen(*I) + 1;
+    if (ArgLength > size_t(ArgMax)) {
+      return false;
+    }
+  }
+  return true;
+}
+
 }
index 691d6d45550123b7ee6a9f76d38b4fa30d453d22..994a09764e3b8fc81aa70c898395b35c98c2f4a6 100644 (file)
@@ -396,4 +396,20 @@ error_code Program::ChangeStderrToBinary(){
   return make_error_code(errc::success);
 }
 
+bool llvm::sys::argumentsFitWithinSystemLimits(ArrayRef<const char*> Args) {
+  // The documented max length of the command line passed to CreateProcess.
+  static const size_t MaxCommandStringLength = 32768;
+  size_t ArgLength = 0;
+  for (ArrayRef<const char*>::iterator I = Args.begin(), E = Args.end();
+       I != E; ++I) {
+    // Account for the trailing space for every arg but the last one and the
+    // trailing NULL of the last argument.
+    ArgLength += ArgLenWithQuotes(*I) + 1;
+    if (ArgLength > MaxCommandStringLength) {
+      return false;
+    }
+  }
+  return true;
+}
+
 }