From Pid to Path

With inspiration from ps.c ... given a pid, determine the full path to the corresponding executable.

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <sys/sysctl.h>

int
main (int argc, const char * argv[])
{
 if (argc != 2) {
  printf("usage: pidtopath <pid>\n");
  return -1;
 }
 
 int pid = strtol(argv[1], NULL, 10);
 size_t size;
 int mib[3], argmax;
 char *procargs, *cp, *ep;
 
 if (pid <= 0)
  return -1;
 
 mib[0] = CTL_KERN;
 mib[1] = KERN_ARGMAX;
 
 size = sizeof(argmax);
 
 // get the max size for arguments; last I checked this was 262,144 bytes.
 if (-1 == sysctl(mib, 2, &argmax, &size, NULL, 0))
  return -1;
 
 if (NULL == (procargs = (char *)malloc(argmax)))
  return -1;
 
 mib[0] = CTL_KERN;
 mib[1] = KERN_PROCARGS2;
 mib[2] = pid;
 
 size = (size_t)argmax;
 
 // obtain the arguments for the target process
 if (-1 == sysctl(mib, 3, procargs, &size, NULL, 0)) {
  free(procargs);
  return -1;
 }
 
 cp = procargs + sizeof(int);
 ep = &procargs[size];
 
 // advance past the saved exec path
 while (*cp != '\0' && cp++ < ep)
  ;
 
 // we should not already be at the end of the arguments
 if (cp == ep) {
  free(procargs);
  return -1;
 }
 
 // advance until we hit the first argument
 while (*cp == '\0' && cp++ < ep)
  ;
 
 printf("%s\n", cp);
 
 free(procargs);
 
 return 0;
}

Subscribe to A garage sale for your mind

Don’t miss out on the latest posts. Sign up now to get access to the library of members-only posts.
[email protected]
Subscribe