New test.
[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 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_SYS_STATVFS_H
18 #include <sys/statvfs.h>
19 #endif /* def HAVE_SYS_STATVFS_H */
20
21 #ifdef HAVE_GETFSSTAT
22 #include <sys/param.h>
23 #include <sys/ucred.h>
24 #include <sys/mount.h>
25 #include <unistd.h>     /* for pathconf */
26 #endif /* def HAVE_GETFSSTAT */
27
28 G_BEGIN_DECLS
29
30 struct Mono_Posix_Statvfs {
31         guint64         f_bsize;    /* file system block size */
32         guint64         f_frsize;   /* fragment size */
33         mph_fsblkcnt_t  f_blocks;   /* size of fs in f_frsize units */
34         mph_fsblkcnt_t  f_bfree;    /* # free blocks */
35         mph_fsblkcnt_t  f_bavail;   /* # free blocks for non-root */
36         mph_fsfilcnt_t  f_files;    /* # inodes */
37         mph_fsfilcnt_t  f_ffree;    /* # free inodes */
38         mph_fsfilcnt_t  f_favail;   /* # free inodes for non-root */
39         guint64         f_fsid;     /* file system id */
40         guint64         f_flag;     /* mount flags */
41         guint64         f_namemax;  /* maximum filename length */
42 };
43
44 #ifdef HAVE_SYS_STATVFS_H
45 static void
46 copy_statvfs (struct Mono_Posix_Statvfs *to, struct statvfs *from)
47 {
48   to->f_bsize   = from->f_bsize;
49   to->f_frsize  = from->f_frsize;
50   to->f_blocks  = from->f_blocks;
51   to->f_bfree   = from->f_bfree;
52   to->f_bavail  = from->f_bavail;
53   to->f_files   = from->f_files;
54   to->f_ffree   = from->f_ffree;
55   to->f_favail  = from->f_favail;
56   to->f_fsid    = from->f_fsid;
57   Mono_Posix_ToMountFlags (from->f_flag, &to->f_flag);
58   to->f_namemax =       from->f_namemax;
59 }
60 #endif /* ndef HAVE_SYS_STATVFS_H */
61
62 /*
63  * System V-compatible definitions
64  */
65
66 #ifdef HAVE_STATVFS
67 gint32
68 Mono_Posix_Syscall_statvfs (const char *path, struct Mono_Posix_Statvfs *buf)
69 {
70         struct statvfs s;
71         int r;
72
73         if (buf == NULL) {
74                 errno = EFAULT;
75                 return -1;
76         }
77
78         if ((r = statvfs (path, &s)) == 0)
79                 copy_statvfs (buf, &s);
80
81         return r;
82 }
83 #endif /* ndef HAVA_STATVFS */
84
85 #ifdef HAVE_FSTATVFS
86 gint32
87 Mono_Posix_Syscall_fstatvfs (gint32 fd, struct Mono_Posix_Statvfs *buf)
88 {
89         struct statvfs s;
90         int r;
91
92         if (buf == NULL) {
93                 errno = EFAULT;
94                 return -1;
95         }
96
97         if ((r = fstatvfs (fd, &s)) == 0)
98                 copy_statvfs (buf, &s);
99
100         return r;
101 }
102 #endif /* ndef HAVA_FSTATVFS */
103
104 /*
105  * BSD-compatible definitions.
106  *
107  * Linux also provides these, but are deprecated in favor of (f)statvfs.
108  */
109
110 #if (defined (HAVE_STATFS) || defined (HAVE_FSTATFS)) && !defined (HAVE_STATVFS)
111 static void
112 copy_statfs (struct Mono_Posix_Statvfs *to, struct statfs *from)
113 {
114   to->f_bsize   = from->f_bsize;
115   to->f_frsize  = from->f_bsize;
116   to->f_blocks  = from->f_blocks;
117   to->f_bfree   = from->f_bfree;
118   to->f_bavail  = from->f_bavail;
119   to->f_files   = from->f_files;
120   to->f_ffree   = from->f_ffree;
121   to->f_favail  = from->f_ffree; /* OSX doesn't have f_avail */
122   Mono_Posix_ToMountFlags (from->f_flags, &to->f_flag);
123         // from->f_fsid is an int32[2], to->f_fsid is a uint64, 
124         // so this shouldn't lose anything.
125         memcpy (&to->f_fsid, &from->f_fsid, sizeof(to->f_fsid));
126 }
127
128 static void
129 set_namemax (const char *path, struct Mono_Posix_Statvfs *buf)
130 {
131   buf->f_namemax = pathconf (path, _PC_NAME_MAX);
132 }
133
134 static void
135 set_fnamemax (int fd, struct Mono_Posix_Statvfs *buf)
136 {
137   buf->f_namemax = fpathconf (fd, _PC_NAME_MAX);
138 }
139 #endif /* (def HAVE_STATFS || def HAVE_FSTATFS) && !def HAVE_STATVFS */
140
141 #if !defined (HAVE_STATVFS) && defined (HAVE_STATFS)
142 gint32
143 Mono_Posix_Syscall_statvfs (const char *path, struct Mono_Posix_Statvfs *buf)
144 {
145         struct statfs s;
146         int r;
147
148         if (buf == NULL) {
149                 errno = EFAULT;
150                 return -1;
151         }
152
153         if ((r = statfs (path, &s)) == 0) {
154                 copy_statfs (buf, &s);
155                 set_namemax (path, buf);
156         }
157
158         return r;
159 }
160 #endif /* !def HAVE_STATVFS && def HAVE_STATFS */
161
162 #if !defined (HAVE_STATVFS) && defined (HAVE_STATFS)
163 gint32
164 Mono_Posix_Syscall_fstatvfs (gint32 fd, struct Mono_Posix_Statvfs *buf)
165 {
166         struct statfs s;
167         int r;
168
169         if (buf == NULL) {
170                 errno = EFAULT;
171                 return -1;
172         }
173
174         if ((r = fstatfs (fd, &s)) == 0) {
175                 copy_statfs (buf, &s);
176                 set_fnamemax (fd, buf);
177         }
178
179         return r;
180 }
181 #endif /* !def HAVE_FSTATVFS && def HAVE_STATFS */
182
183 G_END_DECLS
184
185 /*
186  * vim: noexpandtab
187  */