a575963da9
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
196 lines
5.0 KiB
C#
196 lines
5.0 KiB
C#
//
|
|
// Mono.Unix/UnixDriveInfo.cs
|
|
//
|
|
// Authors:
|
|
// Jonathan Pryor (jonpryor@vt.edu)
|
|
//
|
|
// (C) 2004-2006 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 Native.Statvfs stat;
|
|
private string fstype, mount_point, block_device;
|
|
|
|
public UnixDriveInfo (string mountPoint)
|
|
{
|
|
if (mountPoint == null)
|
|
throw new ArgumentNullException ("mountPoint");
|
|
Native.Fstab fstab = Native.Syscall.getfsfile (mountPoint);
|
|
if (fstab != null) {
|
|
FromFstab (fstab);
|
|
}
|
|
else {
|
|
this.mount_point = mountPoint;
|
|
this.block_device = "";
|
|
this.fstype = "Unknown";
|
|
}
|
|
}
|
|
|
|
private void FromFstab (Native.Fstab fstab)
|
|
{
|
|
this.fstype = fstab.fs_vfstype;
|
|
this.mount_point = fstab.fs_file;
|
|
this.block_device = fstab.fs_spec;
|
|
}
|
|
|
|
public static UnixDriveInfo GetForSpecialFile (string specialFile)
|
|
{
|
|
if (specialFile == null)
|
|
throw new ArgumentNullException ("specialFile");
|
|
Native.Fstab f = Native.Syscall.getfsspec (specialFile);
|
|
if (f == null)
|
|
throw new ArgumentException ("specialFile isn't valid: " + specialFile);
|
|
return new UnixDriveInfo (f);
|
|
}
|
|
|
|
private UnixDriveInfo (Native.Fstab fstab)
|
|
{
|
|
FromFstab (fstab);
|
|
}
|
|
|
|
public long AvailableFreeSpace {
|
|
get {Refresh (); return Convert.ToInt64 (stat.f_bavail * stat.f_frsize);}
|
|
}
|
|
|
|
public string DriveFormat {
|
|
get {return fstype;}
|
|
}
|
|
|
|
public UnixDriveType DriveType {
|
|
get {return UnixDriveType.Unknown;}
|
|
}
|
|
|
|
// this throws no exceptions
|
|
public bool IsReady {
|
|
get {
|
|
bool ready = Refresh (false);
|
|
if (mount_point == "/" || !ready)
|
|
return ready;
|
|
Native.Statvfs parent;
|
|
int r = Native.Syscall.statvfs (RootDirectory.Parent.FullName,
|
|
out parent);
|
|
if (r != 0)
|
|
return false;
|
|
return parent.f_fsid != stat.f_fsid;
|
|
}
|
|
}
|
|
|
|
public string Name {
|
|
get {return mount_point;}
|
|
}
|
|
|
|
public UnixDirectoryInfo RootDirectory {
|
|
get {return new UnixDirectoryInfo (mount_point);}
|
|
}
|
|
|
|
public long TotalFreeSpace {
|
|
get {Refresh (); return (long) (stat.f_bfree * stat.f_frsize);}
|
|
}
|
|
|
|
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 block_device;}
|
|
// set {}
|
|
}
|
|
|
|
public long MaximumFilenameLength {
|
|
get {Refresh (); return Convert.ToInt64 (stat.f_namemax);}
|
|
}
|
|
|
|
public static UnixDriveInfo[] GetDrives ()
|
|
{
|
|
// TODO: Return any drives mentioned by getmntent(3) once getmntent(3)
|
|
// is exported by Syscall.
|
|
|
|
// throws IOException, UnauthorizedAccessException (no permission)
|
|
ArrayList entries = new ArrayList ();
|
|
|
|
lock (Native.Syscall.fstab_lock) {
|
|
int r = Native.Syscall.setfsent ();
|
|
if (r != 1)
|
|
throw new IOException ("Error calling setfsent(3)", new UnixIOException ());
|
|
try {
|
|
Native.Fstab fs;
|
|
while ((fs = Native.Syscall.getfsent()) != null) {
|
|
// avoid virtual entries, such as "swap"
|
|
if (fs.fs_file != null && fs.fs_file.StartsWith ("/"))
|
|
entries.Add (new UnixDriveInfo (fs));
|
|
}
|
|
}
|
|
finally {
|
|
Native.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 = Native.Syscall.statvfs (mount_point, out stat);
|
|
if (r == -1 && throwException) {
|
|
Native.Errno e = Native.Syscall.GetLastError ();
|
|
throw new InvalidOperationException (
|
|
UnixMarshal.GetErrorDescription (e),
|
|
new UnixIOException (e));
|
|
}
|
|
else if (r == -1)
|
|
return false;
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
// vim: noexpandtab
|