diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2013-04-11 14:06:34 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2013-04-11 14:06:34 +0000 |
commit | 845a932af74ecbd2a20af5751dd61fa8cf2246f5 (patch) | |
tree | 2798ed9fdf58bc3ed72a9afa5bc4cc0e4644b07d | |
parent | 305e3b277c5e721431e60808293a9228c62e319e (diff) | |
download | external_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.h | 5 | ||||
-rw-r--r-- | lib/Support/Unix/Program.inc | 24 | ||||
-rw-r--r-- | lib/Support/Windows/Program.inc | 16 |
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; +} + } |