Print this page
3946 ::gcore
Reviewed by: Adam Leventhal <ahl@delphix.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>


   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */



  25 
  26 #define __EXTENSIONS__
  27 #include <string.h>
  28 #undef  __EXTENSIONS__
  29 
  30 #include <libgen.h>
  31 #include <limits.h>
  32 #include <stdio.h>
  33 #include <errno.h>
  34 #include <unistd.h>
  35 #include <zone.h>
  36 
  37 #include "libproc.h"
  38 #include "Pcontrol.h"
  39 
  40 /*
  41  * Pexecname.c - Way too much code to attempt to derive the full pathname of
  42  * the executable file from a process handle, be it dead or alive.
  43  */
  44 


 219 
 220                         if (*p != '/')
 221                                 continue; /* Ignore anything relative */
 222 
 223                         if (try_exec(P, p, path, buf, isexec, isdata))
 224                                 goto found;
 225                 }
 226         }
 227 
 228         errno = ENOENT;
 229         return (NULL);
 230 
 231 found:
 232         if ((P->execname = strdup(buf)) == NULL)
 233                 dprintf("failed to malloc; executable name is \"%s\"", buf);
 234 
 235         return (P->execname);
 236 }
 237 
 238 /*
 239  * Callback function for Pfindexec().  We return a match if we can stat the
 240  * suggested pathname and confirm its device and inode number match our
 241  * previous information about the /proc/<pid>/object/a.out file.
 242  */
 243 static int
 244 stat_exec(const char *path, struct stat64 *stp)
 245 {
 246         struct stat64 st;
 247 
 248         return (stat64(path, &st) == 0 && S_ISREG(st.st_mode) &&
 249             stp->st_dev == st.st_dev && stp->st_ino == st.st_ino);
 250 }
 251 
 252 /*
 253  * Return the full pathname for the executable file.  If the process handle is
 254  * a core file, we've already tried our best to get the executable name.
 255  * Otherwise, we make an attempt using Pfindexec().
 256  */
 257 char *
 258 Pexecname(struct ps_prochandle *P, char *buf, size_t buflen)
 259 {
 260         if (P->execname != NULL) {
 261                 (void) strncpy(buf, P->execname, buflen);
 262                 return (buf);
 263         }
 264 
 265         if (P->state != PS_DEAD && P->state != PS_IDLE) {
 266                 char exec_name[PATH_MAX];
 267                 char cwd[PATH_MAX];
 268                 char proc_cwd[64];
 269                 struct stat64 st;
 270                 int ret;
 271 
 272                 /*
 273                  * Try to get the path information first.
 274                  */
 275                 (void) snprintf(exec_name, sizeof (exec_name),
 276                     "%s/%d/path/a.out", procfs_path, (int)P->pid);
 277                 if ((ret = readlink(exec_name, buf, buflen - 1)) > 0) {
 278                         buf[ret] = '\0';
 279                         (void) Pfindobj(P, buf, buf, buflen);
 280                         return (buf);
 281                 }
 282 
 283                 /*
 284                  * Stat the executable file so we can compare Pfindexec's
 285                  * suggestions to the actual device and inode number.
 286                  */
 287                 (void) snprintf(exec_name, sizeof (exec_name),
 288                     "%s/%d/object/a.out", procfs_path, (int)P->pid);
 289 
 290                 if (stat64(exec_name, &st) != 0 || !S_ISREG(st.st_mode))
 291                         return (NULL);
 292 
 293                 /*
 294                  * Attempt to figure out the current working directory of the
 295                  * target process.  This only works if the target process has
 296                  * not changed its current directory since it was exec'd.
 297                  */
 298                 (void) snprintf(proc_cwd, sizeof (proc_cwd),
 299                     "%s/%d/path/cwd", procfs_path, (int)P->pid);
 300 
 301                 if ((ret = readlink(proc_cwd, cwd, PATH_MAX - 1)) > 0)
 302                         cwd[ret] = '\0';
 303 
 304                 (void) Pfindexec(P, ret > 0 ? cwd : NULL,
 305                     (int (*)(const char *, void *))stat_exec, &st);
 306         }
 307 
 308         return (NULL);
 309 }


   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 /*
  26  * Copyright (c) 2013 by Delphix. All rights reserved.
  27  */
  28 
  29 #define __EXTENSIONS__
  30 #include <string.h>
  31 #undef  __EXTENSIONS__
  32 
  33 #include <libgen.h>
  34 #include <limits.h>
  35 #include <stdio.h>
  36 #include <errno.h>
  37 #include <unistd.h>
  38 #include <zone.h>
  39 
  40 #include "libproc.h"
  41 #include "Pcontrol.h"
  42 
  43 /*
  44  * Pexecname.c - Way too much code to attempt to derive the full pathname of
  45  * the executable file from a process handle, be it dead or alive.
  46  */
  47 


 222 
 223                         if (*p != '/')
 224                                 continue; /* Ignore anything relative */
 225 
 226                         if (try_exec(P, p, path, buf, isexec, isdata))
 227                                 goto found;
 228                 }
 229         }
 230 
 231         errno = ENOENT;
 232         return (NULL);
 233 
 234 found:
 235         if ((P->execname = strdup(buf)) == NULL)
 236                 dprintf("failed to malloc; executable name is \"%s\"", buf);
 237 
 238         return (P->execname);
 239 }
 240 
 241 /*
 242  * Return the full pathname for the executable file.


 243  */














 244 char *
 245 Pexecname(struct ps_prochandle *P, char *buf, size_t buflen)
 246 {
 247         if (P->execname != NULL) {
 248                 (void) strncpy(buf, P->execname, buflen);
 249                 return (buf);
 250         }
 251 
 252         return (P->ops.pop_execname(P, buf, buflen, P->data));











































 253 }