OSX: proc_pidinfo returns 0 for other user's processes

前端 未结 2 842
轻奢々
轻奢々 2021-02-10 02:28

I need to get some information (PID, UID, GID, process name) about running processes on Mac OSX. I tried proc_pidinfo. For my own processes it works fine. However,

相关标签:
2条回答
  • 2021-02-10 02:50

    You can use :

    int proc_listpids(uint32_t type, uint32_t typeinfo, void *buffer, int buffersize);
    

    combinated to proc_pidinfo to get many others pids informations like :

    #include <unistd.h>
    #include <stdlib.h>
    #include <mach/mach.h>
    #include <libproc.h>
    #include <mach/mach_time.h>
    #include <sys/sysctl.h>
    #include <mach-o/ldsyms.h>
    #include <stdio.h>
    
    void procpid(pid_t pid)
    { struct proc_bsdinfo proc;
      int st = proc_pidinfo(pid, PROC_PIDTBSDINFO, 0, &proc, PROC_PIDTBSDINFO_SIZE);
      printf("name: %s\n", proc.pbi_name);
    }
    
    void pidlist(void)
    { int bufsize = proc_listpids(PROC_ALL_PIDS, 0, NULL, 0);
      pid_t pids[2 * bufsize / sizeof(pid_t)];
      bufsize = proc_listpids(PROC_ALL_PIDS, 0, pids, sizeof(pids));
      size_t num_pids = bufsize / sizeof(pid_t);
      int i = 0;
      while (i < num_pids)
      { printf("pid[%d]::%d\n", i, pids[i]);
        procpid(pids[i]);
        printf("\n-------------------------------\n\n");
        i += 1; }}
    
    int main(void)
    { pidlist();
      return(42); }
    
    0 讨论(0)
  • I found that macOS Mojave (version 10.14.4) had struct proc_bsdshortinfo, which is a subset of struct proc_bsdinfo. You can get other user's processes without SUID by using it instead of struct proc_bsdinfo.

    Well, I don't know from which version it is available.

    edited: It is available since at least macOS 10.10.5 (Yosemite).
    edited again: It may be available since Mac OS X 10.7 (Lion) because tmux uses struct proc_bsdshortinfo if __MAC_10_7 is defined. See here.

    Example:

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    #include <libproc.h>
    
    int main(int argc, char *argv[])
    {
        pid_t pid;
        struct proc_bsdshortinfo proc;
    
        if (argc == 2)
            pid = atoi(argv[1]);
        else
            pid = getpid();
    
        int st = proc_pidinfo(pid, PROC_PIDT_SHORTBSDINFO, 0,
                             &proc, PROC_PIDT_SHORTBSDINFO_SIZE);
    
        if (st != PROC_PIDT_SHORTBSDINFO_SIZE) {
            fprintf(stderr, "Cannot get process info\n");
            return 1;
        }
        printf(" pid: %d\n", (int)proc.pbsi_pid);
        printf("ppid: %d\n", (int)proc.pbsi_ppid);
        printf("comm: %s\n",      proc.pbsi_comm);
        //printf("name: %s\n",      proc.pbsi_name);
        printf(" uid: %d\n", (int)proc.pbsi_uid);
        printf(" gid: %d\n", (int)proc.pbsi_gid);
    
        return 0;
    }
    

    This program prints:

    $ ./pidinfo 
     pid: 3025
    ppid: 250
    comm: pidinfo
     uid: 501
     gid: 20
    $ ./pidinfo 1
     pid: 1
    ppid: 0
    comm: launchd
     uid: 0
     gid: 0
    
    0 讨论(0)
提交回复
热议问题