mirror of
https://github.com/openai/codex.git
synced 2026-11-14 21:40:39 +00:00
Replay exec-server shell snapshots through unnamed files (#48078)
## Why Large shell snapshots need a replay path that does not add their state to the child process environment. ## What changed - Keep captured state cached in memory and give each Bash or Zsh launch an independent, read-only file descriptor to source. Unlink the file before writing shell state, create it under the sandbox-protected daemon directory, and close the carrier descriptor before restoring functions. - Probe descriptor-path access inside the capture sandbox. Retain environment replay for `sh` and when descriptor paths are unavailable; use normal shell startup if preparing the replay file fails. - Group options and aliases during capture so sourcing preserves their parsing behavior. ## Testing Add coverage for concurrent replays with 480 KiB payloads, pipe and TTY execution, stdin preservation, descriptor cleanup, sandbox protection, blocked descriptor-path fallback, and alias/option parsing equivalence. GitOrigin-RevId: 8103d5c37ce4d1885628a4efba3551549f12bea8
This commit is contained in:
@@ -42,6 +42,36 @@ pub struct SnapshotCaptureOptions {
|
||||
pub fn snapshot_capture_script(
|
||||
shell_type: ShellType,
|
||||
options: SnapshotCaptureOptions,
|
||||
) -> Option<String> {
|
||||
capture_script(shell_type, options, Replay::Eval)
|
||||
}
|
||||
|
||||
/// Capture state for incremental sourcing. Parse options and aliases together so
|
||||
/// restored aliases and quoting options cannot reinterpret later declarations.
|
||||
pub fn snapshot_source_capture_script(
|
||||
shell_type: ShellType,
|
||||
options: SnapshotCaptureOptions,
|
||||
) -> Option<String> {
|
||||
capture_script(
|
||||
shell_type,
|
||||
options,
|
||||
if shell_type == ShellType::Sh {
|
||||
Replay::Eval
|
||||
} else {
|
||||
Replay::Source
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
enum Replay {
|
||||
Eval,
|
||||
Source,
|
||||
}
|
||||
|
||||
fn capture_script(
|
||||
shell_type: ShellType,
|
||||
options: SnapshotCaptureOptions,
|
||||
replay: Replay,
|
||||
) -> Option<String> {
|
||||
let script = match shell_type {
|
||||
ShellType::Zsh => zsh_snapshot_script(options.startup),
|
||||
@@ -56,6 +86,8 @@ pub fn snapshot_capture_script(
|
||||
};
|
||||
Some(
|
||||
script
|
||||
.replace("SNAPSHOT_OPTIONS_BEGIN", match replay { Replay::Eval => "", Replay::Source => "printf '{\\n'" })
|
||||
.replace("SNAPSHOT_ALIASES_END", match replay { Replay::Eval => "", Replay::Source => "printf \"case '' in '') ;; esac\\n}\\n\"" })
|
||||
.replace("SNAPSHOT_EXPORTS", &declarations)
|
||||
.replace(
|
||||
"SNAPSHOT_DECLARATION_ENVIRONMENT",
|
||||
@@ -92,16 +124,18 @@ print 'unalias -a 2>/dev/null || true'
|
||||
print '# Functions'
|
||||
functions
|
||||
print ''
|
||||
SNAPSHOT_OPTIONS_BEGIN
|
||||
SNAPSHOT_COMMAND_HELPER
|
||||
setopt_count=$(setopt | __codex_snapshot_command wc -l | __codex_snapshot_command tr -d ' ')
|
||||
print "# setopts $setopt_count"
|
||||
setopt | __codex_snapshot_command sed 's/^/setopt /'
|
||||
print ''
|
||||
printf '\0'
|
||||
alias_count=$(alias -L | __codex_snapshot_command wc -l | __codex_snapshot_command tr -d ' ')
|
||||
alias_count=$(\alias -L | __codex_snapshot_command wc -l | __codex_snapshot_command tr -d ' ')
|
||||
print "# aliases $alias_count"
|
||||
alias -L
|
||||
\alias -L
|
||||
print ''
|
||||
SNAPSHOT_ALIASES_END
|
||||
printf '\0'
|
||||
SNAPSHOT_EXPORTS
|
||||
printf '\0'
|
||||
@@ -122,6 +156,7 @@ shopt -p || true
|
||||
echo '# Functions'
|
||||
declare -f
|
||||
echo ''
|
||||
SNAPSHOT_OPTIONS_BEGIN
|
||||
SNAPSHOT_COMMAND_HELPER
|
||||
bash_opts=$(set -o | __codex_snapshot_command awk '$2=="on"{print $1}')
|
||||
bash_opt_count=$(printf '%s\n' "$bash_opts" | __codex_snapshot_command sed '/^$/d' | __codex_snapshot_command wc -l | __codex_snapshot_command tr -d ' ')
|
||||
@@ -131,10 +166,11 @@ if [ -n "$bash_opts" ]; then
|
||||
fi
|
||||
echo ''
|
||||
printf '\0'
|
||||
alias_count=$(alias -p | __codex_snapshot_command wc -l | __codex_snapshot_command tr -d ' ')
|
||||
alias_count=$(\alias -p | __codex_snapshot_command wc -l | __codex_snapshot_command tr -d ' ')
|
||||
echo "# aliases $alias_count"
|
||||
alias -p
|
||||
\alias -p
|
||||
echo ''
|
||||
SNAPSHOT_ALIASES_END
|
||||
printf '\0'
|
||||
SNAPSHOT_EXPORTS
|
||||
printf '\0'
|
||||
@@ -180,6 +216,7 @@ elif command -v declare >/dev/null 2>&1; then
|
||||
declare -f
|
||||
fi
|
||||
echo ''
|
||||
SNAPSHOT_OPTIONS_BEGIN
|
||||
SNAPSHOT_COMMAND_HELPER
|
||||
if set -o >/dev/null 2>&1; then
|
||||
sh_opts=$(set -o | __codex_snapshot_command awk '$2=="on"{print $1}')
|
||||
@@ -201,6 +238,7 @@ if alias >/dev/null 2>&1; then
|
||||
else
|
||||
echo '# aliases 0'
|
||||
fi
|
||||
SNAPSHOT_ALIASES_END
|
||||
printf '\0'
|
||||
SNAPSHOT_EXPORTS
|
||||
printf '\0'
|
||||
|
||||
Reference in New Issue
Block a user