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]));
}
Exemple #2
0
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();
}
Exemple #4
0
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;
}
Exemple #5
0
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();
}
Exemple #6
0
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());
	}
}