summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorJohn Criswell <criswell@uiuc.edu>2003-09-17 15:20:51 +0000
committerJohn Criswell <criswell@uiuc.edu>2003-09-17 15:20:51 +0000
commit621727c29ead58158121f52e5a8f66d14bb0d4c8 (patch)
tree7afa5482d3614c2e8e6a0d475330bd4dae5d35d3 /tools
parente9ba8b36740f46ba1a7a68706cafda1df1d2ca74 (diff)
downloadllvm-621727c29ead58158121f52e5a8f66d14bb0d4c8.tar.gz
llvm-621727c29ead58158121f52e5a8f66d14bb0d4c8.tar.bz2
llvm-621727c29ead58158121f52e5a8f66d14bb0d4c8.tar.xz
Removed the use of the environ variable and instead use the environment array
passed into main(). This may (or may not) be more portable, but it looks nicer. Added functions to copy the environment array and modify the copy, thus preserving the environment. Switched from using system() to using ExecWait(). The code now removes the assembly file generated when using the -native option. Fixed the remove_env() function: The previous revision truncated the environment variable list. This version just zaps the variable as intended. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@8579 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools')
-rw-r--r--tools/gccld/gccld.cpp141
1 files changed, 120 insertions, 21 deletions
diff --git a/tools/gccld/gccld.cpp b/tools/gccld/gccld.cpp
index d78139db55..1712f0b36d 100644
--- a/tools/gccld/gccld.cpp
+++ b/tools/gccld/gccld.cpp
@@ -22,6 +22,7 @@
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/Scalar.h"
#include "Support/FileUtilities.h"
+#include "Support/SystemUtils.h"
#include "Support/CommandLine.h"
#include "Support/Signals.h"
#include "Config/unistd.h"
@@ -30,9 +31,6 @@
#include <set>
#include <algorithm>
-// This is the environment given to the program.
-extern char ** environ;
-
namespace {
cl::list<std::string>
InputFilenames(cl::Positional, cl::desc("<input bytecode files>"),
@@ -320,6 +318,80 @@ static int PrintAndReturn(const char *progname, const std::string &Message,
}
//
+//
+// Function: copy_env()
+//
+// Description:
+// This function takes an array of environment variables and makes a
+// copy of it. This copy can then be manipulated any way the caller likes
+// without affecting the process's real environment.
+//
+// Inputs:
+// envp - An array of C strings containing an environment.
+//
+// Outputs:
+// None.
+//
+// Return value:
+// NULL - An error occurred.
+// Otherwise, a pointer to a new array of C strings is returned. Every string
+// in the array is a duplicate of the one in the original array (i.e. we do
+// not copy the char *'s from one array to another).
+//
+static char **
+copy_env (char ** envp)
+{
+ // The new environment list
+ char ** newenv;
+
+ // The number of entries in the old environment list
+ int entries;
+
+ //
+ // Count the number of entries in the old list;
+ //
+ for (entries = 0; envp[entries] != NULL; entries++)
+ {
+ ;
+ }
+
+ //
+ // Add one more entry for the NULL pointer that ends the list.
+ //
+ ++entries;
+
+ //
+ // If there are no entries at all, just return NULL.
+ //
+ if (entries == 0)
+ {
+ return NULL;
+ }
+
+ //
+ // Allocate a new environment list.
+ //
+ if ((newenv = new (char *) [entries]) == NULL)
+ {
+ return NULL;
+ }
+
+ //
+ // Make a copy of the list. Don't forget the NULL that ends the list.
+ //
+ entries = 0;
+ while (envp[entries] != NULL)
+ {
+ newenv[entries] = strdup (envp[entries]);
+ ++entries;
+ }
+ newenv[entries] = NULL;
+
+ return newenv;
+}
+
+
+//
// Function: remove_env()
//
// Description:
@@ -371,7 +443,7 @@ remove_env (const char * name, char ** envp)
//
if (!strcmp (name, envp[index]))
{
- envp[index] = NULL;
+ *envp[index] = '\0';
}
else
{
@@ -383,7 +455,7 @@ remove_env (const char * name, char ** envp)
}
-int main(int argc, char **argv) {
+int main(int argc, char **argv, char ** envp) {
cl::ParseCommandLineOptions(argc, argv, " llvm linker for GCC\n");
std::string ErrorMessage;
@@ -509,26 +581,39 @@ int main(int argc, char **argv) {
//
if (Native)
{
- // Name of the output assembly file
- std::string AssemblyFile = OutputFilename + ".s";
-
- // Name of the command to execute
- std::string cmd;
-
//
- // Create an executable file from the bytecode file.
+ // Remove these environment variables from the environment of the
+ // programs that we will execute. It appears that GCC sets these
+ // environment variables so that the programs it uses can configure
+ // themselves identically.
+ //
+ // However, when we invoke GCC below, we want it to use its normal
+ // configuration. Hence, we must sanitize it's environment.
//
- remove_env ("LIBRARY_PATH", environ);
- remove_env ("COLLECT_GCC_OPTIONS", environ);
- remove_env ("GCC_EXEC_PREFIX", environ);
- remove_env ("COMPILER_PATH", environ);
- remove_env ("COLLECT_GCC", environ);
+ char ** clean_env = copy_env (envp);
+ if (clean_env == NULL)
+ {
+ return PrintAndReturn (argv[0], "Failed to duplicate environment");
+ }
+ remove_env ("LIBRARY_PATH", clean_env);
+ remove_env ("COLLECT_GCC_OPTIONS", clean_env);
+ remove_env ("GCC_EXEC_PREFIX", clean_env);
+ remove_env ("COMPILER_PATH", clean_env);
+ remove_env ("COLLECT_GCC", clean_env);
//
// Run LLC to convert the bytecode file into assembly code.
//
- cmd = "llc -f -o " + AssemblyFile + " " + RealBytecodeOutput;
- if ((system (cmd.c_str())) == -1)
+ char * cmd[8];
+ std::string AssemblyFile = OutputFilename + ".s";
+
+ cmd[0] = (char *) "llc";
+ cmd[1] = (char *) "-f";
+ cmd[2] = (char *) "-o";
+ cmd[3] = (char *) AssemblyFile.c_str();
+ cmd[4] = (char *) RealBytecodeOutput.c_str();
+ cmd[5] = (char *) NULL;
+ if ((ExecWait (cmd, clean_env)) == -1)
{
return PrintAndReturn (argv[0], "Failed to compile bytecode");
}
@@ -541,11 +626,25 @@ int main(int argc, char **argv) {
// and linker because we don't know where to put the _start symbol.
// GCC mysteriously knows how to do it.
//
- cmd = "gcc -o " + OutputFilename + " " + AssemblyFile;
- if ((system (cmd.c_str())) == -1)
+ cmd[0] = (char *) "gcc";
+ cmd[1] = (char *) "-o";
+ cmd[2] = (char *) OutputFilename.c_str();
+ cmd[3] = (char *) AssemblyFile.c_str();
+ cmd[4] = (char *) NULL;
+ if ((ExecWait (cmd, clean_env)) == -1)
{
return PrintAndReturn (argv[0], "Failed to link native code file");
}
+
+ //
+ // The assembly file is no longer needed. Remove it, but do not exit
+ // if we fail to unlink it.
+ //
+ if (((access (AssemblyFile.c_str(), F_OK)) != -1) &&
+ ((unlink (AssemblyFile.c_str())) == -1))
+ {
+ std::cerr << "Warning: Failed to unlink " << AssemblyFile << "\n";
+ }
}
else
{