]> git.ipfire.org Git - people/arne_f/ipfire-3.x.git/blame - lsof/patches/lsof_4.81-threads.patch
autoconf: updated to 2.69.
[people/arne_f/ipfire-3.x.git] / lsof / patches / lsof_4.81-threads.patch
CommitLineData
071e59e9
MT
1diff -up lsof_4.81-rh/dialects/linux/dproc.c.kzak lsof_4.81-rh/dialects/linux/dproc.c
2--- lsof_4.81-rh/dialects/linux/dproc.c.kzak 2008-10-21 18:17:25.000000000 +0200
3+++ lsof_4.81-rh/dialects/linux/dproc.c 2008-12-02 10:54:54.000000000 +0100
4@@ -89,7 +89,8 @@ _PROTOTYPE(static void process_proc_map,
5 _PROTOTYPE(static int process_id,(char *idp, int idpl, char *cmd, UID_ARG uid,
6 int pid, int ppid, int pgid));
7 _PROTOTYPE(static int statEx,(char *p, struct stat *s, int *ss));
8-
9+_PROTOTYPE(static int get_other_thread,(int pid, char **tid));
10+
11
12 #if defined(HASSELINUX)
13 _PROTOTYPE(static int cmp_cntx_eq,(char *pcntx, char *ucntx));
14@@ -159,6 +160,7 @@ gather_proc_info()
15 struct dirent *dp;
16 struct stat sb;
17 int lwp, n, nl, pgid, pid, ppid, rv, tx;
18+ char *tid = NULL;
19 static char *lwppath = (char *)NULL;
20 static int lwppathl = 0;
21 static char *path = (char *)NULL;
22@@ -252,6 +254,13 @@ gather_proc_info()
23 while ((dp = readdir(ps))) {
24 if (nm2id(dp->d_name, &pid, &n))
25 continue;
26+
27+ tid = NULL;
28+ if (get_other_thread(pid, &tid) < 0)
29+ continue;
30+ if (tid)
31+ n += sizeof("task/") + strlen(tid);
32+
33 /*
34 * Build path to PID's directory.
35 */
36@@ -265,7 +274,14 @@ gather_proc_info()
37 Exit(1);
38 }
39 }
40- (void) snpf(pidpath + pidx, pidpathl - pidx, "%s/", dp->d_name);
41+ if (tid) {
42+ /* /proc/<pid> is useless (zombie), we have to use /proc/<pid>/task/<tid>
43+ * where is still running thread
44+ */
45+ (void) snpf(pidpath + pidx, pidpathl - pidx, "%s/task/%s/", dp->d_name, tid);
46+ free(tid);
47+ } else
48+ (void) snpf(pidpath + pidx, pidpathl - pidx, "%s/", dp->d_name);
49 n += (pidx + 1);
50 /*
51 * Process the PID's stat info.
52@@ -1007,6 +1023,64 @@ process_id(idp, idpl, cmd, uid, pid, ppi
53 return(0);
54 }
55
56+/* fill tid if the initial thread is zombie,
57+ * but other thread still alive
58+ *
59+ * returns -1=error, 0=nothing, 1=ok
60+ */
61+static int
62+get_other_thread(pid, tid)
63+ int pid;
64+ char **tid;
65+{
66+ char path[MAXPATHLEN];
67+ DIR *tdp;
68+ struct dirent *td;
69+ char pstate;
70+ FILE *f;
71+ int _pid;
72+ int re = 0, x;
73+
74+ snpf(path, sizeof(path), "%s/%d/stat", PROCFS, pid);
75+ if (!(f = fopen(path, "r")))
76+ return -1;
77+ x = fscanf(f, "%d %*s %c", &_pid, &pstate);
78+ fclose(f);
79+ if (x!=2)
80+ return -1;
81+ if (_pid != pid)
82+ return -1; /* corrupted /proc? */
83+ if (pstate!='Z')
84+ return 0; /* ignore normal proceses */
85+
86+ snpf(path, sizeof(path), "%s/%d/task", PROCFS, pid);
87+
88+ /* open /proc/<pid>/task */
89+ if (!(tdp = opendir(path)))
90+ return 0; /* kernel < 2.6.x */
91+
92+ /* look for first alive thread */
93+ while ((td = readdir(tdp))) {
94+ if (strcmp(td->d_name, ".")==0 || strcmp(td->d_name, "..")==0)
95+ continue;
96+
97+ /* /proc/<pid>/task/<tid>/stat */
98+ snpf(path, sizeof(path), "%s/%d/task/%s/stat", PROCFS, pid, td->d_name);
99+ if (!(f = fopen(path, "r")))
100+ continue;
101+ x = fscanf(f, "%*d %*s %c", &pstate);
102+ fclose(f);
103+ if (x!=1)
104+ continue;
105+ if (pstate!='Z') {
106+ re = 1;
107+ *tid = strdup(td->d_name);
108+ break;
109+ }
110+ }
111+ closedir(tdp);
112+ return re;
113+}
114
115 /*
116 * process_proc_map() - process the memory map of a process
117@@ -1250,12 +1324,6 @@ read_id_stat(ty, p, id, cmd, ppid, pgid)
118 return(1);
119 }
120 /*
121- * Convert the first field to an integer; its conversion must match the
122- * ID argument.
123- */
124- if (!fp[0] || (atoi(fp[0]) != id))
125- return(1);
126-/*
127 * Get the command name from the second field. Strip a starting '(' and
128 * an ending ')'. Allocate space to hold the result and return the space
129 * pointer.