1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
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 /*
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #include <stdlib.h>
28 #include <unistd.h>
29 #include <string.h>
30 #include <fcntl.h>
31 #include <errno.h>
32 #include "libproc.h"
33
34 /*
35 * open() system call -- executed by subject process.
36 */
37 int
pr_open(struct ps_prochandle * Pr,const char * filename,int flags,mode_t mode)38 pr_open(struct ps_prochandle *Pr, const char *filename, int flags, mode_t mode)
39 {
40 sysret_t rval; /* return value from openat() */
41 argdes_t argd[4]; /* arg descriptors for openat() */
42 argdes_t *adp;
43 int error;
44
45 if (Pr == NULL) /* no subject process */
46 return (open(filename, flags, mode));
47
48 adp = &argd[0]; /* AT_FDCWD argument */
49 adp->arg_value = AT_FDCWD;
50 adp->arg_object = NULL;
51 adp->arg_type = AT_BYVAL;
52 adp->arg_inout = AI_INPUT;
53 adp->arg_size = 0;
54
55 adp++; /* filename argument */
56 adp->arg_value = 0;
57 adp->arg_object = (void *)filename;
58 adp->arg_type = AT_BYREF;
59 adp->arg_inout = AI_INPUT;
60 adp->arg_size = strlen(filename)+1;
61
62 adp++; /* flags argument */
63 adp->arg_value = (long)flags;
64 adp->arg_object = NULL;
65 adp->arg_type = AT_BYVAL;
66 adp->arg_inout = AI_INPUT;
67 adp->arg_size = 0;
68
69 adp++; /* mode argument */
70 adp->arg_value = (long)mode;
71 adp->arg_object = NULL;
72 adp->arg_type = AT_BYVAL;
73 adp->arg_inout = AI_INPUT;
74 adp->arg_size = 0;
75
76 error = Psyscall(Pr, &rval, SYS_openat, 4, &argd[0]);
77
78 if (error) {
79 errno = (error > 0)? error : ENOSYS;
80 return (-1);
81 }
82 return (rval.sys_rval1);
83 }
84
85 /*
86 * creat() system call -- executed by subject process.
87 */
88 int
pr_creat(struct ps_prochandle * Pr,const char * filename,mode_t mode)89 pr_creat(struct ps_prochandle *Pr, const char *filename, mode_t mode)
90 {
91 sysret_t rval; /* return value from openat() */
92 argdes_t argd[4]; /* arg descriptors for openat() */
93 argdes_t *adp;
94 int error;
95
96 if (Pr == NULL) /* no subject process */
97 return (creat(filename, mode));
98
99 adp = &argd[0]; /* AT_FDCWD argument */
100 adp->arg_value = AT_FDCWD;
101 adp->arg_object = NULL;
102 adp->arg_type = AT_BYVAL;
103 adp->arg_inout = AI_INPUT;
104 adp->arg_size = 0;
105
106 adp++; /* filename argument */
107 adp->arg_value = 0;
108 adp->arg_object = (void *)filename;
109 adp->arg_type = AT_BYREF;
110 adp->arg_inout = AI_INPUT;
111 adp->arg_size = strlen(filename)+1;
112
113 adp++; /* flags argument */
114 adp->arg_value = (O_WRONLY | O_CREAT | O_TRUNC);
115 adp->arg_object = NULL;
116 adp->arg_type = AT_BYVAL;
117 adp->arg_inout = AI_INPUT;
118 adp->arg_size = 0;
119
120 adp++; /* mode argument */
121 adp->arg_value = (long)mode;
122 adp->arg_object = NULL;
123 adp->arg_type = AT_BYVAL;
124 adp->arg_inout = AI_INPUT;
125 adp->arg_size = 0;
126
127 error = Psyscall(Pr, &rval, SYS_openat, 4, &argd[0]);
128
129 if (error) {
130 errno = (error > 0)? error : ENOSYS;
131 return (-1);
132 }
133 return (rval.sys_rval1);
134 }
135
136 /*
137 * close() system call -- executed by subject process.
138 */
139 int
pr_close(struct ps_prochandle * Pr,int fd)140 pr_close(struct ps_prochandle *Pr, int fd)
141 {
142 sysret_t rval; /* return value from close() */
143 argdes_t argd[1]; /* arg descriptors for close() */
144 argdes_t *adp;
145 int error;
146
147 if (Pr == NULL) /* no subject process */
148 return (close(fd));
149
150 adp = &argd[0]; /* fd argument */
151 adp->arg_value = (int)fd;
152 adp->arg_object = NULL;
153 adp->arg_type = AT_BYVAL;
154 adp->arg_inout = AI_INPUT;
155 adp->arg_size = 0;
156
157 error = Psyscall(Pr, &rval, SYS_close, 1, &argd[0]);
158
159 if (error) {
160 errno = (error > 0)? error : ENOSYS;
161 return (-1);
162 }
163 return (rval.sys_rval1);
164 }
165
166 /*
167 * access() system call -- executed by subject process.
168 */
169 int
pr_access(struct ps_prochandle * Pr,const char * path,int amode)170 pr_access(struct ps_prochandle *Pr, const char *path, int amode)
171 {
172 sysret_t rval; /* return from access() */
173 argdes_t argd[4]; /* arg descriptors for access() */
174 argdes_t *adp;
175 int err;
176
177 if (Pr == NULL) /* no subject process */
178 return (access(path, amode));
179
180 adp = &argd[0]; /* directory fd argument */
181 adp->arg_value = AT_FDCWD;
182 adp->arg_object = NULL;
183 adp->arg_type = AT_BYVAL;
184 adp->arg_inout = AI_INPUT;
185 adp->arg_size = 0;
186
187 adp++; /* path argument */
188 adp->arg_value = 0;
189 adp->arg_object = (void *)path;
190 adp->arg_type = AT_BYREF;
191 adp->arg_inout = AI_INPUT;
192 adp->arg_size = strlen(path) + 1;
193
194 adp++; /* amode argument */
195 adp->arg_value = (long)amode;
196 adp->arg_object = NULL;
197 adp->arg_type = AT_BYVAL;
198 adp->arg_inout = AI_INPUT;
199 adp->arg_size = 0;
200
201 adp++; /* flag argument */
202 adp->arg_value = 0;
203 adp->arg_object = NULL;
204 adp->arg_type = AT_BYVAL;
205 adp->arg_inout = AI_INPUT;
206 adp->arg_size = 0;
207
208 err = Psyscall(Pr, &rval, SYS_faccessat, 4, &argd[0]);
209
210 if (err) {
211 errno = (err > 0) ? err : ENOSYS;
212 return (-1);
213 }
214
215 return (rval.sys_rval1);
216 }
217