xref: /illumos-gate/usr/src/lib/libproc/common/pr_statvfs.c (revision ef8846857fcf954444cdc77e72249afef48377d2)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright (c) 1998-2000 by Sun Microsystems, Inc.
24  * All rights reserved.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <sys/isa_defs.h>
30 #include <stdlib.h>
31 #include <unistd.h>
32 #include <string.h>
33 #include <errno.h>
34 #include <sys/types.h>
35 #include <sys/statvfs.h>
36 #include <sys/sysmacros.h>
37 #include "libproc.h"
38 
39 #ifdef _LP64
40 static void
41 statvfs_32_to_n(statvfs32_t *src, statvfs_t *dest)
42 {
43 	dest->f_bsize = src->f_bsize;
44 	dest->f_frsize = src->f_frsize;
45 	dest->f_blocks = src->f_blocks;
46 	dest->f_bfree = src->f_bfree;
47 	dest->f_bavail = src->f_bavail;
48 	dest->f_files = src->f_files;
49 	dest->f_ffree = src->f_ffree;
50 	dest->f_favail = src->f_favail;
51 	dest->f_fsid = src->f_fsid;
52 	(void) memcpy(dest->f_basetype, src->f_basetype,
53 		sizeof (dest->f_basetype));
54 	dest->f_flag = src->f_flag;
55 	dest->f_namemax = src->f_namemax;
56 	(void) memcpy(dest->f_fstr, src->f_fstr,
57 		sizeof (dest->f_fstr));
58 }
59 #endif	/* _LP64 */
60 
61 /*
62  * statvfs() system call -- executed by subject process
63  */
64 int
65 pr_statvfs(struct ps_prochandle *Pr, const char *path, statvfs_t *buf)
66 {
67 	sysret_t rval;			/* return value from statvfs() */
68 	argdes_t argd[2];		/* arg descriptors for statvfs() */
69 	argdes_t *adp = &argd[0];	/* first argument */
70 	int error;
71 #ifdef _LP64
72 	statvfs32_t statvfs32;
73 #endif	/* _LP64 */
74 
75 	if (Pr == NULL)		/* no subject process */
76 		return (statvfs(path, buf));
77 
78 	adp->arg_value = 0;
79 	adp->arg_object = (void *)path;
80 	adp->arg_type = AT_BYREF;
81 	adp->arg_inout = AI_INPUT;
82 	adp->arg_size = strlen(path)+1;
83 	adp++;			/* move to buffer argument */
84 
85 	adp->arg_value = 0;
86 	adp->arg_type = AT_BYREF;
87 	adp->arg_inout = AI_OUTPUT;
88 #ifdef _LP64
89 	if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32) {
90 		adp->arg_object = &statvfs32;
91 		adp->arg_size = sizeof (statvfs32);
92 	} else {
93 		adp->arg_object = buf;
94 		adp->arg_size = sizeof (*buf);
95 	}
96 #else	/* _LP64 */
97 	adp->arg_object = buf;
98 	adp->arg_size = sizeof (*buf);
99 #endif	/* _LP64 */
100 
101 	error = Psyscall(Pr, &rval, SYS_statvfs, 2, &argd[0]);
102 
103 	if (error) {
104 		errno = (error > 0)? error : ENOSYS;
105 		return (-1);
106 	}
107 #ifdef _LP64
108 	if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32)
109 		statvfs_32_to_n(&statvfs32, buf);
110 #endif	/* _LP64 */
111 	return (0);
112 }
113 
114 /*
115  * fstatvfs() system call -- executed by subject process
116  */
117 int
118 pr_fstatvfs(struct ps_prochandle *Pr, int fd, statvfs_t *buf)
119 {
120 	sysret_t rval;			/* return value from fstatvfs() */
121 	argdes_t argd[2];		/* arg descriptors for fstatvfs() */
122 	argdes_t *adp = &argd[0];	/* first argument */
123 	int error;
124 #ifdef _LP64
125 	statvfs32_t statvfs32;
126 #endif	/* _LP64 */
127 
128 	if (Pr == NULL)		/* no subject process */
129 		return (fstatvfs(fd, buf));
130 
131 	adp->arg_value = fd;
132 	adp->arg_object = NULL;
133 	adp->arg_type = AT_BYVAL;
134 	adp->arg_inout = AI_INPUT;
135 	adp->arg_size = 0;
136 	adp++;			/* move to buffer argument */
137 
138 	adp->arg_value = 0;
139 	adp->arg_type = AT_BYREF;
140 	adp->arg_inout = AI_OUTPUT;
141 #ifdef _LP64
142 	if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32) {
143 		adp->arg_object = &statvfs32;
144 		adp->arg_size = sizeof (statvfs32);
145 	} else {
146 		adp->arg_object = buf;
147 		adp->arg_size = sizeof (*buf);
148 	}
149 #else	/* _LP64 */
150 	adp->arg_object = buf;
151 	adp->arg_size = sizeof (*buf);
152 #endif	/* _LP64 */
153 
154 	error = Psyscall(Pr, &rval, SYS_fstatvfs, 2, &argd[0]);
155 
156 	if (error) {
157 		errno = (error > 0)? error : ENOSYS;
158 		return (-1);
159 	}
160 #ifdef _LP64
161 	if (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32)
162 		statvfs_32_to_n(&statvfs32, buf);
163 #endif	/* _LP64 */
164 	return (0);
165 }
166