From b9de6e35b79cbc10909a856df6b1caa770bd4ac4 Mon Sep 17 00:00:00 2001
From: Po Lu
Date: Mon, 1 May 2023 21:23:12 +0800
Subject: Fix cwd relative process execution on Android
* exec/exec.c (format_pid): New function.
(exec_0): Make cwd relative file names relative to
/proc/pid/cwd.
* exec/trace.c (handle_exec): Handle EINTR.
(process_system_call): Report failure without clobbering x0.
---
exec/exec.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 53 insertions(+)
(limited to 'exec/exec.c')
diff --git a/exec/exec.c b/exec/exec.c
index 662c8bf69d2..c7a73f221f5 100644
--- a/exec/exec.c
+++ b/exec/exec.c
@@ -26,6 +26,7 @@ along with GNU Emacs. If not, see . */
#include
#include
#include
+#include
#include
#include
@@ -808,6 +809,35 @@ insert_args (struct exec_tracee *tracee, USER_REGS_STRUCT *regs,
+/* Format PID, an unsigned process identifier, in base 10. Place the
+ result in *IN, and return a pointer to the byte after the
+ result. REM should be NULL. */
+
+static char *
+format_pid (char *in, unsigned int pid)
+{
+ unsigned int digits[32], *fill;
+
+ fill = digits;
+
+ for (; pid != 0; pid = pid / 10)
+ *fill++ = pid % 10;
+
+ /* Insert 0 if the number would otherwise be empty. */
+
+ if (fill == digits)
+ *fill++ = 0;
+
+ while (fill != digits)
+ {
+ --fill;
+ *in++ = '0' + *fill;
+ }
+
+ *in = '\0';
+ return in;
+}
+
/* Return a sequence of actions required to load the executable under
the file NAME for the given TRACEE. First, see if the file starts
with #!; in that case, find the program to open and use that
@@ -836,6 +866,29 @@ exec_0 (const char *name, struct exec_tracee *tracee,
#if defined __mips__ && !defined MIPS_NABI
int fpu_mode;
#endif /* defined __mips__ && !defined MIPS_NABI */
+ char buffer[PATH_MAX + 80], *rewrite;
+ size_t remaining;
+
+ /* If name is not absolute, then make it relative to TRACEE's
+ cwd. Use stpcpy, as sprintf is not reentrant. */
+
+ if (name[0] && name[0] != '/')
+ {
+ /* Clear `buffer'. */
+ memset (buffer, 0, sizeof buffer);
+
+ /* Copy over /proc, the PID, and /cwd/. */
+ rewrite = stpcpy (buffer, "/proc/");
+ rewrite = format_pid (rewrite, tracee->pid);
+ rewrite = stpcpy (rewrite, "/cwd/");
+
+ /* Make sure there is enough free space. */
+ remaining = buffer + sizeof buffer - rewrite - 1;
+ rewrite = stpncpy (rewrite, name, remaining);
+
+ /* Replace name with buffer. */
+ name = buffer;
+ }
fd = open (name, O_RDONLY);
if (fd < 0)
--
cgit v1.2.1