2 // Mono.Unix/UnixFileSystemInfo.cs
5 // Jonathan Pryor (jonpryor@vt.edu)
7 // (C) 2004 Jonathan Pryor
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:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
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.
36 public abstract class UnixFileSystemInfo
39 private string fullPath;
40 private string originalPath;
41 private bool valid = false;
43 protected UnixFileSystemInfo (string path)
45 UnixPath.CheckPath (path);
46 this.originalPath = path;
47 this.fullPath = UnixPath.GetFullPath (path);
51 internal UnixFileSystemInfo (String path, Stat stat)
53 this.originalPath = path;
54 this.fullPath = UnixPath.GetFullPath (path);
59 protected string FullPath {
60 get {return fullPath;}
61 set {fullPath = value;}
64 protected string OriginalPath {
65 get {return originalPath;}
66 set {originalPath = value;}
69 private void AssertValid ()
73 throw new InvalidOperationException ("Path doesn't exist!");
76 public virtual string FullName {
77 get {return FullPath;}
80 public abstract string Name {get;}
84 int r = Syscall.access (FullPath, AccessMode.F_OK);
92 get {AssertValid (); return stat.st_dev;}
96 get {AssertValid (); return stat.st_ino;}
99 public FilePermissions Mode {
100 get {AssertValid (); return stat.st_mode;}
103 public FilePermissions Permissions {
104 get {AssertValid (); return stat.st_mode & ~FilePermissions.S_IFMT;}
107 public FilePermissions FileType {
108 get {AssertValid (); return stat.st_mode & FilePermissions.S_IFMT;}
111 public ulong LinkCount {
112 get {AssertValid (); return (ulong) stat.st_nlink;}
115 public uint OwnerUser {
116 get {AssertValid (); return stat.st_uid;}
119 public uint OwnerGroup {
120 get {AssertValid (); return stat.st_gid;}
123 public ulong DeviceType {
124 get {AssertValid (); return stat.st_rdev;}
128 get {AssertValid (); return (long) stat.st_size;}
131 public long BlockSize {
132 get {AssertValid (); return (long) stat.st_blksize;}
135 public long BlocksAllocated {
136 get {AssertValid (); return (long) stat.st_blocks;}
139 public DateTime LastAccessTime {
140 get {AssertValid (); return UnixConvert.ToDateTime (stat.st_atime);}
143 public DateTime LastAccessTimeUtc {
144 get {return LastAccessTime.ToUniversalTime ();}
147 public DateTime LastWriteTime {
148 get {AssertValid (); return UnixConvert.ToDateTime (stat.st_mtime);}
151 public DateTime LastWriteTimeUtc {
152 get {return LastWriteTime.ToUniversalTime ();}
155 public DateTime LastStatusChangeTime {
156 get {AssertValid (); return UnixConvert.ToDateTime (stat.st_ctime);}
159 public DateTime LastStatusChangeTimeUtc {
160 get {return LastStatusChangeTime.ToUniversalTime ();}
163 public bool IsDirectory {
164 get {AssertValid (); return IsType (stat.st_mode, FilePermissions.S_IFDIR);}
167 public bool IsCharacterDevice {
168 get {AssertValid (); return IsType (stat.st_mode, FilePermissions.S_IFCHR);}
171 public bool IsBlockDevice {
172 get {AssertValid (); return IsType (stat.st_mode, FilePermissions.S_IFBLK);}
176 get {AssertValid (); return IsType (stat.st_mode, FilePermissions.S_IFREG);}
180 get {AssertValid (); return IsType (stat.st_mode, FilePermissions.S_IFIFO);}
183 public bool IsSymbolicLink {
184 get {AssertValid (); return IsType (stat.st_mode, FilePermissions.S_IFLNK);}
187 public bool IsSocket {
188 get {AssertValid (); return IsType (stat.st_mode, FilePermissions.S_IFSOCK);}
191 public bool IsSetUser {
192 get {AssertValid (); return IsType (stat.st_mode, FilePermissions.S_ISUID);}
195 public bool IsSetGroup {
196 get {AssertValid (); return IsType (stat.st_mode, FilePermissions.S_ISGID);}
199 public bool IsSticky {
200 get {AssertValid (); return IsType (stat.st_mode, FilePermissions.S_ISVTX);}
203 internal static bool IsType (FilePermissions mode, FilePermissions type)
205 return (mode & type) == type;
208 public bool CanAccess (AccessMode mode)
210 int r = Syscall.access (FullPath, mode);
214 public UnixFileSystemInfo CreateLink (string path)
216 int r = Syscall.link (FullName, path);
217 UnixMarshal.ThrowExceptionForLastErrorIf (r);
218 return Create (path);
221 public UnixSymbolicLinkInfo CreateSymbolicLink (string path)
223 int r = Syscall.symlink (FullName, path);
224 UnixMarshal.ThrowExceptionForLastErrorIf (r);
225 return new UnixSymbolicLinkInfo (path);
228 public abstract void Delete ();
230 public long GetConfigurationValue (PathConf name)
232 Syscall.SetLastError ((Error) 0);
233 long r = Syscall.pathconf (FullPath, name);
234 if (r == -1 && Syscall.GetLastError() != (Error) 0)
235 UnixMarshal.ThrowExceptionForLastError ();
239 public void Refresh ()
244 internal void Refresh (bool force)
248 int r = GetFileStatus (FullPath, out this.stat);
252 protected virtual int GetFileStatus (string path, out Stat stat)
254 return Syscall.stat (path, out stat);
257 public void SetLength (long length)
261 r = Syscall.truncate (FullPath, length);
262 } while (UnixMarshal.ShouldRetrySyscall (r));
263 UnixMarshal.ThrowExceptionForLastErrorIf (r);
266 public void SetPermissions (FilePermissions perms)
268 int r = Syscall.chmod (FullPath, perms);
269 UnixMarshal.ThrowExceptionForLastErrorIf (r);
272 public virtual void SetOwner (uint owner, uint group)
274 int r = Syscall.chown (FullPath, owner, group);
275 UnixMarshal.ThrowExceptionForLastErrorIf (r);
278 public void SetOwner (string owner)
280 Passwd pw = Syscall.getpwnam (owner);
282 throw new ArgumentException (Locale.GetText ("invalid username"), "owner");
283 uint uid = pw.pw_uid;
284 uint gid = pw.pw_gid;
288 public void SetOwner (string owner, string group)
290 uint uid = UnixUser.GetUserId (owner);
291 uint gid = UnixGroup.GetGroupId (group);
296 public override string ToString ()
301 internal static UnixFileSystemInfo Create (string path)
304 int r = Syscall.lstat (path, out stat);
305 UnixMarshal.ThrowExceptionForLastErrorIf (r);
307 if (IsType (stat.st_mode, FilePermissions.S_IFDIR))
308 return new UnixDirectoryInfo (path, stat);
309 else if (IsType (stat.st_mode, FilePermissions.S_IFLNK))
310 return new UnixSymbolicLinkInfo (path, stat);
311 return new UnixFileInfo (path, stat);