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