10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*11798SRoger.Faulkner@Sun.COM * Common Development and Distribution License (the "License").
6*11798SRoger.Faulkner@Sun.COM * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
21*11798SRoger.Faulkner@Sun.COM
220Sstevel@tonic-gate /*
23*11798SRoger.Faulkner@Sun.COM * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24*11798SRoger.Faulkner@Sun.COM * Use is subject to license terms.
250Sstevel@tonic-gate */
260Sstevel@tonic-gate
270Sstevel@tonic-gate #include <sys/isa_defs.h>
280Sstevel@tonic-gate #include <stdlib.h>
290Sstevel@tonic-gate #include <unistd.h>
300Sstevel@tonic-gate #include <string.h>
310Sstevel@tonic-gate #include <errno.h>
320Sstevel@tonic-gate #include <sys/types.h>
330Sstevel@tonic-gate #include <sys/stat.h>
34*11798SRoger.Faulkner@Sun.COM #include <sys/fcntl.h>
350Sstevel@tonic-gate #include <sys/sysmacros.h>
360Sstevel@tonic-gate #include "libproc.h"
370Sstevel@tonic-gate
380Sstevel@tonic-gate #ifdef _LP64
390Sstevel@tonic-gate /*
400Sstevel@tonic-gate * in case of 64-bit *stat() and *stat64 library call and 32-bit subject
410Sstevel@tonic-gate * process convert 64-bit struct stat/stat64 into 32-bit struct stat64
420Sstevel@tonic-gate */
430Sstevel@tonic-gate static void
stat64_32_to_n(struct stat64_32 * src,struct stat * dest)440Sstevel@tonic-gate stat64_32_to_n(struct stat64_32 *src, struct stat *dest)
450Sstevel@tonic-gate {
460Sstevel@tonic-gate (void) memset(dest, 0, sizeof (*dest));
470Sstevel@tonic-gate dest->st_dev = DEVEXPL(src->st_dev);
480Sstevel@tonic-gate dest->st_ino = (ino_t)src->st_ino;
490Sstevel@tonic-gate dest->st_mode = (mode_t)src->st_mode;
500Sstevel@tonic-gate dest->st_nlink = (nlink_t)src->st_nlink;
510Sstevel@tonic-gate dest->st_uid = (uid_t)src->st_uid;
520Sstevel@tonic-gate dest->st_gid = (gid_t)src->st_gid;
530Sstevel@tonic-gate dest->st_rdev = DEVEXPL(src->st_rdev);
540Sstevel@tonic-gate dest->st_size = (off_t)src->st_size;
550Sstevel@tonic-gate TIMESPEC32_TO_TIMESPEC(&dest->st_atim, &src->st_atim);
560Sstevel@tonic-gate TIMESPEC32_TO_TIMESPEC(&dest->st_mtim, &src->st_mtim);
570Sstevel@tonic-gate TIMESPEC32_TO_TIMESPEC(&dest->st_ctim, &src->st_ctim);
580Sstevel@tonic-gate dest->st_blksize = (blksize_t)src->st_blksize;
590Sstevel@tonic-gate dest->st_blocks = (blkcnt_t)src->st_blocks;
600Sstevel@tonic-gate (void) memcpy(dest->st_fstype, src->st_fstype,
610Sstevel@tonic-gate sizeof (dest->st_fstype));
620Sstevel@tonic-gate }
630Sstevel@tonic-gate #endif /* _LP64 */
640Sstevel@tonic-gate
650Sstevel@tonic-gate /*
660Sstevel@tonic-gate * stat() system call -- executed by subject process
670Sstevel@tonic-gate */
680Sstevel@tonic-gate int
pr_stat(struct ps_prochandle * Pr,const char * path,struct stat * buf)690Sstevel@tonic-gate pr_stat(struct ps_prochandle *Pr, const char *path, struct stat *buf)
700Sstevel@tonic-gate {
710Sstevel@tonic-gate sysret_t rval; /* return value from stat() */
72*11798SRoger.Faulkner@Sun.COM argdes_t argd[4]; /* arg descriptors for fstatat() */
730Sstevel@tonic-gate argdes_t *adp = &argd[0]; /* first argument */
74*11798SRoger.Faulkner@Sun.COM int syscall; /* SYS_fstatat or SYS_fstatat64 */
750Sstevel@tonic-gate int error;
760Sstevel@tonic-gate #ifdef _LP64
770Sstevel@tonic-gate struct stat64_32 statb64_32;
780Sstevel@tonic-gate #endif /* _LP64 */
790Sstevel@tonic-gate
800Sstevel@tonic-gate if (Pr == NULL) /* no subject process */
810Sstevel@tonic-gate return (stat(path, buf));
820Sstevel@tonic-gate
83*11798SRoger.Faulkner@Sun.COM if (Pstatus(Pr)->pr_dmodel != PR_MODEL_NATIVE) {
84*11798SRoger.Faulkner@Sun.COM /* 64-bit process controls 32-bit subject process */
85*11798SRoger.Faulkner@Sun.COM syscall = SYS_fstatat64;
86*11798SRoger.Faulkner@Sun.COM } else {
87*11798SRoger.Faulkner@Sun.COM syscall = SYS_fstatat;
88*11798SRoger.Faulkner@Sun.COM }
89*11798SRoger.Faulkner@Sun.COM
90*11798SRoger.Faulkner@Sun.COM adp->arg_value = AT_FDCWD;
910Sstevel@tonic-gate adp->arg_object = NULL;
920Sstevel@tonic-gate adp->arg_type = AT_BYVAL;
930Sstevel@tonic-gate adp->arg_inout = AI_INPUT;
940Sstevel@tonic-gate adp->arg_size = 0;
95*11798SRoger.Faulkner@Sun.COM adp++; /* move to path argument */
960Sstevel@tonic-gate
970Sstevel@tonic-gate adp->arg_value = 0;
980Sstevel@tonic-gate adp->arg_object = (void *)path;
990Sstevel@tonic-gate adp->arg_type = AT_BYREF;
1000Sstevel@tonic-gate adp->arg_inout = AI_INPUT;
1010Sstevel@tonic-gate adp->arg_size = strlen(path) + 1;
1020Sstevel@tonic-gate adp++; /* move to buffer argument */
1030Sstevel@tonic-gate
1040Sstevel@tonic-gate adp->arg_value = 0;
1050Sstevel@tonic-gate adp->arg_type = AT_BYREF;
1060Sstevel@tonic-gate adp->arg_inout = AI_OUTPUT;
1070Sstevel@tonic-gate #ifdef _LP64
1080Sstevel@tonic-gate if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32) {
1090Sstevel@tonic-gate adp->arg_object = &statb64_32;
1100Sstevel@tonic-gate adp->arg_size = sizeof (statb64_32);
1110Sstevel@tonic-gate } else {
1120Sstevel@tonic-gate adp->arg_object = buf;
1130Sstevel@tonic-gate adp->arg_size = sizeof (*buf);
1140Sstevel@tonic-gate }
1150Sstevel@tonic-gate #else /* _LP64 */
1160Sstevel@tonic-gate adp->arg_object = buf;
1170Sstevel@tonic-gate adp->arg_size = sizeof (*buf);
1180Sstevel@tonic-gate #endif /* _LP64 */
119*11798SRoger.Faulkner@Sun.COM adp++; /* move to flags argument */
1200Sstevel@tonic-gate
121*11798SRoger.Faulkner@Sun.COM adp->arg_value = 0;
122*11798SRoger.Faulkner@Sun.COM adp->arg_object = NULL;
123*11798SRoger.Faulkner@Sun.COM adp->arg_type = AT_BYVAL;
124*11798SRoger.Faulkner@Sun.COM adp->arg_inout = AI_INPUT;
125*11798SRoger.Faulkner@Sun.COM adp->arg_size = 0;
126*11798SRoger.Faulkner@Sun.COM
127*11798SRoger.Faulkner@Sun.COM error = Psyscall(Pr, &rval, syscall, 4, &argd[0]);
1280Sstevel@tonic-gate
1290Sstevel@tonic-gate if (error) {
1300Sstevel@tonic-gate errno = (error > 0)? error : ENOSYS;
1310Sstevel@tonic-gate return (-1);
1320Sstevel@tonic-gate }
1330Sstevel@tonic-gate #ifdef _LP64
1340Sstevel@tonic-gate if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32)
1350Sstevel@tonic-gate stat64_32_to_n(&statb64_32, buf);
1360Sstevel@tonic-gate #endif /* _LP64 */
1370Sstevel@tonic-gate return (0);
1380Sstevel@tonic-gate }
1390Sstevel@tonic-gate
1400Sstevel@tonic-gate /*
1410Sstevel@tonic-gate * lstat() system call -- executed by subject process
1420Sstevel@tonic-gate */
1430Sstevel@tonic-gate int
pr_lstat(struct ps_prochandle * Pr,const char * path,struct stat * buf)1440Sstevel@tonic-gate pr_lstat(struct ps_prochandle *Pr, const char *path, struct stat *buf)
1450Sstevel@tonic-gate {
146*11798SRoger.Faulkner@Sun.COM sysret_t rval; /* return value from stat() */
147*11798SRoger.Faulkner@Sun.COM argdes_t argd[4]; /* arg descriptors for fstatat() */
1480Sstevel@tonic-gate argdes_t *adp = &argd[0]; /* first argument */
149*11798SRoger.Faulkner@Sun.COM int syscall; /* SYS_fstatat or SYS_fstatat64 */
1500Sstevel@tonic-gate int error;
1510Sstevel@tonic-gate #ifdef _LP64
1520Sstevel@tonic-gate struct stat64_32 statb64_32;
1530Sstevel@tonic-gate #endif /* _LP64 */
1540Sstevel@tonic-gate
1550Sstevel@tonic-gate if (Pr == NULL) /* no subject process */
1560Sstevel@tonic-gate return (lstat(path, buf));
1570Sstevel@tonic-gate
158*11798SRoger.Faulkner@Sun.COM if (Pstatus(Pr)->pr_dmodel != PR_MODEL_NATIVE) {
159*11798SRoger.Faulkner@Sun.COM /* 64-bit process controls 32-bit subject process */
160*11798SRoger.Faulkner@Sun.COM syscall = SYS_fstatat64;
161*11798SRoger.Faulkner@Sun.COM } else {
162*11798SRoger.Faulkner@Sun.COM syscall = SYS_fstatat;
163*11798SRoger.Faulkner@Sun.COM }
164*11798SRoger.Faulkner@Sun.COM
165*11798SRoger.Faulkner@Sun.COM adp->arg_value = AT_FDCWD;
1660Sstevel@tonic-gate adp->arg_object = NULL;
1670Sstevel@tonic-gate adp->arg_type = AT_BYVAL;
1680Sstevel@tonic-gate adp->arg_inout = AI_INPUT;
1690Sstevel@tonic-gate adp->arg_size = 0;
170*11798SRoger.Faulkner@Sun.COM adp++; /* move to path argument */
1710Sstevel@tonic-gate
1720Sstevel@tonic-gate adp->arg_value = 0;
1730Sstevel@tonic-gate adp->arg_object = (void *)path;
1740Sstevel@tonic-gate adp->arg_type = AT_BYREF;
1750Sstevel@tonic-gate adp->arg_inout = AI_INPUT;
1760Sstevel@tonic-gate adp->arg_size = strlen(path) + 1;
1770Sstevel@tonic-gate adp++; /* move to buffer argument */
1780Sstevel@tonic-gate
1790Sstevel@tonic-gate adp->arg_value = 0;
1800Sstevel@tonic-gate adp->arg_type = AT_BYREF;
1810Sstevel@tonic-gate adp->arg_inout = AI_OUTPUT;
1820Sstevel@tonic-gate #ifdef _LP64
1830Sstevel@tonic-gate if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32) {
1840Sstevel@tonic-gate adp->arg_object = &statb64_32;
1850Sstevel@tonic-gate adp->arg_size = sizeof (statb64_32);
1860Sstevel@tonic-gate } else {
1870Sstevel@tonic-gate adp->arg_object = buf;
1880Sstevel@tonic-gate adp->arg_size = sizeof (*buf);
1890Sstevel@tonic-gate }
1900Sstevel@tonic-gate #else /* _LP64 */
1910Sstevel@tonic-gate adp->arg_object = buf;
1920Sstevel@tonic-gate adp->arg_size = sizeof (*buf);
1930Sstevel@tonic-gate #endif /* _LP64 */
194*11798SRoger.Faulkner@Sun.COM adp++; /* move to flags argument */
1950Sstevel@tonic-gate
196*11798SRoger.Faulkner@Sun.COM adp->arg_value = AT_SYMLINK_NOFOLLOW;
197*11798SRoger.Faulkner@Sun.COM adp->arg_object = NULL;
198*11798SRoger.Faulkner@Sun.COM adp->arg_type = AT_BYVAL;
199*11798SRoger.Faulkner@Sun.COM adp->arg_inout = AI_INPUT;
200*11798SRoger.Faulkner@Sun.COM adp->arg_size = 0;
201*11798SRoger.Faulkner@Sun.COM
202*11798SRoger.Faulkner@Sun.COM error = Psyscall(Pr, &rval, syscall, 4, &argd[0]);
2030Sstevel@tonic-gate
2040Sstevel@tonic-gate if (error) {
2050Sstevel@tonic-gate errno = (error > 0)? error : ENOSYS;
2060Sstevel@tonic-gate return (-1);
2070Sstevel@tonic-gate }
2080Sstevel@tonic-gate #ifdef _LP64
2090Sstevel@tonic-gate if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32)
2100Sstevel@tonic-gate stat64_32_to_n(&statb64_32, buf);
2110Sstevel@tonic-gate #endif /* _LP64 */
2120Sstevel@tonic-gate return (0);
2130Sstevel@tonic-gate }
2140Sstevel@tonic-gate
2150Sstevel@tonic-gate /*
2160Sstevel@tonic-gate * fstat() system call -- executed by subject process
2170Sstevel@tonic-gate */
2180Sstevel@tonic-gate int
pr_fstat(struct ps_prochandle * Pr,int fd,struct stat * buf)2190Sstevel@tonic-gate pr_fstat(struct ps_prochandle *Pr, int fd, struct stat *buf)
2200Sstevel@tonic-gate {
221*11798SRoger.Faulkner@Sun.COM sysret_t rval; /* return value from stat() */
222*11798SRoger.Faulkner@Sun.COM argdes_t argd[4]; /* arg descriptors for fstatat() */
2230Sstevel@tonic-gate argdes_t *adp = &argd[0]; /* first argument */
224*11798SRoger.Faulkner@Sun.COM int syscall; /* SYS_fstatat or SYS_fstatat64 */
2250Sstevel@tonic-gate int error;
2260Sstevel@tonic-gate #ifdef _LP64
2270Sstevel@tonic-gate struct stat64_32 statb64_32;
2280Sstevel@tonic-gate #endif /* _LP64 */
2290Sstevel@tonic-gate
2300Sstevel@tonic-gate if (Pr == NULL) /* no subject process */
2310Sstevel@tonic-gate return (fstat(fd, buf));
2320Sstevel@tonic-gate
233*11798SRoger.Faulkner@Sun.COM if (Pstatus(Pr)->pr_dmodel != PR_MODEL_NATIVE) {
234*11798SRoger.Faulkner@Sun.COM /* 64-bit process controls 32-bit subject process */
235*11798SRoger.Faulkner@Sun.COM syscall = SYS_fstatat64;
236*11798SRoger.Faulkner@Sun.COM } else {
237*11798SRoger.Faulkner@Sun.COM syscall = SYS_fstatat;
238*11798SRoger.Faulkner@Sun.COM }
239*11798SRoger.Faulkner@Sun.COM
240*11798SRoger.Faulkner@Sun.COM adp->arg_value = fd;
2410Sstevel@tonic-gate adp->arg_object = NULL;
2420Sstevel@tonic-gate adp->arg_type = AT_BYVAL;
2430Sstevel@tonic-gate adp->arg_inout = AI_INPUT;
2440Sstevel@tonic-gate adp->arg_size = 0;
245*11798SRoger.Faulkner@Sun.COM adp++; /* move to path argument */
2460Sstevel@tonic-gate
247*11798SRoger.Faulkner@Sun.COM adp->arg_value = 0;
2480Sstevel@tonic-gate adp->arg_object = NULL;
2490Sstevel@tonic-gate adp->arg_type = AT_BYVAL;
2500Sstevel@tonic-gate adp->arg_inout = AI_INPUT;
2510Sstevel@tonic-gate adp->arg_size = 0;
2520Sstevel@tonic-gate adp++; /* move to buffer argument */
2530Sstevel@tonic-gate
2540Sstevel@tonic-gate adp->arg_value = 0;
2550Sstevel@tonic-gate adp->arg_type = AT_BYREF;
2560Sstevel@tonic-gate adp->arg_inout = AI_OUTPUT;
2570Sstevel@tonic-gate #ifdef _LP64
2580Sstevel@tonic-gate if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32) {
2590Sstevel@tonic-gate adp->arg_object = &statb64_32;
2600Sstevel@tonic-gate adp->arg_size = sizeof (statb64_32);
2610Sstevel@tonic-gate } else {
2620Sstevel@tonic-gate adp->arg_object = buf;
2630Sstevel@tonic-gate adp->arg_size = sizeof (*buf);
2640Sstevel@tonic-gate }
2650Sstevel@tonic-gate #else /* _LP64 */
2660Sstevel@tonic-gate adp->arg_object = buf;
2670Sstevel@tonic-gate adp->arg_size = sizeof (*buf);
2680Sstevel@tonic-gate #endif /* _LP64 */
269*11798SRoger.Faulkner@Sun.COM adp++; /* move to flags argument */
2700Sstevel@tonic-gate
271*11798SRoger.Faulkner@Sun.COM adp->arg_value = 0;
272*11798SRoger.Faulkner@Sun.COM adp->arg_object = NULL;
273*11798SRoger.Faulkner@Sun.COM adp->arg_type = AT_BYVAL;
274*11798SRoger.Faulkner@Sun.COM adp->arg_inout = AI_INPUT;
275*11798SRoger.Faulkner@Sun.COM adp->arg_size = 0;
276*11798SRoger.Faulkner@Sun.COM
277*11798SRoger.Faulkner@Sun.COM error = Psyscall(Pr, &rval, syscall, 4, &argd[0]);
2780Sstevel@tonic-gate
2790Sstevel@tonic-gate if (error) {
2800Sstevel@tonic-gate errno = (error > 0)? error : ENOSYS;
2810Sstevel@tonic-gate return (-1);
2820Sstevel@tonic-gate }
2830Sstevel@tonic-gate #ifdef _LP64
2840Sstevel@tonic-gate if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32)
2850Sstevel@tonic-gate stat64_32_to_n(&statb64_32, buf);
2860Sstevel@tonic-gate #endif /* _LP64 */
2870Sstevel@tonic-gate return (0);
2880Sstevel@tonic-gate }
2890Sstevel@tonic-gate
2900Sstevel@tonic-gate /*
2910Sstevel@tonic-gate * stat64() system call -- executed by subject process
2920Sstevel@tonic-gate */
2930Sstevel@tonic-gate int
pr_stat64(struct ps_prochandle * Pr,const char * path,struct stat64 * buf)2940Sstevel@tonic-gate pr_stat64(struct ps_prochandle *Pr, const char *path, struct stat64 *buf)
2950Sstevel@tonic-gate {
296*11798SRoger.Faulkner@Sun.COM sysret_t rval; /* return value from stat() */
297*11798SRoger.Faulkner@Sun.COM argdes_t argd[4]; /* arg descriptors for fstatat() */
2980Sstevel@tonic-gate argdes_t *adp = &argd[0]; /* first argument */
299*11798SRoger.Faulkner@Sun.COM int syscall; /* SYS_fstatat or SYS_fstatat64 */
3000Sstevel@tonic-gate int error;
3010Sstevel@tonic-gate #ifdef _LP64
3020Sstevel@tonic-gate struct stat64_32 statb64_32;
3030Sstevel@tonic-gate #endif /* _LP64 */
3040Sstevel@tonic-gate
3050Sstevel@tonic-gate if (Pr == NULL) /* no subject process */
3060Sstevel@tonic-gate return (stat64(path, buf));
3070Sstevel@tonic-gate
3080Sstevel@tonic-gate if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32) {
3090Sstevel@tonic-gate /*
3100Sstevel@tonic-gate * 32-bit native and
3110Sstevel@tonic-gate * 64-bit process controls 32-bit subject process
3120Sstevel@tonic-gate */
313*11798SRoger.Faulkner@Sun.COM syscall = SYS_fstatat64;
3140Sstevel@tonic-gate } else {
3150Sstevel@tonic-gate /* 64-bit native */
316*11798SRoger.Faulkner@Sun.COM syscall = SYS_fstatat;
3170Sstevel@tonic-gate }
3180Sstevel@tonic-gate
319*11798SRoger.Faulkner@Sun.COM adp->arg_value = AT_FDCWD;
320*11798SRoger.Faulkner@Sun.COM adp->arg_object = NULL;
321*11798SRoger.Faulkner@Sun.COM adp->arg_type = AT_BYVAL;
322*11798SRoger.Faulkner@Sun.COM adp->arg_inout = AI_INPUT;
323*11798SRoger.Faulkner@Sun.COM adp->arg_size = 0;
324*11798SRoger.Faulkner@Sun.COM adp++; /* move to path argument */
325*11798SRoger.Faulkner@Sun.COM
3260Sstevel@tonic-gate adp->arg_value = 0;
3270Sstevel@tonic-gate adp->arg_object = (void *)path;
3280Sstevel@tonic-gate adp->arg_type = AT_BYREF;
3290Sstevel@tonic-gate adp->arg_inout = AI_INPUT;
3300Sstevel@tonic-gate adp->arg_size = strlen(path) + 1;
3310Sstevel@tonic-gate adp++; /* move to buffer argument */
3320Sstevel@tonic-gate
3330Sstevel@tonic-gate adp->arg_value = 0;
3340Sstevel@tonic-gate adp->arg_type = AT_BYREF;
3350Sstevel@tonic-gate adp->arg_inout = AI_OUTPUT;
3360Sstevel@tonic-gate #ifdef _LP64
3370Sstevel@tonic-gate if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32) {
3380Sstevel@tonic-gate adp->arg_object = &statb64_32;
3390Sstevel@tonic-gate adp->arg_size = sizeof (statb64_32);
3400Sstevel@tonic-gate } else {
3410Sstevel@tonic-gate adp->arg_object = buf;
3420Sstevel@tonic-gate adp->arg_size = sizeof (*buf);
3430Sstevel@tonic-gate }
3440Sstevel@tonic-gate #else /* _LP64 */
3450Sstevel@tonic-gate adp->arg_object = buf;
3460Sstevel@tonic-gate adp->arg_size = sizeof (*buf);
3470Sstevel@tonic-gate #endif /* _LP64 */
348*11798SRoger.Faulkner@Sun.COM adp++; /* move to flags argument */
3490Sstevel@tonic-gate
350*11798SRoger.Faulkner@Sun.COM adp->arg_value = 0;
351*11798SRoger.Faulkner@Sun.COM adp->arg_object = NULL;
352*11798SRoger.Faulkner@Sun.COM adp->arg_type = AT_BYVAL;
353*11798SRoger.Faulkner@Sun.COM adp->arg_inout = AI_INPUT;
354*11798SRoger.Faulkner@Sun.COM adp->arg_size = 0;
355*11798SRoger.Faulkner@Sun.COM
356*11798SRoger.Faulkner@Sun.COM error = Psyscall(Pr, &rval, syscall, 4, &argd[0]);
3570Sstevel@tonic-gate
3580Sstevel@tonic-gate if (error) {
3590Sstevel@tonic-gate errno = (error > 0)? error : ENOSYS;
3600Sstevel@tonic-gate return (-1);
3610Sstevel@tonic-gate }
3620Sstevel@tonic-gate #ifdef _LP64
3630Sstevel@tonic-gate if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32)
3640Sstevel@tonic-gate stat64_32_to_n(&statb64_32, (struct stat *)buf);
3650Sstevel@tonic-gate #endif /* _LP64 */
3660Sstevel@tonic-gate return (0);
3670Sstevel@tonic-gate }
3680Sstevel@tonic-gate
3690Sstevel@tonic-gate /*
3700Sstevel@tonic-gate * lstat64() system call -- executed by subject process
3710Sstevel@tonic-gate */
3720Sstevel@tonic-gate int
pr_lstat64(struct ps_prochandle * Pr,const char * path,struct stat64 * buf)3730Sstevel@tonic-gate pr_lstat64(struct ps_prochandle *Pr, const char *path, struct stat64 *buf)
3740Sstevel@tonic-gate {
375*11798SRoger.Faulkner@Sun.COM sysret_t rval; /* return value from stat() */
376*11798SRoger.Faulkner@Sun.COM argdes_t argd[4]; /* arg descriptors for fstatat() */
3770Sstevel@tonic-gate argdes_t *adp = &argd[0]; /* first argument */
378*11798SRoger.Faulkner@Sun.COM int syscall; /* SYS_fstatat or SYS_fstatat64 */
3790Sstevel@tonic-gate int error;
3800Sstevel@tonic-gate #ifdef _LP64
3810Sstevel@tonic-gate struct stat64_32 statb64_32;
3820Sstevel@tonic-gate #endif /* _LP64 */
3830Sstevel@tonic-gate
3840Sstevel@tonic-gate if (Pr == NULL) /* no subject process */
3850Sstevel@tonic-gate return (lstat64(path, buf));
3860Sstevel@tonic-gate
3870Sstevel@tonic-gate if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32) {
3880Sstevel@tonic-gate /*
3890Sstevel@tonic-gate * 32-bit native and
3900Sstevel@tonic-gate * 64-bit process controls 32-bit subject process
3910Sstevel@tonic-gate */
392*11798SRoger.Faulkner@Sun.COM syscall = SYS_fstatat64;
3930Sstevel@tonic-gate } else {
3940Sstevel@tonic-gate /* 64-bit native */
395*11798SRoger.Faulkner@Sun.COM syscall = SYS_fstatat;
3960Sstevel@tonic-gate }
3970Sstevel@tonic-gate
398*11798SRoger.Faulkner@Sun.COM adp->arg_value = AT_FDCWD;
399*11798SRoger.Faulkner@Sun.COM adp->arg_object = NULL;
400*11798SRoger.Faulkner@Sun.COM adp->arg_type = AT_BYVAL;
401*11798SRoger.Faulkner@Sun.COM adp->arg_inout = AI_INPUT;
402*11798SRoger.Faulkner@Sun.COM adp->arg_size = 0;
403*11798SRoger.Faulkner@Sun.COM adp++; /* move to path argument */
404*11798SRoger.Faulkner@Sun.COM
4050Sstevel@tonic-gate adp->arg_value = 0;
4060Sstevel@tonic-gate adp->arg_object = (void *)path;
4070Sstevel@tonic-gate adp->arg_type = AT_BYREF;
4080Sstevel@tonic-gate adp->arg_inout = AI_INPUT;
4090Sstevel@tonic-gate adp->arg_size = strlen(path) + 1;
4100Sstevel@tonic-gate adp++; /* move to buffer argument */
4110Sstevel@tonic-gate
4120Sstevel@tonic-gate adp->arg_value = 0;
4130Sstevel@tonic-gate adp->arg_type = AT_BYREF;
4140Sstevel@tonic-gate adp->arg_inout = AI_OUTPUT;
4150Sstevel@tonic-gate #ifdef _LP64
4160Sstevel@tonic-gate if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32) {
4170Sstevel@tonic-gate adp->arg_object = &statb64_32;
4180Sstevel@tonic-gate adp->arg_size = sizeof (statb64_32);
4190Sstevel@tonic-gate } else {
4200Sstevel@tonic-gate adp->arg_object = buf;
4210Sstevel@tonic-gate adp->arg_size = sizeof (*buf);
4220Sstevel@tonic-gate }
4230Sstevel@tonic-gate #else /* _LP64 */
4240Sstevel@tonic-gate adp->arg_object = buf;
4250Sstevel@tonic-gate adp->arg_size = sizeof (*buf);
4260Sstevel@tonic-gate #endif /* _LP64 */
427*11798SRoger.Faulkner@Sun.COM adp++; /* move to flags argument */
4280Sstevel@tonic-gate
429*11798SRoger.Faulkner@Sun.COM adp->arg_value = AT_SYMLINK_NOFOLLOW;
430*11798SRoger.Faulkner@Sun.COM adp->arg_object = NULL;
431*11798SRoger.Faulkner@Sun.COM adp->arg_type = AT_BYVAL;
432*11798SRoger.Faulkner@Sun.COM adp->arg_inout = AI_INPUT;
433*11798SRoger.Faulkner@Sun.COM adp->arg_size = 0;
434*11798SRoger.Faulkner@Sun.COM
435*11798SRoger.Faulkner@Sun.COM error = Psyscall(Pr, &rval, syscall, 4, &argd[0]);
4360Sstevel@tonic-gate
4370Sstevel@tonic-gate if (error) {
4380Sstevel@tonic-gate errno = (error > 0)? error : ENOSYS;
4390Sstevel@tonic-gate return (-1);
4400Sstevel@tonic-gate }
4410Sstevel@tonic-gate #ifdef _LP64
4420Sstevel@tonic-gate if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32)
4430Sstevel@tonic-gate stat64_32_to_n(&statb64_32, (struct stat *)buf);
4440Sstevel@tonic-gate #endif /* _LP64 */
4450Sstevel@tonic-gate return (0);
4460Sstevel@tonic-gate }
4470Sstevel@tonic-gate
4480Sstevel@tonic-gate /*
4490Sstevel@tonic-gate * fstat64() system call -- executed by subject process
4500Sstevel@tonic-gate */
4510Sstevel@tonic-gate int
pr_fstat64(struct ps_prochandle * Pr,int fd,struct stat64 * buf)4520Sstevel@tonic-gate pr_fstat64(struct ps_prochandle *Pr, int fd, struct stat64 *buf)
4530Sstevel@tonic-gate {
454*11798SRoger.Faulkner@Sun.COM sysret_t rval; /* return value from stat() */
455*11798SRoger.Faulkner@Sun.COM argdes_t argd[4]; /* arg descriptors for fstatat() */
4560Sstevel@tonic-gate argdes_t *adp = &argd[0]; /* first argument */
457*11798SRoger.Faulkner@Sun.COM int syscall; /* SYS_fstatat or SYS_fstatat64 */
4580Sstevel@tonic-gate int error;
4590Sstevel@tonic-gate #ifdef _LP64
4600Sstevel@tonic-gate struct stat64_32 statb64_32;
4610Sstevel@tonic-gate #endif /* _LP64 */
4620Sstevel@tonic-gate
4630Sstevel@tonic-gate if (Pr == NULL) /* no subject process */
4640Sstevel@tonic-gate return (fstat64(fd, buf));
4650Sstevel@tonic-gate
4660Sstevel@tonic-gate if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32) {
4670Sstevel@tonic-gate /*
4680Sstevel@tonic-gate * 32-bit native and
4690Sstevel@tonic-gate * 64-bit process controls 32-bit subject process
4700Sstevel@tonic-gate */
471*11798SRoger.Faulkner@Sun.COM syscall = SYS_fstatat64;
4720Sstevel@tonic-gate } else {
4730Sstevel@tonic-gate /* 64-bit native */
474*11798SRoger.Faulkner@Sun.COM syscall = SYS_fstatat;
4750Sstevel@tonic-gate }
4760Sstevel@tonic-gate
4770Sstevel@tonic-gate adp->arg_value = fd;
4780Sstevel@tonic-gate adp->arg_object = NULL;
4790Sstevel@tonic-gate adp->arg_type = AT_BYVAL;
4800Sstevel@tonic-gate adp->arg_inout = AI_INPUT;
4810Sstevel@tonic-gate adp->arg_size = 0;
482*11798SRoger.Faulkner@Sun.COM adp++; /* move to path argument */
483*11798SRoger.Faulkner@Sun.COM
484*11798SRoger.Faulkner@Sun.COM adp->arg_value = 0;
485*11798SRoger.Faulkner@Sun.COM adp->arg_object = NULL;
486*11798SRoger.Faulkner@Sun.COM adp->arg_type = AT_BYVAL;
487*11798SRoger.Faulkner@Sun.COM adp->arg_inout = AI_INPUT;
488*11798SRoger.Faulkner@Sun.COM adp->arg_size = 0;
4890Sstevel@tonic-gate adp++; /* move to buffer argument */
4900Sstevel@tonic-gate
4910Sstevel@tonic-gate adp->arg_value = 0;
4920Sstevel@tonic-gate adp->arg_type = AT_BYREF;
4930Sstevel@tonic-gate adp->arg_inout = AI_OUTPUT;
4940Sstevel@tonic-gate #ifdef _LP64
4950Sstevel@tonic-gate if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32) {
4960Sstevel@tonic-gate adp->arg_object = &statb64_32;
4970Sstevel@tonic-gate adp->arg_size = sizeof (statb64_32);
4980Sstevel@tonic-gate } else {
4990Sstevel@tonic-gate adp->arg_object = buf;
5000Sstevel@tonic-gate adp->arg_size = sizeof (*buf);
5010Sstevel@tonic-gate }
5020Sstevel@tonic-gate #else /* _LP64 */
5030Sstevel@tonic-gate adp->arg_object = buf;
5040Sstevel@tonic-gate adp->arg_size = sizeof (*buf);
5050Sstevel@tonic-gate #endif /* _LP64 */
506*11798SRoger.Faulkner@Sun.COM adp++; /* move to flags argument */
5070Sstevel@tonic-gate
508*11798SRoger.Faulkner@Sun.COM adp->arg_value = 0;
509*11798SRoger.Faulkner@Sun.COM adp->arg_object = NULL;
510*11798SRoger.Faulkner@Sun.COM adp->arg_type = AT_BYVAL;
511*11798SRoger.Faulkner@Sun.COM adp->arg_inout = AI_INPUT;
512*11798SRoger.Faulkner@Sun.COM adp->arg_size = 0;
513*11798SRoger.Faulkner@Sun.COM
514*11798SRoger.Faulkner@Sun.COM error = Psyscall(Pr, &rval, syscall, 4, &argd[0]);
5150Sstevel@tonic-gate
5160Sstevel@tonic-gate if (error) {
5170Sstevel@tonic-gate errno = (error > 0)? error : ENOSYS;
5180Sstevel@tonic-gate return (-1);
5190Sstevel@tonic-gate }
5200Sstevel@tonic-gate #ifdef _LP64
5210Sstevel@tonic-gate if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32)
5220Sstevel@tonic-gate stat64_32_to_n(&statb64_32, (struct stat *)buf);
5230Sstevel@tonic-gate #endif /* _LP64 */
5240Sstevel@tonic-gate return (0);
5250Sstevel@tonic-gate }
526