aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2013-04-11 14:06:34 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2013-04-11 14:06:34 +0000
commit845a932af74ecbd2a20af5751dd61fa8cf2246f5 (patch)
tree2798ed9fdf58bc3ed72a9afa5bc4cc0e4644b07d
parent305e3b277c5e721431e60808293a9228c62e319e (diff)
downloadexternal_llvm-845a932af74ecbd2a20af5751dd61fa8cf2246f5.zip
external_llvm-845a932af74ecbd2a20af5751dd61fa8cf2246f5.tar.gz
external_llvm-845a932af74ecbd2a20af5751dd61fa8cf2246f5.tar.bz2
Add a function to check if an argument list is too long.
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
-rw-r--r--include/llvm/Support/Program.h5
-rw-r--r--lib/Support/Unix/Program.inc24
-rw-r--r--lib/Support/Windows/Program.inc16
3 files changed, 45 insertions, 0 deletions
diff --git a/include/llvm/Support/Program.h b/include/llvm/Support/Program.h
index bf65011..fb177de 100644
--- a/include/llvm/Support/Program.h
+++ b/include/llvm/Support/Program.h
@@ -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);
}
}
diff --git a/lib/Support/Unix/Program.inc b/lib/Support/Unix/Program.inc
index 117151c..aa03d48 100644
--- a/lib/Support/Unix/Program.inc
+++ b/lib/Support/Unix/Program.inc
@@ -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;
+}
+
}
diff --git a/lib/Support/Windows/Program.inc b/lib/Support/Windows/Program.inc
index 691d6d4..994a097 100644
--- a/lib/Support/Windows/Program.inc
+++ b/lib/Support/Windows/Program.inc
@@ -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;
+}
+
}