void Agent::handleStartProcessPacket()

in src/agent/Agent.cc [351:421]


void Agent::handleStartProcessPacket(ReadBuffer &packet)
{
    ASSERT(m_childProcess == nullptr);
    ASSERT(!m_closingOutputPipes);

    const uint64_t spawnFlags = packet.getInt64();
    const bool wantProcessHandle = packet.getInt32() != 0;
    const bool wantThreadHandle = packet.getInt32() != 0;
    const auto program = packet.getWString();
    const auto cmdline = packet.getWString();
    const auto cwd = packet.getWString();
    const auto env = packet.getWString();
    const auto desktop = packet.getWString();
    packet.assertEof();

    auto cmdlineV = vectorWithNulFromString(cmdline);
    auto desktopV = vectorWithNulFromString(desktop);
    auto envV = vectorFromString(env);

    LPCWSTR programArg = program.empty() ? nullptr : program.c_str();
    LPWSTR cmdlineArg = cmdline.empty() ? nullptr : cmdlineV.data();
    LPCWSTR cwdArg = cwd.empty() ? nullptr : cwd.c_str();
    LPWSTR envArg = env.empty() ? nullptr : envV.data();

    STARTUPINFOW sui = {};
    PROCESS_INFORMATION pi = {};
    sui.cb = sizeof(sui);
    sui.lpDesktop = desktop.empty() ? nullptr : desktopV.data();
    BOOL inheritHandles = FALSE;
    if (m_useConerr) {
        inheritHandles = TRUE;
        sui.dwFlags |= STARTF_USESTDHANDLES;
        sui.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
        sui.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
        sui.hStdError = m_errorBuffer->conout();
    }

    const BOOL success =
        CreateProcessW(programArg, cmdlineArg, nullptr, nullptr,
                       /*bInheritHandles=*/inheritHandles,
                       /*dwCreationFlags=*/CREATE_UNICODE_ENVIRONMENT,
                       envArg, cwdArg, &sui, &pi);
    const int lastError = success ? 0 : GetLastError();

    trace("CreateProcess: %s %u",
          (success ? "success" : "fail"),
          static_cast<unsigned int>(pi.dwProcessId));

    auto reply = newPacket();
    if (success) {
        int64_t replyProcess = 0;
        int64_t replyThread = 0;
        if (wantProcessHandle) {
            replyProcess = int64FromHandle(duplicateHandle(pi.hProcess));
        }
        if (wantThreadHandle) {
            replyThread = int64FromHandle(duplicateHandle(pi.hThread));
        }
        CloseHandle(pi.hThread);
        m_childProcess = pi.hProcess;
        m_autoShutdown = (spawnFlags & WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN) != 0;
        m_exitAfterShutdown = (spawnFlags & WINPTY_SPAWN_FLAG_EXIT_AFTER_SHUTDOWN) != 0;
        reply.putInt32(static_cast<int32_t>(StartProcessResult::ProcessCreated));
        reply.putInt64(replyProcess);
        reply.putInt64(replyThread);
    } else {
        reply.putInt32(static_cast<int32_t>(StartProcessResult::CreateProcessFailed));
        reply.putInt32(lastError);
    }
    writePacket(reply);
}