8

I am on OSX Mountain Lion and am trying to retrieve a processes' name using its PID.

The following is the code I am using:

pid_t pid = 10687;
char pathBuffer [PROC_PIDPATHINFO_MAXSIZE] = "";
char nameBuffer [256] = "";

int sizeOfVal = sizeof(nameBuffer);
proc_pidpath(pid, pathBuffer, sizeof(pathBuffer));
proc_name(pid, nameBuffer, sizeof(nameBuffer));

NSLog(@"Path: %s\n Name: %s\n", pathBuffer, nameBuffer);

The code above is able to retrieve the name properly, however it only retrieves the first 15 characters and "ignores" the rest. Note this is not a problem with displaying the name, but with retrieving it. The problem is not with the rest of my application as I am testing the above code in a standalone application. Also note that I tried changing the PID, but regardless of what PID I try the code only retrieves the first 15 characters of the name. Path retrieval works perfectly.

Does anyone have any ideas about what I am doing wrong?

fdh
  • 5,256
  • 13
  • 58
  • 101
  • As I investigated this issue, I found some more weirdness. If the buffer length specified is less than 32 bytes, nothing will be placed into the string, even if the name is short (and would fit into the 31 byte buffer) – charliehorse55 Sep 05 '12 at 04:24

1 Answers1

11

The function looks at the value is the struct proc_bsdshortinfo. It is limited to return a 16 byte string, or 15 readable characters when including the null terminator.

From sys/param.h:

#define MAXCOMLEN   16      /* max command name remembered */

From sys/proc_info.h:

struct proc_bsdshortinfo {
        uint32_t                pbsi_pid;       /* process id */
        uint32_t                pbsi_ppid;      /* process parent id */
        uint32_t                pbsi_pgid;      /* process perp id */
    uint32_t                pbsi_status;        /* p_stat value, SZOMB, SRUN, etc */
    char                    pbsi_comm[MAXCOMLEN];   /* upto 16 characters of process name */
    uint32_t                pbsi_flags;              /* 64bit; emulated etc */
        uid_t                   pbsi_uid;       /* current uid on process */
        gid_t                   pbsi_gid;       /* current gid on process */
        uid_t                   pbsi_ruid;      /* current ruid on process */
        gid_t                   pbsi_rgid;      /* current tgid on process */
        uid_t                   pbsi_svuid;     /* current svuid on process */
        gid_t                   pbsi_svgid;     /* current svgid on process */
        uint32_t                pbsi_rfu;       /* reserved for future use*/
};

EDIT: To get around this, get the last path component:

pid_t pid = 3051;
char pathBuffer [PROC_PIDPATHINFO_MAXSIZE];
proc_pidpath(pid, pathBuffer, sizeof(pathBuffer));

char nameBuffer[256];

int position = strlen(pathBuffer);
while(position >= 0 && pathBuffer[position] != '/')
{
    position--;
}

strcpy(nameBuffer, pathBuffer + position + 1);

printf("path: %s\n\nname:%s\n\n", pathBuffer, nameBuffer);
charliehorse55
  • 1,940
  • 5
  • 24
  • 38
  • get the full path and then trim the string down to the last path component. – charliehorse55 Sep 05 '12 at 05:01
  • Isn't there a more elegant solution? Considering retrieving process info is a vital part of many programs, there should be a more efficient interface for retrieving such info. – fdh Sep 05 '12 at 05:04
  • While retrieving process info is important, most applications do not even care what the name is. – charliehorse55 Sep 05 '12 at 05:07
  • 2
    If you look at the source for programs like `ps`, this is how they get the long name. – charliehorse55 Sep 05 '12 at 05:13
  • @charliehorse55 how would 1 get the command arguments with which a process is launched? –  Jan 10 '15 at 09:01