2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License (the "License"). 2N/A * You may not use this file except in compliance with the License. 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 2N/A * Use is subject to license terms. 2N/A * Pexecname.c - Way too much code to attempt to derive the full pathname of 2N/A * the executable file from a process handle, be it dead or alive. 2N/A * Once we've computed a cwd and a relative path, we use try_exec() to 2N/A * form an absolute path, call resolvepath() on it, and then let the 2N/A * caller's function do the final confirmation. 2N/A return (0);
/* resolvepath failed */ 2N/A * The Pfindexec function contains the logic for the executable name dance. 2N/A * The caller provides a possible executable name or likely directory (the 2N/A * aout parameter), and a function which is responsible for doing any 2N/A * final confirmation on the executable pathname once a possible full 2N/A * pathname has been chosen. 2N/A errno = 0;
/* Set to zero so we can tell if stat() failed */ 2N/A * First try: use the provided default value, if it is not a directory. 2N/A * If the aout parameter turns out to be a directory, this is 2N/A * interpreted as the directory to use as an alternate cwd for 2N/A * our subsequent attempts to locate the executable. 2N/A * At this point 'aout' is either "." or an alternate cwd. We use 2N/A * realpath(3c) to turn this into a full pathname free of ".", "..", 2N/A * and symlinks. If this fails for some reason, fall back to "." 2N/A * Second try: read the string pointed to by the AT_SUN_EXECNAME 2N/A * auxv element, saved when the program was exec'd. If the full 2N/A * pathname try_exec() forms fails, try again using just the 2N/A * basename appended to our cwd. If that also fails, and the process 2N/A * is in a zone, try again with the zone path instead of our cwd. 2N/A * try_exec() only combines its cwd and path arguments 2N/A * if path is relative; but in our case even an absolute 2N/A * path inside a zone is a relative path from the global 2N/A * zone perspective. So we turn a non-global zone's 2N/A * absolute path into a relative path here before 2N/A * calling try_exec(). 2N/A * Third try: try using the first whitespace-separated token 2N/A * saved in the psinfo_t's pr_psargs (the initial value of argv[0]). 2N/A * Fourth try: read the string pointed to by argv[0] out of the 2N/A * stack in the process's address space. 2N/A * Fifth try: read the process's $PATH environment variable and 2N/A * search each directory named there for the name matching pr_fname. 2N/A * If the name from pr_psargs contains pr_fname as its 2N/A * leading string, then accept the name from pr_psargs 2N/A * because more bytes are saved there. Otherwise use 2N/A * pr_fname because this gives us new information. 2N/A * Now iterate over the $PATH elements, trying to form 2N/A * an executable pathname with each one. 2N/A continue;
/* Ignore anything relative */ 2N/A * Callback function for Pfindexec(). We return a match if we can stat the 2N/A * suggested pathname and confirm its device and inode number match our 2N/A * Return the full pathname for the executable file. If the process handle is 2N/A * a core file, we've already tried our best to get the executable name. 2N/A * Otherwise, we make an attempt using Pfindexec(). 2N/A * Try to get the path information first. 2N/A * Stat the executable file so we can compare Pfindexec's 2N/A * suggestions to the actual device and inode number. 2N/A * Attempt to figure out the current working directory of the 2N/A * target process. This only works if the target process has 2N/A * not changed its current directory since it was exec'd.