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 [Obsolete ("Use Protection.")]
113 public FilePermissions Mode {
114 get {AssertValid (); return (FilePermissions) stat.st_mode;}
117 [CLSCompliant (false)]
118 [Obsolete ("Use FileAccessPermissions.")]
119 public FilePermissions Permissions {
120 get {AssertValid (); return (FilePermissions) stat.st_mode & ~FilePermissions.S_IFMT;}
123 [CLSCompliant (false)]
124 public Native.FilePermissions Protection {
125 get {AssertValid (); return (Native.FilePermissions) stat.st_mode;}
127 int r = Native.Syscall.chmod (FullPath, value);
128 UnixMarshal.ThrowExceptionForLastErrorIf (r);
132 public FileTypes FileType {
135 int type = (int) stat.st_mode;
136 return (FileTypes) (type & (int) AllFileTypes);
138 // no set as chmod(2) won't accept changing the file type.
141 public FileAccessPermissions FileAccessPermissions {
144 int perms = (int) stat.st_mode;
145 return (FileAccessPermissions) (perms & (int) FileAccessPermissions.AllPermissions);
149 int perms = (int) stat.st_mode;
150 perms &= (int) ~FileAccessPermissions.AllPermissions;
151 perms |= (int) value;
152 Protection = (Native.FilePermissions) perms;
156 public FileSpecialAttributes FileSpecialAttributes {
159 int attrs = (int) stat.st_mode;
160 return (FileSpecialAttributes) (attrs & (int) AllSpecialAttributes);
164 int perms = (int) stat.st_mode;
165 perms &= (int) ~AllSpecialAttributes;
166 perms |= (int) value;
167 Protection = (Native.FilePermissions) perms;
171 public long LinkCount {
172 get {AssertValid (); return Convert.ToInt64 (stat.st_nlink);}
175 public UnixUserInfo OwnerUser {
176 get {AssertValid (); return new UnixUserInfo (stat.st_uid);}
179 public long OwnerUserId {
180 get {AssertValid (); return stat.st_uid;}
183 public UnixGroupInfo OwnerGroup {
184 get {AssertValid (); return new UnixGroupInfo (stat.st_gid);}
187 public long OwnerGroupId {
188 get {AssertValid (); return stat.st_gid;}
191 public long DeviceType {
192 get {AssertValid (); return Convert.ToInt64 (stat.st_rdev);}
196 get {AssertValid (); return (long) stat.st_size;}
199 public long BlockSize {
200 get {AssertValid (); return (long) stat.st_blksize;}
203 public long BlocksAllocated {
204 get {AssertValid (); return (long) stat.st_blocks;}
207 public DateTime LastAccessTime {
208 get {AssertValid (); return Native.NativeConvert.ToDateTime (stat.st_atime);}
211 public DateTime LastAccessTimeUtc {
212 get {return LastAccessTime.ToUniversalTime ();}
215 public DateTime LastWriteTime {
216 get {AssertValid (); return Native.NativeConvert.ToDateTime (stat.st_mtime);}
219 public DateTime LastWriteTimeUtc {
220 get {return LastWriteTime.ToUniversalTime ();}
223 public DateTime LastStatusChangeTime {
224 get {AssertValid (); return Native.NativeConvert.ToDateTime (stat.st_ctime);}
227 public DateTime LastStatusChangeTimeUtc {
228 get {return LastStatusChangeTime.ToUniversalTime ();}
231 public bool IsDirectory {
232 get {AssertValid (); return IsType (stat.st_mode, Native.FilePermissions.S_IFDIR);}
235 public bool IsCharacterDevice {
236 get {AssertValid (); return IsType (stat.st_mode, Native.FilePermissions.S_IFCHR);}
239 public bool IsBlockDevice {
240 get {AssertValid (); return IsType (stat.st_mode, Native.FilePermissions.S_IFBLK);}
243 [Obsolete ("Use IsRegularFile")]
245 get {AssertValid (); return IsType (stat.st_mode, Native.FilePermissions.S_IFREG);}
248 public bool IsRegularFile {
249 get {AssertValid (); return IsType (stat.st_mode, Native.FilePermissions.S_IFREG);}
252 [Obsolete ("Use IsFifo")]
253 [CLSCompliant (false)]
255 get {AssertValid (); return IsType (stat.st_mode, Native.FilePermissions.S_IFIFO);}
259 get {AssertValid (); return IsType (stat.st_mode, Native.FilePermissions.S_IFIFO);}
262 public bool IsSymbolicLink {
263 get {AssertValid (); return IsType (stat.st_mode, Native.FilePermissions.S_IFLNK);}
266 public bool IsSocket {
267 get {AssertValid (); return IsType (stat.st_mode, Native.FilePermissions.S_IFSOCK);}
270 public bool IsSetUser {
271 get {AssertValid (); return IsType (stat.st_mode, Native.FilePermissions.S_ISUID);}
274 public bool IsSetGroup {
275 get {AssertValid (); return IsType (stat.st_mode, Native.FilePermissions.S_ISGID);}
278 public bool IsSticky {
279 get {AssertValid (); return IsType (stat.st_mode, Native.FilePermissions.S_ISVTX);}
282 [Obsolete ("Use IsType(Native.FilePermissions, Native.FilePermissions)", true)]
283 internal static bool IsType (FilePermissions mode, FilePermissions type)
285 return (mode & type) == type;
288 internal static bool IsType (Native.FilePermissions mode, Native.FilePermissions type)
290 return (mode & type) == type;
293 [CLSCompliant (false)]
294 [Obsolete ("Use CanAccess (Mono.Unix.Native.AccessModes)", true)]
295 public bool CanAccess (AccessMode mode)
297 int r = Syscall.access (FullPath, mode);
301 [CLSCompliant (false)]
302 public bool CanAccess (Native.AccessModes mode)
304 int r = Native.Syscall.access (FullPath, mode);
308 public UnixFileSystemInfo CreateLink (string path)
310 int r = Native.Syscall.link (FullName, path);
311 UnixMarshal.ThrowExceptionForLastErrorIf (r);
312 return Create (path);
315 public UnixSymbolicLinkInfo CreateSymbolicLink (string path)
317 int r = Native.Syscall.symlink (FullName, path);
318 UnixMarshal.ThrowExceptionForLastErrorIf (r);
319 return new UnixSymbolicLinkInfo (path);
322 public abstract void Delete ();
324 [CLSCompliant (false)]
325 [Obsolete ("Use GetConfigurationValue (Mono.Unix.Native.PathconfName)", true)]
326 public long GetConfigurationValue (PathConf name)
328 long r = Syscall.pathconf (FullPath, name);
329 if (r == -1 && Syscall.GetLastError() != (Error) 0)
330 UnixMarshal.ThrowExceptionForLastError ();
334 [CLSCompliant (false)]
335 public long GetConfigurationValue (Native.PathconfName name)
337 long r = Native.Syscall.pathconf (FullPath, name);
338 if (r == -1 && Native.Stdlib.GetLastError() != (Native.Errno) 0)
339 UnixMarshal.ThrowExceptionForLastError ();
343 public void Refresh ()
348 internal void Refresh (bool force)
352 valid = GetFileStatus (FullPath, out this.stat);
355 protected virtual bool GetFileStatus (string path, out Native.Stat stat)
357 return Native.Syscall.stat (path, out stat) == 0;
360 public void SetLength (long length)
364 r = Native.Syscall.truncate (FullPath, length);
365 } while (UnixMarshal.ShouldRetrySyscall (r));
366 UnixMarshal.ThrowExceptionForLastErrorIf (r);
369 [CLSCompliant (false)]
370 [Obsolete ("Use Protection setter", true)]
371 public void SetPermissions (FilePermissions perms)
373 int r = Syscall.chmod (FullPath, perms);
374 UnixMarshal.ThrowExceptionForLastErrorIf (r);
377 [CLSCompliant (false)]
378 [Obsolete ("Use SetOwner (long, long)", true)]
379 public virtual void SetOwner (uint owner, uint group)
381 int r = Syscall.chown (FullPath, owner, group);
382 UnixMarshal.ThrowExceptionForLastErrorIf (r);
385 public virtual void SetOwner (long owner, long group)
387 uint _owner = Convert.ToUInt32 (owner);
388 uint _group = Convert.ToUInt32 (group);
389 int r = Native.Syscall.chown (FullPath, _owner, _group);
390 UnixMarshal.ThrowExceptionForLastErrorIf (r);
393 public void SetOwner (string owner)
395 Native.Passwd pw = Native.Syscall.getpwnam (owner);
397 throw new ArgumentException (Locale.GetText ("invalid username"), "owner");
398 uint uid = pw.pw_uid;
399 uint gid = pw.pw_gid;
400 SetOwner ((long) uid, (long) gid);
403 public void SetOwner (string owner, string group)
407 uid = new UnixUserInfo (owner).UserId;
410 gid = new UnixGroupInfo (group).GroupId;
415 public void SetOwner (UnixUserInfo owner)
426 public void SetOwner (UnixUserInfo owner, UnixGroupInfo group)
437 public override string ToString ()
442 public Native.Stat ToStat ()
448 internal static UnixFileSystemInfo Create (string path)
451 int r = Native.Syscall.lstat (path, out stat);
452 UnixMarshal.ThrowExceptionForLastErrorIf (r);
454 if (IsType (stat.st_mode, Native.FilePermissions.S_IFDIR))
455 return new UnixDirectoryInfo (path, stat);
456 else if (IsType (stat.st_mode, Native.FilePermissions.S_IFLNK))
457 return new UnixSymbolicLinkInfo (path, stat);
458 return new UnixFileInfo (path, stat);