99#import < AppKit/AppKit.h>
1010#include < sys/sysctl.h>
1111#include < sys/proc_info.h>
12+ #include < libproc.h>
1213#include < pwd.h>
1314#import " Process.h"
1415#import " Service.h"
@@ -156,9 +157,7 @@ static int GetBSDProcessList(kinfo_proc **procList, size_t *procCount)
156157 // Call sysctl with a NULL buffer.
157158
158159 length = 0 ;
159- err = sysctl ( (int *) name, (sizeof (name) / sizeof (*name)) - 1 ,
160- NULL , &length,
161- NULL , 0 );
160+ err = sysctl ( (int *) name, (sizeof (name) / sizeof (*name)) - 1 , NULL , &length, NULL , 0 );
162161 if (err == -1 ) {
163162 err = errno;
164163 }
@@ -177,9 +176,7 @@ static int GetBSDProcessList(kinfo_proc **procList, size_t *procCount)
177176 // error, toss away our buffer and start again.
178177
179178 if (err == 0 ) {
180- err = sysctl ( (int *) name, (sizeof (name) / sizeof (*name)) - 1 ,
181- result, &length,
182- NULL , 0 );
179+ err = sysctl ( (int *) name, (sizeof (name) / sizeof (*name)) - 1 , result, &length, NULL , 0 );
183180 if (err == -1 ) {
184181 err = errno;
185182 }
@@ -192,6 +189,7 @@ static int GetBSDProcessList(kinfo_proc **procList, size_t *procCount)
192189 err = 0 ;
193190 }
194191 }
192+
195193 } while (err == 0 && ! done);
196194
197195 // Clean up and establish post conditions.
@@ -206,10 +204,29 @@ static int GetBSDProcessList(kinfo_proc **procList, size_t *procCount)
206204 }
207205
208206 assert ( (err == 0 ) == (*procList != NULL ) );
209-
210207 return err;
211208}
212209
210+ /* *
211+ see https://stackoverflow.com/questions/12273546/get-name-from-pid/12274588#12274588
212+ */
213+ static char * getBSDProcessName ( pid_t pid ) {
214+
215+ char pathBuffer [PROC_PIDPATHINFO_MAXSIZE];
216+ proc_pidpath (pid, pathBuffer, sizeof (pathBuffer));
217+
218+ long strLen = strlen (pathBuffer);
219+ long position = strLen;
220+ while (position >= 0 && pathBuffer[position] != ' /' )
221+ {
222+ position--;
223+ }
224+
225+ char *nameBuffer = (char *) malloc (sizeof (char ) * ( strLen - position +1 ));
226+ strcpy (nameBuffer, pathBuffer + position + 1 );
227+ return nameBuffer;
228+ }
229+
213230+ (NSArray *)getBSDProcessList
214231{
215232 kinfo_proc *mylist =NULL ;
@@ -225,8 +242,15 @@ + (NSArray*)getBSDProcessList
225242
226243 NSNumber *processID = [NSNumber numberWithInt: currentProcess->kp_proc.p_pid];
227244 NSString *processName = [NSString stringWithFormat: @" %s " ,currentProcess->kp_proc.p_comm];
228-
229- if (processID)[entry setObject: processID forKey: @" processID" ];
245+
246+ if (processID) {
247+ [entry setObject: processID forKey: @" processID" ];
248+
249+ // if there is a process id we'll try to figure out the process name using another function
250+ // the reason is, that the kinfo_proc->p_comm is shortened and even ps uses this kind of API to retrieve the full name.
251+ processName = [NSString stringWithFormat: @" %s " ,getBSDProcessName (currentProcess->kp_proc.p_pid)];
252+ }
253+
230254 if (processName)[entry setObject: processName forKey: @" processName" ];
231255
232256 if (user){
@@ -240,16 +264,15 @@ + (NSArray*)getBSDProcessList
240264 [processes addObject: [NSDictionary dictionaryWithDictionary: entry]];
241265 }
242266 free (mylist);
243-
267+
244268 return [NSArray arrayWithArray: processes];
245269}
246270
247271+ (NSDictionary *)getProcessByService : (Service *)service {
248272
249273 for ( NSDictionary *process in [Process getBSDProcessList ] ) {
250-
274+
251275 if ( [[process objectForKey: @" processName" ] isEqualToString: [[service program ] lastPathComponent ]] ) {
252-
253276 NSString *path = @" /bin/ps" ;
254277 NSArray *args = [NSArray arrayWithObjects: @" -o" , @" command=" ,[(NSNumber *)[process objectForKey: @" processID" ] stringValue ], nil ];
255278 NSTask *task = [[NSTask alloc ] init ];
0 commit comments