Skip to content

Manually-numbered redirects interfere with fish's own descriptors #12618

Description

@CGamesPlay

Manually assigning a file descriptor number will happily interfere with fish's own internal selection of file descriptor numbers. This is possibly the same root cause as #3303 and would be resolved blocked by the proposal in #12547. I don't think this is a straight duplicate of either of those; my apologies if I'm wrong here.

$ fish --no-config
rpatterson@macbook-pro ~> echo $FISH_VERSION
4.5.0

rpatterson@macbook-pro ~> cat Downloads/test.py
import os, sys
# Verify stdout is actually a tty
is_tty = os.isatty(1)
# Write the result to fd 3 (captured by fish)
os.write(3, f"stdout_isatty={is_tty}\n".encode())
# Write visible output to stdout (which should be /dev/tty)
print(f"(visible on tty)")

rpatterson@macbook-pro ~> set x (python Downloads/test.py 3>&1 >/dev/tty); echo "x: $x"
(visible on tty)
x: stdout_isatty=True
rpatterson@macbook-pro ~> cd . # Do nothing
rpatterson@macbook-pro ~> set x (python Downloads/test.py 3>&1 >/dev/tty); echo "x: $x"
x: stdout_isatty=False (visible on tty)
rpatterson@macbook-pro ~> cd .  # Do nothing again
rpatterson@macbook-pro ~> set x (python Downloads/test.py 3>&1 >/dev/tty); echo "x: $x"
(visible on tty)
x: stdout_isatty=True
rpatterson@macbook-pro ~> cd .  # Do nothing an odd number of times
rpatterson@macbook-pro ~> set x (python Downloads/test.py 3>&1 >/dev/tty); echo "x: $x"
x: stdout_isatty=False (visible on tty)

My goal here is to run an interactive command (attached to the TTY) with the output to FD 3 gets stored in the variable. In this demonstration, we see that writing to FD 1 (stdout) actually goes to FD 3, because fish incorrectly merged the two FDs.

Notes:

  • The cd is an infuriating red herring. Internally, cd causes fish to open the directory FD, which consumes/releases an FD, shifting around which ones are free.
  • wopen_cloexec("/dev/tty") goes to the next free FD.
  • dup2_list_resolve_chain can clobber that FD.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions