void ProcessLauncher::launchProcess() { GPid pid = 0; int sockets[2]; if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sockets) < 0) { g_printerr("Creation of socket failed: %s.\n", g_strerror(errno)); ASSERT_NOT_REACHED(); return; } GOwnPtr<gchar> binaryPath(g_build_filename(applicationDirectoryPath().data(), gWebKitWebProcessName, NULL)); GOwnPtr<gchar> socket(g_strdup_printf("%d", sockets[0])); char* argv[3]; argv[0] = binaryPath.get(); argv[1] = socket.get(); argv[2] = 0; GOwnPtr<GError> error; int spawnFlags = G_SPAWN_LEAVE_DESCRIPTORS_OPEN | G_SPAWN_DO_NOT_REAP_CHILD; if (!g_spawn_async(0, argv, 0, static_cast<GSpawnFlags>(spawnFlags), childSetupFunction, GINT_TO_POINTER(sockets[1]), &pid, &error.outPtr())) { g_printerr("Unable to fork a new WebProcess: %s.\n", error->message); ASSERT_NOT_REACHED(); } close(sockets[0]); m_processIdentifier = pid; // We've finished launching the process, message back to the main run loop. RunLoop::main()->scheduleWork(WorkItem::create(this, &ProcessLauncher::didFinishLaunchingProcess, m_processIdentifier, sockets[1])); }
QString WebService::installPrefix() const { #ifndef Q_OS_WIN32DOWS QDir binaryPath(QCoreApplication::applicationDirPath()); if (binaryPath.cdUp()) { return QDir::toNativeSeparators(binaryPath.canonicalPath()); } #endif #ifdef Q_OS_LINUX QString basePath(qgetenv("PLEXYDESK_DIR")); if (basePath.isEmpty() || basePath.isNull()) { return PLEXYPREFIX; } return basePath; #endif #ifdef Q_OS_MAC CFURLRef appUrlRef = CFBundleCopyBundleURL(CFBundleGetMainBundle()); CFStringRef macPath = CFURLCopyFileSystemPath(appUrlRef, kCFURLPOSIXPathStyle); const char *pathPtr = CFStringGetCStringPtr(macPath, CFStringGetSystemEncoding()); CFRelease(appUrlRef); CFRelease(macPath); return QLatin1String(pathPtr) + QString("/Contents/"); #endif return QString(); }
void VcsCommand::run(QFutureInterface<void> &future) { // Check that the binary path is not empty if (binaryPath().isEmpty()) { emit errorText(tr("Unable to start process, binary is empty")); return; } QString stdOut; QString stdErr; if (d->m_progressParser) d->m_progressParser->setFuture(&future); else future.setProgressRange(0, 1); const int count = d->m_jobs.size(); d->m_lastExecExitCode = -1; d->m_lastExecSuccess = true; for (int j = 0; j < count; j++) { const Internal::VcsCommandPrivate::Job &job = d->m_jobs.at(j); const int timeOutSeconds = job.timeout; Utils::SynchronousProcessResponse resp = runVcs( job.arguments, timeOutSeconds >= 0 ? timeOutSeconds * 1000 : -1, job.exitCodeInterpreter); stdOut += resp.stdOut; stdErr += resp.stdErr; d->m_lastExecExitCode = resp.exitCode; d->m_lastExecSuccess = resp.result == Utils::SynchronousProcessResponse::Finished; if (!d->m_lastExecSuccess) break; } if (!d->m_aborted) { if (!d->m_progressiveOutput) { emit output(stdOut); if (!stdErr.isEmpty()) emit errorText(stdErr); } emit finished(d->m_lastExecSuccess, d->m_lastExecExitCode, cookie()); if (d->m_lastExecSuccess) emit success(cookie()); future.setProgressValue(future.progressMaximum()); } if (d->m_progressParser) d->m_progressParser->setFuture(0); // As it is used asynchronously, we need to delete ourselves this->deleteLater(); }
Utils::FileName GitSettings::gitExecutable(bool *ok, QString *errorMessage) const { // Locate binary in path if one is specified, otherwise default // to pathless binary if (ok) *ok = true; if (errorMessage) errorMessage->clear(); Utils::FileName binPath = binaryPath(); if (binPath.isEmpty()) { if (ok) *ok = false; if (errorMessage) *errorMessage = QCoreApplication::translate("Git::Internal::GitSettings", "The binary \"%1\" could not be located in the path \"%2\"") .arg(stringValue(binaryPathKey), stringValue(pathKey)); } return binPath; }
void Command::run() { // Check that the binary path is not empty if (binaryPath().trimmed().isEmpty()) { emit errorText(tr("Unable to start process, binary is empty")); return; } const unsigned processFlags = unixTerminalDisabled() ? unsigned(Utils::SynchronousProcess::UnixTerminalDisabled) : unsigned(0); const QSharedPointer<QProcess> process = Utils::SynchronousProcess::createProcess(processFlags); if (!workingDirectory().isEmpty()) process->setWorkingDirectory(workingDirectory()); process->setProcessEnvironment(processEnvironment()); QByteArray stdOut; QByteArray stdErr; QString error; const int count = d->m_jobs.size(); int exitCode = -1; bool ok = true; for (int j = 0; j < count; j++) { process->start(binaryPath(), d->m_jobs.at(j).arguments); if (!process->waitForStarted()) { ok = false; error += QString::fromLatin1("Error: \"%1\" could not be started: %2") .arg(binaryPath(), process->errorString()); break; } process->closeWriteChannel(); const int timeOutSeconds = d->m_jobs.at(j).timeout; if (!Utils::SynchronousProcess::readDataFromProcess(*process, timeOutSeconds * 1000, &stdOut, &stdErr, false)) { Utils::SynchronousProcess::stopProcess(*process); ok = false; error += msgTimeout(timeOutSeconds); break; } error += QString::fromLocal8Bit(stdErr); exitCode = process->exitCode(); switch (reportTerminationMode()) { case NoReport: break; case ReportStdout: stdOut += msgTermination(exitCode, binaryPath(), d->m_jobs.at(j).arguments).toUtf8(); break; case ReportStderr: error += msgTermination(exitCode, binaryPath(), d->m_jobs.at(j).arguments); break; } } // Special hack: Always produce output for diff if (ok && stdOut.isEmpty() && d->m_jobs.front().arguments.at(0) == QLatin1String("diff")) { stdOut += "No difference to HEAD"; } else { // @TODO: Remove, see below if (ok && d->m_jobs.front().arguments.at(0) == QLatin1String("status")) removeColorCodes(&stdOut); } d->m_lastExecSuccess = ok; d->m_lastExecExitCode = exitCode; if (ok && !stdOut.isEmpty()) emit outputData(stdOut); if (!error.isEmpty()) emit errorText(error); emit finished(ok, exitCode, cookie()); if (ok) emit success(cookie()); // As it is used asynchronously, we need to delete ourselves this->deleteLater(); }
void Path::init(const std::string& argv0) { // This works in the development environment: // argv0 = root/bin/program; chdir to root; everything else is right here as well. boost::filesystem::path binaryPath(argv0); if (binaryPath.has_parent_path()) { boost::filesystem::current_path(binaryPath.parent_path()); } boost::filesystem::current_path(".."); globalDataDir = boost::filesystem::current_path() / "data"; localConfigDir = boost::filesystem::current_path() / "local"; localDataDir = boost::filesystem::current_path() / "local"; // Override the global data dir with preprocessor. #if defined(GLOBAL_DATA_DIR) globalDataDir = GLOBAL_DATA_DIR; #endif #if !defined(USE_SYSTEM_PATHS) // Do nothing; use the development paths above. #elif defined(_WIN32) // Windows: use Application Data for local stuff. /* The program is not made for the UTF-16 used in Windows, * but to be nice, we'll use a small hack, as follows: * * The installation dir is like C:\Program Files\PutkaRTS. * The path is likely to contain only 8-bit characters ("ANSI codepage"). * The user data dir is like C:\Users\Jørgen-äijä\Application Data. * The path may contain just anything, depending on the login name. * * So the trick is to chdir to Application Data here with * any Unicode characters and then use relative paths for * the local files. This way the rest of the program doesn't * need to care about UTF-16 at all. */ TCHAR w32ApplicationData[MAX_PATH]; if (SHGetFolderPath(0, CSIDL_APPDATA, 0, 0, w32ApplicationData) == S_OK) { if (SetCurrentDirectory(w32ApplicationData)) { localDataDir = localConfigDir = "PutkaRTS"; } } #else // Others: try some environment variables. const char *home = getenv("HOME"); const char *config = getenv("XDG_CONFIG_HOME"); const char *data = getenv("XDG_DATA_HOME"); if (!boost::filesystem::exists(home)) { home = 0; } if (!boost::filesystem::exists(config)) { config = 0; } if (!boost::filesystem::exists(data)) { data = 0; } if (config) { localConfigDir = config; localConfigDir /= "PutkaRTS"; } else if (home) { localConfigDir = home; localConfigDir /= ".config/PutkaRTS"; } if (data) { localDataDir = data; localDataDir /= "PutkaRTS"; } else if (home) { localDataDir = home; localDataDir /= ".local/share/PutkaRTS"; } #endif if (!boost::filesystem::exists(globalDataDir)) { throw std::runtime_error("Could not find global data dir! Tried: " + globalDataDir.string()); } }