From b7182d34e12130ced98dee7726b3bc87d4584ca9 Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Thu, 1 Oct 2026 02:57:15 -0300 Subject: An open past the session's 64 open records reaches a mount's caller as EMFILE, "Too many open files": pardes re-pins cloud9, whose 9ns maps the words The refusal's words said too many open files, but 9ns matched none of its needles and handed the shell Input/output error. The re-pinned cloud9's 9ns maps them to EMFILE. selfmount opens the root exec for writing eighty times through the mount and hears EMFILE at the 65th. Co-Authored-By: Claude Opus 5.5 --- build.zig.zon | 4 ++-- test/selfmount.py | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/build.zig.zon b/build.zig.zon index 1cb6e091..502ae074 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -9,8 +9,8 @@ // read-only HTTPS URL is what a manifest can carry. Re-pin with // `zig fetch --save=cloud9 git+https://git.sr.ht/~gbrls/cloud9#`. .cloud9 = .{ - .url = "git+https://git.sr.ht/~gbrls/cloud9#a03d1649108510cda5951e918e561d7cae43d6b0", - .hash = "cloud9-0.1.0-yt86qiISHgBgvO5D4UOz0pZnWrLmL337v38Z8ROAeLG0", + .url = "git+https://git.sr.ht/~gbrls/cloud9#12d78be492351e29144daa379232bbd955b47631", + .hash = "cloud9-0.1.0-yt86qjoTHgAqXvz1h23WqTagtZNodmM5lkWFZ7Ld_880", }, // Pinned to the exact libvaxis commit ghostty is built against, so it // is compatible with ghostty's uucode configuration (the one we share diff --git a/test/selfmount.py b/test/selfmount.py index 503ce1e0..6b9d8740 100644 --- a/test/selfmount.py +++ b/test/selfmount.py @@ -196,6 +196,16 @@ def run(binary): looped.unlink(missing_ok=True) check(ran == '0' and got_line.startswith('FX') and got_line.rstrip().endswith('Msg ev-loop'), f'a bash read loop on event reads a whole record ({got_line!r})') + # Past the session's 64 open records (write opens of exec take + # them too) an open is refused EMFILE, "Too many open files". + # (>> here: a truncating open of exec through the mount can + # hang, reported, not yet understood.) + many = Path(f'/tmp/{name}.many') + ran = run((f"timeout 10 bash -c 'for i in $(seq 80); do exec {{fd}}>>{mount}/exec || exit 9; done' 2> {many}; " + f"st=$?; echo rc=$st >> {many}; exit $st\n").encode()) + said_many = many.read_text() if many.exists() else '' + many.unlink(missing_ok=True) + check(ran == '9' and 'Too many open files' in said_many, f'an open past the 64 records is EMFILE ({ran!r}, {said_many[-80:]!r})') client.write('/exec', b'Msg still here\n') text = ''.join(cell[0] for cell in client.screen()['cells']) check('still here' in text, 'the editor answers after all of that') -- cgit v1.3