{"version":3,"file":"runCommandInTemporaryPackageManagerProject.cjs","names":["fs","path","os","sandboxUserName","forceRemove","createDirectoryWithoutFollowingSymlinks","copyWithoutFollowingSymlinks","wrapCommandWithSandboxUser","prependInsideSandboxWrapper","startSandboxTimeoutWatchdog","childProcess","getSandboxUserEnvOverrides","nodeFs"],"sources":["../../src/helpers/runCommandInTemporaryPackageManagerProject.ts"],"sourcesContent":["import childProcess from 'node:child_process';\nimport nodeFs from 'node:fs';\nimport fs from 'node:fs/promises';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport {\n  forceRemove,\n  getSandboxUserEnvOverrides,\n  killSandboxUserProcesses,\n  makeAccessibleToSandboxUser,\n  prependInsideSandboxWrapper,\n  SANDBOX_WATCHDOG_GRACE_SECONDS,\n  sandboxUserName,\n  startSandboxTimeoutWatchdog,\n  wrapCommandWithSandboxUser,\n} from './sandboxUser.js';\nimport { copyWithoutFollowingSymlinks, createDirectoryWithoutFollowingSymlinks } from './safeFs.js';\n\nexport type PackageManager = 'bun' | 'cargo' | 'go' | 'gradle' | 'maven' | 'npm' | 'pnpm' | 'ruby' | 'uv' | 'yarn';\ntype PackageManagerInstallCommand = readonly [string, ...string[]];\n\nexport interface PackageManagerCommandRunResult {\n  stdin: string;\n  stdout: string;\n  stderr: string;\n  status: number | undefined;\n  timeSeconds: number;\n  memoryBytes: number;\n  timedOut: boolean;\n  signal: NodeJS.Signals | undefined;\n  outputLimitExceeded: boolean;\n}\n\nexport interface RunCommandInTemporaryPackageManagerProjectOptions {\n  cwd: string;\n  projectDir: string;\n  packageManager: PackageManager;\n  command: readonly [string, ...string[]] | ((context: { runDir: string }) => readonly [string, ...string[]]);\n  /**\n   * Set to false when `command` prepares the dependencies it needs.\n   * Defaults to true.\n   */\n  prepareDependencies?: boolean;\n  stdin?: string;\n  env?: NodeJS.ProcessEnv;\n  timeLimitSeconds: number;\n  outputLimitBytes?: number;\n  tempDirPrefix?: string;\n  projectFilePaths?: readonly string[];\n}\n\nconst packageManagerProjectFilePaths = {\n  bun: ['package.json', 'bun.lock', 'bun.lockb'],\n  cargo: ['Cargo.toml', 'Cargo.lock'],\n  go: ['go.mod', 'go.sum'],\n  gradle: [\n    'build.gradle',\n    'build.gradle.kts',\n    'settings.gradle',\n    'settings.gradle.kts',\n    'gradle.properties',\n    'gradle.lockfile',\n    'buildscript-gradle.lockfile',\n    'gradle',\n    'gradlew',\n    'gradlew.bat',\n  ],\n  maven: ['pom.xml', '.mvn', 'mvnw', 'mvnw.cmd'],\n  npm: ['package.json', 'package-lock.json'],\n  pnpm: ['package.json', 'pnpm-lock.yaml', 'pnpm-workspace.yaml'],\n  ruby: ['Gemfile', 'Gemfile.lock', '.ruby-version'],\n  uv: ['pyproject.toml', 'uv.lock'],\n  yarn: ['package.json', 'yarn.lock', '.yarnrc', '.yarnrc.yml', '.yarn'],\n} as const satisfies Record<PackageManager, readonly string[]>;\n\nconst packageManagerInstallCommandResolvers = {\n  bun: resolveBunInstallCommand,\n  cargo: resolveCargoInstallCommand,\n  go: resolveGoInstallCommand,\n  gradle: resolveGradleInstallCommand,\n  maven: resolveMavenInstallCommand,\n  npm: resolveNpmInstallCommand,\n  pnpm: resolvePnpmInstallCommand,\n  ruby: resolveRubyInstallCommand,\n  uv: resolveUvInstallCommand,\n  yarn: resolveYarnInstallCommand,\n} as const satisfies Record<PackageManager, (runDir: string) => Promise<PackageManagerInstallCommand | undefined>>;\n\nconst defaultOutputLimitBytes = 50 * 1024 * 1024;\nconst killGracePeriodMilliseconds = 1000;\n// Added to the watchdog's own deadline so its kill has time to land and `close` to arrive.\nconst watchdogSettleMarginMilliseconds = 2000;\nconst timeCommand = resolveTimeCommand();\n\n/**\n * Copies a submission directory to a temporary directory, overlays package\n * manager project files from the problem directory, prepares dependencies,\n * runs a command, and then removes the temporary directory.\n *\n * Under `EXERCODE_SANDBOX_USER` delegation, cleanup kills every process of the sandbox user, so do\n * not run multiple invocations concurrently in that mode — one finishing would kill the others.\n */\nexport async function runCommandInTemporaryPackageManagerProject(\n  options: RunCommandInTemporaryPackageManagerProjectOptions\n): Promise<PackageManagerCommandRunResult> {\n  const runDir = await fs.mkdtemp(path.join(os.tmpdir(), options.tempDirPrefix ?? 'exercode-'));\n  try {\n    await fs.cp(options.cwd, runDir, { recursive: true });\n    await copyPackageManagerProjectFiles({\n      packageManager: options.packageManager,\n      projectDir: options.projectDir,\n      runDir,\n      projectFilePaths: options.projectFilePaths,\n    });\n    // The sandbox user (if any) runs the install/run commands below and must read the copied\n    // sources and create outputs (e.g. `node_modules`, `.venv`) next to them.\n    makeAccessibleToSandboxUser(runDir);\n\n    const env = options.env ? { ...process.env, ...options.env } : process.env;\n    const installCommand =\n      options.prepareDependencies === false ? undefined : await resolveInstallCommand(options.packageManager, runDir);\n    const command = typeof options.command === 'function' ? options.command({ runDir }) : options.command;\n    const startedAt = Date.now();\n    const outputLimitBytes = options.outputLimitBytes ?? defaultOutputLimitBytes;\n    let installResult: Awaited<ReturnType<typeof spawnWithInput>> | undefined;\n\n    if (installCommand) {\n      installResult = await spawnWithInput(installCommand, {\n        cwd: runDir,\n        env,\n        outputLimitBytes,\n        stdin: '',\n        timeLimitSeconds: options.timeLimitSeconds,\n      });\n      if (isFailedSpawnResult(installResult)) {\n        return toPackageManagerCommandRunResult({\n          elapsedTimeSeconds: (Date.now() - startedAt) / 1000,\n          options,\n          result: installResult,\n        });\n      }\n    }\n\n    const remainingTimeLimitSeconds = options.timeLimitSeconds - (Date.now() - startedAt) / 1000;\n    if (remainingTimeLimitSeconds <= 0) {\n      return {\n        stdin: options.stdin ?? '',\n        stdout: installResult?.stdout ?? '',\n        stderr: installResult?.stderr ?? '',\n        status: 0,\n        timeSeconds: options.timeLimitSeconds + 1e-3,\n        memoryBytes: installResult?.memoryBytes ?? 0,\n        timedOut: true,\n        signal: installResult?.signal,\n        outputLimitExceeded: false,\n      };\n    }\n\n    const result = await spawnWithInput(command, {\n      cwd: runDir,\n      env,\n      outputLimitBytes,\n      stdin: options.stdin ?? '',\n      timeLimitSeconds: remainingTimeLimitSeconds,\n    });\n    const elapsedTimeSeconds = (Date.now() - startedAt) / 1000;\n\n    if (installResult) {\n      return toPackageManagerCommandRunResult({\n        elapsedTimeSeconds,\n        options,\n        result: {\n          ...result,\n          timeSeconds: installResult.timeSeconds + result.timeSeconds,\n          memoryBytes: Math.max(installResult.memoryBytes, result.memoryBytes),\n        },\n      });\n    }\n\n    return toPackageManagerCommandRunResult({ elapsedTimeSeconds, options, result });\n  } finally {\n    try {\n      // Daemonized children of the sandboxed command would otherwise outlive the run.\n      if (sandboxUserName) killSandboxUserProcesses();\n    } finally {\n      // Must run even when the sweep fails closed, or the temporary submission copy leaks.\n      await forceRemove(runDir);\n    }\n  }\n}\n\nfunction toPackageManagerCommandRunResult(context: {\n  elapsedTimeSeconds: number;\n  options: RunCommandInTemporaryPackageManagerProjectOptions;\n  result: Awaited<ReturnType<typeof spawnWithInput>>;\n}): PackageManagerCommandRunResult {\n  return {\n    stdin: context.options.stdin ?? '',\n    stdout: context.result.stdout,\n    stderr: context.result.stderr,\n    status: context.result.timedOut || context.result.outputLimitExceeded ? 0 : context.result.status,\n    timeSeconds: context.result.timedOut\n      ? context.options.timeLimitSeconds + 1e-3\n      : context.result.timeSeconds || context.elapsedTimeSeconds,\n    memoryBytes: context.result.memoryBytes,\n    timedOut: context.result.timedOut,\n    signal: context.result.signal,\n    outputLimitExceeded: context.result.outputLimitExceeded,\n  };\n}\n\nfunction resolveInstallCommand(\n  packageManager: PackageManager,\n  runDir: string\n): Promise<PackageManagerInstallCommand | undefined> {\n  return packageManagerInstallCommandResolvers[packageManager](runDir);\n}\n\nfunction isFailedSpawnResult(result: Awaited<ReturnType<typeof spawnWithInput>>): boolean {\n  return result.status !== 0 || result.timedOut || result.outputLimitExceeded;\n}\n\nasync function resolveBunInstallCommand(runDir: string): Promise<PackageManagerInstallCommand | undefined> {\n  if (!(await pathExists(path.join(runDir, 'package.json')))) return undefined;\n  // Bun supports --silent and it keeps successful preparation output out of judge output buffers.\n  return (await hasAnyPath(runDir, ['bun.lock', 'bun.lockb']))\n    ? ['bun', 'install', '--frozen-lockfile', '--silent']\n    : ['bun', 'install', '--silent'];\n}\n\nasync function resolveCargoInstallCommand(runDir: string): Promise<PackageManagerInstallCommand | undefined> {\n  if (!(await pathExists(path.join(runDir, 'Cargo.toml')))) return undefined;\n  return (await pathExists(path.join(runDir, 'Cargo.lock'))) ? ['cargo', 'fetch', '--locked'] : ['cargo', 'fetch'];\n}\n\nasync function resolveGoInstallCommand(runDir: string): Promise<PackageManagerInstallCommand | undefined> {\n  if (!(await pathExists(path.join(runDir, 'go.mod')))) return undefined;\n  return ['go', 'mod', 'download'];\n}\n\nasync function resolveGradleInstallCommand(runDir: string): Promise<PackageManagerInstallCommand | undefined> {\n  if (\n    !(await hasAnyPath(runDir, [\n      'build.gradle',\n      'build.gradle.kts',\n      'settings.gradle',\n      'settings.gradle.kts',\n      'gradlew',\n      'gradlew.bat',\n    ]))\n  )\n    return undefined;\n  const args = ['--no-daemon', '--quiet', 'dependencies'] as const;\n  if (process.platform === 'win32') {\n    return (await pathExists(path.join(runDir, 'gradlew.bat')))\n      ? ['cmd.exe', '/c', 'gradlew.bat', ...args]\n      : ['gradle', ...args];\n  }\n  return (await pathExists(path.join(runDir, 'gradlew'))) ? ['sh', './gradlew', ...args] : ['gradle', ...args];\n}\n\nasync function resolveMavenInstallCommand(runDir: string): Promise<PackageManagerInstallCommand | undefined> {\n  if (!(await pathExists(path.join(runDir, 'pom.xml')))) return undefined;\n  const args = ['-q', 'dependency:go-offline'] as const;\n  if (process.platform === 'win32') {\n    return (await pathExists(path.join(runDir, 'mvnw.cmd')))\n      ? ['cmd.exe', '/c', 'mvnw.cmd', ...args]\n      : ['mvn', ...args];\n  }\n  return (await pathExists(path.join(runDir, 'mvnw'))) ? ['sh', './mvnw', ...args] : ['mvn', ...args];\n}\n\nasync function resolveNpmInstallCommand(runDir: string): Promise<PackageManagerInstallCommand | undefined> {\n  if (!(await pathExists(path.join(runDir, 'package.json')))) return undefined;\n  return (await pathExists(path.join(runDir, 'package-lock.json')))\n    ? ['npm', 'ci', '--silent']\n    : ['npm', 'install', '--silent'];\n}\n\nasync function resolvePnpmInstallCommand(runDir: string): Promise<PackageManagerInstallCommand | undefined> {\n  if (!(await pathExists(path.join(runDir, 'package.json')))) return undefined;\n  return (await pathExists(path.join(runDir, 'pnpm-lock.yaml')))\n    ? ['pnpm', 'install', '--frozen-lockfile', '--silent']\n    : ['pnpm', 'install', '--silent'];\n}\n\nasync function resolveRubyInstallCommand(runDir: string): Promise<PackageManagerInstallCommand | undefined> {\n  if (!(await pathExists(path.join(runDir, 'Gemfile')))) return undefined;\n  return (await pathExists(path.join(runDir, 'Gemfile.lock')))\n    ? ['bundle', 'install', '--frozen', '--quiet']\n    : ['bundle', 'install', '--quiet'];\n}\n\nasync function resolveUvInstallCommand(): Promise<undefined> {\n  return undefined;\n}\n\nasync function resolveYarnInstallCommand(runDir: string): Promise<PackageManagerInstallCommand | undefined> {\n  if (!(await pathExists(path.join(runDir, 'package.json')))) return undefined;\n  const isBerry = await isYarnBerryProject(runDir);\n  const hasLockfile = await pathExists(path.join(runDir, 'yarn.lock'));\n  if (isBerry) return hasLockfile ? ['yarn', 'install', '--immutable'] : ['yarn', 'install'];\n  return hasLockfile ? ['yarn', 'install', '--frozen-lockfile', '--silent'] : ['yarn', 'install', '--silent'];\n}\n\nasync function isYarnBerryProject(runDir: string): Promise<boolean> {\n  if (await pathExists(path.join(runDir, '.yarnrc.yml'))) return true;\n\n  const packageJson = await readJson(path.join(runDir, 'package.json'));\n  const packageManager = typeof packageJson.packageManager === 'string' ? packageJson.packageManager : undefined;\n  const yarnMajorVersion = /^yarn@(\\d+)/.exec(packageManager ?? '')?.[1];\n  return yarnMajorVersion !== undefined && Number(yarnMajorVersion) >= 2;\n}\n\nasync function hasAnyPath(directoryPath: string, relativePaths: readonly string[]): Promise<boolean> {\n  for (const relativePath of relativePaths) {\n    if (await pathExists(path.join(directoryPath, relativePath))) return true;\n  }\n  return false;\n}\n\nasync function pathExists(filePath: string): Promise<boolean> {\n  try {\n    await fs.access(filePath);\n    return true;\n  } catch (error) {\n    const code =\n      typeof error === 'object' && error !== null && 'code' in error ? (error as { code: unknown }).code : undefined;\n    if (code !== 'ENOENT') throw error;\n    return false;\n  }\n}\n\nasync function readJson(filePath: string): Promise<Record<string, unknown>> {\n  try {\n    const parsed = JSON.parse(await fs.readFile(filePath, 'utf8')) as unknown;\n    return typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)\n      ? (parsed as Record<string, unknown>)\n      : {};\n  } catch (error) {\n    if (error instanceof SyntaxError) return {};\n    const code =\n      typeof error === 'object' && error !== null && 'code' in error ? (error as { code: unknown }).code : undefined;\n    if (code === 'ENOENT') return {};\n    throw error;\n  }\n}\n\nexport async function copyPackageManagerProjectFiles(options: {\n  packageManager: PackageManager;\n  projectDir: string;\n  runDir: string;\n  projectFilePaths?: readonly string[];\n}): Promise<void> {\n  for (const projectFilePath of options.projectFilePaths ?? packageManagerProjectFilePaths[options.packageManager]) {\n    await copyPathIfExists(\n      path.join(options.projectDir, projectFilePath),\n      path.join(options.runDir, projectFilePath),\n      options.runDir\n    );\n  }\n}\n\nasync function copyPathIfExists(sourcePath: string, destinationPath: string, runDir: string): Promise<void> {\n  try {\n    // Before touching the destination: creating the parent levels replaces whatever the submission\n    // put there, which must not happen for a project file the problem does not even ship.\n    await fs.lstat(sourcePath);\n    // No-follow copy: the destination was seeded from the (sandbox-writable) submission tree, so a\n    // planted symlink there — at the destination itself or at any directory level of a nested\n    // project file path — must not redirect this trusted project-file overlay outside runDir.\n    await createDirectoryWithoutFollowingSymlinks(runDir, path.dirname(destinationPath));\n    await copyWithoutFollowingSymlinks(sourcePath, destinationPath);\n  } catch (error) {\n    const code =\n      typeof error === 'object' && error !== null && 'code' in error ? (error as { code: unknown }).code : undefined;\n    if (code !== 'ENOENT') throw error;\n  }\n}\n\nasync function spawnWithInput(\n  command: readonly [string, ...string[]],\n  context: {\n    cwd: string;\n    env: NodeJS.ProcessEnv;\n    outputLimitBytes: number;\n    stdin: string;\n    timeLimitSeconds: number;\n  }\n): Promise<{\n  stdout: string;\n  stderr: string;\n  status: number | undefined;\n  timeSeconds: number;\n  memoryBytes: number;\n  timedOut: boolean;\n  signal: NodeJS.Signals | undefined;\n  outputLimitExceeded: boolean;\n}> {\n  const timeOutputPath = timeCommand === undefined ? undefined : path.join(context.cwd, '.exercode-time-result');\n  // `wrapCommandWithSandboxUser` is idempotent, so a command the presets already wrapped is not\n  // nested; `time` is then spliced INSIDE that wrapper so it runs as the sandbox user, never as the\n  // harness user writing `--output` into this sandbox-writable directory.\n  const wrappedCommand = wrapCommandWithSandboxUser(command);\n  const spawnedCommand =\n    timeCommand === undefined\n      ? wrappedCommand\n      : prependInsideSandboxWrapper(wrappedCommand, [...timeCommand, `--output=${timeOutputPath}`]);\n  // Started BEFORE the submission: `killSubprocessGroup` cannot spawn its `sudo` once a submission\n  // has exhausted the PID cgroup, and a submission spawned first could exhaust it before this\n  // watchdog exists. It is the deadline of last resort on this path.\n  const watchdog = startSandboxTimeoutWatchdog(context.timeLimitSeconds);\n  const watchdogDeadlineAt = Date.now() + (Math.ceil(context.timeLimitSeconds) + SANDBOX_WATCHDOG_GRACE_SECONDS) * 1000;\n  let subprocess: childProcess.ChildProcessWithoutNullStreams;\n  try {\n    subprocess = childProcess.spawn(spawnedCommand[0], spawnedCommand.slice(1), {\n      cwd: context.cwd,\n      detached: process.platform !== 'win32',\n      env: { ...context.env, ...getSandboxUserEnvOverrides(context.env) },\n      stdio: ['pipe', 'pipe', 'pipe'],\n    });\n  } catch (error) {\n    watchdog.cancel();\n    throw error;\n  }\n\n  const stdoutChunks: Buffer[] = [];\n  const stderrChunks: Buffer[] = [];\n  let outputBytes = 0;\n  let timedOut = false;\n  let outputLimitExceeded = false;\n  // Set when terminating the submission failed (the cleanup `sudo` could not be spawned). The run\n  // then waits for the watchdog to end the submission rather than throwing out of an EventEmitter\n  // callback, which would be an uncaught exception that kills the harness before any cleanup.\n  let killError: Error | undefined;\n  let onKillFailure: (() => void) | undefined;\n  const killOrRecordFailure = (signal: NodeJS.Signals): void => {\n    try {\n      killSubprocessGroup(subprocess, signal);\n    } catch (error) {\n      killError ??= error instanceof Error ? error : new Error(String(error));\n      onKillFailure?.();\n    }\n  };\n\n  const appendOutputChunk = (chunks: Buffer[], chunk: Buffer): void => {\n    if (outputBytes >= context.outputLimitBytes) {\n      if (chunk.byteLength > 0) {\n        outputLimitExceeded = true;\n        killOrRecordFailure('SIGKILL');\n      }\n      return;\n    }\n\n    const remainingBytes = context.outputLimitBytes - outputBytes;\n    const appendedChunk = chunk.byteLength > remainingBytes ? chunk.subarray(0, remainingBytes) : chunk;\n    chunks.push(appendedChunk);\n    outputBytes += appendedChunk.byteLength;\n\n    if (chunk.byteLength > remainingBytes) {\n      outputLimitExceeded = true;\n      killOrRecordFailure('SIGKILL');\n    }\n  };\n\n  subprocess.stdout.on('data', (chunk: Buffer) => appendOutputChunk(stdoutChunks, chunk));\n  subprocess.stderr.on('data', (chunk: Buffer) => appendOutputChunk(stderrChunks, chunk));\n\n  const timeout = setTimeout(() => {\n    timedOut = true;\n    killOrRecordFailure('SIGTERM');\n  }, context.timeLimitSeconds * 1000);\n  const killTimeout = setTimeout(\n    () => {\n      if (timedOut) killOrRecordFailure('SIGKILL');\n    },\n    context.timeLimitSeconds * 1000 + killGracePeriodMilliseconds\n  );\n  killTimeout.unref();\n  // Bounds the wait after a kill failure: the watchdog force-kills the sandbox user at its own\n  // deadline, so `close` should arrive; if even that fails, give up rather than hang.\n  let killFailureTimeout: ReturnType<typeof setTimeout> | undefined;\n  let closeObserved = false;\n\n  const { status, signal } = await new Promise<{ status: number | undefined; signal: NodeJS.Signals | undefined }>(\n    (resolve, reject) => {\n      let settled = false;\n      let pendingError: Error | undefined;\n      const failAfterClose = (error: Error): void => {\n        if (settled) return;\n        pendingError = error;\n        killOrRecordFailure('SIGKILL');\n        if (subprocess.pid === undefined) {\n          settled = true;\n          reject(error);\n        }\n      };\n      // Terminating the submission failed. Keep waiting: the watchdog (started before the\n      // submission) force-kills the sandbox user at its own deadline, so `close` still arrives and\n      // the run reports its real verdict. Give up only once that deadline has passed without the\n      // submission ending, so the run can neither hang nor abandon a still-running submission\n      // while its watchdog could still fire.\n      onKillFailure = () => {\n        killFailureTimeout ??= setTimeout(\n          () => {\n            if (settled) return;\n            settled = true;\n            reject(killError ?? new Error('failed to terminate the submission'));\n          },\n          Math.max(0, watchdogDeadlineAt - Date.now()) + watchdogSettleMarginMilliseconds\n        );\n      };\n      subprocess.on('error', failAfterClose);\n      subprocess.stdin.on('error', (error: NodeJS.ErrnoException) => {\n        if (error.code !== 'EPIPE') failAfterClose(error);\n      });\n      subprocess.on('close', (code, closeSignal) => {\n        if (settled) return;\n        settled = true;\n        // The submission ended, so the watchdog has nothing left to kill and must not outlive this\n        // run. A kill that failed once but succeeded on retry (or was superseded by the watchdog)\n        // is not an error: the timeout/output-limit verdict below is the correct one to report.\n        closeObserved = true;\n        if (pendingError) {\n          reject(pendingError);\n          return;\n        }\n        resolve({ status: code ?? undefined, signal: closeSignal ?? undefined });\n      });\n      subprocess.stdin.end(context.stdin);\n    }\n  ).finally(() => {\n    clearTimeout(timeout);\n    clearTimeout(killTimeout);\n    if (killFailureTimeout) clearTimeout(killFailureTimeout);\n    // Cancel unless the submission is still running after a failed kill: the watchdog is then the\n    // only remaining mechanism able to stop it, and cancelling would leave it running unchecked.\n    if (closeObserved || !killError) watchdog.cancel();\n  });\n\n  const { timeSeconds, memoryBytes } =\n    timeOutputPath === undefined ? { timeSeconds: 0, memoryBytes: 0 } : await readTimeResult(timeOutputPath);\n\n  return {\n    stdout: Buffer.concat(stdoutChunks).toString(),\n    stderr: Buffer.concat(stderrChunks).toString(),\n    status,\n    timeSeconds,\n    memoryBytes,\n    timedOut,\n    signal,\n    outputLimitExceeded,\n  };\n}\n\nfunction resolveTimeCommand(): readonly [string, ...string[]] | undefined {\n  const command = os.platform() === 'darwin' ? 'gtime' : '/usr/bin/time';\n  const result = childProcess.spawnSync(command, ['--version'], { stdio: 'ignore' });\n  if (result.error || result.status !== 0) return undefined;\n\n  return [command, '--format', '%e %M'];\n}\n\nfunction killSubprocessGroup(subprocess: childProcess.ChildProcess, signal: NodeJS.Signals): void {\n  if (subprocess.pid === undefined) return;\n\n  // The current user cannot signal the root-owned sudo wrapper nor the sandbox user's processes,\n  // so go through sudo with the requested signal only; the callers' existing timers provide the\n  // TERM → grace → KILL escalation.\n  // Throws when the cleanup `sudo` cannot even be spawned (a submission can exhaust the PID\n  // cgroup). Only `killOrRecordFailure` may call this: it records the failure and lets the\n  // watchdog (or, past its deadline, a bounded timer) settle the run instead of letting the throw\n  // escape an EventEmitter callback.\n  if (sandboxUserName) {\n    killSandboxUserProcesses([signal === 'SIGKILL' ? 'KILL' : 'TERM']);\n    return;\n  }\n\n  try {\n    if (process.platform === 'win32') {\n      subprocess.kill(signal);\n      return;\n    }\n    process.kill(-subprocess.pid, signal);\n  } catch (error) {\n    const code =\n      typeof error === 'object' && error !== null && 'code' in error ? (error as { code: unknown }).code : undefined;\n    if (code !== 'ESRCH' && code !== 'EPERM') throw error;\n  }\n}\n\nfunction isErrorWithCode(error: unknown, code: string): boolean {\n  return typeof error === 'object' && error !== null && 'code' in error && (error as { code: unknown }).code === code;\n}\n\nasync function readTimeResult(timeOutputPath: string): Promise<{ timeSeconds: number; memoryBytes: number }> {\n  // The submission owns this directory and can put anything at this path, so decide what was\n  // opened from the handle itself rather than from a prior `lstat` it could race:\n  // - `O_NOFOLLOW` refuses a symlink to a harness-readable file (e.g. the problem's expected\n  //   outputs), which would otherwise report that file's trailing numbers as the submission's own\n  //   time and memory usage;\n  // - `O_NONBLOCK` keeps a planted FIFO from blocking the harness forever waiting for a writer;\n  // - the `fstat` then rejects anything that is not a regular file.\n  //\n  // Only an absent file means \"no measurement\" (the command was killed before `time` wrote one).\n  // Anything else at this path is the submission tampering with its own accounting — reporting zero\n  // memory would let it slip past a memory limit — so that fails the run instead.\n  let content: string;\n  let fileHandle: Awaited<ReturnType<typeof fs.open>> | undefined;\n  try {\n    fileHandle = await fs.open(\n      timeOutputPath,\n      nodeFs.constants.O_RDONLY | nodeFs.constants.O_NOFOLLOW | nodeFs.constants.O_NONBLOCK\n    );\n    const stats = await fileHandle.stat();\n    if (!stats.isFile()) throw new Error(`${timeOutputPath} is not a regular file`);\n    content = await fileHandle.readFile('utf8');\n  } catch (error) {\n    if (isErrorWithCode(error, 'ENOENT')) return { timeSeconds: 0, memoryBytes: 0 };\n    throw new Error(`failed to read the time measurement at ${timeOutputPath}`, { cause: error });\n  } finally {\n    await fileHandle?.close();\n  }\n\n  const match = /(\\d+(?:[.,]\\d+)?) (\\d+)\\s*$/.exec(content);\n  if (!match) return { timeSeconds: 0, memoryBytes: 0 };\n\n  return { timeSeconds: Number(match[1]!.replace(',', '.')), memoryBytes: Number(match[2]) * 1024 };\n}\n"],"mappings":"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"}