33#include "common/io/io.h"
44#include "common/time.h"
55#include "util/stringUtils.h"
6+ #include "util/mallocHelper.h"
67
78#include <stdlib.h>
89#include <unistd.h>
1718 #include <sys/user.h>
1819 #include <sys/sysctl.h>
1920#endif
21+ #ifdef __APPLE__
22+ #include <libproc.h>
23+ #endif
2024
2125enum { FF_PIPE_BUFSIZ = 8192 };
2226
@@ -119,28 +123,31 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons
119123 char filePath [64 ];
120124 snprintf (filePath , sizeof (filePath ), "/proc/%d/cmdline" , (int )pid );
121125
122- if (ffAppendFileBuffer (filePath , exe ))
126+ if (ffReadFileBuffer (filePath , exe ))
123127 {
124- ffStrbufTrimRightSpace (exe );
125128 ffStrbufRecalculateLength (exe ); //Trim the arguments
129+ ffStrbufTrimRightSpace (exe );
126130 ffStrbufTrimLeft (exe , '-' ); //Login shells start with a dash
127131 }
128132
129- snprintf (filePath , sizeof (filePath ), "/proc/%d/exe" , (int )pid );
130- ffStrbufEnsureFixedLengthFree (exePath , PATH_MAX );
131- ssize_t length = readlink (filePath , exePath -> chars , exePath -> allocated - 1 );
132- if (length > 0 ) // doesn't contain trailing NUL
133+ if (exePath )
133134 {
134- exePath -> chars [length ] = '\0' ;
135- exePath -> length = (uint32_t ) length ;
135+ snprintf (filePath , sizeof (filePath ), "/proc/%d/exe" , (int )pid );
136+ ffStrbufEnsureFixedLengthFree (exePath , PATH_MAX );
137+ ssize_t length = readlink (filePath , exePath -> chars , exePath -> allocated - 1 );
138+ if (length > 0 ) // doesn't contain trailing NUL
139+ {
140+ exePath -> chars [length ] = '\0' ;
141+ exePath -> length = (uint32_t ) length ;
142+ }
136143 }
137144
138145 #elif defined(__APPLE__ )
139146
140147 size_t len = 0 ;
141148 int mibs [] = { CTL_KERN , KERN_PROCARGS2 , pid };
142149 if (sysctl (mibs , sizeof (mibs ) / sizeof (* mibs ), NULL , & len , NULL , 0 ) == 0 )
143- {
150+ {// try get arg0
144151 #ifndef MAC_OS_X_VERSION_10_15
145152 //don't know why if don't let len longer, proArgs2 and len will change during the following sysctl() in old MacOS version.
146153 len ++ ;
@@ -153,7 +160,8 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons
153160 const char * realExePath = procArgs2 + sizeof (argc );
154161
155162 const char * arg0 = memchr (realExePath , '\0' , len - (size_t ) (realExePath - procArgs2 ));
156- ffStrbufSetNS (exePath , (uint32_t ) (arg0 - realExePath ), realExePath );
163+ if (exePath )
164+ ffStrbufSetNS (exePath , (uint32_t ) (arg0 - realExePath ), realExePath );
157165
158166 do arg0 ++ ; while (* arg0 == '\0' );
159167 assert (arg0 < procArgs2 + len );
@@ -162,6 +170,17 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons
162170 ffStrbufSetS (exe , arg0 );
163171 }
164172 }
173+ else
174+ {
175+ ffStrbufEnsureFixedLengthFree (exe , PATH_MAX );
176+ int length = proc_pidpath (pid , exe -> chars , exe -> allocated );
177+ if (length > 0 )
178+ {
179+ exe -> length = (uint32_t ) length ;
180+ if (exePath )
181+ ffStrbufSet (exePath , exe );
182+ }
183+ }
165184
166185 #elif defined(__FreeBSD__ )
167186
@@ -170,7 +189,7 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons
170189
171190 static_assert (ARG_MAX > PATH_MAX , "" );
172191
173- if (sysctl (
192+ if (exePath && sysctl (
174193 (int []){CTL_KERN , KERN_PROC , KERN_PROC_PATHNAME , pid }, 4 ,
175194 args , & size ,
176195 NULL , 0
@@ -213,34 +232,46 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons
213232 * exeName = exe -> chars + lastSlashIndex + 1 ;
214233}
215234
216- const char * ffProcessGetBasicInfoLinux (pid_t pid , char * name , pid_t * ppid , int32_t * tty )
235+ const char * ffProcessGetBasicInfoLinux (pid_t pid , FFstrbuf * name , pid_t * ppid , int32_t * tty )
217236{
218237 if (pid <= 0 )
219238 return "Invalid pid" ;
220239
221240 #ifdef __linux__
222241
223- char statFilePath [64 ];
224- snprintf (statFilePath , sizeof (statFilePath ), "/proc/%d/stat" , (int )pid );
225- char buf [PROC_FILE_BUFFSIZ ];
226- ssize_t nRead = ffReadFileData (statFilePath , sizeof (buf ) - 1 , buf );
227- if (nRead < 0 )
228- return "ffReadFileData(statFilePath, sizeof(buf)-1, buf) failed" ;
229- buf [nRead ] = '\0' ;
230-
231- * ppid = 0 ;
232- static_assert (sizeof (* ppid ) == sizeof (int ), "" );
233-
234- int tty_ ;
235- if (
236- sscanf (buf , "%*s (%255[^)]) %*c %d %*d %*d %d" , name , ppid , & tty_ ) < 2 || //stat (comm) state ppid pgrp session tty
237- !ffStrSet (name ) ||
238- * ppid == 0
239- )
240- return "sscanf(stat) failed" ;
241-
242- if (tty )
243- * tty = tty_ & 0xFF ;
242+ char procFilePath [64 ];
243+ if (ppid )
244+ {
245+ snprintf (procFilePath , sizeof (procFilePath ), "/proc/%d/stat" , (int )pid );
246+ char buf [PROC_FILE_BUFFSIZ ];
247+ ssize_t nRead = ffReadFileData (procFilePath , sizeof (buf ) - 1 , buf );
248+ if (nRead < 0 )
249+ return "ffReadFileData(/proc/pid/stat, PROC_FILE_BUFFSIZ-1, buf) failed" ;
250+ buf [nRead ] = '\0' ;
251+
252+ * ppid = 0 ;
253+ static_assert (sizeof (* ppid ) == sizeof (int ), "" );
254+
255+ ffStrbufEnsureFixedLengthFree (name , 255 );
256+ int tty_ ;
257+ if (
258+ sscanf (buf , "%*s (%255[^)]) %*c %d %*d %*d %d" , name -> chars , ppid , & tty_ ) < 2 || //stat (comm) state ppid pgrp session tty
259+ name -> chars [0 ] == '\0'
260+ )
261+ return "sscanf(stat) failed" ;
262+
263+ ffStrbufRecalculateLength (name );
264+ if (tty )
265+ * tty = tty_ & 0xFF ;
266+ }
267+ else
268+ {
269+ snprintf (procFilePath , sizeof (procFilePath ), "/proc/%d/comm" , (int )pid );
270+ ssize_t nRead = ffReadFileBuffer (procFilePath , name );
271+ if (nRead < 0 )
272+ return "ffReadFileBuffer(/proc/pid/comm, name) failed" ;
273+ ffStrbufTrimRightSpace (name );
274+ }
244275
245276 #elif defined(__APPLE__ )
246277
@@ -253,8 +284,9 @@ const char* ffProcessGetBasicInfoLinux(pid_t pid, char* name, pid_t* ppid, int32
253284 ))
254285 return "sysctl(KERN_PROC_PID) failed" ;
255286
256- * ppid = (pid_t )proc .kp_eproc .e_ppid ;
257- strcpy (name , proc .kp_proc .p_comm ); //trancated to 16 chars
287+ ffStrbufSetS (name , proc .kp_proc .p_comm ); //trancated to 16 chars
288+ if (ppid )
289+ * ppid = (pid_t )proc .kp_eproc .e_ppid ;
258290 if (tty )
259291 {
260292 * tty = ((proc .kp_eproc .e_tdev >> 24 ) & 0xFF ) == 0x10
@@ -273,8 +305,9 @@ const char* ffProcessGetBasicInfoLinux(pid_t pid, char* name, pid_t* ppid, int32
273305 ))
274306 return "sysctl(KERN_PROC_PID) failed" ;
275307
276- * ppid = (pid_t )proc .ki_ppid ;
277- strcpy (name , proc .ki_comm );
308+ ffStrbufSetS (name , proc .ki_comm );
309+ if (ppid )
310+ * ppid = (pid_t )proc .ki_ppid ;
278311 if (tty )
279312 {
280313 if (proc .ki_tdev != NODEV && proc .ki_flag & P_CONTROLT )
0 commit comments