Go to the documentation of this file.00001
00002
00003 #include <cerrno>
00004 #include <cstdlib>
00005 #include <exception>
00006 #include <iostream>
00007 #include <string>
00008
00009 #include <sys/wait.h>
00010 #include <unistd.h>
00011 #include <cstring>
00012
00013 #include "boost/version.hpp"
00014 #include "boost/filesystem/convenience.hpp"
00015
00016 #include "FWCore/Utilities/interface/EDMException.h"
00017 #include "FWCore/Utilities/interface/Exception.h"
00018 #include "FWCore/Utilities/interface/RegexMatch.h"
00019 #include "FWCore/Utilities/interface/TestHelper.h"
00020
00021 namespace bf = boost::filesystem;
00022
00023 int run_script(std::string const& shell, std::string const& script) {
00024 pid_t pid = 0;
00025 int status = 0;
00026
00027 if((pid = fork()) < 0) {
00028 std::cerr << "fork failed, to run " << script << std::endl;;
00029 return -1;
00030 }
00031
00032 if(pid == 0) {
00033 execlp(shell.c_str(), "sh", "-c", script.c_str(), static_cast<char const*>(0));
00034 std::cerr << "child failed becuase '" << strerror(errno) << "'\n";
00035 _exit(127);
00036 } else {
00037 while(waitpid(pid, &status, 0) < 0) {
00038 if(errno != EINTR) {
00039 std::cerr << "child process failed " << strerror(errno) << "\n";
00040 status = -1;
00041 break;
00042 } else {
00043 if(WIFSIGNALED(status)) {
00044 std::cerr << "child existed because of a signal " << WTERMSIG(status) << "\n";
00045 }
00046 }
00047 }
00048 if(WIFSIGNALED(status)) {
00049 std::cerr << "child existed because of a signal " << WTERMSIG(status) << "\n";
00050 }
00051 if(WIFEXITED(status)) {
00052 }
00053 }
00054 return status;
00055 }
00056
00057 int do_work(int argc, char* argv[], char** env) {
00058 bf::path currentPath(bf::initial_path().string());
00059
00060 if(argc < 4) {
00061 std::cout << "Usage: " << argv[0] << " shell subdir script1 script2 ... scriptN\n\n"
00062 << "where shell is the path+shell (e.g., /bin/bash) intended to run the scripts\n"
00063 << "and subdir is the subsystem/package/subdir in which the scripts are found\n"
00064 << "(e.g., FWCore/Utilities/test)\n"
00065 << std::endl;
00066
00067 std::cout << "Current directory is: " << currentPath.string() << '\n';
00068 std::cout << "Current environment:\n";
00069 std::cout << "---------------------\n";
00070 for(int i = 0; env[i] != 0; ++i) std::cout << env[i] << '\n';
00071 std::cout << "---------------------\n";
00072 std::cout << "Executable name: " << argv[0] << '\n';
00073 return -1;
00074 }
00075
00076 char const* goodDirectory = "[A-Za-z0-9/_.-]+";
00077
00078 for(int i = 0; i < argc; ++i) {
00079 std::cout << "argument " << i << ": " << argv[i] << '\n';
00080 }
00081
00082 std::string shell(argv[1]);
00083 std::cerr << "shell is: " << shell << '\n';
00084
00085 std::cout << "Current directory is: " << currentPath.string() << '\n';
00086
00087
00088 char const* topdir = getenv("SCRAMRT_LOCALRT");
00089 if(!topdir) topdir = getenv("LOCALRT");
00090 try {
00091 if(!edm::untaintString(topdir, goodDirectory)) {
00092 std::cerr << "Invalid top directory '" << topdir << "'" << std::endl;;
00093 return -1;
00094 }
00095 }
00096 catch(std::runtime_error const& e) {
00097 std::cerr << "Invalid top directory '" << topdir << "'" << std::endl;;
00098 std::cerr << "e.what" << std::endl;;
00099 return -1;
00100 }
00101
00102 char const* arch = getenv("SCRAM_ARCH");
00103
00104 if(!arch) {
00105
00106 bf::path exepath(argv[0]);
00107 #if (BOOST_VERSION / 100000) >= 1 && ((BOOST_VERSION / 100) % 1000) >= 47
00108 std::string maybe_arch = exepath.parent_path().filename().string();
00109 #else
00110 std::string maybe_arch = exepath.branch_path().leaf();
00111 #endif
00112 if(setenv("SCRAM_ARCH", maybe_arch.c_str(), 1) != 0) {
00113 std::cerr << "SCRAM_ARCH not set and attempt to set it failed\n";
00114 return -1;
00115 }
00116 arch = getenv("SCRAM_ARCH");
00117 }
00118
00119 int rc = 0;
00120
00121 if(!topdir) {
00122 std::cerr << "Neither SCRAMRT_LOCALRT nor LOCALRT is defined" << std::endl;;
00123 return -1;
00124 }
00125
00126 try {
00127 if(!edm::untaintString(argv[2], goodDirectory)) {
00128 std::cerr << "Invalid test directory '" << argv[2] << "'" << std::endl;;
00129 return -1;
00130 }
00131 }
00132 catch(std::runtime_error const& e) {
00133 std::cerr << "Invalid test directory '" << argv[2] << "'" << std::endl;;
00134 std::cerr << "e.what" << std::endl;;
00135 return -1;
00136 }
00137
00138 std::string testdir(topdir); testdir += "/src/"; testdir += argv[2];
00139 std::string tmpdir(topdir); tmpdir += "/tmp/"; tmpdir += arch;
00140 std::string testbin(topdir); testbin += "/test/"; testbin += arch;
00141
00142 std::cout << "topdir is: " << topdir << '\n';
00143 std::cout << "testdir is: " << testdir << '\n';
00144 std::cout << "tmpdir is: " << tmpdir << '\n';
00145 std::cout << "testbin is: " << testbin << '\n';
00146
00147 if(setenv("LOCAL_TEST_DIR", testdir.c_str(),1) != 0) {
00148 std::cerr << "Could not set LOCAL_TEST_DIR to " << testdir << std::endl;;
00149 return -1;
00150 }
00151 if(setenv("LOCAL_TMP_DIR", tmpdir.c_str(),1) != 0) {
00152 std::cerr << "Could not set LOCAL_TMP_DIR to " << tmpdir << std::endl;;
00153 return -1;
00154 }
00155 if(setenv("LOCAL_TOP_DIR", topdir,1) != 0) {
00156 std::cerr << "Could not set LOCAL_TOP_DIR to " << topdir << std::endl;;
00157 return -1;
00158 }
00159 if(setenv("LOCAL_TEST_BIN", testbin.c_str(),1) != 0) {
00160 std::cerr << "Could not set LOCAL_TEST_BIN to " << testbin << std::endl;;
00161 return -1;
00162 }
00163
00164 testdir += "/";
00165
00166 for(int i = 3; i < argc && rc == 0; ++i) {
00167 std::string scriptname(testdir);
00168 scriptname += argv[i];
00169 std::cout << "Running script: " << scriptname << std::endl;
00170 rc = run_script(shell, scriptname);
00171 }
00172
00173 std::cout << "status = " << rc << std::endl;
00174 return rc == 0 ? 0 : -1;
00175 }
00176
00177 int ptomaine(int argc, char* argv[], char** env) {
00178 int rc = 1;
00179 try {
00180 rc = do_work(argc, argv, env);
00181 }
00182 catch(edm::Exception& x) {
00183 std::cerr << "Caught an edm::Exception in "
00184 << argv[0] << '\n'
00185 << x;
00186 }
00187 catch(cms::Exception& x) {
00188 std::cerr << "Caught a cms::Exception in "
00189 << argv[0] << '\n'
00190 << x;
00191 }
00192 catch(std::exception& x) {
00193 std::cerr << "Caught a std::exception in "
00194 << argv[0] << '\n'
00195 << x.what();
00196 }
00197 catch(...) {
00198 std::cerr << "Caught an unknown exception in "
00199 << argv[0];
00200 }
00201 return rc;
00202 }