// Authors:
// Jonathan Pryor (jonpryor@vt.edu)
//
-// (C) 2004-2005 Jonathan Pryor
+// (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
public abstract class UnixFileSystemInfo
{
- private Stat stat;
+ private Native.Stat stat;
private string fullPath;
private string originalPath;
private bool valid = false;
+ internal const FileSpecialAttributes AllSpecialAttributes =
+ FileSpecialAttributes.SetUserId | FileSpecialAttributes.SetGroupId |
+ FileSpecialAttributes.Sticky;
+ internal const FileTypes AllFileTypes =
+ FileTypes.Directory | FileTypes.CharacterDevice | FileTypes.BlockDevice |
+ FileTypes.RegularFile | FileTypes.Fifo | FileTypes.SymbolicLink |
+ FileTypes.Socket;
+
protected UnixFileSystemInfo (string path)
{
UnixPath.CheckPath (path);
Refresh (true);
}
- [Obsolete ("Use UnixFileSystemInfo (string, Mono.Unix.Native.Stat)")]
- internal UnixFileSystemInfo (String path, Stat stat)
- {
- this.originalPath = path;
- this.fullPath = UnixPath.GetFullPath (path);
- this.stat = stat;
- this.valid = true;
- }
-
internal UnixFileSystemInfo (String path, Native.Stat stat)
{
this.originalPath = path;
this.fullPath = UnixPath.GetFullPath (path);
- // this.stat = stat;
+ this.stat = stat;
this.valid = true;
}
protected string FullPath {
get {return fullPath;}
- set {fullPath = value;}
+ set {
+ if (fullPath != value) {
+ UnixPath.CheckPath (value);
+ valid = false;
+ fullPath = value;
+ }
+ }
}
protected string OriginalPath {
}
}
- [CLSCompliant (false)]
- [Obsolete ("The type of this property will change to Int64 in the next release.")]
- public ulong Device {
- get {AssertValid (); return stat.st_dev;}
- }
-
- [CLSCompliant (false)]
- [Obsolete ("The type of this property will change to Int64 in the next release.")]
- public ulong Inode {
- get {AssertValid (); return stat.st_ino;}
+ public long Device {
+ get {AssertValid (); return Convert.ToInt64 (stat.st_dev);}
}
- [CLSCompliant (false)]
- [Obsolete ("Use Protection.")]
- public FilePermissions Mode {
- get {AssertValid (); return stat.st_mode;}
- }
-
- [CLSCompliant (false)]
- [Obsolete ("Use FileAccessPermissions.")]
- public FilePermissions Permissions {
- get {AssertValid (); return stat.st_mode & ~FilePermissions.S_IFMT;}
- }
-
- [CLSCompliant (false)]
- [Obsolete ("The type of this property will change to FileTypes in the next release.")]
- public FilePermissions FileType {
- get {AssertValid (); return stat.st_mode & FilePermissions.S_IFMT;}
+ public long Inode {
+ get {AssertValid (); return Convert.ToInt64 (stat.st_ino);}
}
[CLSCompliant (false)]
}
}
-#if false
public FileTypes FileType {
get {
AssertValid ();
- int type = (int) stat.st_mode;
- return (FileTypes) (type & (int) FileTypes.AllTypes);
+ return (FileTypes) (stat.st_mode & Native.FilePermissions.S_IFMT);
}
// no set as chmod(2) won't accept changing the file type.
}
-#endif
public FileAccessPermissions FileAccessPermissions {
get {
get {
AssertValid ();
int attrs = (int) stat.st_mode;
- return (FileSpecialAttributes) (attrs & (int) FileSpecialAttributes.AllAttributes);
+ return (FileSpecialAttributes) (attrs & (int) AllSpecialAttributes);
}
set {
AssertValid ();
int perms = (int) stat.st_mode;
- perms &= (int) ~FileSpecialAttributes.AllAttributes;
+ perms &= (int) ~AllSpecialAttributes;
perms |= (int) value;
Protection = (Native.FilePermissions) perms;
}
}
- [CLSCompliant (false)]
- [Obsolete ("The type of this property will change to Int64 in the next release.")]
- public ulong LinkCount {
- get {AssertValid (); return (ulong) stat.st_nlink;}
+ public long LinkCount {
+ get {AssertValid (); return Convert.ToInt64 (stat.st_nlink);}
}
- [CLSCompliant (false)]
- [Obsolete ("Use OwnerUserId. " +
- "The type of this property will change to UnixUserInfo in the next release.")]
- public uint OwnerUser {
- get {AssertValid (); return stat.st_uid;}
+ public UnixUserInfo OwnerUser {
+ get {AssertValid (); return new UnixUserInfo (stat.st_uid);}
}
public long OwnerUserId {
get {AssertValid (); return stat.st_uid;}
}
- [CLSCompliant (false)]
- [Obsolete ("Use OwnerGroupId. " +
- "The type of this property will change to UnixGroupInfo in the next release.")]
- public uint OwnerGroup {
- get {AssertValid (); return stat.st_gid;}
+ public UnixGroupInfo OwnerGroup {
+ get {AssertValid (); return new UnixGroupInfo (stat.st_gid);}
}
public long OwnerGroupId {
get {AssertValid (); return stat.st_gid;}
}
- [CLSCompliant (false)]
- [Obsolete ("The type of this property will change to Int64 in the next release.")]
- public ulong DeviceType {
- get {AssertValid (); return stat.st_rdev;}
+ public long DeviceType {
+ get {AssertValid (); return Convert.ToInt64 (stat.st_rdev);}
}
public long Length {
}
public DateTime LastAccessTime {
- get {AssertValid (); return UnixConvert.ToDateTime (stat.st_atime);}
+ get {AssertValid (); return Native.NativeConvert.ToDateTime (stat.st_atime, stat.st_atime_nsec);}
}
public DateTime LastAccessTimeUtc {
}
public DateTime LastWriteTime {
- get {AssertValid (); return UnixConvert.ToDateTime (stat.st_mtime);}
+ get {AssertValid (); return Native.NativeConvert.ToDateTime (stat.st_mtime, stat.st_mtime_nsec);}
}
public DateTime LastWriteTimeUtc {
}
public DateTime LastStatusChangeTime {
- get {AssertValid (); return UnixConvert.ToDateTime (stat.st_ctime);}
+ get {AssertValid (); return Native.NativeConvert.ToDateTime (stat.st_ctime, stat.st_ctime_nsec);}
}
public DateTime LastStatusChangeTimeUtc {
}
public bool IsDirectory {
- get {AssertValid (); return IsType (stat.st_mode, FilePermissions.S_IFDIR);}
+ get {AssertValid (); return IsFileType (stat.st_mode, Native.FilePermissions.S_IFDIR);}
}
public bool IsCharacterDevice {
- get {AssertValid (); return IsType (stat.st_mode, FilePermissions.S_IFCHR);}
+ get {AssertValid (); return IsFileType (stat.st_mode, Native.FilePermissions.S_IFCHR);}
}
public bool IsBlockDevice {
- get {AssertValid (); return IsType (stat.st_mode, FilePermissions.S_IFBLK);}
+ get {AssertValid (); return IsFileType (stat.st_mode, Native.FilePermissions.S_IFBLK);}
}
- public bool IsFile {
- get {AssertValid (); return IsType (stat.st_mode, FilePermissions.S_IFREG);}
- }
-
- [Obsolete ("Use IsFifo")]
- [CLSCompliant (false)]
- public bool IsFIFO {
- get {AssertValid (); return IsType (stat.st_mode, FilePermissions.S_IFIFO);}
+ public bool IsRegularFile {
+ get {AssertValid (); return IsFileType (stat.st_mode, Native.FilePermissions.S_IFREG);}
}
public bool IsFifo {
- get {AssertValid (); return IsType (stat.st_mode, FilePermissions.S_IFIFO);}
+ get {AssertValid (); return IsFileType (stat.st_mode, Native.FilePermissions.S_IFIFO);}
}
public bool IsSymbolicLink {
- get {AssertValid (); return IsType (stat.st_mode, FilePermissions.S_IFLNK);}
+ get {AssertValid (); return IsFileType (stat.st_mode, Native.FilePermissions.S_IFLNK);}
}
public bool IsSocket {
- get {AssertValid (); return IsType (stat.st_mode, FilePermissions.S_IFSOCK);}
+ get {AssertValid (); return IsFileType (stat.st_mode, Native.FilePermissions.S_IFSOCK);}
}
public bool IsSetUser {
- get {AssertValid (); return IsType (stat.st_mode, FilePermissions.S_ISUID);}
+ get {AssertValid (); return IsSet (stat.st_mode, Native.FilePermissions.S_ISUID);}
}
public bool IsSetGroup {
- get {AssertValid (); return IsType (stat.st_mode, FilePermissions.S_ISGID);}
+ get {AssertValid (); return IsSet (stat.st_mode, Native.FilePermissions.S_ISGID);}
}
public bool IsSticky {
- get {AssertValid (); return IsType (stat.st_mode, FilePermissions.S_ISVTX);}
+ get {AssertValid (); return IsSet (stat.st_mode, Native.FilePermissions.S_ISVTX);}
}
- internal static bool IsType (FilePermissions mode, FilePermissions type)
+ internal static bool IsFileType (Native.FilePermissions mode, Native.FilePermissions type)
{
- return (mode & type) == type;
+ return (mode & Native.FilePermissions.S_IFMT) == type;
}
- internal static bool IsType (Native.FilePermissions mode, Native.FilePermissions type)
+ internal static bool IsSet (Native.FilePermissions mode, Native.FilePermissions type)
{
return (mode & type) == type;
}
- [CLSCompliant (false)]
- [Obsolete ("Use CanAccess (Mono.Unix.Native.AccessModes)")]
- public bool CanAccess (AccessMode mode)
- {
- int r = Syscall.access (FullPath, mode);
- return r == 0;
- }
-
[CLSCompliant (false)]
public bool CanAccess (Native.AccessModes mode)
{
public UnixFileSystemInfo CreateLink (string path)
{
- int r = Syscall.link (FullName, path);
+ int r = Native.Syscall.link (FullName, path);
UnixMarshal.ThrowExceptionForLastErrorIf (r);
- return Create (path);
+ return GetFileSystemEntry (path);
}
public UnixSymbolicLinkInfo CreateSymbolicLink (string path)
{
- int r = Syscall.symlink (FullName, path);
+ int r = Native.Syscall.symlink (FullName, path);
UnixMarshal.ThrowExceptionForLastErrorIf (r);
return new UnixSymbolicLinkInfo (path);
}
public abstract void Delete ();
- [CLSCompliant (false)]
- [Obsolete ("Use GetConfigurationValue (Mono.Unix.Native.PathconfName)")]
- public long GetConfigurationValue (PathConf name)
- {
- long r = Syscall.pathconf (FullPath, name);
- if (r == -1 && Syscall.GetLastError() != (Error) 0)
- UnixMarshal.ThrowExceptionForLastError ();
- return r;
- }
-
[CLSCompliant (false)]
public long GetConfigurationValue (Native.PathconfName name)
{
long r = Native.Syscall.pathconf (FullPath, name);
- if (r == -1 && Syscall.GetLastError() != (Error) 0)
+ if (r == -1 && Native.Stdlib.GetLastError() != (Native.Errno) 0)
UnixMarshal.ThrowExceptionForLastError ();
return r;
}
{
if (valid && !force)
return;
- int r = GetFileStatus (FullPath, out this.stat);
- valid = r == 0;
+ valid = GetFileStatus (FullPath, out this.stat);
}
- [Obsolete ("Use GetFileStatus (string, Mono.Unix.Native.Stat)")]
- protected virtual int GetFileStatus (string path, out Stat stat)
+ protected virtual bool GetFileStatus (string path, out Native.Stat stat)
{
- return Syscall.stat (path, out stat);
- }
-
- protected virtual int GetFileStatus (string path, out Native.Stat stat)
- {
- return Native.Syscall.stat (path, out stat);
+ return Native.Syscall.stat (path, out stat) == 0;
}
public void SetLength (long length)
{
int r;
do {
- r = Syscall.truncate (FullPath, length);
+ r = Native.Syscall.truncate (FullPath, length);
} while (UnixMarshal.ShouldRetrySyscall (r));
UnixMarshal.ThrowExceptionForLastErrorIf (r);
}
- [CLSCompliant (false)]
- [Obsolete ("Use Protection setter")]
- public void SetPermissions (FilePermissions perms)
- {
- int r = Syscall.chmod (FullPath, perms);
- UnixMarshal.ThrowExceptionForLastErrorIf (r);
- }
-
- [CLSCompliant (false)]
- [Obsolete ("Use SetOwner (long, long)")]
- public virtual void SetOwner (uint owner, uint group)
- {
- int r = Syscall.chown (FullPath, owner, group);
- UnixMarshal.ThrowExceptionForLastErrorIf (r);
- }
-
public virtual void SetOwner (long owner, long group)
{
uint _owner = Convert.ToUInt32 (owner);
uint _group = Convert.ToUInt32 (group);
- int r = Syscall.chown (FullPath, _owner, _group);
+ int r = Native.Syscall.chown (FullPath, _owner, _group);
UnixMarshal.ThrowExceptionForLastErrorIf (r);
}
public void SetOwner (string owner)
{
- Passwd pw = Syscall.getpwnam (owner);
+ Native.Passwd pw = Native.Syscall.getpwnam (owner);
if (pw == null)
throw new ArgumentException (Locale.GetText ("invalid username"), "owner");
uint uid = pw.pw_uid;
uint gid = pw.pw_gid;
- SetOwner (uid, gid);
+ SetOwner ((long) uid, (long) gid);
}
public void SetOwner (string owner, string group)
{
- uint uid = UnixUser.GetUserId (owner);
- uint gid = UnixGroup.GetGroupId (group);
+ long uid = -1;
+ if (owner != null)
+ uid = new UnixUserInfo (owner).UserId;
+ long gid = -1;
+ if (group != null)
+ gid = new UnixGroupInfo (group).GroupId;
+
+ SetOwner (uid, gid);
+ }
+
+ public void SetOwner (UnixUserInfo owner)
+ {
+ long uid, gid;
+ uid = gid = -1;
+ if (owner != null) {
+ uid = owner.UserId;
+ gid = owner.GroupId;
+ }
+ SetOwner (uid, gid);
+ }
+ public void SetOwner (UnixUserInfo owner, UnixGroupInfo group)
+ {
+ long uid, gid;
+ uid = gid = -1;
+ if (owner != null)
+ uid = owner.UserId;
+ if (group != null)
+ gid = owner.GroupId;
SetOwner (uid, gid);
}
public Native.Stat ToStat ()
{
- Native.Stat stat = new Native.Stat ();
- stat.st_dev = this.stat.st_dev;
- stat.st_ino = this.stat.st_ino;
- stat.st_mode = (Native.FilePermissions) this.stat.st_mode;
- stat.st_nlink = this.stat.st_nlink;
- stat.st_uid = this.stat.st_uid;
- stat.st_gid = this.stat.st_gid;
- stat.st_rdev = this.stat.st_rdev;
- stat.st_size = this.stat.st_size;
- stat.st_blksize = this.stat.st_blksize;
- stat.st_blocks = this.stat.st_blocks;
- stat.st_atime = this.stat.st_atime;
- stat.st_mtime = this.stat.st_mtime;
- stat.st_ctime = this.stat.st_ctime;
+ AssertValid ();
return stat;
}
- internal static UnixFileSystemInfo Create (string path)
+ public static UnixFileSystemInfo GetFileSystemEntry (string path)
{
- Stat stat;
- int r = Syscall.lstat (path, out stat);
- UnixMarshal.ThrowExceptionForLastErrorIf (r);
+ UnixFileSystemInfo info;
+ if (TryGetFileSystemEntry (path, out info))
+ return info;
+
+ UnixMarshal.ThrowExceptionForLastError ();
+
+ // Throw DirectoryNotFoundException because lstat(2) probably failed
+ // because of ENOTDIR (e.g. "/path/to/file/wtf"), so
+ // DirectoryNotFoundException is what would have been thrown anyway.
+ throw new DirectoryNotFoundException ("UnixMarshal.ThrowExceptionForLastError didn't throw?!");
+ }
+
+ public static bool TryGetFileSystemEntry (string path, out UnixFileSystemInfo entry)
+ {
+ Native.Stat stat;
+ int r = Native.Syscall.lstat (path, out stat);
+ if (r == -1) {
+ if (Native.Stdlib.GetLastError() == Native.Errno.ENOENT) {
+ entry = new UnixFileInfo (path);
+ return true;
+ }
+ entry = null;
+ return false;
+ }
+
+ if (IsFileType (stat.st_mode, Native.FilePermissions.S_IFDIR))
+ entry = new UnixDirectoryInfo (path, stat);
+ else if (IsFileType (stat.st_mode, Native.FilePermissions.S_IFLNK))
+ entry = new UnixSymbolicLinkInfo (path, stat);
+ else
+ entry = new UnixFileInfo (path, stat);
- if (IsType (stat.st_mode, FilePermissions.S_IFDIR))
- return new UnixDirectoryInfo (path, stat);
- else if (IsType (stat.st_mode, FilePermissions.S_IFLNK))
- return new UnixSymbolicLinkInfo (path, stat);
- return new UnixFileInfo (path, stat);
+ return true;
}
}
}