-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy path0001-osdep_get_cwd-linux-recurse-parents-until-one-yields.patch
80 lines (72 loc) · 1.87 KB
/
0001-osdep_get_cwd-linux-recurse-parents-until-one-yields.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
From 4ac7fe1acc6675ce0e569cf029aef3fa41a9ad18 Mon Sep 17 00:00:00 2001
From: "Chris West (Faux)" <[email protected]>
Date: Fri, 21 Mar 2014 23:38:23 +0000
Subject: [PATCH] osdep_get_cwd: linux: recurse parents until one yields
This helps when a command is running as a different user, it is common
to be able to see its parents, but not its cwd. It may make sense, in
this situation, to present the parent's path. e.g. if a user runs a set
of commands like:
$ cd /foo/bar
$ sudo hang-for-a-bit
.. it could be expected that get_cwd returns "/foo/bar", not NULL, as
previously. sudo's cwd is not available, as the process itself is
running as root, but its parent process is, and its parent (the shell)'s
cwd is available to us.
---
osdep-linux.c | 38 +++++++++++++++++++++++++++++++-------
1 file changed, 31 insertions(+), 7 deletions(-)
diff --git a/osdep-linux.c b/osdep-linux.c
index ccac267..91d0e5d 100644
--- a/osdep-linux.c
+++ b/osdep-linux.c
@@ -60,6 +60,26 @@ osdep_get_name(int fd, unused char *tty)
return (buf);
}
+// 0 on failure
+pid_t
+parent_pid_of(pid_t pid) {
+ char *path;
+ FILE *f;
+ pid_t ret = 0;
+
+ xasprintf(&path, "/proc/%lld/stat", (long long) pid);
+ f = fopen(path, "r");
+ if (!f)
+ return 0;
+
+ if (1 != fscanf(f, "%*d %*s %*c %d", &ret)) {
+ ret = 0;
+ }
+
+ fclose(f);
+ return ret;
+}
+
char *
osdep_get_cwd(int fd)
{
@@ -71,13 +91,17 @@ osdep_get_cwd(int fd)
if ((pgrp = tcgetpgrp(fd)) == -1)
return (NULL);
- xasprintf(&path, "/proc/%lld/cwd", (long long) pgrp);
- n = readlink(path, target, MAXPATHLEN);
- free(path);
- if (n > 0) {
- target[n] = '\0';
- return (target);
- }
+ do {
+ xasprintf(&path, "/proc/%lld/cwd", (long long) pgrp);
+ n = readlink(path, target, MAXPATHLEN);
+ free(path);
+ if (n > 0) {
+ target[n] = '\0';
+ return (target);
+ }
+ pgrp = parent_pid_of(pgrp);
+ } while (pgrp);
+
return (NULL);
}
--
1.9.1