This source file includes following definitions.
- get_progname_of
- main
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 #include <config.h>
  19 
  20 
  21 #include "get_progname_of.h"
  22 
  23 #include <stdio.h>
  24 #include <stdlib.h>
  25 #include <string.h>
  26 
  27 #if defined __linux__ || defined __ANDROID__ || (defined __FreeBSD_kernel__ && !defined __FreeBSD__) || defined __GNU__ || defined __NetBSD__ || defined __FreeBSD__ 
  28 # include <unistd.h>
  29 # if defined __ANDROID__
  30 #  include <fcntl.h>
  31 # endif
  32 #endif
  33 
  34 #if defined __minix || defined __sun                        
  35 # include <fcntl.h>
  36 # include <unistd.h>
  37 #endif
  38 
  39 #if defined __OpenBSD__                                     
  40 # include <sys/sysctl.h> 
  41 #endif
  42 
  43 #if defined __APPLE__ && defined __MACH__                   
  44 
  45 
  46 
  47 # include <AvailabilityMacros.h>
  48 # if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
  49 #  include <libproc.h>
  50 # endif
  51 #endif
  52 
  53 #if defined _AIX                                            
  54 # include <procinfo.h>
  55 #endif
  56 
  57 #if defined __hpux                                          
  58 # include <unistd.h>
  59 # include <sys/param.h>
  60 # include <sys/pstat.h>
  61 #endif
  62 
  63 #if defined __sgi                                           
  64 # include <unistd.h>
  65 # include <fcntl.h>
  66 # include <sys/procfs.h>
  67 #endif
  68 
  69 #if defined __CYGWIN__                                      
  70 # define WIN32_LEAN_AND_MEAN
  71 # include <windows.h> 
  72 # include <sys/cygwin.h>
  73 #endif
  74 
  75 #if defined __BEOS__ || defined __HAIKU__                   
  76 # include <OS.h>
  77 #endif
  78 
  79 char *
  80 get_progname_of (pid_t pid)
     
  81 {
  82 #if defined __linux__ || defined __ANDROID__ || (defined __FreeBSD_kernel__ && !defined __FreeBSD__) || defined __GNU__ || defined __NetBSD__ 
  83 
  84 
  85 
  86   
  87   {
  88     char filename[6 + 10 + 4 + 1];
  89     char linkbuf[1024 + 1];
  90     ssize_t linklen;
  91 
  92     sprintf (filename, "/proc/%u/exe", (unsigned int) pid);
  93     linklen = readlink (filename, linkbuf, sizeof (linkbuf) - 1);
  94     if (linklen > 0)
  95       {
  96         char *slash;
  97 
  98         
  99         linkbuf[linklen] = '\0';
 100         
 101         slash = strrchr (linkbuf, '/');
 102         return strdup (slash != NULL ? slash + 1 : linkbuf);
 103       }
 104   }
 105 
 106 # if defined __ANDROID__
 107   
 108 
 109   {
 110     char filename[6 + 10 + 8 + 1];
 111     int fd;
 112 
 113     sprintf (filename, "/proc/%u/cmdline", (unsigned int) pid);
 114     fd = open (filename, O_RDONLY | O_CLOEXEC);
 115     if (fd >= 0)
 116       {
 117         char buf[4096 + 1];
 118         ssize_t nread = read (fd, buf, sizeof (buf) - 1);
 119         close (fd);
 120         if (nread >= 0)
 121           {
 122             char *slash;
 123 
 124             
 125 
 126             buf[nread] = '\0';
 127             
 128             
 129             slash = strrchr (buf, '/');
 130             return strdup (slash != NULL ? slash + 1 : buf);
 131           }
 132       }
 133   }
 134 # endif
 135 
 136 #endif
 137 
 138 #if defined __FreeBSD__                                     
 139 
 140   
 141   char filename[6 + 10 + 5 + 1];
 142   char linkbuf[1024 + 1];
 143   ssize_t linklen;
 144 
 145   sprintf (filename, "/proc/%u/file", (unsigned int) pid);
 146   linklen = readlink (filename, linkbuf, sizeof (linkbuf) - 1);
 147   if (linklen > 0)
 148     {
 149       char *slash;
 150 
 151       
 152       linkbuf[linklen] = '\0';
 153       
 154       slash = strrchr (linkbuf, '/');
 155       return strdup (slash != NULL ? slash + 1 : linkbuf);
 156     }
 157 
 158 #endif
 159 
 160 #if defined __minix                                         
 161 
 162   
 163   char filename[6 + 10 + 7 + 1];
 164   int fd;
 165 
 166   sprintf (filename, "/proc/%u/psinfo", (unsigned int) pid);
 167   fd = open (filename, O_RDONLY | O_CLOEXEC);
 168   if (fd >= 0)
 169     {
 170       char buf[4096 + 1];
 171       ssize_t nread = read (fd, buf, sizeof (buf) - 1);
 172       close (fd);
 173       if (nread >= 0)
 174         {
 175           char *p;
 176           int count;
 177 
 178           
 179           buf[nread] = '\0';
 180 
 181           
 182           p = strchr (buf, ' ');
 183           for (count = 1; p != NULL && count < 3; count++)
 184             p = strchr (p + 1, ' ');
 185           if (p != NULL)
 186             {
 187               char *start = p + 1;
 188               char *end = strchr (p + 1, ' ');
 189               if (end != NULL)
 190                 {
 191                   *end = '\0';
 192                   return strdup (start);
 193                 }
 194             }
 195         }
 196     }
 197 
 198 #endif
 199 
 200 #if defined __sun                                           
 201 
 202   
 203 
 204   {
 205     char filename[6 + 10 + 11 + 1];
 206     char linkbuf[1024 + 1];
 207     ssize_t linklen;
 208 
 209     sprintf (filename, "/proc/%u/path/a.out", (unsigned int) pid);
 210     linklen = readlink (filename, linkbuf, sizeof (linkbuf) - 1);
 211     if (linklen > 0)
 212       {
 213         char *slash;
 214 
 215         
 216         linkbuf[linklen] = '\0';
 217         
 218         slash = strrchr (linkbuf, '/');
 219         return strdup (slash != NULL ? slash + 1 : linkbuf);
 220       }
 221   }
 222 
 223   
 224 
 225 
 226 
 227   {
 228     char filename[6 + 10 + 7 + 1];
 229     int fd;
 230 
 231     sprintf (filename, "/proc/%u/psinfo", (unsigned int) pid);
 232     fd = open (filename, O_RDONLY | O_CLOEXEC);
 233     if (fd >= 0)
 234       {
 235         
 236 
 237 
 238 
 239         #if defined __LP64__
 240         # define PSINFO_SIZE 416
 241         # define PSINFO_FNAME_OFFSET 136
 242         #else
 243         # define PSINFO_SIZE 336
 244         # define PSINFO_FNAME_OFFSET 88
 245         #endif
 246         char buf[PSINFO_SIZE];
 247         ssize_t nread = read (fd, buf, sizeof (buf));
 248         close (fd);
 249         if (nread >= PSINFO_FNAME_OFFSET + 16)
 250           {
 251             
 252             buf[PSINFO_FNAME_OFFSET + 16] = '\0';
 253             return strdup (&buf[PSINFO_FNAME_OFFSET]);
 254           }
 255       }
 256   }
 257 
 258 #endif
 259 
 260 #if defined __OpenBSD__                                     
 261 
 262   
 263   int info_path[] =
 264     { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid, sizeof (struct kinfo_proc), 1 };
 265   struct kinfo_proc info;
 266   size_t len;
 267 
 268   len = sizeof (info);
 269   if (sysctl (info_path, 6, &info, &len, NULL, 0) >= 0 && len == sizeof (info))
 270     return strdup (info.p_comm);
 271 
 272 #endif
 273 
 274 #if defined __APPLE__ && defined __MACH__                   
 275 # if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
 276 
 277   
 278 #  if defined PROC_PIDT_SHORTBSDINFO
 279   struct proc_bsdshortinfo info;
 280 
 281   if (proc_pidinfo (pid, PROC_PIDT_SHORTBSDINFO, 0, &info, sizeof (info))
 282       == sizeof (info))
 283     return strdup (info.pbsi_comm);
 284 #  endif
 285 
 286 #  if MAC_OS_X_VERSION_MIN_REQUIRED < 1070
 287   
 288   
 289 
 290 
 291 
 292   struct proc_bsdinfo info;
 293 
 294   if (proc_pidinfo (pid, PROC_PIDTBSDINFO, 0, &info, 128) == 128)
 295     return strdup (info.pbi_comm);
 296 #  endif
 297 
 298 # endif
 299 #endif
 300 
 301 #if defined _AIX                                            
 302 
 303   
 304 
 305   struct procentry64 procs;
 306   if (getprocs64 (&procs, sizeof procs, NULL, 0, &pid, 1) > 0)
 307     return strdup (procs.pi_comm);
 308 
 309 #endif
 310 
 311 #if defined __hpux                                          
 312 
 313   char *p;
 314   struct pst_status status;
 315   if (pstat_getproc (&status, sizeof status, 0, pid) > 0)
 316     {
 317       char *ucomm = status.pst_ucomm;
 318       char *cmd = status.pst_cmd;
 319       if (strlen (ucomm) < PST_UCOMMLEN - 1)
 320         p = ucomm;
 321       else
 322         {
 323           
 324 
 325           char *space = strchr (cmd, ' ');
 326           if (space != NULL)
 327             *space = '\0';
 328           p = strrchr (cmd, '/');
 329           if (p != NULL)
 330             p++;
 331           else
 332             p = cmd;
 333           if (strlen (p) > PST_UCOMMLEN - 1
 334               && memcmp (p, ucomm, PST_UCOMMLEN - 1) == 0)
 335             
 336             ;
 337           else
 338             p = ucomm;
 339         }
 340       p = strdup (p);
 341     }
 342   else
 343     {
 344 # if !defined __LP64__
 345       
 346 
 347 
 348 
 349 
 350       char status64[1216];
 351       if (__pstat_getproc64 (status64, sizeof status64, 0, pid) > 0)
 352         {
 353           char *ucomm = status64 + 288;
 354           char *cmd = status64 + 168;
 355           if (strlen (ucomm) < PST_UCOMMLEN - 1)
 356             p = ucomm;
 357           else
 358             {
 359               
 360 
 361               char *space = strchr (cmd, ' ');
 362               if (space != NULL)
 363                 *space = '\0';
 364               p = strrchr (cmd, '/');
 365               if (p != NULL)
 366                 p++;
 367               else
 368                 p = cmd;
 369               if (strlen (p) > PST_UCOMMLEN - 1
 370                   && memcmp (p, ucomm, PST_UCOMMLEN - 1) == 0)
 371                 
 372                 ;
 373               else
 374                 p = ucomm;
 375             }
 376           p = strdup (p);
 377         }
 378       else
 379 # endif
 380         p = NULL;
 381     }
 382   if (p != NULL)
 383     return strdup (p);
 384 
 385 #endif
 386 
 387 #if defined __sgi                                           
 388 
 389   char filename[12 + 10 + 1];
 390   int fd;
 391 
 392   sprintf (filename, "/proc/pinfo/%u", pid);
 393   fd = open (filename, O_RDONLY | O_CLOEXEC);
 394   if (0 <= fd)
 395     {
 396       prpsinfo_t buf;
 397       int ioctl_ok = 0 <= ioctl (fd, PIOCPSINFO, &buf);
 398       close (fd);
 399       if (ioctl_ok)
 400         {
 401           char *name = buf.pr_fname;
 402           size_t namesize = sizeof buf.pr_fname;
 403           
 404           char *namenul = memchr (name, '\0', namesize);
 405           size_t namelen = namenul ? namenul - name : namesize;
 406           char *namecopy = malloc (namelen + 1);
 407           if (namecopy)
 408             {
 409               namecopy[namelen] = '\0';
 410               return memcpy (namecopy, name, namelen);
 411             }
 412         }
 413     }
 414 
 415 #endif
 416 
 417 #if defined __CYGWIN__                                      
 418 
 419   struct external_pinfo *info =
 420     (struct external_pinfo *) cygwin_internal (CW_GETPINFO, pid);
 421   if (info != NULL)
 422     {
 423       const char *name = info->progname;
 424       size_t namesize = sizeof (info->progname);
 425       
 426       const char *namenul = memchr (name, '\0', namesize);
 427       size_t namelen = namenul ? namenul - name : namesize;
 428 
 429       
 430 
 431       {
 432         const char *backslash = memchr (name, '\\', namelen);
 433         if (backslash != NULL)
 434           {
 435             const char *name_end = name + namelen;
 436             for (;;)
 437               {
 438                 const char *next_backslash =
 439                   memchr (backslash + 1, '\\', name_end - (backslash + 1));
 440                 if (next_backslash == NULL)
 441                   break;
 442                 backslash = next_backslash;
 443               }
 444             name = backslash + 1;
 445             namelen = name_end - name;
 446           }
 447       }
 448 
 449       {
 450         char *namecopy = malloc (namelen + 1);
 451         if (namecopy)
 452           {
 453             namecopy[namelen] = '\0';
 454             return memcpy (namecopy, name, namelen);
 455           }
 456       }
 457     }
 458 
 459 #endif
 460 
 461 #if defined __BEOS__ || defined __HAIKU__                   
 462 
 463   team_info info;
 464   if (_get_team_info (pid, &info, sizeof (info)) == B_OK)
 465     {
 466       const char *name = info.args;
 467       size_t namesize = sizeof (info.args);
 468       
 469       const char *namenul = memchr (name, '\0', namesize);
 470       size_t namelen = namenul ? namenul - name : namesize;
 471 
 472       
 473       {
 474         const char *space = memchr (name, ' ', namelen);
 475         if (space != NULL)
 476           namelen = space - name;
 477       }
 478 
 479       
 480       {
 481         const char *slash = memchr (name, '/', namelen);
 482         if (slash != NULL)
 483           {
 484             const char *name_end = name + namelen;
 485             for (;;)
 486               {
 487                 const char *next_slash =
 488                   memchr (slash + 1, '/', name_end - (slash + 1));
 489                 if (next_slash == NULL)
 490                   break;
 491                 slash = next_slash;
 492               }
 493             name = slash + 1;
 494             namelen = name_end - name;
 495           }
 496       }
 497 
 498       {
 499         char *namecopy = malloc (namelen + 1);
 500         if (namecopy)
 501           {
 502             namecopy[namelen] = '\0';
 503             return memcpy (namecopy, name, namelen);
 504           }
 505       }
 506     }
 507 
 508 #endif
 509 
 510   return NULL;
 511 }
 512 
 513 #ifdef TEST
 514 
 515 #include <stdlib.h>
 516 #include <unistd.h>
 517 
 518 
 519 
 520 
 521 int
 522 main (int argc, char *argv[])
     
 523 {
 524   char *arg = argv[1];
 525   pid_t pid = (arg != NULL ? atoi (arg) : getpid ());
 526   char *progname = get_progname_of (pid);
 527   printf ("PID=%lu COMMAND=%s\n",
 528           (unsigned long) pid, progname != NULL ? progname : "(null)");
 529   free (progname);
 530   return 0;
 531 }
 532 
 533 
 534 
 535 
 536 
 537 
 538 
 539 #endif