Skip to content

Commit e36f7c6

Browse files
committed
Restore atomic write property in SSH runtime
Use readlink -f to resolve symlinks first, then mv the temp file to the resolved path. This maintains atomicity (readers see old or new file, never partial) while preserving symlinks. Addresses Codex review feedback.
1 parent 338c849 commit e36f7c6

File tree

1 file changed

+5
-4
lines changed

1 file changed

+5
-4
lines changed

src/runtime/SSHRuntime.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -263,14 +263,15 @@ export class SSHRuntime implements Runtime {
263263

264264
/**
265265
* Write file contents over SSH atomically from a stream
266-
* Preserves symlinks by writing through them to the target file
266+
* Preserves symlinks by resolving them first, then writing to the target
267267
*/
268268
writeFile(path: string): WritableStream<Uint8Array> {
269269
const tempPath = `${path}.tmp.${Date.now()}`;
270-
// Create parent directory if needed, then write file atomically
271-
// Use cat to copy through symlinks (preserves them), then chmod and mv
270+
// Resolve symlinks to get the actual target path, preserving the symlink itself
271+
// If path doesn't exist, readlink fails and we use the original path
272+
// Then write atomically using mv (all-or-nothing for readers)
272273
// Use shescape.quote for safe path escaping
273-
const writeCommand = `mkdir -p $(dirname ${shescape.quote(path)}) && cat > ${shescape.quote(tempPath)} && chmod 600 ${shescape.quote(tempPath)} && cat ${shescape.quote(tempPath)} > ${shescape.quote(path)} && rm ${shescape.quote(tempPath)}`;
274+
const writeCommand = `RESOLVED=$(readlink -f ${shescape.quote(path)} 2>/dev/null || echo ${shescape.quote(path)}) && mkdir -p $(dirname "$RESOLVED") && cat > ${shescape.quote(tempPath)} && chmod 600 ${shescape.quote(tempPath)} && mv ${shescape.quote(tempPath)} "$RESOLVED"`;
274275

275276
// Need to get the exec stream in async callbacks
276277
let execPromise: Promise<ExecStream> | null = null;

0 commit comments

Comments
 (0)