#include #include #include #include #include #include #include void child(int writefd) { ptrace(PTRACE_TRACEME, 0, 0, 0); raise(SIGSTOP); assert(write(writefd, "x", 1) == 1); raise(SIGSTOP); } void parent(pid_t child, int readfd) { int status; assert(waitpid(child, &status, 0) == child); assert(WIFSTOPPED(status)); assert(WSTOPSIG(status) == SIGSTOP); fd_set set; struct timeval tv; FD_ZERO(&set); FD_SET(readfd, &set); tv.tv_sec = 0; tv.tv_usec = 0; assert(select(readfd+1, &set, 0, 0, &tv) == 0); FD_ZERO(&set); FD_SET(readfd, &set); tv.tv_sec = 0; tv.tv_usec = 0; assert(ptrace(PTRACE_CONT, child, 0, 0) == 0); assert(waitpid(child, &status, 0) == child); assert(select(readfd+1, &set, 0, 0, &tv) == 1); kill(child, SIGKILL); assert(close(readfd) == 0); assert(waitpid(child, &status, 0) == child); assert(WIFSIGNALED(status)); assert(WTERMSIG(status) == SIGKILL); } int main(int argc) { int pipefd[2]; int i = 0; for (;;) { ++i; if (!(i%10)) printf("%d\n", i); assert(openpty(pipefd+0, pipefd+1, 0, 0) == 0); // assert(pipe(pipefd) == 0); pid_t pid = fork(); assert(pid != -1); if (pid == 0) { assert(close(pipefd[0]) == 0); child(pipefd[1]); return 1; } else { assert(close(pipefd[1]) == 0); parent(pid, pipefd[0]); } } return 0; }