1
1
#define _GNU_SOURCE
2
+ #include <errno.h>
2
3
#include <fcntl.h>
3
4
#include <stdlib.h>
4
5
#include <string.h>
@@ -20,6 +21,42 @@ __attribute__((visibility("default"))) ssize_t readlink(const char *restrict pat
20
21
memcpy (buf , termux_self_exe , bytes_to_copy );
21
22
return bytes_to_copy ;
22
23
}
24
+ } else if (strncmp (pathname , "/proc/" , strlen ("/proc/" )) == 0 ) {
25
+ // See if /proc/$PID/exe is being resolved.
26
+ size_t path_len = strlen (pathname );
27
+ if (pathname [path_len - 4 ] == '/' && pathname [path_len - 3 ] == 'e' && pathname [path_len - 2 ] == 'x' &&
28
+ pathname [path_len - 1 ] == 'e' && path_len < 30 ) {
29
+ char environ_path_buf [PATH_MAX ];
30
+ memcpy (environ_path_buf , pathname , path_len - 3 );
31
+ memcpy (environ_path_buf + (path_len - 3 ), "environ" , sizeof ("environ" ));
32
+ int environ_fd = TEMP_FAILURE_RETRY (open (environ_path_buf , O_RDONLY ));
33
+ if (environ_fd > 0 ) {
34
+ char environ_buf [16 * 4096 ];
35
+ ssize_t environ_size = TEMP_FAILURE_RETRY (read (environ_fd , environ_buf , sizeof (environ_buf )));
36
+ close (environ_fd );
37
+ if (environ_size > 0 ) {
38
+ size_t start_offset = 0 ;
39
+ for (size_t i = 0 ; i < (size_t )environ_size ; i ++ ) {
40
+ if (environ_buf [i ] == 0 && start_offset != i ) {
41
+ if (strncmp (& environ_buf [start_offset ],
42
+ "TERMUX_EXEC__PROC_SELF_EXE=" , strlen ("TERMUX_EXEC__PROC_SELF_EXE=" )) == 0 ) {
43
+ char * termux_self_exe = & environ_buf [start_offset + strlen ("TERMUX_EXEC__PROC_SELF_EXE=" )];
44
+ char resolved_path_buf [PATH_MAX ];
45
+ char * resolved_path = realpath (termux_self_exe , resolved_path_buf );
46
+ if (resolved_path ) {
47
+ termux_self_exe = resolved_path_buf ;
48
+ }
49
+ size_t termux_self_exe_len = strlen (termux_self_exe );
50
+ size_t bytes_to_copy = (termux_self_exe_len < bufsiz ) ? termux_self_exe_len : bufsiz ;
51
+ memcpy (buf , termux_self_exe , bytes_to_copy );
52
+ return bytes_to_copy ;
53
+ }
54
+ start_offset = i + 1 ;
55
+ }
56
+ }
57
+ }
58
+ }
59
+ }
23
60
}
24
61
25
62
return syscall (SYS_readlinkat , AT_FDCWD , pathname , buf , bufsiz );
0 commit comments