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

*** 20,29 **** --- 20,32 ---- */ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ + /* + * Copyright (c) 2013 by Delphix. All rights reserved. + */ #define __EXTENSIONS__ #include <string.h> #undef __EXTENSIONS__
*** 234,309 **** return (P->execname); } /* ! * Callback function for Pfindexec(). We return a match if we can stat the ! * suggested pathname and confirm its device and inode number match our ! * previous information about the /proc/<pid>/object/a.out file. */ - static int - stat_exec(const char *path, struct stat64 *stp) - { - struct stat64 st; - - return (stat64(path, &st) == 0 && S_ISREG(st.st_mode) && - stp->st_dev == st.st_dev && stp->st_ino == st.st_ino); - } - - /* - * Return the full pathname for the executable file. If the process handle is - * a core file, we've already tried our best to get the executable name. - * Otherwise, we make an attempt using Pfindexec(). - */ char * Pexecname(struct ps_prochandle *P, char *buf, size_t buflen) { if (P->execname != NULL) { (void) strncpy(buf, P->execname, buflen); return (buf); } ! if (P->state != PS_DEAD && P->state != PS_IDLE) { ! char exec_name[PATH_MAX]; ! char cwd[PATH_MAX]; ! char proc_cwd[64]; ! struct stat64 st; ! int ret; ! ! /* ! * Try to get the path information first. ! */ ! (void) snprintf(exec_name, sizeof (exec_name), ! "%s/%d/path/a.out", procfs_path, (int)P->pid); ! if ((ret = readlink(exec_name, buf, buflen - 1)) > 0) { ! buf[ret] = '\0'; ! (void) Pfindobj(P, buf, buf, buflen); ! return (buf); ! } ! ! /* ! * Stat the executable file so we can compare Pfindexec's ! * suggestions to the actual device and inode number. ! */ ! (void) snprintf(exec_name, sizeof (exec_name), ! "%s/%d/object/a.out", procfs_path, (int)P->pid); ! ! if (stat64(exec_name, &st) != 0 || !S_ISREG(st.st_mode)) ! return (NULL); ! ! /* ! * Attempt to figure out the current working directory of the ! * target process. This only works if the target process has ! * not changed its current directory since it was exec'd. ! */ ! (void) snprintf(proc_cwd, sizeof (proc_cwd), ! "%s/%d/path/cwd", procfs_path, (int)P->pid); ! ! if ((ret = readlink(proc_cwd, cwd, PATH_MAX - 1)) > 0) ! cwd[ret] = '\0'; ! ! (void) Pfindexec(P, ret > 0 ? cwd : NULL, ! (int (*)(const char *, void *))stat_exec, &st); ! } ! ! return (NULL); } --- 237,253 ---- return (P->execname); } /* ! * Return the full pathname for the executable file. */ char * Pexecname(struct ps_prochandle *P, char *buf, size_t buflen) { if (P->execname != NULL) { (void) strncpy(buf, P->execname, buflen); return (buf); } ! return (P->ops.pop_execname(P, buf, buflen, P->data)); }