[llvm-commits] CVS: llvm/tools/gccld/gccld.cpp

John Criswell criswell at cs.uiuc.edu
Wed Sep 17 10:22:02 PDT 2003


Changes in directory llvm/tools/gccld:

gccld.cpp updated: 1.46 -> 1.47

---
Log message:

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.


---
Diffs of the changes:

Index: llvm/tools/gccld/gccld.cpp
diff -u llvm/tools/gccld/gccld.cpp:1.46 llvm/tools/gccld/gccld.cpp:1.47
--- llvm/tools/gccld/gccld.cpp:1.46	Tue Sep 16 16:27:35 2003
+++ llvm/tools/gccld/gccld.cpp	Wed Sep 17 10:20:51 2003
@@ -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 @@
 }
 
 //
+//
+// 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 @@
     //
     if (!strcmp (name, envp[index]))
     {
-      envp[index] = NULL;
+      *envp[index] = '\0';
     }
     else
     {
@@ -383,7 +455,7 @@
 }
 
 
-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 @@
     //
     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,10 +626,24 @@
       //  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





More information about the llvm-commits mailing list