17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*8fd04b83SRoger A. Faulkner  * Common Development and Distribution License (the "License").
6*8fd04b83SRoger A. Faulkner  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
21*8fd04b83SRoger A. Faulkner 
227c478bd9Sstevel@tonic-gate /*
23*8fd04b83SRoger A. Faulkner  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
24*8fd04b83SRoger A. Faulkner  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate #include <stdlib.h>
287c478bd9Sstevel@tonic-gate #include <unistd.h>
297c478bd9Sstevel@tonic-gate #include <string.h>
307c478bd9Sstevel@tonic-gate #include <fcntl.h>
317c478bd9Sstevel@tonic-gate #include <errno.h>
327c478bd9Sstevel@tonic-gate #include "libproc.h"
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate /*
357c478bd9Sstevel@tonic-gate  * open() system call -- executed by subject process.
367c478bd9Sstevel@tonic-gate  */
377c478bd9Sstevel@tonic-gate int
pr_open(struct ps_prochandle * Pr,const char * filename,int flags,mode_t mode)387c478bd9Sstevel@tonic-gate pr_open(struct ps_prochandle *Pr, const char *filename, int flags, mode_t mode)
397c478bd9Sstevel@tonic-gate {
40*8fd04b83SRoger A. Faulkner 	sysret_t rval;			/* return value from openat() */
41*8fd04b83SRoger A. Faulkner 	argdes_t argd[4];		/* arg descriptors for openat() */
427c478bd9Sstevel@tonic-gate 	argdes_t *adp;
437c478bd9Sstevel@tonic-gate 	int error;
447c478bd9Sstevel@tonic-gate 
457c478bd9Sstevel@tonic-gate 	if (Pr == NULL)		/* no subject process */
467c478bd9Sstevel@tonic-gate 		return (open(filename, flags, mode));
477c478bd9Sstevel@tonic-gate 
48*8fd04b83SRoger A. Faulkner 	adp = &argd[0];		/* AT_FDCWD argument */
49*8fd04b83SRoger A. Faulkner 	adp->arg_value = AT_FDCWD;
50*8fd04b83SRoger A. Faulkner 	adp->arg_object = NULL;
51*8fd04b83SRoger A. Faulkner 	adp->arg_type = AT_BYVAL;
52*8fd04b83SRoger A. Faulkner 	adp->arg_inout = AI_INPUT;
53*8fd04b83SRoger A. Faulkner 	adp->arg_size = 0;
54*8fd04b83SRoger A. Faulkner 
55*8fd04b83SRoger A. Faulkner 	adp++;			/* filename argument */
567c478bd9Sstevel@tonic-gate 	adp->arg_value = 0;
577c478bd9Sstevel@tonic-gate 	adp->arg_object = (void *)filename;
587c478bd9Sstevel@tonic-gate 	adp->arg_type = AT_BYREF;
597c478bd9Sstevel@tonic-gate 	adp->arg_inout = AI_INPUT;
607c478bd9Sstevel@tonic-gate 	adp->arg_size = strlen(filename)+1;
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate 	adp++;			/* flags argument */
637c478bd9Sstevel@tonic-gate 	adp->arg_value = (long)flags;
647c478bd9Sstevel@tonic-gate 	adp->arg_object = NULL;
657c478bd9Sstevel@tonic-gate 	adp->arg_type = AT_BYVAL;
667c478bd9Sstevel@tonic-gate 	adp->arg_inout = AI_INPUT;
677c478bd9Sstevel@tonic-gate 	adp->arg_size = 0;
687c478bd9Sstevel@tonic-gate 
697c478bd9Sstevel@tonic-gate 	adp++;			/* mode argument */
707c478bd9Sstevel@tonic-gate 	adp->arg_value = (long)mode;
717c478bd9Sstevel@tonic-gate 	adp->arg_object = NULL;
727c478bd9Sstevel@tonic-gate 	adp->arg_type = AT_BYVAL;
737c478bd9Sstevel@tonic-gate 	adp->arg_inout = AI_INPUT;
747c478bd9Sstevel@tonic-gate 	adp->arg_size = 0;
757c478bd9Sstevel@tonic-gate 
76*8fd04b83SRoger A. Faulkner 	error = Psyscall(Pr, &rval, SYS_openat, 4, &argd[0]);
777c478bd9Sstevel@tonic-gate 
787c478bd9Sstevel@tonic-gate 	if (error) {
797c478bd9Sstevel@tonic-gate 		errno = (error > 0)? error : ENOSYS;
807c478bd9Sstevel@tonic-gate 		return (-1);
817c478bd9Sstevel@tonic-gate 	}
827c478bd9Sstevel@tonic-gate 	return (rval.sys_rval1);
837c478bd9Sstevel@tonic-gate }
847c478bd9Sstevel@tonic-gate 
857c478bd9Sstevel@tonic-gate /*
867c478bd9Sstevel@tonic-gate  * creat() system call -- executed by subject process.
877c478bd9Sstevel@tonic-gate  */
887c478bd9Sstevel@tonic-gate int
pr_creat(struct ps_prochandle * Pr,const char * filename,mode_t mode)897c478bd9Sstevel@tonic-gate pr_creat(struct ps_prochandle *Pr, const char *filename, mode_t mode)
907c478bd9Sstevel@tonic-gate {
91*8fd04b83SRoger A. Faulkner 	sysret_t rval;			/* return value from openat() */
92*8fd04b83SRoger A. Faulkner 	argdes_t argd[4];		/* arg descriptors for openat() */
937c478bd9Sstevel@tonic-gate 	argdes_t *adp;
947c478bd9Sstevel@tonic-gate 	int error;
957c478bd9Sstevel@tonic-gate 
967c478bd9Sstevel@tonic-gate 	if (Pr == NULL)		/* no subject process */
977c478bd9Sstevel@tonic-gate 		return (creat(filename, mode));
987c478bd9Sstevel@tonic-gate 
99*8fd04b83SRoger A. Faulkner 	adp = &argd[0];		/* AT_FDCWD argument */
100*8fd04b83SRoger A. Faulkner 	adp->arg_value = AT_FDCWD;
101*8fd04b83SRoger A. Faulkner 	adp->arg_object = NULL;
102*8fd04b83SRoger A. Faulkner 	adp->arg_type = AT_BYVAL;
103*8fd04b83SRoger A. Faulkner 	adp->arg_inout = AI_INPUT;
104*8fd04b83SRoger A. Faulkner 	adp->arg_size = 0;
105*8fd04b83SRoger A. Faulkner 
106*8fd04b83SRoger A. Faulkner 	adp++;			/* filename argument */
1077c478bd9Sstevel@tonic-gate 	adp->arg_value = 0;
1087c478bd9Sstevel@tonic-gate 	adp->arg_object = (void *)filename;
1097c478bd9Sstevel@tonic-gate 	adp->arg_type = AT_BYREF;
1107c478bd9Sstevel@tonic-gate 	adp->arg_inout = AI_INPUT;
1117c478bd9Sstevel@tonic-gate 	adp->arg_size = strlen(filename)+1;
1127c478bd9Sstevel@tonic-gate 
113*8fd04b83SRoger A. Faulkner 	adp++;			/* flags argument */
114*8fd04b83SRoger A. Faulkner 	adp->arg_value = (O_WRONLY | O_CREAT | O_TRUNC);
115*8fd04b83SRoger A. Faulkner 	adp->arg_object = NULL;
116*8fd04b83SRoger A. Faulkner 	adp->arg_type = AT_BYVAL;
117*8fd04b83SRoger A. Faulkner 	adp->arg_inout = AI_INPUT;
118*8fd04b83SRoger A. Faulkner 	adp->arg_size = 0;
119*8fd04b83SRoger A. Faulkner 
1207c478bd9Sstevel@tonic-gate 	adp++;			/* mode argument */
1217c478bd9Sstevel@tonic-gate 	adp->arg_value = (long)mode;
1227c478bd9Sstevel@tonic-gate 	adp->arg_object = NULL;
1237c478bd9Sstevel@tonic-gate 	adp->arg_type = AT_BYVAL;
1247c478bd9Sstevel@tonic-gate 	adp->arg_inout = AI_INPUT;
1257c478bd9Sstevel@tonic-gate 	adp->arg_size = 0;
1267c478bd9Sstevel@tonic-gate 
127*8fd04b83SRoger A. Faulkner 	error = Psyscall(Pr, &rval, SYS_openat, 4, &argd[0]);
1287c478bd9Sstevel@tonic-gate 
1297c478bd9Sstevel@tonic-gate 	if (error) {
1307c478bd9Sstevel@tonic-gate 		errno = (error > 0)? error : ENOSYS;
1317c478bd9Sstevel@tonic-gate 		return (-1);
1327c478bd9Sstevel@tonic-gate 	}
1337c478bd9Sstevel@tonic-gate 	return (rval.sys_rval1);
1347c478bd9Sstevel@tonic-gate }
1357c478bd9Sstevel@tonic-gate 
1367c478bd9Sstevel@tonic-gate /*
1377c478bd9Sstevel@tonic-gate  * close() system call -- executed by subject process.
1387c478bd9Sstevel@tonic-gate  */
1397c478bd9Sstevel@tonic-gate int
pr_close(struct ps_prochandle * Pr,int fd)1407c478bd9Sstevel@tonic-gate pr_close(struct ps_prochandle *Pr, int fd)
1417c478bd9Sstevel@tonic-gate {
1427c478bd9Sstevel@tonic-gate 	sysret_t rval;			/* return value from close() */
1437c478bd9Sstevel@tonic-gate 	argdes_t argd[1];		/* arg descriptors for close() */
1447c478bd9Sstevel@tonic-gate 	argdes_t *adp;
1457c478bd9Sstevel@tonic-gate 	int error;
1467c478bd9Sstevel@tonic-gate 
1477c478bd9Sstevel@tonic-gate 	if (Pr == NULL)		/* no subject process */
1487c478bd9Sstevel@tonic-gate 		return (close(fd));
1497c478bd9Sstevel@tonic-gate 
1507c478bd9Sstevel@tonic-gate 	adp = &argd[0];		/* fd argument */
1517c478bd9Sstevel@tonic-gate 	adp->arg_value = (int)fd;
1527c478bd9Sstevel@tonic-gate 	adp->arg_object = NULL;
1537c478bd9Sstevel@tonic-gate 	adp->arg_type = AT_BYVAL;
1547c478bd9Sstevel@tonic-gate 	adp->arg_inout = AI_INPUT;
1557c478bd9Sstevel@tonic-gate 	adp->arg_size = 0;
1567c478bd9Sstevel@tonic-gate 
1577c478bd9Sstevel@tonic-gate 	error = Psyscall(Pr, &rval, SYS_close, 1, &argd[0]);
1587c478bd9Sstevel@tonic-gate 
1597c478bd9Sstevel@tonic-gate 	if (error) {
1607c478bd9Sstevel@tonic-gate 		errno = (error > 0)? error : ENOSYS;
1617c478bd9Sstevel@tonic-gate 		return (-1);
1627c478bd9Sstevel@tonic-gate 	}
1637c478bd9Sstevel@tonic-gate 	return (rval.sys_rval1);
1647c478bd9Sstevel@tonic-gate }
1657c478bd9Sstevel@tonic-gate 
1667c478bd9Sstevel@tonic-gate /*
1677c478bd9Sstevel@tonic-gate  * access() system call -- executed by subject process.
1687c478bd9Sstevel@tonic-gate  */
1697c478bd9Sstevel@tonic-gate int
pr_access(struct ps_prochandle * Pr,const char * path,int amode)1707c478bd9Sstevel@tonic-gate pr_access(struct ps_prochandle *Pr, const char *path, int amode)
1717c478bd9Sstevel@tonic-gate {
1727c478bd9Sstevel@tonic-gate 	sysret_t rval;			/* return from access() */
173*8fd04b83SRoger A. Faulkner 	argdes_t argd[4];		/* arg descriptors for access() */
1747c478bd9Sstevel@tonic-gate 	argdes_t *adp;
1757c478bd9Sstevel@tonic-gate 	int err;
1767c478bd9Sstevel@tonic-gate 
1777c478bd9Sstevel@tonic-gate 	if (Pr == NULL)		/* no subject process */
1787c478bd9Sstevel@tonic-gate 		return (access(path, amode));
1797c478bd9Sstevel@tonic-gate 
180*8fd04b83SRoger A. Faulkner 	adp = &argd[0];		/* directory fd argument */
181*8fd04b83SRoger A. Faulkner 	adp->arg_value = AT_FDCWD;
182*8fd04b83SRoger A. Faulkner 	adp->arg_object = NULL;
183*8fd04b83SRoger A. Faulkner 	adp->arg_type = AT_BYVAL;
184*8fd04b83SRoger A. Faulkner 	adp->arg_inout = AI_INPUT;
185*8fd04b83SRoger A. Faulkner 	adp->arg_size = 0;
186*8fd04b83SRoger A. Faulkner 
187*8fd04b83SRoger A. Faulkner 	adp++;			/* path argument */
1887c478bd9Sstevel@tonic-gate 	adp->arg_value = 0;
1897c478bd9Sstevel@tonic-gate 	adp->arg_object = (void *)path;
1907c478bd9Sstevel@tonic-gate 	adp->arg_type = AT_BYREF;
1917c478bd9Sstevel@tonic-gate 	adp->arg_inout = AI_INPUT;
1927c478bd9Sstevel@tonic-gate 	adp->arg_size = strlen(path) + 1;
1937c478bd9Sstevel@tonic-gate 
1947c478bd9Sstevel@tonic-gate 	adp++;			/* amode argument */
1957c478bd9Sstevel@tonic-gate 	adp->arg_value = (long)amode;
1967c478bd9Sstevel@tonic-gate 	adp->arg_object = NULL;
1977c478bd9Sstevel@tonic-gate 	adp->arg_type = AT_BYVAL;
1987c478bd9Sstevel@tonic-gate 	adp->arg_inout = AI_INPUT;
1997c478bd9Sstevel@tonic-gate 	adp->arg_size = 0;
2007c478bd9Sstevel@tonic-gate 
201*8fd04b83SRoger A. Faulkner 	adp++;			/* flag argument */
202*8fd04b83SRoger A. Faulkner 	adp->arg_value = 0;
203*8fd04b83SRoger A. Faulkner 	adp->arg_object = NULL;
204*8fd04b83SRoger A. Faulkner 	adp->arg_type = AT_BYVAL;
205*8fd04b83SRoger A. Faulkner 	adp->arg_inout = AI_INPUT;
206*8fd04b83SRoger A. Faulkner 	adp->arg_size = 0;
207*8fd04b83SRoger A. Faulkner 
208*8fd04b83SRoger A. Faulkner 	err = Psyscall(Pr, &rval, SYS_faccessat, 4, &argd[0]);
2097c478bd9Sstevel@tonic-gate 
2107c478bd9Sstevel@tonic-gate 	if (err) {
2117c478bd9Sstevel@tonic-gate 		errno = (err > 0) ? err : ENOSYS;
2127c478bd9Sstevel@tonic-gate 		return (-1);
2137c478bd9Sstevel@tonic-gate 	}
2147c478bd9Sstevel@tonic-gate 
2157c478bd9Sstevel@tonic-gate 	return (rval.sys_rval1);
2167c478bd9Sstevel@tonic-gate }
217