xref: /onnv-gate/usr/src/lib/libproc/common/pr_stat.c (revision 11798:1e7f1f154004)
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