diff options
Diffstat (limited to 'mcs/class/Mono.Posix/Mono.Unix/UnixDriveInfo.cs')
-rw-r--r-- | mcs/class/Mono.Posix/Mono.Unix/UnixDriveInfo.cs | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/mcs/class/Mono.Posix/Mono.Unix/UnixDriveInfo.cs b/mcs/class/Mono.Posix/Mono.Unix/UnixDriveInfo.cs new file mode 100644 index 00000000000..8eacd5cf879 --- /dev/null +++ b/mcs/class/Mono.Posix/Mono.Unix/UnixDriveInfo.cs @@ -0,0 +1,169 @@ +// +// Mono.Unix/UnixDriveInfo.cs +// +// Authors: +// Jonathan Pryor (jonpryor@vt.edu) +// +// (C) 2004 Jonathan Pryor +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections; +using System.IO; +using Mono.Unix; + +namespace Mono.Unix { + + public enum UnixDriveType { + Unknown, + NoRootDirectory, + Removable, + Fixed, + Network, + CDRom, + Ram + } + + // All methods & properties can throw IOException + public sealed class UnixDriveInfo + { + private Statvfs stat; + private Fstab fstab; + + public UnixDriveInfo (string mountPoint) + { + if (mountPoint == null) + throw new ArgumentNullException ("mountPoint"); + fstab = Syscall.getfsfile (mountPoint); + if (fstab == null) + throw new ArgumentException ("mountPoint isn't valid: " + mountPoint); + // throws ArgumentException if driveName isn't valid + // though .NET also has a DriveNotFoundException class, so maybe that's + // more appropriate? + } + + public static UnixDriveInfo GetForSpecialFile (string specialFile) + { + if (specialFile == null) + throw new ArgumentNullException ("specialFile"); + Fstab f = Syscall.getfsspec (specialFile); + if (f == null) + throw new ArgumentException ("specialFile isn't valid: " + specialFile); + return new UnixDriveInfo (f); + } + + private UnixDriveInfo (Fstab fstab) + { + this.fstab = fstab; + } + + public long AvailableFreeSpace { + get {Refresh (); return (long) (stat.f_bavail * stat.f_bsize);} + } + + public string DriveFormat { + get {return fstab.fs_vfstype;} + } + + public UnixDriveType DriveType { + get {return UnixDriveType.Unknown;} + } + + // this throws no exceptions + public bool IsReady { + get {return Refresh (false);} + } + + public string Name { + get {return fstab.fs_file;} + } + + public UnixDirectoryInfo RootDirectory { + get {return new UnixDirectoryInfo (fstab.fs_file);} + } + + public long TotalFreeSpace { + get {Refresh (); return (long) (stat.f_bfree * stat.f_bsize);} + } + + public long TotalSize { + get {Refresh (); return (long) (stat.f_frsize * stat.f_blocks);} + } + + // also throws SecurityException if caller lacks perms + public string VolumeLabel { + get {return fstab.fs_spec;} + // set {} + } + + public ulong MaximumFilenameLength { + get {Refresh (); return stat.f_namemax;} + } + + public static UnixDriveInfo[] GetDrives () + { + // throws IOException, UnauthorizedAccessException (no permission) + Syscall.SetLastError ((Error) 0); + int r = Syscall.setfsent (); + if (r != 1) + throw new IOException ("Error calling setfsent(3)"); + ArrayList entries = new ArrayList (); + try { + Fstab fs; + while ((fs = Syscall.getfsent()) != null) { + // avoid virtual entries, such as "swap" + if (fs.fs_file.StartsWith ("/")) + entries.Add (new UnixDriveInfo (fs)); + } + } + finally { + Syscall.endfsent (); + } + return (UnixDriveInfo[]) entries.ToArray (typeof(UnixDriveInfo)); + } + + public override string ToString () + { + return VolumeLabel; + } + + private void Refresh () + { + Refresh (true); + } + + private bool Refresh (bool throwException) + { + int r = Syscall.statvfs (fstab.fs_file, out stat); + if (r == -1 && throwException) { + Error e = Syscall.GetLastError (); + throw new IOException (UnixMarshal.GetErrorDescription (e), + UnixMarshal.CreateExceptionForError (e)); + } + else if (r == -1) + return false; + return true; + } + } +} + +// vim: noexpandtab |