2 // Mono.Unix/UnixFileSystemInfo.cs
5 // Jonathan Pryor (jonpryor@vt.edu)
7 // (C) 2004-2006 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
38 private Native.Stat stat;
39 private string fullPath;
40 private string originalPath;
41 private bool valid = false;
43 internal const FileSpecialAttributes AllSpecialAttributes =
44 FileSpecialAttributes.SetUserId | FileSpecialAttributes.SetGroupId |
45 FileSpecialAttributes.Sticky;
46 internal const FileTypes AllFileTypes =
47 FileTypes.Directory | FileTypes.CharacterDevice | FileTypes.BlockDevice |
48 FileTypes.RegularFile | FileTypes.Fifo | FileTypes.SymbolicLink |
51 protected UnixFileSystemInfo (string path)
53 UnixPath.CheckPath (path);
54 this.originalPath = path;
55 this.fullPath = UnixPath.GetFullPath (path);
59 internal UnixFileSystemInfo (String path, Native.Stat stat)
61 this.originalPath = path;
62 this.fullPath = UnixPath.GetFullPath (path);
67 protected string FullPath {
68 get {return fullPath;}
70 if (fullPath != value) {
71 UnixPath.CheckPath (value);
78 protected string OriginalPath {
79 get {return originalPath;}
80 set {originalPath = value;}
83 private void AssertValid ()
87 throw new InvalidOperationException ("Path doesn't exist!");
90 public virtual string FullName {
91 get {return FullPath;}
94 public abstract string Name {get;}
104 get {AssertValid (); return Convert.ToInt64 (stat.st_dev);}
108 get {AssertValid (); return Convert.ToInt64 (stat.st_ino);}
111 [CLSCompliant (false)]
112 public Native.FilePermissions Protection {
113 get {AssertValid (); return (Native.FilePermissions) stat.st_mode;}
115 int r = Native.Syscall.chmod (FullPath, value);
116 UnixMarshal.ThrowExceptionForLastErrorIf (r);
120 public FileTypes FileType {
123 int type = (int) stat.st_mode;
124 return (FileTypes) (type & (int) AllFileTypes);
126 // no set as chmod(2) won't accept changing the file type.
129 public FileAccessPermissions FileAccessPermissions {
132 int perms = (int) stat.st_mode;
133 return (FileAccessPermissions) (perms & (int) FileAccessPermissions.AllPermissions);
137 int perms = (int) stat.st_mode;
138 perms &= (int) ~FileAccessPermissions.AllPermissions;
139 perms |= (int) value;
140 Protection = (Native.FilePermissions) perms;
144 public FileSpecialAttributes FileSpecialAttributes {
147 int attrs = (int) stat.st_mode;
148 return (FileSpecialAttributes) (attrs & (int) AllSpecialAttributes);
152 int perms = (int) stat.st_mode;
153 perms &= (int) ~AllSpecialAttributes;
154 perms |= (int) value;
155 Protection = (Native.FilePermissions) perms;
159 public long LinkCount {
160 get {AssertValid (); return Convert.ToInt64 (stat.st_nlink);}
163 public UnixUserInfo OwnerUser {
164 get {AssertValid (); return new UnixUserInfo (stat.st_uid);}
167 public long OwnerUserId {
168 get {AssertValid (); return stat.st_uid;}
171 public UnixGroupInfo OwnerGroup {
172 get {AssertValid (); return new UnixGroupInfo (stat.st_gid);}
175 public long OwnerGroupId {
176 get {AssertValid (); return stat.st_gid;}
179 public long DeviceType {
180 get {AssertValid (); return Convert.ToInt64 (stat.st_rdev);}
184 get {AssertValid (); return (long) stat.st_size;}
187 public long BlockSize {
188 get {AssertValid (); return (long) stat.st_blksize;}
191 public long BlocksAllocated {
192 get {AssertValid (); return (long) stat.st_blocks;}
195 public DateTime LastAccessTime {
196 get {AssertValid (); return Native.NativeConvert.ToDateTime (stat.st_atime);}
199 public DateTime LastAccessTimeUtc {
200 get {return LastAccessTime.ToUniversalTime ();}
203 public DateTime LastWriteTime {
204 get {AssertValid (); return Native.NativeConvert.ToDateTime (stat.st_mtime);}
207 public DateTime LastWriteTimeUtc {
208 get {return LastWriteTime.ToUniversalTime ();}
211 public DateTime LastStatusChangeTime {
212 get {AssertValid (); return Native.NativeConvert.ToDateTime (stat.st_ctime);}
215 public DateTime LastStatusChangeTimeUtc {
216 get {return LastStatusChangeTime.ToUniversalTime ();}
219 public bool IsDirectory {
220 get {AssertValid (); return IsType (stat.st_mode, Native.FilePermissions.S_IFDIR);}
223 public bool IsCharacterDevice {
224 get {AssertValid (); return IsType (stat.st_mode, Native.FilePermissions.S_IFCHR);}
227 public bool IsBlockDevice {
228 get {AssertValid (); return IsType (stat.st_mode, Native.FilePermissions.S_IFBLK);}
231 public bool IsRegularFile {
232 get {AssertValid (); return IsType (stat.st_mode, Native.FilePermissions.S_IFREG);}
236 get {AssertValid (); return IsType (stat.st_mode, Native.FilePermissions.S_IFIFO);}
239 public bool IsSymbolicLink {
240 get {AssertValid (); return IsType (stat.st_mode, Native.FilePermissions.S_IFLNK);}
243 public bool IsSocket {
244 get {AssertValid (); return IsType (stat.st_mode, Native.FilePermissions.S_IFSOCK);}
247 public bool IsSetUser {
248 get {AssertValid (); return IsType (stat.st_mode, Native.FilePermissions.S_ISUID);}
251 public bool IsSetGroup {
252 get {AssertValid (); return IsType (stat.st_mode, Native.FilePermissions.S_ISGID);}
255 public bool IsSticky {
256 get {AssertValid (); return IsType (stat.st_mode, Native.FilePermissions.S_ISVTX);}
259 internal static bool IsType (Native.FilePermissions mode, Native.FilePermissions type)
261 return (mode & type) == type;
264 [CLSCompliant (false)]
265 public bool CanAccess (Native.AccessModes mode)
267 int r = Native.Syscall.access (FullPath, mode);
271 public UnixFileSystemInfo CreateLink (string path)
273 int r = Native.Syscall.link (FullName, path);
274 UnixMarshal.ThrowExceptionForLastErrorIf (r);
275 return Create (path);
278 public UnixSymbolicLinkInfo CreateSymbolicLink (string path)
280 int r = Native.Syscall.symlink (FullName, path);
281 UnixMarshal.ThrowExceptionForLastErrorIf (r);
282 return new UnixSymbolicLinkInfo (path);
285 public abstract void Delete ();
287 [CLSCompliant (false)]
288 public long GetConfigurationValue (Native.PathconfName name)
290 long r = Native.Syscall.pathconf (FullPath, name);
291 if (r == -1 && Native.Stdlib.GetLastError() != (Native.Errno) 0)
292 UnixMarshal.ThrowExceptionForLastError ();
296 public void Refresh ()
301 internal void Refresh (bool force)
305 valid = GetFileStatus (FullPath, out this.stat);
308 protected virtual bool GetFileStatus (string path, out Native.Stat stat)
310 return Native.Syscall.stat (path, out stat) == 0;
313 public void SetLength (long length)
317 r = Native.Syscall.truncate (FullPath, length);
318 } while (UnixMarshal.ShouldRetrySyscall (r));
319 UnixMarshal.ThrowExceptionForLastErrorIf (r);
322 public virtual void SetOwner (long owner, long group)
324 uint _owner = Convert.ToUInt32 (owner);
325 uint _group = Convert.ToUInt32 (group);
326 int r = Native.Syscall.chown (FullPath, _owner, _group);
327 UnixMarshal.ThrowExceptionForLastErrorIf (r);
330 public void SetOwner (string owner)
332 Native.Passwd pw = Native.Syscall.getpwnam (owner);
334 throw new ArgumentException (Locale.GetText ("invalid username"), "owner");
335 uint uid = pw.pw_uid;
336 uint gid = pw.pw_gid;
337 SetOwner ((long) uid, (long) gid);
340 public void SetOwner (string owner, string group)
344 uid = new UnixUserInfo (owner).UserId;
347 gid = new UnixGroupInfo (group).GroupId;
352 public void SetOwner (UnixUserInfo owner)
363 public void SetOwner (UnixUserInfo owner, UnixGroupInfo group)
374 public override string ToString ()
379 public Native.Stat ToStat ()
385 internal static UnixFileSystemInfo Create (string path)
388 int r = Native.Syscall.lstat (path, out stat);
389 UnixMarshal.ThrowExceptionForLastErrorIf (r);
391 if (IsType (stat.st_mode, Native.FilePermissions.S_IFDIR))
392 return new UnixDirectoryInfo (path, stat);
393 else if (IsType (stat.st_mode, Native.FilePermissions.S_IFLNK))
394 return new UnixSymbolicLinkInfo (path, stat);
395 return new UnixFileInfo (path, stat);