Initial commit of an platform-indepdendent implementation for the
authorReid Spencer <rspencer@reidspencer.com>
Sun, 29 Aug 2004 19:20:41 +0000 (19:20 +0000)
committerReid Spencer <rspencer@reidspencer.com>
Sun, 29 Aug 2004 19:20:41 +0000 (19:20 +0000)
"Program" operating system concept (find and execute programs).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16084 91177308-0d34-0410-b5e6-96231b3b80d8

lib/System/AIX/Program.cpp [new file with mode: 0644]
lib/System/Cygwin/Program.cpp [new file with mode: 0644]
lib/System/Darwin/Program.cpp [new file with mode: 0644]
lib/System/Linux/Program.cpp [new file with mode: 0644]
lib/System/Program.cpp [new file with mode: 0644]
lib/System/SunOS/Program.cpp [new file with mode: 0644]
lib/System/Unix/Program.cpp [new file with mode: 0644]
lib/System/Unix/Program.inc [new file with mode: 0644]
lib/System/Win32/Program.cpp [new file with mode: 0644]
lib/System/Win32/Program.inc [new file with mode: 0644]

diff --git a/lib/System/AIX/Program.cpp b/lib/System/AIX/Program.cpp
new file mode 100644 (file)
index 0000000..3646cfd
--- /dev/null
@@ -0,0 +1,22 @@
+//===- AIX/Program.cpp - AIX Program Implementation ----------- -*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the 
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This file provides the AIX specific implementation of the Program class.
+//
+//===----------------------------------------------------------------------===//
+
+// Include the generic Unix implementation
+#include "../Unix/Program.cpp"
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only AIX specific code 
+//===          and must not be generic UNIX code (see ../Unix/Program.cpp)
+//===----------------------------------------------------------------------===//
+
+// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab
diff --git a/lib/System/Cygwin/Program.cpp b/lib/System/Cygwin/Program.cpp
new file mode 100644 (file)
index 0000000..2de0c3b
--- /dev/null
@@ -0,0 +1,22 @@
+//===- Cygwin/Program.cpp - Cygwin Program Implementation ----- -*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the 
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This file provides the Cygwin specific implementation of the Program class.
+//
+//===----------------------------------------------------------------------===//
+
+// Include the generic Unix implementation
+#include "../Unix/Program.cpp"
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only Cygwin specific code 
+//===          and must not be generic UNIX code (see ../Unix/Program.cpp)
+//===----------------------------------------------------------------------===//
+
+// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab
diff --git a/lib/System/Darwin/Program.cpp b/lib/System/Darwin/Program.cpp
new file mode 100644 (file)
index 0000000..8c829df
--- /dev/null
@@ -0,0 +1,22 @@
+//===- Darwin/Program.cpp - Darwin Program Implementatino. ---- -*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the 
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This file provides the Darwin specific implementation of the Program class.
+//
+//===----------------------------------------------------------------------===//
+
+// Include the generic Unix implementation
+#include "../Unix/Program.cpp"
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only Darwin specific code 
+//===          and must not be generic UNIX code (see ../Unix/Program.cpp)
+//===----------------------------------------------------------------------===//
+
+// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab
diff --git a/lib/System/Linux/Program.cpp b/lib/System/Linux/Program.cpp
new file mode 100644 (file)
index 0000000..0dd29d2
--- /dev/null
@@ -0,0 +1,22 @@
+//===- Linux/Program.cpp - Linux Program Implementation ------- -*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the 
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This file provides the Linux specific implementation of the Program class.
+//
+//===----------------------------------------------------------------------===//
+
+// Include the generic Unix implementation
+#include "../Unix/Program.cpp"
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only Linux specific code 
+//===          and must not be generic UNIX code (see ../Unix/Program.cpp)
+//===----------------------------------------------------------------------===//
+
+// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab
diff --git a/lib/System/Program.cpp b/lib/System/Program.cpp
new file mode 100644 (file)
index 0000000..c1dd38f
--- /dev/null
@@ -0,0 +1,29 @@
+//===-- Program.cpp - Implement OS Program Concept --------------*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the 
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+//  This header file implements the operating system Program concept.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/System/Program.h"
+
+namespace llvm {
+using namespace sys;
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only TRULY operating system
+//===          independent code. 
+//===----------------------------------------------------------------------===//
+
+}
+
+// Include the platform-specific parts of this class.
+#include "platform/Program.cpp"
+
+// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab
diff --git a/lib/System/SunOS/Program.cpp b/lib/System/SunOS/Program.cpp
new file mode 100644 (file)
index 0000000..45ec6e1
--- /dev/null
@@ -0,0 +1,22 @@
+//===- SunOS/Program.cpp - SunOS Program Implementation ------- -*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the 
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This file provides the SunOS specific implementation of the Program class.
+//
+//===----------------------------------------------------------------------===//
+
+// Include the generic Unix implementation
+#include "../Unix/Program.cpp"
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only SunOS specific code 
+//===          and must not be generic UNIX code (see ../Unix/Program.cpp)
+//===----------------------------------------------------------------------===//
+
+// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab
diff --git a/lib/System/Unix/Program.cpp b/lib/System/Unix/Program.cpp
new file mode 100644 (file)
index 0000000..6943d52
--- /dev/null
@@ -0,0 +1,133 @@
+//===- llvm/System/Unix/Program.cpp -----------------------------*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the 
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Unix specific portion of the Program class.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic UNIX code that
+//===          is guaranteed to work on *all* UNIX variants.
+//===----------------------------------------------------------------------===//
+
+#include "Unix.h"
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <Config/config.h>
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+namespace llvm {
+using namespace sys;
+
+// This function just uses the PATH environment variable to find the program.
+Program
+Program::FindProgramByName(const std::string& progName) {
+
+  // Check some degenerate cases
+  if (progName.length() == 0) // no program
+    return Program();
+  Program temp;
+  if (!temp.set_file(progName)) // invalid name
+    return Program();
+  if (temp.executable()) // already executable as is
+    return temp;
+
+  // At this point, the file name is valid and its not executable
+  // Get the path. If its empty, we can't do anything to find it.
+  const char *PathStr = getenv("PATH");
+  if (PathStr == 0) 
+    return Program();
+
+  // Now we have a colon separated list of directories to search; try them.
+  unsigned PathLen = strlen(PathStr);
+  while (PathLen) {
+    // Find the first colon...
+    const char *Colon = std::find(PathStr, PathStr+PathLen, ':');
+
+    // Check to see if this first directory contains the executable...
+    Program FilePath;
+    if (FilePath.set_directory(std::string(PathStr,Colon))) {
+      FilePath.append_file(progName);
+      if (FilePath.executable())
+        return FilePath;                    // Found the executable!
+    }
+
+    // Nope it wasn't in this directory, check the next path in the list!
+    PathLen -= Colon-PathStr;
+    PathStr = Colon;
+
+    // Advance past duplicate colons
+    while (*PathStr == ':') {
+      PathStr++;
+      PathLen--;
+    }
+  }
+  return Program();
+}
+
+//
+int 
+Program::ExecuteAndWait(const std::vector<std::string>& args) const {
+  if (!executable())
+    throw get() + " is not executable"; 
+
+#ifdef HAVE_SYS_WAIT_H
+  // Create local versions of the parameters that can be passed into execve()
+  // without creating const problems.
+  const char* argv[ args.size() + 2 ];
+  unsigned index = 0;
+  std::string progname(this->getLast());
+  argv[index++] = progname.c_str();
+  for (unsigned i = 0; i < args.size(); i++)
+    argv[index++] = args[i].c_str();
+  argv[index] = 0;
+
+  // Create a child process.
+  switch (fork()) {
+    // An error occured:  Return to the caller.
+    case -1:
+      ThrowErrno(std::string("Couldn't execute program '") + get() + "'");
+      break;
+
+    // Child process: Execute the program.
+    case 0:
+      execve (get().c_str(), (char** const)argv, environ);
+      // If the execve() failed, we should exit and let the parent pick up
+      // our non-zero exit status.
+      exit (errno);
+
+    // Parent process: Break out of the switch to do our processing.
+    default:
+      break;
+  }
+
+  // Parent process: Wait for the child process to terminate.
+  int status;
+  if ((::wait (&status)) == -1)
+    ThrowErrno(std::string("Failed waiting for program '") + get() + "'");
+
+  // If the program exited normally with a zero exit status, return success!
+  if (WIFEXITED (status))
+    return WEXITSTATUS(status);
+  else if (WIFSIGNALED(status))
+    throw std::string("Program '") + get() + "' received terminating signal.";
+  else
+    return 0;
+    
+#else
+  throw std::string("Program::ExecuteAndWait not implemented on this platform!\n");
+#endif
+
+}
+
+}
+// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab
diff --git a/lib/System/Unix/Program.inc b/lib/System/Unix/Program.inc
new file mode 100644 (file)
index 0000000..6943d52
--- /dev/null
@@ -0,0 +1,133 @@
+//===- llvm/System/Unix/Program.cpp -----------------------------*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the 
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Unix specific portion of the Program class.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic UNIX code that
+//===          is guaranteed to work on *all* UNIX variants.
+//===----------------------------------------------------------------------===//
+
+#include "Unix.h"
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <Config/config.h>
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+namespace llvm {
+using namespace sys;
+
+// This function just uses the PATH environment variable to find the program.
+Program
+Program::FindProgramByName(const std::string& progName) {
+
+  // Check some degenerate cases
+  if (progName.length() == 0) // no program
+    return Program();
+  Program temp;
+  if (!temp.set_file(progName)) // invalid name
+    return Program();
+  if (temp.executable()) // already executable as is
+    return temp;
+
+  // At this point, the file name is valid and its not executable
+  // Get the path. If its empty, we can't do anything to find it.
+  const char *PathStr = getenv("PATH");
+  if (PathStr == 0) 
+    return Program();
+
+  // Now we have a colon separated list of directories to search; try them.
+  unsigned PathLen = strlen(PathStr);
+  while (PathLen) {
+    // Find the first colon...
+    const char *Colon = std::find(PathStr, PathStr+PathLen, ':');
+
+    // Check to see if this first directory contains the executable...
+    Program FilePath;
+    if (FilePath.set_directory(std::string(PathStr,Colon))) {
+      FilePath.append_file(progName);
+      if (FilePath.executable())
+        return FilePath;                    // Found the executable!
+    }
+
+    // Nope it wasn't in this directory, check the next path in the list!
+    PathLen -= Colon-PathStr;
+    PathStr = Colon;
+
+    // Advance past duplicate colons
+    while (*PathStr == ':') {
+      PathStr++;
+      PathLen--;
+    }
+  }
+  return Program();
+}
+
+//
+int 
+Program::ExecuteAndWait(const std::vector<std::string>& args) const {
+  if (!executable())
+    throw get() + " is not executable"; 
+
+#ifdef HAVE_SYS_WAIT_H
+  // Create local versions of the parameters that can be passed into execve()
+  // without creating const problems.
+  const char* argv[ args.size() + 2 ];
+  unsigned index = 0;
+  std::string progname(this->getLast());
+  argv[index++] = progname.c_str();
+  for (unsigned i = 0; i < args.size(); i++)
+    argv[index++] = args[i].c_str();
+  argv[index] = 0;
+
+  // Create a child process.
+  switch (fork()) {
+    // An error occured:  Return to the caller.
+    case -1:
+      ThrowErrno(std::string("Couldn't execute program '") + get() + "'");
+      break;
+
+    // Child process: Execute the program.
+    case 0:
+      execve (get().c_str(), (char** const)argv, environ);
+      // If the execve() failed, we should exit and let the parent pick up
+      // our non-zero exit status.
+      exit (errno);
+
+    // Parent process: Break out of the switch to do our processing.
+    default:
+      break;
+  }
+
+  // Parent process: Wait for the child process to terminate.
+  int status;
+  if ((::wait (&status)) == -1)
+    ThrowErrno(std::string("Failed waiting for program '") + get() + "'");
+
+  // If the program exited normally with a zero exit status, return success!
+  if (WIFEXITED (status))
+    return WEXITSTATUS(status);
+  else if (WIFSIGNALED(status))
+    throw std::string("Program '") + get() + "' received terminating signal.";
+  else
+    return 0;
+    
+#else
+  throw std::string("Program::ExecuteAndWait not implemented on this platform!\n");
+#endif
+
+}
+
+}
+// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab
diff --git a/lib/System/Win32/Program.cpp b/lib/System/Win32/Program.cpp
new file mode 100644 (file)
index 0000000..7a6b124
--- /dev/null
@@ -0,0 +1,19 @@
+//===- Win32/Program.cpp - Win32 Program Implelementation ----- -*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the 
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This file provides the Win32 specific implementation of the Program class.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic Win32 code that
+//===          is guaranteed to work on *all* Win32 variants.
+//===----------------------------------------------------------------------===//
+
+// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab
diff --git a/lib/System/Win32/Program.inc b/lib/System/Win32/Program.inc
new file mode 100644 (file)
index 0000000..7a6b124
--- /dev/null
@@ -0,0 +1,19 @@
+//===- Win32/Program.cpp - Win32 Program Implelementation ----- -*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the 
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This file provides the Win32 specific implementation of the Program class.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic Win32 code that
+//===          is guaranteed to work on *all* Win32 variants.
+//===----------------------------------------------------------------------===//
+
+// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab