void replaceStringInFile(const char *filename, const string &toFind, const string &replaceWith) { FILE *f = fopen(filename, "r"); if (f == NULL) { int e = errno; string message = "Cannot open file '"; message.append(filename); message.append("' for reading"); throw FileSystemException(message, e, filename); } string content(readAll(fileno(f))); fclose(f); f = fopen(filename, "w"); if (f == NULL) { int e = errno; string message = "Cannot open file '"; message.append(filename); message.append("' for writing"); throw FileSystemException(message, e, filename); } content = replaceString(content, toFind, replaceWith); fwrite(content.data(), 1, content.size(), f); fclose(f); }
void FS::copy(const QString &from, const QString &to) { QFile file(from); if (!file.copy(to)) { throw FileSystemException("Error copying file to " + to + ": " + file.errorString()); } }
void FS::ensureExists(const QDir &dir) { if (!QDir().mkpath(dir.absolutePath())) { throw FileSystemException("Unable to create directory " + dir.dirName() + " (" + dir.absolutePath() + ")"); } }
QByteArray FS::read(const QString &filename) { QFile file(filename); if (!file.open(QFile::ReadOnly)) { throw FileSystemException("Unable to open " + filename + " for reading: " + file.errorString()); } const qint64 size = file.size(); QByteArray data(size, 0); const qint64 ret = file.read(data.data(), size); if (ret == -1 || ret != size) { throw FileSystemException("Error reading data from " + filename + ": " + file.errorString()); } return data; }
void FS::write(const QString &filename, const QByteArray &data) { QSaveFile file(filename); if (!file.open(QSaveFile::WriteOnly)) { throw FileSystemException("Couldn't open " + filename + " for writing: " + file.errorString()); } if (data.size() != file.write(data)) { throw FileSystemException("Error writing data to " + filename + ": " + file.errorString()); } if (!file.commit()) { throw FileSystemException("Error while committing data to " + filename + ": " + file.errorString()); } }
void FS::remove(const QString &filename) { QFile file(filename); if (!file.remove()) { throw FileSystemException("Unable to remove " + filename + ": " + file.errorString()); } }
void writeFile(const string &filename, const string &contents) { FILE *f = fopen(filename.c_str(), "w"); if (f == NULL) { int e = errno; string message = "Cannot open file '"; message.append(filename); message.append("' for writing"); throw FileSystemException(message, e, filename); } fwrite(contents.data(), 1, contents.size(), f); fclose(f); }
void replaceStringInFile(const char *filename, const string &toFind, const string &replaceWith) { string content = readAll(filename); FILE *f = fopen(filename, "w"); if (f == NULL) { int e = errno; string message = "Cannot open file '"; message.append(filename); message.append("' for writing"); throw FileSystemException(message, e, filename); } else { StdioGuard guard(f, __FILE__, __LINE__); content = replaceString(content, toFind, replaceWith); fwrite(content.data(), 1, content.size(), f); } }
string readAll(const string &filename) { FILE *f = fopen(filename.c_str(), "rb"); if (f != NULL) { try { string result = readAll(fileno(f)); fclose(f); return result; } catch (...) { fclose(f); throw; } } else { int e = errno; throw FileSystemException("Cannot open '" + filename + "' for reading", e, filename); } }
vector<string> listDir(const string &path) { vector<string> result; DIR *d = opendir(path.c_str()); struct dirent *ent; if (d == NULL) { int e = errno; throw FileSystemException("Cannot open directory " + path, e, path); } while ((ent = readdir(d)) != NULL) { if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) { continue; } result.push_back(ent->d_name); } return result; }
void touchFile(const char *filename, time_t timestamp) { FILE *f = fopen(filename, "a"); if (f != NULL) { fclose(f); } else if (errno != EISDIR) { int e = errno; string message = "Cannot touch file '"; message.append(filename); message.append("'"); throw FileSystemException(message, e, filename); } if (timestamp != (time_t) -1) { struct utimbuf times; times.actime = timestamp; times.modtime = timestamp; utime(filename, ×); } }
VariantMap initializeAgent(int argc, char *argv[], const char *processName) { TRACE_POINT(); VariantMap options; ignoreSigpipe(); installAbortHandler(); setup_syscall_interruption_support(); setvbuf(stdout, NULL, _IONBF, 0); setvbuf(stderr, NULL, _IONBF, 0); try { if (argc == 1) { int ret = fcntl(FEEDBACK_FD, F_GETFL); if (ret == -1) { if (errno == EBADF) { fprintf(stderr, "You're not supposed to start this program from the command line. " "It's used internally by Phusion Passenger.\n"); exit(1); } else { int e = errno; fprintf(stderr, "Encountered an error in feedback file descriptor 3: %s (%d)\n", strerror(e), e); exit(1); } } else { _feedbackFdAvailable = true; options.readFrom(FEEDBACK_FD); if (options.getBool("fire_and_forget", false)) { _feedbackFdAvailable = false; close(FEEDBACK_FD); } } } else { options.readFrom((const char **) argv + 1, argc - 1); } setLogLevel(options.getInt("log_level", false, 0)); if (!options.get("debug_log_file", false).empty()) { if (strcmp(processName, "PassengerWatchdog") == 0) { /* Have the watchdog set STDOUT and STDERR to the debug * log file so that system abort() calls that stuff * are properly logged. */ string filename = options.get("debug_log_file"); options.erase("debug_log_file"); int fd = open(filename.c_str(), O_CREAT | O_WRONLY | O_APPEND, 0644); if (fd == -1) { int e = errno; throw FileSystemException("Cannot open debug log file " + filename, e, filename); } dup2(fd, STDOUT_FILENO); dup2(fd, STDERR_FILENO); close(fd); } else { setDebugFile(options.get("debug_log_file").c_str()); } } } catch (const tracable_exception &e) { P_ERROR("*** ERROR: " << e.what() << "\n" << e.backtrace()); exit(1); } // Change process title. strncpy(argv[0], processName, strlen(argv[0])); for (int i = 1; i < argc; i++) { memset(argv[i], '\0', strlen(argv[i])); } return options; }
/** * * @param exe Full path to the exe, probably derived from argv0. */ KatFS(const char* argv) { path exe(argv); //cout << exe << endl; if(exe.is_absolute()) { //cout << "Absolute" << endl; // Easy job... nothing special to do, resolve symlink then take two levels up katExe = fs::canonical(exe); rootDir = katExe.parent_path().parent_path(); } else if (exe.string().find('/') != string::npos) { //cout << "Relative" << endl; // Relative with some parent paths... get absolute path, resolving symlinks then take two levels up katExe = fs::canonical(fs::system_complete(exe)); rootDir = katExe.parent_path().parent_path(); } else { //cout << "name only" << endl; // Tricky one... just exe name, no indication of where if comes from. Now we have to resort to using which. string cmd = string("which ") + exe.string(); string res = exec(cmd.c_str()); string fullpath = res.substr(0, res.length() - 1); //cout << "fullpath" << fullpath << endl; katExe = fs::canonical(path(fullpath)); rootDir = katExe.parent_path().parent_path(); } binDir = path(rootDir); binDir /= "bin"; libsDir = path(rootDir); libsDir /= ".libs"; path srcDir = path(rootDir); srcDir /= "src"; path testDir = path(rootDir); testDir /= "tests"; if (katExe.parent_path() == srcDir || katExe.parent_path() == libsDir || katExe.parent_path() == testDir) { scriptsDir = path(rootDir); scriptsDir /= "scripts"; } else { scriptsDir = path(binDir); } if (!exists(scriptsDir)) { BOOST_THROW_EXCEPTION(FileSystemException() << FileSystemErrorInfo(string( "Could not find suitable directory containing KAT scripts at: ") + scriptsDir.c_str())); } }
VariantMap initializeAgent(int argc, char *argv[], const char *processName) { VariantMap options; const char *seedStr; seedStr = getenv("PASSENGER_RANDOM_SEED"); if (seedStr == NULL || *seedStr == '\0') { randomSeed = (unsigned int) time(NULL); } else { randomSeed = (unsigned int) atoll(seedStr); } srand(randomSeed); srandom(randomSeed); ignoreSigpipe(); if (hasEnvOption("PASSENGER_ABORT_HANDLER", true)) { shouldDumpWithCrashWatch = hasEnvOption("PASSENGER_DUMP_WITH_CRASH_WATCH", true); beepOnAbort = hasEnvOption("PASSENGER_BEEP_ON_ABORT", false); stopOnAbort = hasEnvOption("PASSENGER_STOP_ON_ABORT", false); IGNORE_SYSCALL_RESULT(pipe(emergencyPipe1)); IGNORE_SYSCALL_RESULT(pipe(emergencyPipe2)); installAbortHandler(); } oxt::initialize(); setup_syscall_interruption_support(); if (getenv("PASSENGER_SIMULATE_SYSCALL_FAILURES")) { initializeSyscallFailureSimulation(processName); } setvbuf(stdout, NULL, _IONBF, 0); setvbuf(stderr, NULL, _IONBF, 0); TRACE_POINT(); try { if (argc == 1) { int e; switch (fdIsSocket(FEEDBACK_FD)) { case FISR_YES: _feedbackFdAvailable = true; options.readFrom(FEEDBACK_FD); if (options.getBool("fire_and_forget", false)) { _feedbackFdAvailable = false; close(FEEDBACK_FD); } break; case FISR_NO: fprintf(stderr, "You're not supposed to start this program from the command line. " "It's used internally by Phusion Passenger.\n"); exit(1); break; case FISR_ERROR: e = errno; fprintf(stderr, "Encountered an error in feedback file descriptor 3: %s (%d)\n", strerror(e), e); exit(1); break; } } else { options.readFrom((const char **) argv + 1, argc - 1); } #ifdef __linux__ if (options.has("passenger_root")) { ResourceLocator locator(options.get("passenger_root", true)); string ruby = options.get("default_ruby", false, DEFAULT_RUBY); string path = ruby + " \"" + locator.getHelperScriptsDir() + "/backtrace-sanitizer.rb\""; backtraceSanitizerCommand = strdup(path.c_str()); } #endif if (backtraceSanitizerCommand == NULL) { backtraceSanitizerCommand = "c++filt -n"; backtraceSanitizerPassProgramInfo = false; } options.setDefaultInt("log_level", DEFAULT_LOG_LEVEL); setLogLevel(options.getInt("log_level")); if (!options.get("debug_log_file", false).empty()) { if (strcmp(processName, "PassengerWatchdog") == 0) { /* Have the watchdog set STDOUT and STDERR to the debug * log file so that system abort() calls that stuff * are properly logged. */ string filename = options.get("debug_log_file"); options.erase("debug_log_file"); int fd = open(filename.c_str(), O_CREAT | O_WRONLY | O_APPEND, 0644); if (fd == -1) { int e = errno; throw FileSystemException("Cannot open debug log file " + filename, e, filename); } dup2(fd, STDOUT_FILENO); dup2(fd, STDERR_FILENO); close(fd); } else { setDebugFile(options.get("debug_log_file").c_str()); } } } catch (const tracable_exception &e) { P_ERROR("*** ERROR: " << e.what() << "\n" << e.backtrace()); exit(1); } // Change process title. argv0 = strdup(argv[0]); strncpy(argv[0], processName, strlen(argv[0])); for (int i = 1; i < argc; i++) { memset(argv[i], '\0', strlen(argv[i])); } P_DEBUG("Random seed: " << randomSeed); return options; }
void FS::remove(const QDir &dir) { if (!QDir(dir).removeRecursively()) { throw FileSystemException("Unable to remove " + dir.dirName()); } }