usr/src/lib/libproc/common/Pexecname.c
changeset 2712 f74a135872bc
parent 2232 8c8716812459
child 2823 2786715d2871
equal deleted inserted replaced
2711:bd82281c775d 2712:f74a135872bc
    32 #include <libgen.h>
    32 #include <libgen.h>
    33 #include <limits.h>
    33 #include <limits.h>
    34 #include <stdio.h>
    34 #include <stdio.h>
    35 #include <errno.h>
    35 #include <errno.h>
    36 #include <unistd.h>
    36 #include <unistd.h>
       
    37 #include <libzonecfg.h>
    37 
    38 
    38 #include "Pcontrol.h"
    39 #include "Pcontrol.h"
    39 
    40 
    40 /*
    41 /*
    41  * Pexecname.c - Way too much code to attempt to derive the full pathname of
    42  * Pexecname.c - Way too much code to attempt to derive the full pathname of
    82 	char cwd[PATH_MAX * 2];
    83 	char cwd[PATH_MAX * 2];
    83 	char path[PATH_MAX];
    84 	char path[PATH_MAX];
    84 	char buf[PATH_MAX];
    85 	char buf[PATH_MAX];
    85 	struct stat st;
    86 	struct stat st;
    86 	uintptr_t addr;
    87 	uintptr_t addr;
    87 	char *p, *q;
    88 	char *p = path, *q;
    88 
    89 
    89 	if (P->execname)
    90 	if (P->execname)
    90 		return (P->execname); /* Already found */
    91 		return (P->execname); /* Already found */
    91 
    92 
    92 	errno = 0; /* Set to zero so we can tell if stat() failed */
    93 	errno = 0; /* Set to zero so we can tell if stat() failed */
   116 
   117 
   117 	/*
   118 	/*
   118 	 * Second try: read the string pointed to by the AT_SUN_EXECNAME
   119 	 * Second try: read the string pointed to by the AT_SUN_EXECNAME
   119 	 * auxv element, saved when the program was exec'd.  If the full
   120 	 * auxv element, saved when the program was exec'd.  If the full
   120 	 * pathname try_exec() forms fails, try again using just the
   121 	 * pathname try_exec() forms fails, try again using just the
   121 	 * basename appended to our cwd.
   122 	 * basename appended to our cwd.  If that also fails, and the process
       
   123 	 * is in a zone, try again with the zone path instead of our cwd.
   122 	 */
   124 	 */
   123 	if ((addr = Pgetauxval(P, AT_SUN_EXECNAME)) != (uintptr_t)-1L &&
   125 	if ((addr = Pgetauxval(P, AT_SUN_EXECNAME)) != (uintptr_t)-1L &&
   124 	    Pread_string(P, path, sizeof (path), (off_t)addr) > 0) {
   126 	    Pread_string(P, path, sizeof (path), (off_t)addr) > 0) {
       
   127 		char		zname[ZONENAME_MAX];
       
   128 		char		zpath[PATH_MAX];
       
   129 		const psinfo_t	*pi = Ppsinfo(P);
   125 
   130 
   126 		if (try_exec(cwd, path, buf, isexec, isdata))
   131 		if (try_exec(cwd, path, buf, isexec, isdata))
   127 			goto found;
   132 			goto found;
   128 
   133 
   129 		if (strchr(path, '/') != NULL && (p = basename(path)) != NULL &&
   134 		if (strchr(path, '/') != NULL && (p = basename(path)) != NULL &&
   130 		    try_exec(cwd, p, buf, isexec, isdata))
   135 		    try_exec(cwd, p, buf, isexec, isdata))
   131 			goto found;
   136 			goto found;
       
   137 
       
   138 		if (getzonenamebyid(pi->pr_zoneid, zname,
       
   139 		    sizeof (zname)) != -1 && strcmp(zname, "global") != 0 &&
       
   140 		    zone_get_zonepath(zname, zpath, sizeof (zpath)) == Z_OK) {
       
   141 			(void) strcat(zpath, "/root");
       
   142 			if (try_exec(zpath, p, buf, isexec, isdata))
       
   143 				goto found;
       
   144 		}
   132 	}
   145 	}
   133 
   146 
   134 	/*
   147 	/*
   135 	 * Third try: try using the first whitespace-separated token
   148 	 * Third try: try using the first whitespace-separated token
   136 	 * saved in the psinfo_t's pr_psargs (the initial value of argv[0]).
   149 	 * saved in the psinfo_t's pr_psargs (the initial value of argv[0]).
   243 
   256 
   244 		/*
   257 		/*
   245 		 * Try to get the path information first.
   258 		 * Try to get the path information first.
   246 		 */
   259 		 */
   247 		(void) snprintf(exec_name, sizeof (exec_name),
   260 		(void) snprintf(exec_name, sizeof (exec_name),
   248 		    "/proc/%d/path/a.out", (int)P->pid);
   261 		    "%s/%d/path/a.out", procfs_path, (int)P->pid);
   249 		if ((ret = readlink(exec_name, buf, buflen - 1)) > 0) {
   262 		if ((ret = readlink(exec_name, buf, buflen - 1)) > 0) {
   250 			buf[ret] = '\0';
   263 			buf[ret] = '\0';
   251 			return (buf);
   264 			return (buf);
   252 		}
   265 		}
   253 
   266 
   254 		/*
   267 		/*
   255 		 * Stat the executable file so we can compare Pfindexec's
   268 		 * Stat the executable file so we can compare Pfindexec's
   256 		 * suggestions to the actual device and inode number.
   269 		 * suggestions to the actual device and inode number.
   257 		 */
   270 		 */
   258 		(void) snprintf(exec_name, sizeof (exec_name),
   271 		(void) snprintf(exec_name, sizeof (exec_name),
   259 		    "/proc/%d/object/a.out", (int)P->pid);
   272 		    "%s/%d/object/a.out", procfs_path, (int)P->pid);
   260 
   273 
   261 		if (stat64(exec_name, &st) != 0 || !S_ISREG(st.st_mode))
   274 		if (stat64(exec_name, &st) != 0 || !S_ISREG(st.st_mode))
   262 			return (NULL);
   275 			return (NULL);
   263 
   276 
   264 		/*
   277 		/*
   265 		 * Attempt to figure out the current working directory of the
   278 		 * Attempt to figure out the current working directory of the
   266 		 * target process.  This only works if the target process has
   279 		 * target process.  This only works if the target process has
   267 		 * not changed its current directory since it was exec'd.
   280 		 * not changed its current directory since it was exec'd.
   268 		 */
   281 		 */
   269 		(void) snprintf(proc_cwd, sizeof (proc_cwd),
   282 		(void) snprintf(proc_cwd, sizeof (proc_cwd),
   270 		    "/proc/%d/path/cwd", (int)P->pid);
   283 		    "%s/%d/path/cwd", procfs_path, (int)P->pid);
   271 
   284 
   272 		if ((ret = readlink(proc_cwd, cwd, PATH_MAX - 1)) > 0)
   285 		if ((ret = readlink(proc_cwd, cwd, PATH_MAX - 1)) > 0)
   273 			cwd[ret] = '\0';
   286 			cwd[ret] = '\0';
   274 
   287 
   275 		(void) Pfindexec(P, ret > 0 ? cwd : NULL,
   288 		(void) Pfindexec(P, ret > 0 ? cwd : NULL,