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.

llvm-svn: 179285
This commit is contained in:
Rafael Espindola 2013-04-11 14:06:34 +00:00
parent 9643a313ac
commit cd848c0866
3 changed files with 45 additions and 0 deletions

View File

@ -14,6 +14,7 @@
#ifndef LLVM_SUPPORT_PROGRAM_H #ifndef LLVM_SUPPORT_PROGRAM_H
#define LLVM_SUPPORT_PROGRAM_H #define LLVM_SUPPORT_PROGRAM_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/Path.h" #include "llvm/Support/Path.h"
namespace llvm { 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);
} }
} }

View File

@ -32,6 +32,9 @@
#if HAVE_FCNTL_H #if HAVE_FCNTL_H
#include <fcntl.h> #include <fcntl.h>
#endif #endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_POSIX_SPAWN #ifdef HAVE_POSIX_SPAWN
#include <spawn.h> #include <spawn.h>
#if !defined(__APPLE__) #if !defined(__APPLE__)
@ -409,4 +412,25 @@ error_code Program::ChangeStderrToBinary(){
return make_error_code(errc::success); 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;
}
} }

View File

@ -396,4 +396,20 @@ error_code Program::ChangeStderrToBinary(){
return make_error_code(errc::success); 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;
}
} }