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.
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.
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]
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #include <sys/isa_defs.h>
32 #include <sys/types.h>
34 #include <sys/fcntl.h>
35 #include <sys/sysmacros.h>
40 * in case of 64-bit *stat() and *stat64 library call and 32-bit subject
41 * process convert 64-bit struct stat/stat64 into 32-bit struct stat64
44 stat64_32_to_n(struct stat64_32
*src
, struct stat
*dest
)
46 (void) memset(dest
, 0, sizeof (*dest
));
47 dest
->st_dev
= DEVEXPL(src
->st_dev
);
48 dest
->st_ino
= (ino_t
)src
->st_ino
;
49 dest
->st_mode
= (mode_t
)src
->st_mode
;
50 dest
->st_nlink
= (nlink_t
)src
->st_nlink
;
51 dest
->st_uid
= (uid_t
)src
->st_uid
;
52 dest
->st_gid
= (gid_t
)src
->st_gid
;
53 dest
->st_rdev
= DEVEXPL(src
->st_rdev
);
54 dest
->st_size
= (off_t
)src
->st_size
;
55 TIMESPEC32_TO_TIMESPEC(&dest
->st_atim
, &src
->st_atim
);
56 TIMESPEC32_TO_TIMESPEC(&dest
->st_mtim
, &src
->st_mtim
);
57 TIMESPEC32_TO_TIMESPEC(&dest
->st_ctim
, &src
->st_ctim
);
58 dest
->st_blksize
= (blksize_t
)src
->st_blksize
;
59 dest
->st_blocks
= (blkcnt_t
)src
->st_blocks
;
60 (void) memcpy(dest
->st_fstype
, src
->st_fstype
,
61 sizeof (dest
->st_fstype
));
66 * stat() system call -- executed by subject process
69 pr_stat(struct ps_prochandle
*Pr
, const char *path
, struct stat
*buf
)
71 sysret_t rval
; /* return value from stat() */
72 argdes_t argd
[4]; /* arg descriptors for fstatat() */
73 argdes_t
*adp
= &argd
[0]; /* first argument */
74 int syscall
; /* SYS_fstatat or SYS_fstatat64 */
77 struct stat64_32 statb64_32
;
80 if (Pr
== NULL
) /* no subject process */
81 return (stat(path
, buf
));
83 if (Pstatus(Pr
)->pr_dmodel
!= PR_MODEL_NATIVE
) {
84 /* 64-bit process controls 32-bit subject process */
85 syscall
= SYS_fstatat64
;
87 syscall
= SYS_fstatat
;
90 adp
->arg_value
= AT_FDCWD
;
91 adp
->arg_object
= NULL
;
92 adp
->arg_type
= AT_BYVAL
;
93 adp
->arg_inout
= AI_INPUT
;
95 adp
++; /* move to path argument */
98 adp
->arg_object
= (void *)path
;
99 adp
->arg_type
= AT_BYREF
;
100 adp
->arg_inout
= AI_INPUT
;
101 adp
->arg_size
= strlen(path
) + 1;
102 adp
++; /* move to buffer argument */
105 adp
->arg_type
= AT_BYREF
;
106 adp
->arg_inout
= AI_OUTPUT
;
108 if (Pstatus(Pr
)->pr_dmodel
== PR_MODEL_ILP32
) {
109 adp
->arg_object
= &statb64_32
;
110 adp
->arg_size
= sizeof (statb64_32
);
112 adp
->arg_object
= buf
;
113 adp
->arg_size
= sizeof (*buf
);
116 adp
->arg_object
= buf
;
117 adp
->arg_size
= sizeof (*buf
);
119 adp
++; /* move to flags argument */
122 adp
->arg_object
= NULL
;
123 adp
->arg_type
= AT_BYVAL
;
124 adp
->arg_inout
= AI_INPUT
;
127 error
= Psyscall(Pr
, &rval
, syscall
, 4, &argd
[0]);
130 errno
= (error
> 0)? error
: ENOSYS
;
134 if (Pstatus(Pr
)->pr_dmodel
== PR_MODEL_ILP32
)
135 stat64_32_to_n(&statb64_32
, buf
);
141 * lstat() system call -- executed by subject process
144 pr_lstat(struct ps_prochandle
*Pr
, const char *path
, struct stat
*buf
)
146 sysret_t rval
; /* return value from stat() */
147 argdes_t argd
[4]; /* arg descriptors for fstatat() */
148 argdes_t
*adp
= &argd
[0]; /* first argument */
149 int syscall
; /* SYS_fstatat or SYS_fstatat64 */
152 struct stat64_32 statb64_32
;
155 if (Pr
== NULL
) /* no subject process */
156 return (lstat(path
, buf
));
158 if (Pstatus(Pr
)->pr_dmodel
!= PR_MODEL_NATIVE
) {
159 /* 64-bit process controls 32-bit subject process */
160 syscall
= SYS_fstatat64
;
162 syscall
= SYS_fstatat
;
165 adp
->arg_value
= AT_FDCWD
;
166 adp
->arg_object
= NULL
;
167 adp
->arg_type
= AT_BYVAL
;
168 adp
->arg_inout
= AI_INPUT
;
170 adp
++; /* move to path argument */
173 adp
->arg_object
= (void *)path
;
174 adp
->arg_type
= AT_BYREF
;
175 adp
->arg_inout
= AI_INPUT
;
176 adp
->arg_size
= strlen(path
) + 1;
177 adp
++; /* move to buffer argument */
180 adp
->arg_type
= AT_BYREF
;
181 adp
->arg_inout
= AI_OUTPUT
;
183 if (Pstatus(Pr
)->pr_dmodel
== PR_MODEL_ILP32
) {
184 adp
->arg_object
= &statb64_32
;
185 adp
->arg_size
= sizeof (statb64_32
);
187 adp
->arg_object
= buf
;
188 adp
->arg_size
= sizeof (*buf
);
191 adp
->arg_object
= buf
;
192 adp
->arg_size
= sizeof (*buf
);
194 adp
++; /* move to flags argument */
196 adp
->arg_value
= AT_SYMLINK_NOFOLLOW
;
197 adp
->arg_object
= NULL
;
198 adp
->arg_type
= AT_BYVAL
;
199 adp
->arg_inout
= AI_INPUT
;
202 error
= Psyscall(Pr
, &rval
, syscall
, 4, &argd
[0]);
205 errno
= (error
> 0)? error
: ENOSYS
;
209 if (Pstatus(Pr
)->pr_dmodel
== PR_MODEL_ILP32
)
210 stat64_32_to_n(&statb64_32
, buf
);
216 * fstat() system call -- executed by subject process
219 pr_fstat(struct ps_prochandle
*Pr
, int fd
, struct stat
*buf
)
221 sysret_t rval
; /* return value from stat() */
222 argdes_t argd
[4]; /* arg descriptors for fstatat() */
223 argdes_t
*adp
= &argd
[0]; /* first argument */
224 int syscall
; /* SYS_fstatat or SYS_fstatat64 */
227 struct stat64_32 statb64_32
;
230 if (Pr
== NULL
) /* no subject process */
231 return (fstat(fd
, buf
));
233 if (Pstatus(Pr
)->pr_dmodel
!= PR_MODEL_NATIVE
) {
234 /* 64-bit process controls 32-bit subject process */
235 syscall
= SYS_fstatat64
;
237 syscall
= SYS_fstatat
;
241 adp
->arg_object
= NULL
;
242 adp
->arg_type
= AT_BYVAL
;
243 adp
->arg_inout
= AI_INPUT
;
245 adp
++; /* move to path argument */
248 adp
->arg_object
= NULL
;
249 adp
->arg_type
= AT_BYVAL
;
250 adp
->arg_inout
= AI_INPUT
;
252 adp
++; /* move to buffer argument */
255 adp
->arg_type
= AT_BYREF
;
256 adp
->arg_inout
= AI_OUTPUT
;
258 if (Pstatus(Pr
)->pr_dmodel
== PR_MODEL_ILP32
) {
259 adp
->arg_object
= &statb64_32
;
260 adp
->arg_size
= sizeof (statb64_32
);
262 adp
->arg_object
= buf
;
263 adp
->arg_size
= sizeof (*buf
);
266 adp
->arg_object
= buf
;
267 adp
->arg_size
= sizeof (*buf
);
269 adp
++; /* move to flags argument */
272 adp
->arg_object
= NULL
;
273 adp
->arg_type
= AT_BYVAL
;
274 adp
->arg_inout
= AI_INPUT
;
277 error
= Psyscall(Pr
, &rval
, syscall
, 4, &argd
[0]);
280 errno
= (error
> 0)? error
: ENOSYS
;
284 if (Pstatus(Pr
)->pr_dmodel
== PR_MODEL_ILP32
)
285 stat64_32_to_n(&statb64_32
, buf
);
291 * stat64() system call -- executed by subject process
294 pr_stat64(struct ps_prochandle
*Pr
, const char *path
, struct stat64
*buf
)
296 sysret_t rval
; /* return value from stat() */
297 argdes_t argd
[4]; /* arg descriptors for fstatat() */
298 argdes_t
*adp
= &argd
[0]; /* first argument */
299 int syscall
; /* SYS_fstatat or SYS_fstatat64 */
302 struct stat64_32 statb64_32
;
305 if (Pr
== NULL
) /* no subject process */
306 return (stat64(path
, buf
));
308 if (Pstatus(Pr
)->pr_dmodel
== PR_MODEL_ILP32
) {
311 * 64-bit process controls 32-bit subject process
313 syscall
= SYS_fstatat64
;
316 syscall
= SYS_fstatat
;
319 adp
->arg_value
= AT_FDCWD
;
320 adp
->arg_object
= NULL
;
321 adp
->arg_type
= AT_BYVAL
;
322 adp
->arg_inout
= AI_INPUT
;
324 adp
++; /* move to path argument */
327 adp
->arg_object
= (void *)path
;
328 adp
->arg_type
= AT_BYREF
;
329 adp
->arg_inout
= AI_INPUT
;
330 adp
->arg_size
= strlen(path
) + 1;
331 adp
++; /* move to buffer argument */
334 adp
->arg_type
= AT_BYREF
;
335 adp
->arg_inout
= AI_OUTPUT
;
337 if (Pstatus(Pr
)->pr_dmodel
== PR_MODEL_ILP32
) {
338 adp
->arg_object
= &statb64_32
;
339 adp
->arg_size
= sizeof (statb64_32
);
341 adp
->arg_object
= buf
;
342 adp
->arg_size
= sizeof (*buf
);
345 adp
->arg_object
= buf
;
346 adp
->arg_size
= sizeof (*buf
);
348 adp
++; /* move to flags argument */
351 adp
->arg_object
= NULL
;
352 adp
->arg_type
= AT_BYVAL
;
353 adp
->arg_inout
= AI_INPUT
;
356 error
= Psyscall(Pr
, &rval
, syscall
, 4, &argd
[0]);
359 errno
= (error
> 0)? error
: ENOSYS
;
363 if (Pstatus(Pr
)->pr_dmodel
== PR_MODEL_ILP32
)
364 stat64_32_to_n(&statb64_32
, (struct stat
*)buf
);
370 * lstat64() system call -- executed by subject process
373 pr_lstat64(struct ps_prochandle
*Pr
, const char *path
, struct stat64
*buf
)
375 sysret_t rval
; /* return value from stat() */
376 argdes_t argd
[4]; /* arg descriptors for fstatat() */
377 argdes_t
*adp
= &argd
[0]; /* first argument */
378 int syscall
; /* SYS_fstatat or SYS_fstatat64 */
381 struct stat64_32 statb64_32
;
384 if (Pr
== NULL
) /* no subject process */
385 return (lstat64(path
, buf
));
387 if (Pstatus(Pr
)->pr_dmodel
== PR_MODEL_ILP32
) {
390 * 64-bit process controls 32-bit subject process
392 syscall
= SYS_fstatat64
;
395 syscall
= SYS_fstatat
;
398 adp
->arg_value
= AT_FDCWD
;
399 adp
->arg_object
= NULL
;
400 adp
->arg_type
= AT_BYVAL
;
401 adp
->arg_inout
= AI_INPUT
;
403 adp
++; /* move to path argument */
406 adp
->arg_object
= (void *)path
;
407 adp
->arg_type
= AT_BYREF
;
408 adp
->arg_inout
= AI_INPUT
;
409 adp
->arg_size
= strlen(path
) + 1;
410 adp
++; /* move to buffer argument */
413 adp
->arg_type
= AT_BYREF
;
414 adp
->arg_inout
= AI_OUTPUT
;
416 if (Pstatus(Pr
)->pr_dmodel
== PR_MODEL_ILP32
) {
417 adp
->arg_object
= &statb64_32
;
418 adp
->arg_size
= sizeof (statb64_32
);
420 adp
->arg_object
= buf
;
421 adp
->arg_size
= sizeof (*buf
);
424 adp
->arg_object
= buf
;
425 adp
->arg_size
= sizeof (*buf
);
427 adp
++; /* move to flags argument */
429 adp
->arg_value
= AT_SYMLINK_NOFOLLOW
;
430 adp
->arg_object
= NULL
;
431 adp
->arg_type
= AT_BYVAL
;
432 adp
->arg_inout
= AI_INPUT
;
435 error
= Psyscall(Pr
, &rval
, syscall
, 4, &argd
[0]);
438 errno
= (error
> 0)? error
: ENOSYS
;
442 if (Pstatus(Pr
)->pr_dmodel
== PR_MODEL_ILP32
)
443 stat64_32_to_n(&statb64_32
, (struct stat
*)buf
);
449 * fstat64() system call -- executed by subject process
452 pr_fstat64(struct ps_prochandle
*Pr
, int fd
, struct stat64
*buf
)
454 sysret_t rval
; /* return value from stat() */
455 argdes_t argd
[4]; /* arg descriptors for fstatat() */
456 argdes_t
*adp
= &argd
[0]; /* first argument */
457 int syscall
; /* SYS_fstatat or SYS_fstatat64 */
460 struct stat64_32 statb64_32
;
463 if (Pr
== NULL
) /* no subject process */
464 return (fstat64(fd
, buf
));
466 if (Pstatus(Pr
)->pr_dmodel
== PR_MODEL_ILP32
) {
469 * 64-bit process controls 32-bit subject process
471 syscall
= SYS_fstatat64
;
474 syscall
= SYS_fstatat
;
478 adp
->arg_object
= NULL
;
479 adp
->arg_type
= AT_BYVAL
;
480 adp
->arg_inout
= AI_INPUT
;
482 adp
++; /* move to path argument */
485 adp
->arg_object
= NULL
;
486 adp
->arg_type
= AT_BYVAL
;
487 adp
->arg_inout
= AI_INPUT
;
489 adp
++; /* move to buffer argument */
492 adp
->arg_type
= AT_BYREF
;
493 adp
->arg_inout
= AI_OUTPUT
;
495 if (Pstatus(Pr
)->pr_dmodel
== PR_MODEL_ILP32
) {
496 adp
->arg_object
= &statb64_32
;
497 adp
->arg_size
= sizeof (statb64_32
);
499 adp
->arg_object
= buf
;
500 adp
->arg_size
= sizeof (*buf
);
503 adp
->arg_object
= buf
;
504 adp
->arg_size
= sizeof (*buf
);
506 adp
++; /* move to flags argument */
509 adp
->arg_object
= NULL
;
510 adp
->arg_type
= AT_BYVAL
;
511 adp
->arg_inout
= AI_INPUT
;
514 error
= Psyscall(Pr
, &rval
, syscall
, 4, &argd
[0]);
517 errno
= (error
> 0)? error
: ENOSYS
;
521 if (Pstatus(Pr
)->pr_dmodel
== PR_MODEL_ILP32
)
522 stat64_32_to_n(&statb64_32
, (struct stat
*)buf
);