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