std::string EnvExpand(const std::string & str, const EnvMap & map) { // Early exit if no magic characters are found. if(pystring::find(str, "$") == -1 && pystring::find(str, "%") == -1) return str; std::string orig = str; std::string newstr = str; // This walks through the envmap in key order, // from longest to shortest to handle envvars which are // substrings. // ie. '$TEST_$TESTING_$TE' will expand in this order '2 1 3' for (EnvMap::const_iterator iter = map.begin(); iter != map.end(); ++iter) { newstr = pystring::replace(newstr, ("${"+iter->first+"}"), iter->second); newstr = pystring::replace(newstr, ("$"+iter->first), iter->second); newstr = pystring::replace(newstr, ("%"+iter->first+"%"), iter->second); } // recursively call till string doesn't expand anymore if(newstr != orig) { return EnvExpand(newstr, map); } return orig; }
//static ProcessHandlePtr Process::launch(const std::string& command, const Args& args, const EnvMap& envVariables, const std::string& sWorkDir) { if (!sWorkDir.empty()) { File f(sWorkDir); if (!f.createDirectories()) { FIRTEX_THROW(SystemException, "Cannot create work " "directory for: [%s]", command.c_str()); } } int pid = fork(); if (pid < 0) { FIRTEX_THROW(SystemException, "Cannot fork process for: [%s]", command.c_str()); } //fill arguments char** argv = new char*[args.size() + 2]; int i = 0; argv[i++] = const_cast<char*>(command.c_str()); for (Args::const_iterator it = args.begin(); it != args.end(); ++it) { argv[i++] = const_cast<char*>(it->c_str()); } argv[i] = NULL; if (pid == 0) //the child process { for (EnvMap::const_iterator it = envVariables.begin(); it != envVariables.end(); ++it) { Environment::set(it->first, it->second); } if (!sWorkDir.empty()) { if (chdir(sWorkDir.c_str()) == -1) { FIRTEX_THROW(RuntimeException, "chdir(%s) FAILED", sWorkDir.c_str()); } } // close all open file descriptors other than stdin, stdout, stderr for (int i = 3; i < getdtablesize(); ++i) { close(i); } stringstream ss; ss << "." << getpid(); Path path(sWorkDir); path.makeDirectory(); path.setFileName(STDOUT_FILE_NAME + ss.str()); if (freopen(path.toString().c_str(), "w+", stdout) == NULL) { FX_LOG(ERROR, "Reopen [%s] FAILED", path.toString().c_str()); } path.setFileName(STDERR_FILE_NAME + ss.str()); if (freopen(path.toString().c_str(), "w+", stderr) == NULL) { FX_LOG(ERROR, "Reopen [%s] FAILED", path.toString().c_str()); } execvp(command.c_str(), argv); fprintf(stderr, "command: [%s] execvp FAILED, error code: %d(%s)", command.c_str(), errno, strerror(errno)); fflush(stderr); _exit(72); } else { delete[] argv; //parent process return ProcessHandlePtr(new ProcessHandle(pid)); } //never get here return ProcessHandlePtr(); }