Zohar81
Zohar81

Reputation: 5118

get process cmdline in MAC os from another C-based executable

I would like to find out if there's a sys call that gets remote process id and return it's command line in Mac OS X (the equivalent in linux is /proc/PID/cmdline.

I could use the following way of reading output of 'px ax PID' from file, but I believe there's a cleaner way.

enter code here
char sys_cmd[PATH_MAX];
snprintf(sys_cmd, PATH_MAX, "ps ax %d", pid);

fp = popen(sys_cmd, "r");
while (fgets(res, sizeof(res)-1, fp) != NULL) {
    printf("%s", res);
}
pclose(fp);

Upvotes: 5

Views: 1880

Answers (2)

Camden Narzt
Camden Narzt

Reputation: 2013

The correct API to do this is the KERN_PROCARGS2 sysctl, however it is very hard to use correctly (I've checked every use of this API in public code and they're all wrong), so I wrote a library to wrap its use: https://getargv.narzt.cam

Upvotes: 0

Dan
Dan

Reputation: 7737

Depending on exactly what you want to do, you could do something like the following with proc_pidinfo() (source code for the kernel implementation is here and header file with struct definitions is here):

$ cat procname.c 
#include <stdio.h>
#include <stdlib.h>
#include <sys/proc_info.h>

extern int proc_pidinfo(int pid, int flavor, uint64_t arg, user_addr_t buffer,
    uint32_t  buffersize);
#define SHOW_ZOMBIES 0

int main(int argc, char **argv) {
    if(argc != 2) {
        puts("Usage: procname <pid>");
        return 1;
    }

    struct proc_taskallinfo info;

    int ret = proc_pidinfo(atoi(argv[1]), PROC_PIDTASKALLINFO, SHOW_ZOMBIES,
        (user_addr_t) &info, sizeof(struct proc_taskallinfo));
    printf("ret=%d, result=%s\n", ret, (char *) info.pbsd.pbi_comm);

    return 0;
}
$ clang procname.c -o procname 2>/dev/null
$ sudo ./procname 29079
ret=232, result=Google Chrome

I would have used dtruss on ps -p ... -o args to get an exact syscall you could use to get the right information, but unfortunately on El Capitan dtruss doesn't seem to work with some binaries (including ps) because of the following error:

$ sudo dtruss ps -p 29079 -o args

dtrace: failed to execute ps: dtrace cannot control executables signed with restricted entitlements

Instead what I did was run sudo nm $(which ps) to see what library calls were happening from ps, then I looked through those to see what looked like the most likely candidates and Googled for their implementations in the xnu (Mac OS X kernel) source code.

Upvotes: 4

Related Questions