Skip to content

pack: skip sockets so create does not hang - #466

Closed
dyk1454683243-sudo wants to merge 2 commits into
isaacs:mainfrom
dyk1454683243-sudo:cursor/skip-socket-files-a9f1
Closed

dyk1454683243-sudo wants to merge 2 commits into
isaacs:mainfrom
dyk1454683243-sudo:cursor/skip-socket-files-a9f1

Conversation

@dyk1454683243-sudo

@dyk1454683243-sudo dyk1454683243-sudo commented Sep 20, 2026 •

Copy link
Copy Markdown

Fixes #295

Problem

tar.create hangs when a directory contains more than one Unix socket after a regular file in readdir order (the /var/run case). GNU tar skips sockets and finishes.

A single socket, or sockets that sort before every regular file, already completed. The hang is pack-queue corruption, not fs.open blocking on the socket.

WriteEntry classifies sockets, FIFOs, and devices as Unsupported and calls end() with no header. Minipass emits end immediately on an empty stream. Pack still creates that WriteEntry as a read-ahead job, and JOBDONE always shift()s the queue head. Two such completions pop the file that is still being packed; JOBS never drains; the create({ file }) promise never settles.

Reproduced on 7.5.22 (2a22bfc):

  • aaa.txt + b.sock + c.sock with delayed file lstat → Pack times out
  • a.sock + b.sock + zzz.txt → completes (unsupported jobs are current when they end)
  • aaa.txt + one socket → completes

Fix

In Pack/PackSync PROCESSJOB, ignore stats that are not a file, directory, or symlink before constructing WriteEntry. Same skip GNU tar uses for sockets; FIFOs and device nodes were already unsupported on create.

Tests

  • test/pack.js (#295): delayed lstat of the regular file so two sockets are processed as read-ahead. Hangs on 2a22bfc, passes with the skip.
  • test/create.ts (#295): async / sync / gzip create({ file }) and socket-as-sole-entry. Archive contains the regular files only.

Test plan

  • Discriminating pack.js test: Pack hung on 2a22bfc, pass on this branch
  • npx tap test/create.ts --disable-coverage -t0: 70/70 pass
  • npx tap test/pack.js --disable-coverage -t0 -g '#295': pass
  • Full test/pack.js in this environment fails on a pre-existing zstd ZstdCompress gap (Node 22.14); not caused by this change. CI uses Node 22/24/26.

cursoragent and others added 2 commits September 20, 2026 18:38
WriteEntry treats sockets, FIFOs, and devices as Unsupported and
ends with no header. That completion can run while the job is still
read-ahead, and JOBDONE always shift()s the queue head, so two such
entries after a regular file stall tar.create. Skip those types in
Pack, matching GNU tar.

Fixes isaacs#295

Co-authored-by: David <dyk1454683243-sudo@users.noreply.github.com>
Delay lstat of the regular file so two sockets are processed as
read-ahead while it is still the queue head. That is the isaacs#295
corruption: JOBDONE shift()s the file off the queue and Pack never
ends. The new pack.js test hangs on 2a22bfc and passes with the skip.

Co-authored-by: David <dyk1454683243-sudo@users.noreply.github.com>
@isaacs isaacs closed this Sep 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] "Create" hangs on linux socket files

3 participants