e03152a773d95d4f12fe1fc7ad78b240b1cb8f60
[mono.git] / support / sys-statvfs.c
1 /*
2  * <sys/sendfile.h> wrapper functions.
3  *
4  * Authors:
5  *   Jonathan Pryor (jonpryor@vt.edu)
6  *
7  * Copyright (C) 2004-2006 Jonathan Pryor
8  */
9
10 #include <errno.h>
11
12 #include <string.h>
13
14 #include "mph.h"
15 #include "map.h"
16
17 #ifdef HAVE_PATHCONF_H
18 #include <pathconf.h>
19 #endif
20
21 #ifdef HAVE_SYS_STATVFS_H
22 #include <sys/statvfs.h>
23 #elif defined (HAVE_STATFS) || defined (HAVE_FSTATFS)
24 #include <sys/vfs.h>
25 #endif /* def HAVE_SYS_STATVFS_H */
26
27 #ifdef HAVE_GETFSSTAT
28 #ifdef HAVE_SYS_PARAM_H
29 #include <sys/param.h>
30 #endif
31 #include <sys/ucred.h>
32 #include <sys/mount.h>
33 #include <unistd.h>     /* for pathconf */
34 #endif /* def HAVE_GETFSSTAT */
35
36 G_BEGIN_DECLS
37
38 #ifdef HAVE_SYS_STATVFS_H
39 int
40 Mono_Posix_ToStatvfs (void *_from, struct Mono_Posix_Statvfs *to)
41 {
42         struct statvfs *from = _from;
43
44         to->f_bsize   = from->f_bsize;
45         to->f_frsize  = from->f_frsize;
46         to->f_blocks  = from->f_blocks;
47         to->f_bfree   = from->f_bfree;
48         to->f_bavail  = from->f_bavail;
49         to->f_files   = from->f_files;
50         to->f_ffree   = from->f_ffree;
51         to->f_favail  = from->f_favail;
52         to->f_fsid    = from->f_fsid;
53         to->f_namemax = from->f_namemax;
54
55         if (Mono_Posix_ToMountFlags (from->f_flag, &to->f_flag) != 0)
56                 return -1;
57
58         return 0;
59 }
60
61 int
62 Mono_Posix_FromStatvfs (struct Mono_Posix_Statvfs *from, void *_to)
63 {
64         struct statvfs *to = _to;
65         guint64 flag;
66
67         to->f_bsize   = from->f_bsize;
68         to->f_frsize  = from->f_frsize;
69         to->f_blocks  = from->f_blocks;
70         to->f_bfree   = from->f_bfree;
71         to->f_bavail  = from->f_bavail;
72         to->f_files   = from->f_files;
73         to->f_ffree   = from->f_ffree;
74         to->f_favail  = from->f_favail;
75         to->f_fsid    = from->f_fsid;
76         to->f_namemax = from->f_namemax;
77
78         if (Mono_Posix_FromMountFlags (from->f_flag, &flag) != 0)
79                 return -1;
80         to->f_flag = flag;
81
82         return 0;
83 }
84 #endif /* ndef HAVE_SYS_STATVFS_H */
85
86 /*
87  * System V-compatible definitions
88  */
89
90 #ifdef HAVE_STATVFS
91 gint32
92 Mono_Posix_Syscall_statvfs (const char *path, struct Mono_Posix_Statvfs *buf)
93 {
94         struct statvfs s;
95         int r;
96
97         if (buf == NULL) {
98                 errno = EFAULT;
99                 return -1;
100         }
101
102         if ((r = statvfs (path, &s)) == 0)
103                 r = Mono_Posix_ToStatvfs (&s, buf);
104
105         return r;
106 }
107 #endif /* ndef HAVA_STATVFS */
108
109 #ifdef HAVE_FSTATVFS
110 gint32
111 Mono_Posix_Syscall_fstatvfs (gint32 fd, struct Mono_Posix_Statvfs *buf)
112 {
113         struct statvfs s;
114         int r;
115
116         if (buf == NULL) {
117                 errno = EFAULT;
118                 return -1;
119         }
120
121         if ((r = fstatvfs (fd, &s)) == 0)
122                 r = Mono_Posix_ToStatvfs (&s, buf);
123
124         return r;
125 }
126 #endif /* ndef HAVA_FSTATVFS */
127
128 /*
129  * BSD-compatible definitions.
130  *
131  * Linux also provides these, but are deprecated in favor of (f)statvfs.
132  */
133
134 #if (defined (HAVE_STATFS) || defined (HAVE_FSTATFS)) && !defined (HAVE_STATVFS)
135 int
136 Mono_Posix_ToStatvfs (void *_from, struct Mono_Posix_Statvfs *to)
137 {
138         struct statfs *from = _from;
139
140         to->f_bsize   = from->f_bsize;
141         to->f_frsize  = from->f_bsize;
142         to->f_blocks  = from->f_blocks;
143         to->f_bfree   = from->f_bfree;
144         to->f_bavail  = from->f_bavail;
145         to->f_files   = from->f_files;
146         to->f_ffree   = from->f_ffree;
147         to->f_favail  = from->f_ffree; /* OSX doesn't have f_avail */
148
149         // from->f_fsid is an int32[2], to->f_fsid is a uint64, 
150         // so this shouldn't lose anything.
151         memcpy (&to->f_fsid, &from->f_fsid, sizeof(to->f_fsid));
152
153 #if HAVE_STRUCT_STATFS_F_FLAGS
154         if (Mono_Posix_ToMountFlags (from->f_flags, &to->f_flag) != 0)
155                 return -1;
156 #endif  /* def HAVE_STRUCT_STATFS_F_FLAGS */
157
158         return 0;
159 }
160
161 int
162 Mono_Posix_FromStatvfs (struct Mono_Posix_Statvfs *from, void *_to)
163 {
164         struct statfs *to = _to;
165         guint64 flag;
166
167         to->f_bsize   = from->f_bsize;
168         to->f_blocks  = from->f_blocks;
169         to->f_bfree   = from->f_bfree;
170         to->f_bavail  = from->f_bavail;
171         to->f_files   = from->f_files;
172         to->f_ffree   = from->f_ffree;
173
174         // from->f_fsid is an int32[2], to->f_fsid is a uint64, 
175         // so this shouldn't lose anything.
176         memcpy (&to->f_fsid, &from->f_fsid, sizeof(to->f_fsid));
177
178 #if HAVE_STRUCT_STATFS_F_FLAGS
179         if (Mono_Posix_FromMountFlags (from->f_flag, &flag) != 0)
180                 return -1;
181         to->f_flags = flag;
182 #endif  /* def HAVE_STRUCT_STATFS_F_FLAGS */
183
184         return 0;
185 }
186
187 static void
188 set_namemax (const char *path, struct Mono_Posix_Statvfs *buf)
189 {
190   buf->f_namemax = pathconf (path, _PC_NAME_MAX);
191 }
192
193 static void
194 set_fnamemax (int fd, struct Mono_Posix_Statvfs *buf)
195 {
196   buf->f_namemax = fpathconf (fd, _PC_NAME_MAX);
197 }
198 #endif /* (def HAVE_STATFS || def HAVE_FSTATFS) && !def HAVE_STATVFS */
199
200 #if !defined (HAVE_STATVFS) && defined (HAVE_STATFS)
201 gint32
202 Mono_Posix_Syscall_statvfs (const char *path, struct Mono_Posix_Statvfs *buf)
203 {
204         struct statfs s;
205         int r;
206
207         if (buf == NULL) {
208                 errno = EFAULT;
209                 return -1;
210         }
211
212         if ((r = statfs (path, &s)) == 0 &&
213                         (r = Mono_Posix_ToStatvfs (&s, buf)) == 0) {
214                 set_namemax (path, buf);
215         }
216
217         return r;
218 }
219 #endif /* !def HAVE_STATVFS && def HAVE_STATFS */
220
221 #if !defined (HAVE_STATVFS) && defined (HAVE_STATFS)
222 gint32
223 Mono_Posix_Syscall_fstatvfs (gint32 fd, struct Mono_Posix_Statvfs *buf)
224 {
225         struct statfs s;
226         int r;
227
228         if (buf == NULL) {
229                 errno = EFAULT;
230                 return -1;
231         }
232
233         if ((r = fstatfs (fd, &s)) == 0 &&
234                         (r = Mono_Posix_ToStatvfs (&s, buf)) == 0) {
235                 set_fnamemax (fd, buf);
236         }
237
238         return r;
239 }
240 #endif /* !def HAVE_FSTATVFS && def HAVE_STATFS */
241
242 G_END_DECLS
243
244 /*
245  * vim: noexpandtab
246  */