2010-05-27 Jb Evain <jbevain@novell.com>
[mcs.git] / class / Mono.Posix / Mono.Unix / UnixDriveInfo.cs
blob23f82b11a64631d9a921c73acab768483daedf72
1 //
2 // Mono.Unix/UnixDriveInfo.cs
3 //
4 // Authors:
5 // Jonathan Pryor (jonpryor@vt.edu)
6 //
7 // (C) 2004-2006 Jonathan Pryor
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 using System;
30 using System.Collections;
31 using System.IO;
32 using Mono.Unix;
34 namespace Mono.Unix {
36 public enum UnixDriveType {
37 Unknown,
38 NoRootDirectory,
39 Removable,
40 Fixed,
41 Network,
42 CDRom,
43 Ram
46 // All methods & properties can throw IOException
47 public sealed class UnixDriveInfo
49 private Native.Statvfs stat;
50 private string fstype, mount_point, block_device;
52 public UnixDriveInfo (string mountPoint)
54 if (mountPoint == null)
55 throw new ArgumentNullException ("mountPoint");
56 Native.Fstab fstab = Native.Syscall.getfsfile (mountPoint);
57 if (fstab != null) {
58 FromFstab (fstab);
60 else {
61 this.mount_point = mountPoint;
62 this.block_device = "";
63 this.fstype = "Unknown";
67 private void FromFstab (Native.Fstab fstab)
69 this.fstype = fstab.fs_vfstype;
70 this.mount_point = fstab.fs_file;
71 this.block_device = fstab.fs_spec;
74 public static UnixDriveInfo GetForSpecialFile (string specialFile)
76 if (specialFile == null)
77 throw new ArgumentNullException ("specialFile");
78 Native.Fstab f = Native.Syscall.getfsspec (specialFile);
79 if (f == null)
80 throw new ArgumentException ("specialFile isn't valid: " + specialFile);
81 return new UnixDriveInfo (f);
84 private UnixDriveInfo (Native.Fstab fstab)
86 FromFstab (fstab);
89 public long AvailableFreeSpace {
90 get {Refresh (); return Convert.ToInt64 (stat.f_bavail * stat.f_frsize);}
93 public string DriveFormat {
94 get {return fstype;}
97 public UnixDriveType DriveType {
98 get {return UnixDriveType.Unknown;}
101 // this throws no exceptions
102 public bool IsReady {
103 get {
104 bool ready = Refresh (false);
105 if (mount_point == "/" || !ready)
106 return ready;
107 Native.Statvfs parent;
108 int r = Native.Syscall.statvfs (RootDirectory.Parent.FullName,
109 out parent);
110 if (r != 0)
111 return false;
112 return parent.f_fsid != stat.f_fsid;
116 public string Name {
117 get {return mount_point;}
120 public UnixDirectoryInfo RootDirectory {
121 get {return new UnixDirectoryInfo (mount_point);}
124 public long TotalFreeSpace {
125 get {Refresh (); return (long) (stat.f_bfree * stat.f_frsize);}
128 public long TotalSize {
129 get {Refresh (); return (long) (stat.f_frsize * stat.f_blocks);}
132 // also throws SecurityException if caller lacks perms
133 public string VolumeLabel {
134 get {return block_device;}
135 // set {}
138 public long MaximumFilenameLength {
139 get {Refresh (); return Convert.ToInt64 (stat.f_namemax);}
142 public static UnixDriveInfo[] GetDrives ()
144 // TODO: Return any drives mentioned by getmntent(3) once getmntent(3)
145 // is exported by Syscall.
147 // throws IOException, UnauthorizedAccessException (no permission)
148 ArrayList entries = new ArrayList ();
150 lock (Native.Syscall.fstab_lock) {
151 int r = Native.Syscall.setfsent ();
152 if (r != 1)
153 throw new IOException ("Error calling setfsent(3)", new UnixIOException ());
154 try {
155 Native.Fstab fs;
156 while ((fs = Native.Syscall.getfsent()) != null) {
157 // avoid virtual entries, such as "swap"
158 if (fs.fs_file.StartsWith ("/"))
159 entries.Add (new UnixDriveInfo (fs));
162 finally {
163 Native.Syscall.endfsent ();
166 return (UnixDriveInfo[]) entries.ToArray (typeof(UnixDriveInfo));
169 public override string ToString ()
171 return VolumeLabel;
174 private void Refresh ()
176 Refresh (true);
179 private bool Refresh (bool throwException)
181 int r = Native.Syscall.statvfs (mount_point, out stat);
182 if (r == -1 && throwException) {
183 Native.Errno e = Native.Syscall.GetLastError ();
184 throw new InvalidOperationException (
185 UnixMarshal.GetErrorDescription (e),
186 new UnixIOException (e));
188 else if (r == -1)
189 return false;
190 return true;
195 // vim: noexpandtab