reptyr: Attach a running process to a new terminal - Made of Bugs
Archives
Subscribe
Author
Over the last week, I’ve written a nifty tool that I call<br>reptyr. reptyr is a utility for taking an existing running<br>program and attaching it to a new terminal. Started a long-running<br>process over ssh, but have to leave and don’t want to interrupt it?<br>Just start a screen, use reptyr to grab it, and then kill the ssh<br>session and head on home.
You can grab the source, or read on for some more details.
There’s a shell script called screenify that’s been going<br>around the internet for nigh on 10 years now that is supposed to use<br>gdb to accomplish the same thing. There’s also a project called<br>retty that tries to do the same thing, in C using ptrace()<br>directly.
The difference between those programs and reptyr is that reptyr works<br>much, much, better.
If you attach a less using screenify or retty, it will still take<br>input from the old terminal. If you attach an ncurses program, and<br>resize the window, the program probably won’t resize correctly. ^C<br>and ^Z will still be processed on the old terminal – typing them in<br>the new terminal won’t do anything useful.
reptyr fixes all of these problems and more, and is the only such tool<br>I know of that does so. I’ve never seen a program that doesn’t behave<br>noticeably incorrectly after attaching with retty or screenify,<br>whereas with reptyr most programs I have tried work flawlessly.
How does it work? ︎
reptyr works in the same basic way as screenify and retty – it<br>attaches to the target process using the ptrace API, opens the new<br>terminal, and dup2s it over the old file descriptors. It also copies<br>the termios settings from the old terminal to the new terminal.
The main thing that reptyr does that no one else does is that it<br>actually changes the controlling terminal of the process you are<br>attaching. This is the detail that makes many things Just Work,<br>including ^C and ^Z and window resizing.
Switching the target’s controlling terminal is not easy and involves a<br>fair bit of trickery with ptrace and Linux’s terminal APIs. I will<br>probably do another blog post some time about the dirty details of how<br>I make this work, but for now you can check out<br>attach.c if<br>you really want to know.
reptyr still has a number of limitations – it doesn’t generally work,<br>for example, if the target process has any children. I know how to fix<br>most of these problems, though, so expect it to get better with<br>time. Please let me know if you find it useful!
Appendix ︎
(Edited to add:) Nothing is really new. A commenter on reddit pointed out that injcode<br>and neercs both accomplish the same thing, even using the same trick<br>to change the CTTY. Ah well, I had run writing it anyways, and apparently I<br>wasn’t the only one who didn’t know about the existing alternatives. neercs is a full screen replacement, though, and I think that reptyr should be more robust than injcode – I use a different techique for ptrace-hijacking, for example – and so hopefully this tool still has a niche as a more robust standalone utility. Certainly, judging from the amount of enthusiasm I’ve seen for this tool, this still isn’t a problem that is solved to the average user’s satisfaction.