"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "platform/freebsd/freebsd.c" between
reptyr-reptyr-0.7.0.tar.gz and reptyr-reptyr-0.8.0.tar.gz

About: reptyr is a utility for taking an existing running program and attaching it to a new terminal.

freebsd.c  (reptyr-reptyr-0.7.0):freebsd.c  (reptyr-reptyr-0.8.0)
skipping to change at line 42 skipping to change at line 42
int check_pgroup(pid_t target) { int check_pgroup(pid_t target) {
struct procstat *procstat; struct procstat *procstat;
struct kinfo_proc *kp; struct kinfo_proc *kp;
pid_t pg; pid_t pg;
unsigned int cnt; unsigned int cnt;
pg = getpgid(target); pg = getpgid(target);
procstat = procstat_open_sysctl(); procstat = procstat_open_sysctl();
cnt = 0;
kp = procstat_getprocs(procstat, KERN_PROC_PGRP, pg, &cnt); kp = procstat_getprocs(procstat, KERN_PROC_PGRP, pg, &cnt);
procstat_freeprocs(procstat, kp); procstat_freeprocs(procstat, kp);
procstat_close(procstat); procstat_close(procstat);
if (cnt > 1) { if (cnt > 1) {
error("Process %d shares a process group with %d other processes. Unable to attach.\n", target, cnt - 1); error("Process %d shares a process group with %d other processes. Unable to attach.\n", target, cnt - 1);
return EINVAL; return EINVAL;
} }
return 0; return 0;
} }
int check_proc_stopped(pid_t pid, int fd) { int check_proc_stopped(pid_t pid, int fd) {
struct procstat *procstat; struct procstat *procstat;
struct kinfo_proc *kp; struct kinfo_proc *kp;
int state; int state = 0;
unsigned int cnt; unsigned int cnt;
procstat = procstat_open_sysctl(); procstat = procstat_open_sysctl();
cnt = 0;
kp = procstat_getprocs(procstat, KERN_PROC_PID, pid, &cnt); kp = procstat_getprocs(procstat, KERN_PROC_PID, pid, &cnt);
if (cnt > 0) if (cnt > 0)
state = kp->ki_stat; state = kp->ki_stat;
procstat_freeprocs(procstat, kp); procstat_freeprocs(procstat, kp);
procstat_close(procstat); procstat_close(procstat);
if (cnt < 1) if (cnt < 1)
return 1; return 1;
if (state == SSTOP) if (state == SSTOP)
return 1; return 1;
return 0; return 0;
} }
struct filestat_list* get_procfiles(pid_t pid, struct kinfo_proc **kp, struct pr ocstat **procstat, unsigned int *cnt) { struct filestat_list* get_procfiles(pid_t pid, struct kinfo_proc **kp, struct pr ocstat **procstat, unsigned int *cnt) {
int mflg = 0; // include mmapped files int mflg = 0; // include mmapped files
(*procstat) = procstat_open_sysctl(); (*procstat) = procstat_open_sysctl();
*cnt = 0;
(*kp) = procstat_getprocs(*procstat, KERN_PROC_PID, pid, cnt); (*kp) = procstat_getprocs(*procstat, KERN_PROC_PID, pid, cnt);
if ((*kp) == NULL || *cnt < 1) if ((*kp) == NULL || *cnt < 1)
return NULL; return NULL;
return procstat_getfiles(*procstat, *kp, mflg); return procstat_getfiles(*procstat, *kp, mflg);
} }
int *get_child_tty_fds(struct ptrace_child *child, int statfd, int *count) { int *get_child_tty_fds(struct ptrace_child *child, int statfd, int *count) {
struct filestat *fst; struct filestat *fst;
struct filestat_list *head; struct filestat_list *head;
skipping to change at line 109 skipping to change at line 112
head = get_procfiles(child->pid, &kp, &procstat, &cnt); head = get_procfiles(child->pid, &kp, &procstat, &cnt);
STAILQ_FOREACH(fst, head, next) { STAILQ_FOREACH(fst, head, next) {
if (fst->fs_type == PS_FST_TYPE_VNODE) { if (fst->fs_type == PS_FST_TYPE_VNODE) {
er = procstat_get_vnode_info(procstat, fst, &vn, errbuf); er = procstat_get_vnode_info(procstat, fst, &vn, errbuf);
if (er != 0) { if (er != 0) {
error("%s", errbuf); error("%s", errbuf);
goto out; goto out;
} }
if (vn.vn_dev == kp->ki_tdev) { if (vn.vn_dev == kp->ki_tdev && fst->fs_fd >= 0) {
if (fd_array_push(&fds, fst->fs_fd) != 0) { if (fd_array_push(&fds, fst->fs_fd) != 0) {
error("Unable to allocate memory for fd array."); error("Unable to allocate memory for fd array.");
goto out; goto out;
} }
} }
} }
} }
out: out:
procstat_freefiles(procstat, head); procstat_freefiles(procstat, head);
skipping to change at line 139 skipping to change at line 142
// We assume that the terminal emulator is the parent of the session // We assume that the terminal emulator is the parent of the session
// leader. This is true in most cases, although in principle you can // leader. This is true in most cases, although in principle you can
// construct situations where it is false. We should fail safe later // construct situations where it is false. We should fail safe later
// on if this turns out to be wrong, however. // on if this turns out to be wrong, however.
int find_terminal_emulator(struct steal_pty_state *steal) { int find_terminal_emulator(struct steal_pty_state *steal) {
struct procstat *procstat; struct procstat *procstat;
struct kinfo_proc *kp; struct kinfo_proc *kp;
unsigned int cnt; unsigned int cnt;
procstat = procstat_open_sysctl(); procstat = procstat_open_sysctl();
cnt = 0;
kp = procstat_getprocs(procstat, KERN_PROC_PID, steal->target_stat.sid, &cnt ); kp = procstat_getprocs(procstat, KERN_PROC_PID, steal->target_stat.sid, &cnt );
if (kp && cnt > 0) if (kp && cnt > 0)
steal->emulator_pid = kp->ki_ppid; steal->emulator_pid = kp->ki_ppid;
procstat_freeprocs(procstat, kp); procstat_freeprocs(procstat, kp);
procstat_close(procstat); procstat_close(procstat);
return (cnt != 0 ? 0 : 1);
}
int fill_proc_stat(struct steal_pty_state *steal, struct kinfo_proc *kp) {
struct proc_stat *ps = &steal->target_stat;
if (strlcpy(ps->comm, kp->ki_comm, sizeof(ps->comm)) >= sizeof(ps->comm))
return ENOMEM;
ps->pid = kp->ki_pid;
ps->ppid = kp->ki_ppid;
ps->sid = kp->ki_sid;
ps->pgid = kp->ki_pgid;
ps->ctty = kp->ki_tdev;
return 0;
}
int grab_uid(pid_t pid, uid_t *out) {
struct procstat *procstat;
struct kinfo_proc *kp;
unsigned int cnt;
procstat = procstat_open_sysctl();
cnt = 0;
kp = procstat_getprocs(procstat, KERN_PROC_PID, pid, &cnt);
if (kp && cnt > 0)
*out = kp->ki_uid;
else
return ESRCH;
procstat_freeprocs(procstat, kp);
procstat_close(procstat);
return 0; return 0;
} }
int get_terminal_state(struct steal_pty_state *steal, pid_t target) { int get_terminal_state(struct steal_pty_state *steal, pid_t target) {
struct procstat *procstat; struct procstat *procstat;
struct kinfo_proc *kp; struct kinfo_proc *kp;
unsigned int cnt; unsigned int cnt;
int err = 0; int err = 0;
procstat = procstat_open_sysctl(); procstat = procstat_open_sysctl();
cnt = 0;
kp = procstat_getprocs(procstat, KERN_PROC_PID, target, &cnt); kp = procstat_getprocs(procstat, KERN_PROC_PID, target, &cnt);
if (kp == NULL || cnt < 1) if (kp == NULL || cnt < 1)
goto done; goto done;
if (kp->ki_tdev == NODEV) { if (kp->ki_tdev == NODEV) {
error("Child is not connected to a pseudo-TTY. Unable to steal TTY."); error("Child is not connected to a pseudo-TTY. Unable to steal TTY.");
err = EINVAL; err = EINVAL;
goto done; goto done;
} }
if ((err = fill_proc_stat(steal, kp)))
return err;
if ((err = find_terminal_emulator(steal))) if ((err = find_terminal_emulator(steal)))
return err; return err;
if ((err = grab_uid(steal->emulator_pid, &steal->emulator_uid)))
return err;
done: done:
procstat_freeprocs(procstat, kp); procstat_freeprocs(procstat, kp);
procstat_close(procstat); procstat_close(procstat);
return err; return err;
} }
int find_master_fd(struct steal_pty_state *steal) { int find_master_fd(struct steal_pty_state *steal) {
error("How do I find master in FreeBSD? FIXME."); char errbuf[_POSIX2_LINE_MAX];
return EINVAL; struct filestat *fst;
struct filestat_list *head;
struct procstat *procstat;
struct kinfo_proc *kp;
struct ptsstat pts;
unsigned int cnt;
int err;
head = get_procfiles(steal->child.pid, &kp, &procstat, &cnt);
STAILQ_FOREACH(fst, head, next) {
if (fst->fs_type != PS_FST_TYPE_PTS)
continue;
err = procstat_get_pts_info(procstat, fst, &pts, errbuf);
if (err != 0) {
error("error discovering fd=%d", fst->fs_fd);
continue;
}
if (pts.dev != steal->target_stat.ctty)
continue;
if (fd_array_push(&steal->master_fds, fst->fs_fd) != 0) {
error("unable to allocate memory for fd array");
return ENOMEM;
}
}
procstat_freefiles(procstat, head);
procstat_freeprocs(procstat, kp);
procstat_close(procstat);
debug("Found %d master tty fds in child %d.", steal->master_fds.n, steal->ch
ild.pid);
if (steal->master_fds.n == 0)
return ESRCH;
return 0;
} }
int get_pt() { int get_pt() {
return posix_openpt(O_RDWR | O_NOCTTY); return posix_openpt(O_RDWR | O_NOCTTY);
} }
int get_process_tty_termios(pid_t pid, struct termios *tio) { int get_process_tty_termios(pid_t pid, struct termios *tio) {
int err = EINVAL; int err = EINVAL;
struct kinfo_proc *kp; struct kinfo_proc *kp;
unsigned int cnt; unsigned int cnt;
skipping to change at line 230 skipping to change at line 308
} }
void move_process_group(struct ptrace_child *child, pid_t from, pid_t to) { void move_process_group(struct ptrace_child *child, pid_t from, pid_t to) {
struct procstat *procstat; struct procstat *procstat;
struct kinfo_proc *kp; struct kinfo_proc *kp;
unsigned int cnt; unsigned int cnt;
int i; int i;
int err; int err;
procstat = procstat_open_sysctl(); procstat = procstat_open_sysctl();
cnt = 0;
kp = procstat_getprocs(procstat, KERN_PROC_PGRP, from, &cnt); kp = procstat_getprocs(procstat, KERN_PROC_PGRP, from, &cnt);
for (i = 0; i < cnt; i++) { for (i = 0; i < cnt; i++) {
debug("Change pgid for pid %d to %d", kp[i].ki_pid, to); debug("Change pgid for pid %d to %d", kp[i].ki_pid, to);
err = do_syscall(child, setpgid, kp[i].ki_pid, to, 0, 0, 0, 0); err = do_syscall(child, setpgid, kp[i].ki_pid, to, 0, 0, 0, 0);
if (err < 0) if (err < 0)
error(" failed: %s", strerror(-err)); error(" failed: %s", strerror(-err));
} }
procstat_freeprocs(procstat, kp); procstat_freeprocs(procstat, kp);
procstat_close(procstat); procstat_close(procstat);
 End of changes. 12 change blocks. 
4 lines changed or deleted 84 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)