0

There seem to be plenty of similar questions, for example:

https://stackoverflow.com/questions/5374255/how-to-write-data-to-existing-processs-stdin-from-external-process

However the answer given is to prepare the program beforehand by making its stdin a pipe.

There's also:

https://serverfault.com/questions/178457/can-i-send-some-text-to-the-stdin-of-an-active-process-running-in-a-screen-sessi

Which is answered by commanding a terminal multiplexer under which the program in question is running. That means it also needs prior preparation.

This question is about how to do this without having done any preparation beforehand.

At first I thought it might be as simple as:

echo foo > /proc/$p/fd/0

but that just writes to the terminal. So then I tried:

echo foo > /proc/$terminal_emulator/fd/$ptmx_fd

but that also fails because it just opens up a new terminal device slave for echo.

I already have an answer using gdb (sigh) which I'll be posting below, but I wonder if anyone knows of a simpler and better alternative.

8
  • 1
    unix.stackexchange.com/questions/306806/… Commented Aug 6, 2019 at 23:00
  • 1
    @MarkPlotnick That answer works. I'm not sure what to suggest here. Should this be marked as a duplicate of that, or would you make an answer that references and/or quotes that answer? Commented Aug 7, 2019 at 1:00
  • TIOCSTI only works as root or on the controlling tty. And writing stuff into the master side of the tty only works when it's a pseudo-tty, and you can attach to the process holding the master fd -- in the case of a ssh session, that would be a process running as root. Anyways, for yet another TIOCSTI sample, you can also look here. Commented Aug 7, 2019 at 1:15
  • If you're satisfied that one of the other questions/answers qualifies as a duplicate, you can click on close just below your question, then Duplicate of, then paste the URL of the duplicate question. Commented Aug 7, 2019 at 18:29
  • 1
    @Fabby I hadn't noticed I could do that. Thanks for the heads-up. Commented Aug 9, 2019 at 23:29

2 Answers 2

0
#!/usr/bin/zsh

pid="$1"
stdin_data="$2"

for p in $(pstree -sp "$pid" | grep -Po '(?<=\()\d+(?=\))' | tac); do
  [[ -r "/proc/$p/fd" ]] || continue
  for f in /proc/$p/fd/*; do
    if [[ "$(readlink "$f")" = /dev/ptmx ]]; then
      fd="$(basename "$f")"
      break 2
    fi
  done
done

sudo gdb -p "$p" --batch -x =(printf '%s' '            
  p (int)write($fd, "$stdin_data", (int)strlen("$stdin_data"))
')

I don't like that the script argument can be a C injection.

0

Apparently you can't, writing to a process' stdin file doesn't make the process read what you appended. See this answer for a full explanation: https://serverfault.com/a/962956

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.