Hello community,

here is the log from the commit of package reptyr for openSUSE:Factory checked 
in at 2018-12-12 17:28:02
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/reptyr (Old)
 and      /work/SRC/openSUSE:Factory/.reptyr.new.28833 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "reptyr"

Wed Dec 12 17:28:02 2018 rev:11 rq:655903 version:0.7.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/reptyr/reptyr.changes    2017-03-20 
17:10:09.308851825 +0100
+++ /work/SRC/openSUSE:Factory/.reptyr.new.28833/reptyr.changes 2018-12-12 
17:28:03.846908871 +0100
@@ -1,0 +2,17 @@
+Thu Dec  6 00:19:42 UTC 2018 - Jan Engelhardt <jeng...@inai.de>
+
+- Use %make_install.
+
+-------------------------------------------------------------------
+Wed Dec  5 05:27:04 UTC 2018 - Martin Herkt <9+suse@cirno.systems>
+
+- Update to version 0.7.0
+  * Add bash completion support
+  * Fix compilation with musl libc, CentOS, or GCC 7+
+  * Support for PowerPC and aarch64
+- Drop patches
+  0001-Placate-a-gcc7-warning.patch
+  0002-Include-sysmacros.h.patch
+  0003-Build-with-fstrict-aliasing.patch
+
+-------------------------------------------------------------------

Old:
----
  0001-Placate-a-gcc7-warning.patch
  0002-Include-sysmacros.h.patch
  0003-Build-with-fstrict-aliasing.patch
  reptyr-0.6.2.tar.gz

New:
----
  reptyr-0.7.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ reptyr.spec ++++++
--- /var/tmp/diff_new_pack.jHpsDy/_old  2018-12-12 17:28:04.330908257 +0100
+++ /var/tmp/diff_new_pack.jHpsDy/_new  2018-12-12 17:28:04.334908252 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package reptyr
 #
-# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -12,24 +12,20 @@
 # license that conforms to the Open Source Definition (Version 1.9)
 # published by the Open Source Initiative.
 
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
 #
 
 
 Name:           reptyr
-Version:        0.6.2
+Version:        0.7.0
 Release:        0
 Summary:        A tool for "re-ptying" programs
 License:        MIT
 Group:          System/Console
-Url:            http://github.com/nelhage/reptyr
+URL:            http://github.com/nelhage/reptyr
 Source:         
https://github.com/nelhage/reptyr/archive/%{name}-%{version}.tar.gz
-Patch0:         0001-Placate-a-gcc7-warning.patch
-Patch1:         0002-Include-sysmacros.h.patch
-Patch2:         0003-Build-with-fstrict-aliasing.patch
+BuildRequires:  bash-completion
 BuildRequires:  gcc
-BuildRoot:      %{_tmppath}/%{name}-%{version}-build
-ExclusiveArch:  %{ix86} x86_64 %{arm}
 
 %description
 reptyr is a utility for taking an existing running program and
@@ -40,23 +36,21 @@
 
 %prep
 %setup -q -n %{name}-%{name}-%{version}
-%patch0 -p1
-%patch1 -p1
-%patch2 -p1
 
 %build
 export CFLAGS="%{optflags}"
 export CXXFLAGS="%{optflags}"
-make
+make %{?_smp_mflags}
 
 %install
-make PREFIX="%{buildroot}%{_prefix}" install
+%make_install PREFIX="%{_prefix}" 
BASHCOMPDIR="%{_datadir}/bash-completion/completions"
 
 %files
-%defattr(-,root,root)
-%doc ChangeLog COPYING README.md NOTES 
-%doc %{_mandir}/man1/reptyr.1%{ext_man}
-%doc %{_mandir}/fr/man1/reptyr.1%{ext_man}
+%doc ChangeLog README.md NOTES
+%license COPYING
+%{_mandir}/man1/reptyr.1%{?ext_man}
+%{_mandir}/fr/man1/reptyr.1%{?ext_man}
 %{_bindir}/reptyr
+%{_datadir}/bash-completion/completions/reptyr
 
 %changelog

++++++ reptyr-0.6.2.tar.gz -> reptyr-0.7.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reptyr-reptyr-0.6.2/.travis.yml 
new/reptyr-reptyr-0.7.0/.travis.yml
--- old/reptyr-reptyr-0.6.2/.travis.yml 2015-02-01 02:14:27.000000000 +0100
+++ new/reptyr-reptyr-0.7.0/.travis.yml 2018-12-05 04:48:42.000000000 +0100
@@ -1,7 +1,15 @@
 script: make test
+sudo: required
+language: python
+python:
+  - "2.7"
+install:
+  - env -u CFLAGS -u LDFLAGS pip install -r test/requirements.txt
+addons:
+  apt:
+    packages:
+      - gcc-multilib
+      - libcap-dev
 env:
   - CFLAGS=-m32 LDFLAGS=-m32 DISABLE_TESTS=1
   - CFLAGS=-m64 LDFLAGS=-m64
-before_install:
-  - sudo apt-get update
-  - sudo apt-get -y install gcc-multilib python-pexpect
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reptyr-reptyr-0.6.2/ChangeLog 
new/reptyr-reptyr-0.7.0/ChangeLog
--- old/reptyr-reptyr-0.6.2/ChangeLog   2015-02-01 02:14:27.000000000 +0100
+++ new/reptyr-reptyr-0.7.0/ChangeLog   2018-12-05 04:48:42.000000000 +0100
@@ -1,3 +1,8 @@
+* 0.7.0 (Dec 05, 2018)
+ - Add bash completion support
+ - Fix compilation with musl libc, CentOS, or GCC 7+
+ - Support for PowerPC and aarch64
+
 * 0.6.2 (Jan 31, 2015)
  - Fix tty-stealing on i386
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reptyr-reptyr-0.6.2/Makefile 
new/reptyr-reptyr-0.7.0/Makefile
--- old/reptyr-reptyr-0.6.2/Makefile    2015-02-01 02:14:27.000000000 +0100
+++ new/reptyr-reptyr-0.7.0/Makefile    2018-12-05 04:48:42.000000000 +0100
@@ -1,4 +1,4 @@
-override CFLAGS+=-Wall -Werror -D_GNU_SOURCE -g
+override CFLAGS := -Wall -Werror -D_GNU_SOURCE -g $(CFLAGS)
 OBJS=reptyr.o reallocarray.o attach.o
 UNAME_S := $(shell uname -s)
 ifeq ($(UNAME_S),Linux)
@@ -8,11 +8,15 @@
        OBJS += platform/freebsd/freebsd_ptrace.o platform/freebsd/freebsd.o
        LDFLAGS += -lprocstat
 endif
-# Note that because of how Make works, this can be overriden from the
+# Note that because of how Make works, this can be overridden from the
 # command-line.
 #
 # e.g. install to /usr with `make PREFIX=/usr`
 PREFIX=/usr/local
+BINDIR=$(PREFIX)/bin
+MANDIR=$(PREFIX)/share/man
+
+PKG_CONFIG ?= pkg-config
 
 all: reptyr
 
@@ -20,8 +24,8 @@
 
 ifeq ($(DISABLE_TESTS),)
 test: reptyr test/victim PHONY
-       python test/basic.py
-       python test/tty-steal.py
+       python2 test/basic.py
+       python2 test/tty-steal.py
 else
 test: all
 endif
@@ -39,12 +43,18 @@
 clean:
        rm -f reptyr $(OBJS) test/victim.o test/victim
 
+BASHCOMPDIR ?= $(shell $(PKG_CONFIG) --variable=completionsdir bash-completion 
2>/dev/null)
+
 install: reptyr
-       install -d -m 755 $(DESTDIR)$(PREFIX)/bin/
-       install -m 755 reptyr $(DESTDIR)$(PREFIX)/bin/reptyr
-       install -d -m 755 $(DESTDIR)$(PREFIX)/share/man/man1
-       install -m 644 reptyr.1 $(DESTDIR)$(PREFIX)/share/man/man1/reptyr.1
-       install -d -m 755 $(DESTDIR)$(PREFIX)/share/man/fr/man1
-       install -m 644 reptyr.fr.1 
$(DESTDIR)$(PREFIX)/share/man/fr/man1/reptyr.1
+       install -d -m 755 $(DESTDIR)$(BINDIR)
+       install -m 755 reptyr $(DESTDIR)$(BINDIR)/reptyr
+       install -d -m 755 $(DESTDIR)$(MANDIR)/man1
+       install -m 644 reptyr.1 $(DESTDIR)$(MANDIR)/man1/reptyr.1
+       install -d -m 755 $(DESTDIR)$(MANDIR)/fr/man1
+       install -m 644 reptyr.fr.1 $(DESTDIR)$(MANDIR)/fr/man1/reptyr.1
+       bashcompdir=$(BASHCOMPDIR) ; \
+       test -z "$$bashcompdir" && bashcompdir=/etc/bash_completion.d ; \
+       install -d -m 755 $(DESTDIR)$$bashcompdir ; \
+       install -m 644 reptyr.bash $(DESTDIR)$$bashcompdir/reptyr
 
 .PHONY: PHONY
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reptyr-reptyr-0.6.2/README.md 
new/reptyr-reptyr-0.7.0/README.md
--- old/reptyr-reptyr-0.6.2/README.md   2015-02-01 02:14:27.000000000 +0100
+++ new/reptyr-reptyr-0.7.0/README.md   2018-12-05 04:48:42.000000000 +0100
@@ -21,6 +21,21 @@
 terminal. This is likely impossible to fix in a reasonable way without
 patching your shell.)
 
+Typical usage pattern
+---------------------
+
+* Start a long running process, e.g. `top`
+* Background the process with CTRL-Z
+* Resume the process in the background: `bg`
+* Display your running background jobs with `jobs -l`, this should look like 
this:
+  * `[1]+  4711 Stopped (signal)        top`
+  * (The `-l` in `jobs -l` makes sure you'll get the PID)
+* Disown the jobs from the current parent with `disown top`. After that, 
`jobs` will not show the job any more, but `ps -a` will.
+* Start your terminal multiplexer of choice, e.g. `tmux`
+* Reattach to the backgrounded process: `reptyr 4711`
+* Detach your terminal multiplexer (e.g. CTRL-A D) and close ssh
+* Reconnect ssh, attach to your multiplexer (e.g. `tmux attach`), rejoice!
+
 "But wait, isn't this just screenify?"
 --------------------------------------
 
@@ -41,11 +56,16 @@
 PORTABILITY
 -----------
 
-reptyr is Linux-only. It uses ptrace to attach to the target and control it at
-the syscall level, so it is highly dependent on Linux's particular syscall API,
-syscalls, and terminal ioctl()s. A port to Solaris or BSD may be technically
-feasible, but would probably require significant re-architecting to abstract 
out
-the platform-specific bits.
+reptyr supports Linux and FreeBSD. Not all functionality is currently
+available on FreeBSD. (Notably, FreeBSD doesn't support `reptyr -T` at
+this time.
+
+`reptyr` uses ptrace to attach to the target and control it at the
+syscall level, so it is highly dependent on details of the syscall
+API, available syscalls, and terminal ioctl()s. A port to other
+operating systems may be technically feasible, but requires
+significant low-level knowledge of the relevant platform, and may
+entail significant refactors.
 
 reptyr works on i386, x86_64, and ARM. Ports to other architectures should be
 straightforward, and should in most cases be as simple as adding an arch/ARCH.h
@@ -98,4 +118,4 @@
 
 URL
 ---
-[http://github.com/nelhage/reptyr]()
+http://github.com/nelhage/reptyr
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reptyr-reptyr-0.6.2/Vagrantfile 
new/reptyr-reptyr-0.7.0/Vagrantfile
--- old/reptyr-reptyr-0.6.2/Vagrantfile 2015-02-01 02:14:27.000000000 +0100
+++ new/reptyr-reptyr-0.7.0/Vagrantfile 2018-12-05 04:48:42.000000000 +0100
@@ -23,6 +23,14 @@
     machine.vm.box = 'chef/fedora-20'
   end
 
+  config.vm.define 'centos-6-x86_64' do |machine|
+    machine.vm.box = 'bento/centos-6.7'
+  end
+
+  config.vm.define 'centos-5-x86_64' do |machine|
+    machine.vm.box = 'bento/centos-5.11'
+  end
+
   config.vm.synced_folder ".", "/vagrant", type: 'nfs', id: 'vagrant-root'
 
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reptyr-reptyr-0.6.2/attach.c 
new/reptyr-reptyr-0.7.0/attach.c
--- old/reptyr-reptyr-0.6.2/attach.c    2015-02-01 02:14:27.000000000 +0100
+++ new/reptyr-reptyr-0.7.0/attach.c    2018-12-05 04:48:42.000000000 +0100
@@ -69,11 +69,19 @@
     do_syscall(child, munmap, (unsigned long)addr, len, 0, 0, 0, 0);
 }
 
+static int do_fork(struct ptrace_child *child) {
+    if (ptrace_syscall_numbers(child)->nr_fork != -1) {
+        return do_syscall(child, fork, 0, 0, 0, 0, 0, 0);
+    } else {
+        return do_syscall(child, clone, SIGCHLD, 0, 0, 0, 0, 0);
+    }
+}
+
 int do_setsid(struct ptrace_child *child) {
     int err = 0;
     struct ptrace_child dummy;
 
-    err = do_syscall(child, fork, 0, 0, 0, 0, 0, 0);
+    err = do_fork(child);
     if (err < 0)
         return err;
 
@@ -109,12 +117,23 @@
 
 out_kill:
     kill(dummy.pid, SIGKILL);
+    ptrace_wait(&dummy);
     ptrace_detach_child(&dummy);
-    //ptrace_wait(&dummy);
     do_syscall(child, wait4, dummy.pid, 0, WNOHANG, 0, 0, 0);
     return err;
 }
 
+static int do_dup2(struct ptrace_child *child, int oldfd, int newfd) {
+    if (oldfd == newfd) {
+        return 0;
+    }
+    if (ptrace_syscall_numbers(child)->nr_dup2 != -1) {
+        return do_syscall(child, dup2, oldfd, newfd, 0, 0, 0, 0);
+    } else {
+        return do_syscall(child, dup3, oldfd, newfd, 0, 0, 0, 0);
+    }
+}
+
 int ignore_hup(struct ptrace_child *child, child_addr_t scratch_page) {
     int err;
 
@@ -237,6 +256,16 @@
     return err;
 }
 
+int preflight_check(pid_t pid) {
+    struct ptrace_child child;
+    debug("Making sure we have permission to attach...");
+    if (ptrace_attach_child(&child, pid)) {
+        return child.error;
+    }
+    ptrace_detach_child(&child);
+    return 0;
+}
+
 int attach_child(pid_t pid, const char *pty, int force_stdio) {
     struct ptrace_child child;
     child_addr_t scratch_page = -1;
@@ -252,6 +281,10 @@
         return err;
     }
 
+    if ((err = preflight_check(pid))) {
+        return err;
+    }
+
     debug("Using tty: %s", pty);
 
     if ((err = copy_tty_state(pid, pty))) {
@@ -302,9 +335,9 @@
         goto out_free_fds;
     }
 
-    child_fd = do_syscall(&child, open,
-                          scratch_page, O_RDWR | O_NOCTTY,
-                          0, 0, 0, 0);
+    child_fd = do_syscall(&child, openat,
+                          -1, scratch_page, O_RDWR | O_NOCTTY,
+                          0, 0, 0);
     if (child_fd < 0) {
         err = child_fd;
         error("Unable to open the tty in the child.");
@@ -336,7 +369,7 @@
     debug("Set the controlling tty");
 
     for (i = 0; i < n_fds; i++) {
-        err = do_syscall(&child, dup2, child_fd, child_tty_fds[i], 0, 0, 0, 0);
+        err = do_dup2(&child, child_fd, child_tty_fds[i]);
         if (err < 0)
             error("Problem moving child fd number %d to new tty: %s", 
child_tty_fds[i], strerror(errno));
     }
@@ -375,8 +408,11 @@
         return errno;
 
     steal->addr_un.sun_family = AF_UNIX;
-    snprintf(steal->addr_un.sun_path, sizeof(steal->addr_un.sun_path),
-             "%s/reptyr.sock", steal->tmpdir);
+    if (snprintf(steal->addr_un.sun_path, sizeof(steal->addr_un.sun_path),
+                 "%s/reptyr.sock", steal->tmpdir) >= 
sizeof(steal->addr_un.sun_path)) {
+        error("tmpdir path too long!");
+        return ENAMETOOLONG;
+    }
 
     if ((steal->sockfd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0)
         return errno;
@@ -384,9 +420,9 @@
     if (bind(steal->sockfd, &steal->addr, sizeof(steal->addr_un)) < 0)
         return errno;
 
-    if (chown(steal->addr_un.sun_path, steal->target_stat.uid, 
steal->target_stat.gid) < 0)
+    if (chown(steal->addr_un.sun_path, steal->emulator_uid, -1) < 0)
         debug("chown %s: %s", steal->addr_un.sun_path, strerror(errno));
-    if (chown(steal->tmpdir, steal->target_stat.uid, steal->target_stat.gid) < 
0)
+    if (chown(steal->tmpdir, steal->emulator_uid, -1) < 0)
         debug("chown %s: %s", steal->tmpdir, strerror(errno));
 
     return 0;
@@ -484,7 +520,7 @@
 // it doesn't die.
 int steal_block_hup(struct steal_pty_state *steal) {
     struct ptrace_child leader;
-    child_addr_t scratch;
+    child_addr_t scratch = 0;
     int err = 0;
 
     if ((err = grab_pid(steal->target_stat.sid, &leader, &scratch)))
@@ -505,14 +541,14 @@
         return steal->child.error;
     }
 
-    int nullfd = do_syscall(&steal->child, open, steal->child_scratch, O_RDWR, 
0, 0, 0, 0);
+    int nullfd = do_syscall(&steal->child, openat, -1, steal->child_scratch, 
O_RDWR, 0, 0, 0);
     if (nullfd < 0) {
         return steal->child.error;
     }
 
     int i;
     for (i = 0; i < steal->master_fds.n; ++i) {
-        do_syscall(&steal->child, dup2, nullfd, steal->master_fds.fds[i], 0, 
0, 0, 0);
+        do_dup2(&steal->child, nullfd, steal->master_fds.fds[i]);
     }
 
     do_syscall(&steal->child, close, nullfd, 0, 0, 0, 0, 0);
@@ -532,6 +568,9 @@
     struct steal_pty_state steal = {};
     long page_size = sysconf(_SC_PAGE_SIZE);
 
+    if ((err = preflight_check(pid)))
+        goto out;
+
     if ((err = get_terminal_state(&steal, pid)))
         goto out;
 
@@ -539,6 +578,7 @@
         goto out;
 
     debug("Listening on socket: %s", steal.addr_un.sun_path);
+    debug("Attaching terminal emulator pid=%d", steal.emulator_pid);
 
     if ((err = grab_pid(steal.emulator_pid, &steal.child, 
&steal.child_scratch)))
         goto out;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/reptyr-reptyr-0.6.2/platform/freebsd/arch/default-syscalls.h 
new/reptyr-reptyr-0.7.0/platform/freebsd/arch/default-syscalls.h
--- old/reptyr-reptyr-0.6.2/platform/freebsd/arch/default-syscalls.h    
2015-02-01 02:14:27.000000000 +0100
+++ new/reptyr-reptyr-0.7.0/platform/freebsd/arch/default-syscalls.h    
2018-12-05 04:48:42.000000000 +0100
@@ -1,14 +1,11 @@
 #define SC(name) .nr_##name = SYS_##name
 
 {
-#ifdef SYS_mmap
-    SC(mmap),
-#else
-    .nr_mmap = -1,
-#endif
 #ifdef SYS_mmap2
+    .nr_mmap = -1,
     SC(mmap2),
 #else
+    SC(mmap),
     .nr_mmap2 = -1,
 #endif
     SC(munmap),
@@ -16,6 +13,7 @@
     SC(setsid),
     SC(setpgid),
     SC(fork),
+    .nr_clone = -1,
     SC(wait4),
 #ifdef SYS_signal
     SC(signal),
@@ -23,10 +21,11 @@
      .nr_signal = -1,
 #endif
     .nr_rt_sigaction = SYS_sigaction,
-    SC(open),
+    SC(openat),
     SC(close),
     SC(ioctl),
     SC(dup2),
+    .nr_dup3 = -1,
 #ifdef SYS_socketcall
     SC(socketcall),
 #else
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/reptyr-reptyr-0.6.2/platform/freebsd/arch/x86_common.h 
new/reptyr-reptyr-0.7.0/platform/freebsd/arch/x86_common.h
--- old/reptyr-reptyr-0.6.2/platform/freebsd/arch/x86_common.h  2015-02-01 
02:14:27.000000000 +0100
+++ new/reptyr-reptyr-0.7.0/platform/freebsd/arch/x86_common.h  2018-12-05 
04:48:42.000000000 +0100
@@ -34,7 +34,7 @@
     struct x86_personality *x86pers = x86_pers(child);
     struct ptrace_personality *pers = personality(child);
     struct reg *regs = &child->regs;
-#define ptr(user, off) ((unsigned long*)((void*)(user)+(off)))
+#define ptr(regs, off) ((unsigned long*)((void*)(regs)+(off)))
     *ptr(regs, pers->reg_ip) -= 2;
     *ptr(regs, x86pers->ax) = child->saved_syscall;
     //*ptr(user, x86pers->ax) = *ptr(user, x86pers->orig_ax);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reptyr-reptyr-0.6.2/platform/freebsd/freebsd.h 
new/reptyr-reptyr-0.7.0/platform/freebsd/freebsd.h
--- old/reptyr-reptyr-0.6.2/platform/freebsd/freebsd.h  2015-02-01 
02:14:27.000000000 +0100
+++ new/reptyr-reptyr-0.7.0/platform/freebsd/freebsd.h  2018-12-05 
04:48:42.000000000 +0100
@@ -39,9 +39,9 @@
 #include <stdio.h>
 #include <string.h>
 
-#define do_socketcall(child, name, a0, a1, a2, a3, a4)                  \
+#define do_socketcall(child, scratch, name, a0, a1, a2, a3, a4)         \
     ({                                                                  \
-        int __ret=-1;                                                      \
+        int __ret=-1;                                                   \
         if (ptrace_syscall_numbers((child))->nr_##name) {               \
             __ret = do_syscall((child), name, a0, a1, a2, a3, a4, 0);   \
         }                                                               \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/reptyr-reptyr-0.6.2/platform/freebsd/freebsd_ptrace.c 
new/reptyr-reptyr-0.7.0/platform/freebsd/freebsd_ptrace.c
--- old/reptyr-reptyr-0.6.2/platform/freebsd/freebsd_ptrace.c   2015-02-01 
02:14:27.000000000 +0100
+++ new/reptyr-reptyr-0.7.0/platform/freebsd/freebsd_ptrace.c   2018-12-05 
04:48:42.000000000 +0100
@@ -47,7 +47,7 @@
 static int __ptrace_command(struct ptrace_child *child, int req,
                             void *, int);
 
-#define ptrace_command(cld, req, ...) _ptrace_command(cld, req, ## 
__VA_ARGS__, NULL, NULL)
+#define ptrace_command(cld, req, ...) _ptrace_command(cld, req, ## 
__VA_ARGS__, 0, 0)
 #define _ptrace_command(cld, req, addr, data, ...) __ptrace_command((cld), 
(req), (void*)(addr), (int)(data))
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reptyr-reptyr-0.6.2/platform/linux/arch/aarch64.h 
new/reptyr-reptyr-0.7.0/platform/linux/arch/aarch64.h
--- old/reptyr-reptyr-0.6.2/platform/linux/arch/aarch64.h       1970-01-01 
01:00:00.000000000 +0100
+++ new/reptyr-reptyr-0.7.0/platform/linux/arch/aarch64.h       2018-12-05 
04:48:42.000000000 +0100
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2011 by Nelson Elhage
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+static struct ptrace_personality arch_personality[1] = {
+    {
+        offsetof(struct user_regs_struct, regs[0]),
+        offsetof(struct user_regs_struct, regs[0]),
+        offsetof(struct user_regs_struct, regs[1]),
+        offsetof(struct user_regs_struct, regs[2]),
+        offsetof(struct user_regs_struct, regs[3]),
+        offsetof(struct user_regs_struct, regs[4]),
+        offsetof(struct user_regs_struct, regs[5]),
+        offsetof(struct user_regs_struct, pc),
+    }
+};
+
+static inline void arch_fixup_regs(struct ptrace_child *child) {
+    child->regs.pc -= 4;
+}
+
+static inline int arch_set_syscall(struct ptrace_child *child,
+                                   unsigned long sysno) {
+    int syscall_reg = sysno;
+    struct iovec reg_iovec = {
+        .iov_base = &syscall_reg,
+        .iov_len = sizeof(syscall_reg)
+    };
+    return ptrace_command(child, PTRACE_SETREGSET, NT_ARM_SYSTEM_CALL, 
&reg_iovec);
+}
+
+static inline int arch_save_syscall(struct ptrace_child *child) {
+    int syscall_reg;
+    struct iovec reg_iovec = {
+        .iov_base = &syscall_reg,
+        .iov_len = sizeof(syscall_reg)
+    };
+    if (ptrace_command(child, PTRACE_GETREGSET, NT_ARM_SYSTEM_CALL, 
&reg_iovec) < 0)
+        return -1;
+
+    child->saved_syscall = syscall_reg;
+    return 0;
+}
+
+static inline int arch_restore_syscall(struct ptrace_child *child) {
+    return arch_set_syscall(child, child->saved_syscall);
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reptyr-reptyr-0.6.2/platform/linux/arch/amd64.h 
new/reptyr-reptyr-0.7.0/platform/linux/arch/amd64.h
--- old/reptyr-reptyr-0.6.2/platform/linux/arch/amd64.h 2015-02-01 
02:14:27.000000000 +0100
+++ new/reptyr-reptyr-0.7.0/platform/linux/arch/amd64.h 2018-12-05 
04:48:42.000000000 +0100
@@ -25,35 +25,35 @@
 
 static struct ptrace_personality arch_personality[2] = {
     {
-        offsetof(struct user, regs.rax),
-        offsetof(struct user, regs.rdi),
-        offsetof(struct user, regs.rsi),
-        offsetof(struct user, regs.rdx),
-        offsetof(struct user, regs.r10),
-        offsetof(struct user, regs.r8),
-        offsetof(struct user, regs.r9),
-        offsetof(struct user, regs.rip),
+        offsetof(struct user_regs_struct, rax),
+        offsetof(struct user_regs_struct, rdi),
+        offsetof(struct user_regs_struct, rsi),
+        offsetof(struct user_regs_struct, rdx),
+        offsetof(struct user_regs_struct, r10),
+        offsetof(struct user_regs_struct, r8),
+        offsetof(struct user_regs_struct, r9),
+        offsetof(struct user_regs_struct, rip),
     },
     {
-        offsetof(struct user, regs.rax),
-        offsetof(struct user, regs.rbx),
-        offsetof(struct user, regs.rcx),
-        offsetof(struct user, regs.rdx),
-        offsetof(struct user, regs.rsi),
-        offsetof(struct user, regs.rdi),
-        offsetof(struct user, regs.rbp),
-        offsetof(struct user, regs.rip),
+        offsetof(struct user_regs_struct, rax),
+        offsetof(struct user_regs_struct, rbx),
+        offsetof(struct user_regs_struct, rcx),
+        offsetof(struct user_regs_struct, rdx),
+        offsetof(struct user_regs_struct, rsi),
+        offsetof(struct user_regs_struct, rdi),
+        offsetof(struct user_regs_struct, rbp),
+        offsetof(struct user_regs_struct, rip),
     },
 };
 
 struct x86_personality x86_personality[2] = {
     {
-        offsetof(struct user, regs.orig_rax),
-        offsetof(struct user, regs.rax),
+        offsetof(struct user_regs_struct, orig_rax),
+        offsetof(struct user_regs_struct, rax),
     },
     {
-        offsetof(struct user, regs.orig_rax),
-        offsetof(struct user, regs.rax),
+        offsetof(struct user_regs_struct, orig_rax),
+        offsetof(struct user_regs_struct, rax),
     },
 };
 
@@ -65,7 +65,7 @@
          * include unistd_32.h, but those definitions would conflict with the
          * standard ones. So, let's just hardcode the values for now. Probably
          * we should generate this from unistd_32.h during the build process or
-         * soemthing.
+         * something.
          */
         .nr_mmap    = 90,
         .nr_mmap2   = 192,
@@ -77,7 +77,7 @@
         .nr_wait4   = 114,
         .nr_signal  = 48,
         .nr_rt_sigaction = 174,
-        .nr_open    = 5,
+        .nr_openat  = 295,
         .nr_close   = 6,
         .nr_ioctl   = 54,
         .nr_dup2    = 63,
@@ -89,7 +89,7 @@
     unsigned long cs;
 
     cs = ptrace_command(child, PTRACE_PEEKUSER,
-                        offsetof(struct user, regs.cs));
+                        offsetof(struct user_regs_struct, cs));
     if (child->error)
         return -1;
     if (cs == 0x23)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reptyr-reptyr-0.6.2/platform/linux/arch/arm.h 
new/reptyr-reptyr-0.7.0/platform/linux/arch/arm.h
--- old/reptyr-reptyr-0.6.2/platform/linux/arch/arm.h   2015-02-01 
02:14:27.000000000 +0100
+++ new/reptyr-reptyr-0.7.0/platform/linux/arch/arm.h   2018-12-05 
04:48:42.000000000 +0100
@@ -21,19 +21,19 @@
  */
 static struct ptrace_personality arch_personality[1] = {
     {
-        offsetof(struct user, regs.uregs[0]),
-        offsetof(struct user, regs.uregs[0]),
-        offsetof(struct user, regs.uregs[1]),
-        offsetof(struct user, regs.uregs[2]),
-        offsetof(struct user, regs.uregs[3]),
-        offsetof(struct user, regs.uregs[4]),
-        offsetof(struct user, regs.uregs[5]),
-        offsetof(struct user, regs.ARM_pc),
+        offsetof(struct user_regs, uregs[0]),
+        offsetof(struct user_regs, uregs[0]),
+        offsetof(struct user_regs, uregs[1]),
+        offsetof(struct user_regs, uregs[2]),
+        offsetof(struct user_regs, uregs[3]),
+        offsetof(struct user_regs, uregs[4]),
+        offsetof(struct user_regs, uregs[5]),
+        offsetof(struct user_regs, ARM_pc),
     }
 };
 
 static inline void arch_fixup_regs(struct ptrace_child *child) {
-    child->user.regs.ARM_pc -= 4;
+    child->regs.ARM_pc -= 4;
 }
 
 static inline int arch_set_syscall(struct ptrace_child *child,
@@ -43,11 +43,11 @@
 
 static inline int arch_save_syscall(struct ptrace_child *child) {
     unsigned long swi;
-    swi = ptrace_command(child, PTRACE_PEEKTEXT, child->user.regs.ARM_pc);
+    swi = ptrace_command(child, PTRACE_PEEKTEXT, child->regs.ARM_pc);
     if (child->error)
         return -1;
     if (swi == 0xef000000)
-        child->saved_syscall = child->user.regs.uregs[7];
+        child->saved_syscall = child->regs.uregs[7];
     else
         child->saved_syscall = (swi & 0x000fffff);
     return 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/reptyr-reptyr-0.6.2/platform/linux/arch/default-syscalls.h 
new/reptyr-reptyr-0.7.0/platform/linux/arch/default-syscalls.h
--- old/reptyr-reptyr-0.6.2/platform/linux/arch/default-syscalls.h      
2015-02-01 02:14:27.000000000 +0100
+++ new/reptyr-reptyr-0.7.0/platform/linux/arch/default-syscalls.h      
2018-12-05 04:48:42.000000000 +0100
@@ -1,21 +1,24 @@
 #define SC(name) .nr_##name = __NR_##name
 
 {
-#ifdef __NR_mmap
-    SC(mmap),
-#else
-    .nr_mmap = -1,
-#endif
 #ifdef __NR_mmap2
+    .nr_mmap = -1,
     SC(mmap2),
 #else
+    SC(mmap),
     .nr_mmap2 = -1,
 #endif
     SC(munmap),
     SC(getsid),
     SC(setsid),
     SC(setpgid),
+#ifdef __NR_fork
     SC(fork),
+    .nr_clone = -1,
+#else
+    .nr_fork = -1,
+    SC(clone),
+#endif
     SC(wait4),
 #ifdef __NR_signal
     SC(signal),
@@ -23,10 +26,16 @@
      .nr_signal = -1,
 #endif
     SC(rt_sigaction),
-    SC(open),
+    SC(openat),
     SC(close),
     SC(ioctl),
+#ifdef __NR_dup2
     SC(dup2),
+    .nr_dup3 = -1,
+#else
+    .nr_dup2 = -1,
+    SC(dup3),
+#endif
 #ifdef __NR_socketcall
     SC(socketcall),
 #else
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reptyr-reptyr-0.6.2/platform/linux/arch/i386.h 
new/reptyr-reptyr-0.7.0/platform/linux/arch/i386.h
--- old/reptyr-reptyr-0.6.2/platform/linux/arch/i386.h  2015-02-01 
02:14:27.000000000 +0100
+++ new/reptyr-reptyr-0.7.0/platform/linux/arch/i386.h  2018-12-05 
04:48:42.000000000 +0100
@@ -23,20 +23,20 @@
 
 static struct ptrace_personality arch_personality[1] = {
     {
-        offsetof(struct user, regs.eax),
-        offsetof(struct user, regs.ebx),
-        offsetof(struct user, regs.ecx),
-        offsetof(struct user, regs.edx),
-        offsetof(struct user, regs.esi),
-        offsetof(struct user, regs.edi),
-        offsetof(struct user, regs.ebp),
-        offsetof(struct user, regs.eip),
+        offsetof(struct user_regs_struct, eax),
+        offsetof(struct user_regs_struct, ebx),
+        offsetof(struct user_regs_struct, ecx),
+        offsetof(struct user_regs_struct, edx),
+        offsetof(struct user_regs_struct, esi),
+        offsetof(struct user_regs_struct, edi),
+        offsetof(struct user_regs_struct, ebp),
+        offsetof(struct user_regs_struct, eip),
     }
 };
 
 struct x86_personality x86_personality[1] = {
     {
-        offsetof(struct user, regs.orig_eax),
-        offsetof(struct user, regs.eax),
+        offsetof(struct user_regs_struct, orig_eax),
+        offsetof(struct user_regs_struct, eax),
     }
 };
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reptyr-reptyr-0.6.2/platform/linux/arch/powerpc.h 
new/reptyr-reptyr-0.7.0/platform/linux/arch/powerpc.h
--- old/reptyr-reptyr-0.6.2/platform/linux/arch/powerpc.h       1970-01-01 
01:00:00.000000000 +0100
+++ new/reptyr-reptyr-0.7.0/platform/linux/arch/powerpc.h       2018-12-05 
04:48:42.000000000 +0100
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2011 by Nelson Elhage
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+static struct ptrace_personality arch_personality[1] = {
+    {
+        offsetof(struct pt_regs, gpr[3]),
+        offsetof(struct pt_regs, gpr[3]),
+        offsetof(struct pt_regs, gpr[4]),
+        offsetof(struct pt_regs, gpr[5]),
+        offsetof(struct pt_regs, gpr[6]),
+        offsetof(struct pt_regs, gpr[7]),
+        offsetof(struct pt_regs, gpr[8]),
+        offsetof(struct pt_regs, nip),
+    }
+};
+
+static const unsigned long r0off = offsetof(struct pt_regs, gpr[0]);
+
+static inline void arch_fixup_regs(struct ptrace_child *child) {
+    child->regs.nip -= 4;
+}
+
+static inline int arch_set_syscall(struct ptrace_child *child,
+                                   unsigned long sysno) {
+    return ptrace_command(child, PTRACE_POKEUSER, r0off, sysno);
+}
+
+static inline int arch_save_syscall(struct ptrace_child *child) {
+    child->saved_syscall = *ptr(&child->regs, r0off);
+    return 0;
+}
+
+static inline int arch_restore_syscall(struct ptrace_child *child) {
+    return arch_set_syscall(child, child->saved_syscall);
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reptyr-reptyr-0.6.2/platform/linux/arch/x86_common.h 
new/reptyr-reptyr-0.7.0/platform/linux/arch/x86_common.h
--- old/reptyr-reptyr-0.6.2/platform/linux/arch/x86_common.h    2015-02-01 
02:14:27.000000000 +0100
+++ new/reptyr-reptyr-0.7.0/platform/linux/arch/x86_common.h    2018-12-05 
04:48:42.000000000 +0100
@@ -34,10 +34,9 @@
 static inline void arch_fixup_regs(struct ptrace_child *child) {
     struct x86_personality *x86pers = x86_pers(child);
     struct ptrace_personality *pers = personality(child);
-    struct user *user = &child->user;
-#define ptr(user, off) ((unsigned long*)((void*)(user)+(off)))
-    *ptr(user, pers->reg_ip) -= 2;
-    *ptr(user, x86pers->ax) = *ptr(user, x86pers->orig_ax);
+    struct user_regs_struct *regs = &child->regs;
+    *ptr(regs, pers->reg_ip) -= 2;
+    *ptr(regs, x86pers->ax) = *ptr(regs, x86pers->orig_ax);
 }
 
 static inline int arch_set_syscall(struct ptrace_child *child,
@@ -48,12 +47,10 @@
 }
 
 static inline int arch_save_syscall(struct ptrace_child *child) {
-    child->saved_syscall = *ptr(&child->user, x86_pers(child)->orig_ax);
+    child->saved_syscall = *ptr(&child->regs, x86_pers(child)->orig_ax);
     return 0;
 }
 
 static inline int arch_restore_syscall(struct ptrace_child *child) {
     return 0;
 }
-
-#undef ptr
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reptyr-reptyr-0.6.2/platform/linux/linux.c 
new/reptyr-reptyr-0.7.0/platform/linux/linux.c
--- old/reptyr-reptyr-0.6.2/platform/linux/linux.c      2015-02-01 
02:14:27.000000000 +0100
+++ new/reptyr-reptyr-0.7.0/platform/linux/linux.c      2018-12-05 
04:48:42.000000000 +0100
@@ -46,13 +46,6 @@
     }
     out->ctty = dev;
 
-    struct stat st;
-    if (fstat(statfd, &st) != 0)
-        return assert_nonzero(errno);
-
-    out->uid = st.st_uid;
-    out->gid = st.st_gid;
-
     return 0;
 }
 
@@ -67,8 +60,51 @@
         error("Unable to open %s: %s", stat_path, strerror(errno));
         return -statfd;
     }
-
     err = parse_proc_stat(statfd, out);
+
+
+    close(statfd);
+    return err;
+}
+
+int read_uid(pid_t pid, uid_t *out) {
+    char stat_path[PATH_MAX];
+    char buf[1024];
+    int statfd;
+    int err = 0;
+    int n;
+    char *p = buf;
+
+    snprintf(stat_path, sizeof stat_path, "/proc/%d/status", pid);
+    statfd = open(stat_path, O_RDONLY);
+    if (statfd < 0) {
+        error("Unable to open %s: %s", stat_path, strerror(errno));
+        return -statfd;
+    }
+
+    if ((n = read(statfd, buf, sizeof(buf))) < 0) {
+        err = assert_nonzero(errno);
+        goto out;
+    }
+    while (p < buf + n) {
+        if (strncmp(p, "Uid:\t", strlen("Uid:\t")) == 0)
+            break;
+        p = memchr(p, '\n', buf+n-p);
+        if (p == NULL)
+            break;
+        p++;
+        continue;
+    }
+    if (p == NULL || p >= buf + n) {
+        debug("Unable to parse emulator uid: no Uid line found");
+        *out = -1;
+        goto out;
+    }
+    if(sscanf(p, "Uid:\t%d", out) < 0) {
+        debug("Unable to parse emulator uid: unparseable Uid line");
+    }
+
+ out:
     close(statfd);
     return err;
 }
@@ -148,7 +184,7 @@
                 memcpy(pid_stat.comm, "???", 4);
             }
             error("Process %d (%.*s) shares %d's process group. Unable to 
attach.\n"
-                  "(This most commonly means that %d has suprocesses).",
+                  "(This most commonly means that %d has sub-processes).",
                   (int)pid, TASK_COMM_LENGTH, pid_stat.comm, (int)target, 
(int)target);
             err = EINVAL;
             goto out;
@@ -192,9 +228,10 @@
     }
 
     if (stat("/dev/console", &console_st) < 0) {
-        child->error = errno;
         error("Unable to stat /dev/console");
-        return NULL;
+        console_st = (struct stat){
+            .st_rdev = -1,
+        };
     }
 
     snprintf(buf, sizeof buf, "/proc/%d/fd/", child->pid);
@@ -237,6 +274,9 @@
     if ((err = find_terminal_emulator(steal)))
         return err;
 
+    if ((err = read_uid(steal->emulator_pid, &steal->emulator_uid)))
+        return err;
+
     return 0;
 }
 
@@ -362,7 +402,7 @@
 }
 
 void copy_user(struct ptrace_child *d, struct ptrace_child *s) {
-    memcpy(&d->user, &s->user, sizeof(s->user));
+    memcpy(&d->regs, &s->regs, sizeof(s->regs));
 }
 
 unsigned long ptrace_socketcall(struct ptrace_child *child,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reptyr-reptyr-0.6.2/platform/linux/linux.h 
new/reptyr-reptyr-0.7.0/platform/linux/linux.h
--- old/reptyr-reptyr-0.6.2/platform/linux/linux.h      2015-02-01 
02:14:27.000000000 +0100
+++ new/reptyr-reptyr-0.7.0/platform/linux/linux.h      2018-12-05 
04:48:42.000000000 +0100
@@ -24,6 +24,14 @@
 #define LINUX_H
 
 #ifdef __linux__
+
+// Important that we include <sys/wait.h> before <linux/*>, for
+// compatibility with certain older libcs, in which <linux/wait.h>
+// #define's some symbols that <sys/wait.h> defines via
+// `enum. c.f. https://bugs.launchpad.net/ubuntu/+source/eglibc/+bug/1261872/
+// and https://github.com/nelhage/reptyr/issues/67
+#include <sys/wait.h>
+
 #include <linux/major.h>
 #include <linux/net.h>
 #include <linux/limits.h>
@@ -32,8 +40,8 @@
 #include <sys/ptrace.h>
 #include <asm/ptrace.h>
 #include <sys/types.h>
+#include <sys/sysmacros.h>
 #include <sys/user.h>
-#include <sys/wait.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <stdio.h>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reptyr-reptyr-0.6.2/platform/linux/linux_ptrace.c 
new/reptyr-reptyr-0.7.0/platform/linux/linux_ptrace.c
--- old/reptyr-reptyr-0.6.2/platform/linux/linux_ptrace.c       2015-02-01 
02:14:27.000000000 +0100
+++ new/reptyr-reptyr-0.7.0/platform/linux/linux_ptrace.c       2018-12-05 
04:48:42.000000000 +0100
@@ -22,6 +22,7 @@
 
 #ifdef __linux__
 
+#include <elf.h>
 #include "../../ptrace.h"
 #include "../platform.h"
 
@@ -47,12 +48,18 @@
        typeof(y) _min2 = (y);                  \
        _min1 < _min2 ? _min1 : _min2; })
 
+#ifdef PTRACE_TRACEME
+static long __ptrace_command(struct ptrace_child *child, int req,
+                             void *, void*);
+#else
 static long __ptrace_command(struct ptrace_child *child, enum __ptrace_request 
req,
                              void *, void*);
+#endif
 
 #define ptrace_command(cld, req, ...) _ptrace_command(cld, req, ## 
__VA_ARGS__, NULL, NULL)
 #define _ptrace_command(cld, req, addr, data, ...) __ptrace_command((cld), 
(req), (void*)(addr), (void*)(data))
 
+#define ptr(regs, off) ((unsigned long*)((void*)(regs)+(off)))
 
 struct ptrace_personality {
     size_t syscall_rv;
@@ -73,6 +80,10 @@
 #include "arch/i386.h"
 #elif defined(__arm__)
 #include "arch/arm.h"
+#elif defined(__aarch64__)
+#include "arch/aarch64.h"
+#elif defined(__powerpc__)
+#include "arch/powerpc.h"
 #else
 #error Unsupported architecture.
 #endif
@@ -195,7 +206,12 @@
 int ptrace_save_regs(struct ptrace_child *child) {
     if (ptrace_advance_to_state(child, ptrace_at_syscall) < 0)
         return -1;
-    if (ptrace_command(child, PTRACE_GETREGS, 0, &child->user) < 0)
+
+    struct iovec reg_iovec = {
+        .iov_base = &child->regs,
+        .iov_len = sizeof(child->regs)
+    };
+    if (ptrace_command(child, PTRACE_GETREGSET, NT_PRSTATUS, &reg_iovec) < 0)
         return -1;
     arch_fixup_regs(child);
     if (arch_save_syscall(child) < 0)
@@ -205,7 +221,11 @@
 
 int ptrace_restore_regs(struct ptrace_child *child) {
     int err;
-    err = ptrace_command(child, PTRACE_SETREGS, 0, &child->user);
+    struct iovec reg_iovec = {
+        .iov_base = &child->regs,
+        .iov_len = sizeof(child->regs)
+    };
+    err = ptrace_command(child, PTRACE_SETREGSET, NT_PRSTATUS, &reg_iovec);
     if (err < 0)
         return err;
     return arch_restore_syscall(child);
@@ -220,15 +240,21 @@
     if (ptrace_advance_to_state(child, ptrace_at_syscall) < 0)
         return -1;
 
-#define setreg(r, v) do {                                               \
-        if (ptrace_command(child, PTRACE_POKEUSER,                      \
-                           personality(child)->r,                       \
-                           (v)) < 0)                                    \
-            return -1;                                                  \
-    } while (0)
-
     if (arch_set_syscall(child, sysno) < 0)
         return -1;
+
+    typeof(child->regs) regs;
+
+    struct iovec reg_iovec = {
+        .iov_base = &regs,
+        .iov_len = sizeof(regs)
+    };
+
+#define setreg(r, v) (*ptr(&regs, (personality(child)->r))) = (v)
+
+    if (ptrace_command(child, PTRACE_GETREGSET, NT_PRSTATUS, &reg_iovec) < 0)
+        return -1;
+
     setreg(syscall_arg0, p0);
     setreg(syscall_arg1, p1);
     setreg(syscall_arg2, p2);
@@ -236,16 +262,21 @@
     setreg(syscall_arg4, p4);
     setreg(syscall_arg5, p5);
 
+    if (ptrace_command(child, PTRACE_SETREGSET, NT_PRSTATUS, &reg_iovec) < 0)
+        return -1;
+
     if (ptrace_advance_to_state(child, ptrace_after_syscall) < 0)
         return -1;
 
-    rv = ptrace_command(child, PTRACE_PEEKUSER,
-                        personality(child)->syscall_rv);
-    if (child->error)
+    if (ptrace_command(child, PTRACE_GETREGSET, NT_PRSTATUS, &reg_iovec) < 0)
         return -1;
 
-    setreg(reg_ip, *(unsigned long*)((void*)&child->user +
-                                     personality(child)->reg_ip));
+    rv = *ptr(&regs, (personality(child)->syscall_rv));
+
+    setreg(reg_ip, *(unsigned long*)((void*)&child->regs + 
personality(child)->reg_ip));
+
+    if (ptrace_command(child, PTRACE_SETREGSET, NT_PRSTATUS, &reg_iovec) < 0)
+        return -1;
 
 #undef setreg
 
@@ -293,8 +324,13 @@
     return 0;
 }
 
+#ifdef PTRACE_TRACEME
+static long __ptrace_command(struct ptrace_child *child, int req,
+                             void *addr, void *data) {
+#else
 static long __ptrace_command(struct ptrace_child *child, enum __ptrace_request 
req,
                              void *addr, void *data) {
+#endif
     long rv;
     errno = 0;
     rv = ptrace(req, child->pid, addr, data);
@@ -302,31 +338,4 @@
     return rv;
 }
 
-
-#ifdef BUILD_PTRACE_MAIN
-int main(int argc, char **argv) {
-    struct ptrace_child child;
-    pid_t pid;
-
-    if (argc < 2) {
-        printf("Usage: %s pid\n", argv[0]);
-        return 1;
-    }
-    pid = atoi(argv[1]);
-
-    assert(!ptrace_attach_child(&child, pid));
-    assert(!ptrace_save_regs(&child));
-
-    printf("mmap = %lx\n", ptrace_remote_syscall(&child, mmap_syscall, 0,
-            4096, PROT_READ | PROT_WRITE,
-            MAP_ANONYMOUS | MAP_PRIVATE, 0, 0));
-
-    reset_user_struct(&child.user);
-    assert(!ptrace_restore_regs(&child));
-    assert(!ptrace_detach_child(&child));
-
-    return 0;
-}
-#endif
-
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reptyr-reptyr-0.6.2/platform/platform.h 
new/reptyr-reptyr-0.7.0/platform/platform.h
--- old/reptyr-reptyr-0.6.2/platform/platform.h 2015-02-01 02:14:27.000000000 
+0100
+++ new/reptyr-reptyr-0.7.0/platform/platform.h 2018-12-05 04:48:42.000000000 
+0100
@@ -23,6 +23,10 @@
 #ifndef PLATFORM_H
 #define PLATFORM_H
 
+#ifdef __APPLE__
+#error "reptyr does not currently support macOS"
+#endif
+
 #include "linux/linux.h"
 #include "freebsd/freebsd.h"
 #include "../ptrace.h"
@@ -45,14 +49,14 @@
     char state;
     pid_t ppid, sid, pgid;
     dev_t ctty;
-    uid_t uid;
-    gid_t gid;
 };
 
 struct steal_pty_state {
     struct proc_stat target_stat;
 
     pid_t emulator_pid;
+    uid_t emulator_uid;
+
     struct fd_array master_fds;
 
     char tmpdir[PATH_MAX];
@@ -75,7 +79,7 @@
 int *get_child_tty_fds(struct ptrace_child *child, int statfd, int *count);
 int get_terminal_state(struct steal_pty_state *steal, pid_t target);
 int find_master_fd(struct steal_pty_state *steal);
-int get_pt();
+int get_pt(void);
 int get_process_tty_termios(pid_t pid, struct termios *tio);
 void move_process_group(struct ptrace_child *child, pid_t from, pid_t to);
 void copy_user(struct ptrace_child *d, struct ptrace_child *s);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reptyr-reptyr-0.6.2/ptrace.h 
new/reptyr-reptyr-0.7.0/ptrace.h
--- old/reptyr-reptyr-0.6.2/ptrace.h    2015-02-01 02:14:27.000000000 +0100
+++ new/reptyr-reptyr-0.7.0/ptrace.h    2018-12-05 04:48:42.000000000 +0100
@@ -63,9 +63,14 @@
     unsigned long forked_pid;
     unsigned long saved_syscall;
 #ifdef __linux__
-       struct user user;
+#ifdef __arm__
+    struct user_regs regs;
+#elif defined(__powerpc__)
+    struct pt_regs regs;
+#else
+    struct user_regs_struct regs;
 #endif
-#ifdef __FreeBSD__
+#elif defined(__FreeBSD__)
        struct reg regs;
 #endif
 };
@@ -78,13 +83,15 @@
     long nr_setsid;
     long nr_setpgid;
     long nr_fork;
+    long nr_clone;
     long nr_wait4;
     long nr_signal;
     long nr_rt_sigaction;
-    long nr_open;
+    long nr_openat;
     long nr_close;
     long nr_ioctl;
     long nr_dup2;
+    long nr_dup3;
     long nr_socket;
     long nr_connect;
     long nr_sendmsg;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reptyr-reptyr-0.6.2/reptyr.bash 
new/reptyr-reptyr-0.7.0/reptyr.bash
--- old/reptyr-reptyr-0.6.2/reptyr.bash 1970-01-01 01:00:00.000000000 +0100
+++ new/reptyr-reptyr-0.7.0/reptyr.bash 2018-12-05 04:48:42.000000000 +0100
@@ -0,0 +1,19 @@
+# bash completion for reptyr(1)
+
+_reptyr()
+{
+    case $3 in
+        -l|-L|-h|-v) return ;;
+    esac
+
+    if [[ $2 == -* ]]; then
+        COMPREPLY=( $(compgen -W '-l -L -s -T -h -v -V' -- "$2") )
+        return
+    fi
+
+    case $3 in
+        [1-9]*) ;;
+        *) COMPREPLY=( $(compgen -W '$(command ps axo pid=)' -- "$2") ) ;;
+    esac
+} &&
+complete -F _reptyr reptyr
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reptyr-reptyr-0.6.2/reptyr.c 
new/reptyr-reptyr-0.7.0/reptyr.c
--- old/reptyr-reptyr-0.6.2/reptyr.c    2015-02-01 02:14:27.000000000 +0100
+++ new/reptyr-reptyr-0.7.0/reptyr.c    2018-12-05 04:48:42.000000000 +0100
@@ -124,23 +124,34 @@
     char buf[4096];
     ssize_t count;
     fd_set set;
-    struct timeval timeout;
+    sigset_t mask;
+    sigset_t select_mask;
+    struct sigaction sa;
+
+    // Block WINCH while we're outside the select, but unblock it
+    // while we're inside:
+    sigemptyset(&mask);
+    sigaddset(&mask, SIGWINCH);
+    if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) {
+        fprintf(stderr, "sigprocmask: %m");
+        return;
+    }
+    sa.sa_handler = do_winch;
+    sa.sa_flags = 0;
+    sigemptyset(&sa.sa_mask);
+    sigaction(SIGWINCH, &sa, NULL);
+    resize_pty(pty);
+
     while (1) {
         if (winch_happened) {
             winch_happened = 0;
-            /*
-             * FIXME: If a signal comes in after this point but before
-             * select(), the resize will be delayed until we get more
-             * input. signalfd() is probably the cleanest solution.
-             */
             resize_pty(pty);
         }
         FD_ZERO(&set);
         FD_SET(0, &set);
         FD_SET(pty, &set);
-        timeout.tv_sec = 0;
-        timeout.tv_usec = 1000;
-        if (select(pty + 1, &set, NULL, NULL, &timeout) < 0) {
+        sigemptyset(&select_mask);
+        if (pselect(pty + 1, &set, NULL, NULL, NULL, &select_mask) < 0) {
             if (errno == EINTR)
                 continue;
             fprintf(stderr, "select: %m");
@@ -179,7 +190,6 @@
 
 int main(int argc, char **argv) {
     struct termios saved_termios;
-    struct sigaction act;
     int pty;
     int opt;
     int err;
@@ -287,11 +297,6 @@
     }
 
     setup_raw(&saved_termios);
-    memset(&act, 0, sizeof act);
-    act.sa_handler = do_winch;
-    act.sa_flags   = 0;
-    sigaction(SIGWINCH, &act, NULL);
-    resize_pty(pty);
     do_proxy(pty);
     do {
         errno = 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reptyr-reptyr-0.6.2/reptyr.fr.1 
new/reptyr-reptyr-0.7.0/reptyr.fr.1
--- old/reptyr-reptyr-0.6.2/reptyr.fr.1 2015-02-01 02:14:27.000000000 +0100
+++ new/reptyr-reptyr-0.7.0/reptyr.fr.1 2018-12-05 04:48:42.000000000 +0100
@@ -51,7 +51,7 @@
 .B \-l
 .IP
 Plutôt que d'attacher un nouveau processus, crée un couveau couple de
-pty, redirige l'extrémité maîtresse vers le terminal en corus, puis
+pty, redirige l'extrémité maîtresse vers le terminal en cours, puis
 affiche le nom du pty esclave. Il pourra être passé en argument par
 exemple à l'option
 .I set inferior-tty
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reptyr-reptyr-0.6.2/reptyr.h 
new/reptyr-reptyr-0.7.0/reptyr.h
--- old/reptyr-reptyr-0.6.2/reptyr.h    2015-02-01 02:14:27.000000000 +0100
+++ new/reptyr-reptyr-0.7.0/reptyr.h    2018-12-05 04:48:42.000000000 +0100
@@ -20,7 +20,7 @@
  * THE SOFTWARE.
  */
 
-#define REPTYR_VERSION "0.6.2"
+#define REPTYR_VERSION "0.7.0"
 
 #define assert_nonzero(expr) ({                         \
             typeof(expr) __val = expr;                  \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reptyr-reptyr-0.6.2/test/basic.py 
new/reptyr-reptyr-0.7.0/test/basic.py
--- old/reptyr-reptyr-0.6.2/test/basic.py       2015-02-01 02:14:27.000000000 
+0100
+++ new/reptyr-reptyr-0.7.0/test/basic.py       2018-12-05 04:48:42.000000000 
+0100
@@ -1,11 +1,14 @@
 import pexpect
+import sys
 
 child = pexpect.spawn("test/victim")
+child.logfile = sys.stdout
 child.setecho(False)
 child.sendline("hello")
 child.expect("ECHO: hello")
 
-reptyr = pexpect.spawn("./reptyr %d" % (child.pid,))
+reptyr = pexpect.spawn("./reptyr -V %d" % (child.pid,))
+reptyr.logfile = sys.stdout
 reptyr.sendline("world")
 reptyr.expect("ECHO: world")
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reptyr-reptyr-0.6.2/test/requirements.txt 
new/reptyr-reptyr-0.7.0/test/requirements.txt
--- old/reptyr-reptyr-0.6.2/test/requirements.txt       1970-01-01 
01:00:00.000000000 +0100
+++ new/reptyr-reptyr-0.7.0/test/requirements.txt       2018-12-05 
04:48:42.000000000 +0100
@@ -0,0 +1,2 @@
+pexpect
+python-prctl>1.6
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reptyr-reptyr-0.6.2/test/tty-steal.py 
new/reptyr-reptyr-0.7.0/test/tty-steal.py
--- old/reptyr-reptyr-0.6.2/test/tty-steal.py   2015-02-01 02:14:27.000000000 
+0100
+++ new/reptyr-reptyr-0.7.0/test/tty-steal.py   2018-12-05 04:48:42.000000000 
+0100
@@ -3,15 +3,31 @@
 import sys
 
 if os.getenv("NO_TEST_STEAL") is not None:
-    print "Skipping tty-stealing tests because $NO_TEST_STEAL is set."
+    print("Skipping tty-stealing tests because $NO_TEST_STEAL is set.")
     sys.exit(0)
 
+did_prctl = False
+try:
+    import prctl
+    PR_SET_PTRACER_ANY = 0xffffffff
+    if hasattr(prctl, 'set_ptracer'):
+        did_prctl = True
+        prctl.set_ptracer(PR_SET_PTRACER_ANY)
+except ImportError:
+    pass
+
+if not did_prctl:
+  print("Unable to find `prctl.set_ptracer`, skipping `PR_SET_PTRACER`.")
+
 child = pexpect.spawn("test/victim")
 child.setecho(False)
 child.sendline("hello")
 child.expect("ECHO: hello")
 
-reptyr = pexpect.spawn("./reptyr -T %d" % (child.pid,))
+reptyr = pexpect.spawn("./reptyr -V -T %d" % (child.pid,))
+print("spawned children: me={} victim={} reptyr={}".format(os.getpid(), 
child.pid, reptyr.pid))
+reptyr.logfile = sys.stdout
+
 reptyr.sendline("world")
 reptyr.expect("ECHO: world")
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reptyr-reptyr-0.6.2/test/victim.c 
new/reptyr-reptyr-0.7.0/test/victim.c
--- old/reptyr-reptyr-0.6.2/test/victim.c       2015-02-01 02:14:27.000000000 
+0100
+++ new/reptyr-reptyr-0.7.0/test/victim.c       2018-12-05 04:48:42.000000000 
+0100
@@ -1,9 +1,23 @@
 #include <stdio.h>
+#include <sys/prctl.h>
+
+#ifndef PR_SET_PTRACER
+#define PR_SET_PTRACER
+#endif
+
+#ifndef PR_SET_PTRACER_ANY
+# define PR_SET_PTRACER_ANY ((unsigned long)-1)
+#endif
 
 int main(int argc, char **argv) {
     char *line = NULL;
     size_t cap = 0;
 
+    int err = prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY);
+    if (err != 0) {
+        fprintf(stderr, "Unable to PR_SET_PTRACER: %m\n");
+    }
+
     while(getline(&line, &cap, stdin) != -1) {
         printf("ECHO: %s", line);
     }


Reply via email to