実行中プロセスの標準出力を切り替える
This content is a draft and will not be included in production builds.
コンソールから切れたプロセスを標準出力につなげなおすで、gdb を使って標準出力と標準エラー出力を切り替える方法が示されていた。
(gdb) p close(1)$1 = 0(gdb) p open("/dev/pts/5", 1)$2 = 1(gdb) p close(2)$3 = 0(gdb) p open("/dev/pts/5", 1)$4 = 2(gdb) detachgdb で実現できるならシステムコールまたは類似の仕組みがありそうだなと思っていたところ、retty(1)というコマンドが似たようなことを実現していて、これは ptrace(2)で実装していた。
ptrace(PTRACE_ATTACH, pid, 0, 0);waitpid(pid, NULL, 0);ptrace(PTRACE_GETREGS, pid, 0, ®s);memcpy(&oldregs, ®s, sizeof(oldregs));read_mem(pid, &text_backup, nelem(attach_code), oldregs.PC_REG);
regs.SP_REG -= sizeof(long);ptrace(PTRACE_POKEDATA, pid, regs.SP_REG, regs.PC_REG);write_mem(pid, &attach_code, nelem(attach_code), regs.PC_REG);
regs.SP_REG -= n*sizeof(long);ptsnameaddr = regs.SP_REG;write_mem(pid, ptsname, n, regs.SP_REG);
regs.SP_REG -= sizeof(long);ptrace(PTRACE_POKEDATA, pid, regs.SP_REG, ptsnameaddr);
regs.PC_REG += 8;ptrace(PTRACE_SETREGS, pid, 0, ®s);ptrace(PTRACE_CONT, pid, 0, (void*) SIGSTOP);ソースコードの該当箇所はretry.c:192,197あたり。