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