Skip to content

Commit

Permalink
Try to stop the target with SIGTSTP before attaching.
Browse files Browse the repository at this point in the history
This should both cause the target process to redraw / reinitialize the
terminal (since it thinks it's been backgrounded and restarted), and should give
you back the old terminal, since it sees the process now running in the
"background".
  • Loading branch information
nelhage committed Jan 25, 2011
1 parent 0046dc7 commit 6e5dc87
Showing 1 changed file with 42 additions and 0 deletions.
42 changes: 42 additions & 0 deletions attach.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include <sys/wait.h> #include <sys/wait.h>
#include <signal.h> #include <signal.h>
#include <limits.h> #include <limits.h>
#include <time.h>
#include <sys/time.h>


#include "ptrace.h" #include "ptrace.h"
#include "reptyr.h" #include "reptyr.h"
Expand Down Expand Up @@ -166,13 +168,53 @@ int ignore_hup(struct ptrace_child *child, unsigned long scratch_page) {
return err; return err;
} }


void wait_for_stop(pid_t pid) {
struct timeval start, now;
struct timespec sleep;
char stat_path[PATH_MAX], buf[256], *p;
int fd;

snprintf(stat_path, sizeof stat_path, "/proc/%d/stat", pid);
fd = open(stat_path, O_RDONLY);
if (!fd) {
error("Unable to open %s: %s", stat_path, strerror(errno));
return;
}
gettimeofday(&start, NULL);
while (1) {
gettimeofday(&now, NULL);
if ((now.tv_sec > start.tv_sec && now.tv_usec > start.tv_usec)
|| (now.tv_sec - start.tv_sec > 1)) {
error("Timed out waiting for child stop.");
return;
}
lseek(fd, 0, SEEK_SET);
if (read(fd, buf, sizeof buf) <= 0)
return;
p = strchr(buf, ' ');
if (!p)
return;
p = strchr(p+1, ' ');
if (!p)
return;
if (*(p+1) == 'T')
return;

sleep.tv_sec = 0;
sleep.tv_nsec = 10000000;
nanosleep(&sleep, NULL);
}
}

int attach_child(pid_t pid, const char *pty) { int attach_child(pid_t pid, const char *pty) {
struct ptrace_child child; struct ptrace_child child;
unsigned long scratch_page = -1; unsigned long scratch_page = -1;
int *child_tty_fds = NULL, n_fds, child_fd; int *child_tty_fds = NULL, n_fds, child_fd;
int i; int i;
int err = 0; int err = 0;


kill(pid, SIGTSTP);
wait_for_stop(pid);


if (ptrace_attach_child(&child, pid)) if (ptrace_attach_child(&child, pid))
return child.error; return child.error;
Expand Down

0 comments on commit 6e5dc87

Please sign in to comment.