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 }
|