2 // Mono.Unix/UnixFileSystemInfo.cs
5 // Jonathan Pryor (jonpryor@vt.edu)
7 // (C) 2004-2005 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 protected UnixFileSystemInfo (string path)
45 UnixPath.CheckPath (path);
46 this.originalPath = path;
47 this.fullPath = UnixPath.GetFullPath (path);
51 internal UnixFileSystemInfo (String path, Native.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;}
90 get {AssertValid (); return Convert.ToInt64 (stat.st_dev);}
94 get {AssertValid (); return Convert.ToInt64 (stat.st_ino);}
97 [CLSCompliant (false)]
98 [Obsolete ("Use Protection.")]
99 public FilePermissions Mode {
100 get {AssertValid (); return (FilePermissions) stat.st_mode;}
103 [CLSCompliant (false)]
104 [Obsolete ("Use FileAccessPermissions.")]
105 public FilePermissions Permissions {
106 get {AssertValid (); return (FilePermissions) stat.st_mode & ~FilePermissions.S_IFMT;}
109 [CLSCompliant (false)]
110 public Native.FilePermissions Protection {
111 get {AssertValid (); return (Native.FilePermissions) stat.st_mode;}
113 int r = Native.Syscall.chmod (FullPath, value);
114 UnixMarshal.ThrowExceptionForLastErrorIf (r);
118 public FileTypes FileType {
121 int type = (int) stat.st_mode;
122 return (FileTypes) (type & (int) FileTypes.AllTypes);
124 // no set as chmod(2) won't accept changing the file type.
127 public FileAccessPermissions FileAccessPermissions {
130 int perms = (int) stat.st_mode;
131 return (FileAccessPermissions) (perms & (int) FileAccessPermissions.AllPermissions);
135 int perms = (int) stat.st_mode;
136 perms &= (int) ~FileAccessPermissions.AllPermissions;
137 perms |= (int) value;
138 Protection = (Native.FilePermissions) perms;
142 public FileSpecialAttributes FileSpecialAttributes {
145 int attrs = (int) stat.st_mode;
146 return (FileSpecialAttributes) (attrs & (int) FileSpecialAttributes.AllAttributes);
150 int perms = (int) stat.st_mode;
151 perms &= (int) ~FileSpecialAttributes.AllAttributes;
152 perms |= (int) value;
153 Protection = (Native.FilePermissions) perms;
157 public long LinkCount {
158 get {AssertValid (); return Convert.ToInt64 (stat.st_nlink);}
161 public UnixUserInfo OwnerUser {
162 get {AssertValid (); return new UnixUserInfo (stat.st_uid);}
165 public long OwnerUserId {
166 get {AssertValid (); return stat.st_uid;}
169 public UnixGroupInfo OwnerGroup {
170 get {AssertValid (); return new UnixGroupInfo (stat.st_gid);}
173 public long OwnerGroupId {
174 get {AssertValid (); return stat.st_gid;}
177 public long DeviceType {
178 get {AssertValid (); return Convert.ToInt64 (stat.st_rdev);}
182 get {AssertValid (); return (long) stat.st_size;}
185 public long BlockSize {
186 get {AssertValid (); return (long) stat.st_blksize;}
189 public long BlocksAllocated {
190 get {AssertValid (); return (long) stat.st_blocks;}
193 public DateTime LastAccessTime {
194 get {AssertValid (); return UnixConvert.ToDateTime (stat.st_atime);}
197 public DateTime LastAccessTimeUtc {
198 get {return LastAccessTime.ToUniversalTime ();}
201 public DateTime LastWriteTime {
202 get {AssertValid (); return UnixConvert.ToDateTime (stat.st_mtime);}
205 public DateTime LastWriteTimeUtc {
206 get {return LastWriteTime.ToUniversalTime ();}
209 public DateTime LastStatusChangeTime {
210 get {AssertValid (); return UnixConvert.ToDateTime (stat.st_ctime);}
213 public DateTime LastStatusChangeTimeUtc {
214 get {return LastStatusChangeTime.ToUniversalTime ();}
217 public bool IsDirectory {
218 get {AssertValid (); return IsType (stat.st_mode, Native.FilePermissions.S_IFDIR);}
221 public bool IsCharacterDevice {
222 get {AssertValid (); return IsType (stat.st_mode, Native.FilePermissions.S_IFCHR);}
225 public bool IsBlockDevice {
226 get {AssertValid (); return IsType (stat.st_mode, Native.FilePermissions.S_IFBLK);}
229 [Obsolete ("Use IsRegularFile")]
231 get {AssertValid (); return IsType (stat.st_mode, Native.FilePermissions.S_IFREG);}
234 public bool IsRegularFile {
235 get {AssertValid (); return IsType (stat.st_mode, Native.FilePermissions.S_IFREG);}
238 [Obsolete ("Use IsFifo")]
239 [CLSCompliant (false)]
241 get {AssertValid (); return IsType (stat.st_mode, Native.FilePermissions.S_IFIFO);}
245 get {AssertValid (); return IsType (stat.st_mode, Native.FilePermissions.S_IFIFO);}
248 public bool IsSymbolicLink {
249 get {AssertValid (); return IsType (stat.st_mode, Native.FilePermissions.S_IFLNK);}
252 public bool IsSocket {
253 get {AssertValid (); return IsType (stat.st_mode, Native.FilePermissions.S_IFSOCK);}
256 public bool IsSetUser {
257 get {AssertValid (); return IsType (stat.st_mode, Native.FilePermissions.S_ISUID);}
260 public bool IsSetGroup {
261 get {AssertValid (); return IsType (stat.st_mode, Native.FilePermissions.S_ISGID);}
264 public bool IsSticky {
265 get {AssertValid (); return IsType (stat.st_mode, Native.FilePermissions.S_ISVTX);}
268 internal static bool IsType (FilePermissions mode, FilePermissions type)
270 return (mode & type) == type;
273 internal static bool IsType (Native.FilePermissions mode, Native.FilePermissions type)
275 return (mode & type) == type;
278 [CLSCompliant (false)]
279 [Obsolete ("Use CanAccess (Mono.Unix.Native.AccessModes)")]
280 public bool CanAccess (AccessMode mode)
282 int r = Syscall.access (FullPath, mode);
286 [CLSCompliant (false)]
287 public bool CanAccess (Native.AccessModes mode)
289 int r = Native.Syscall.access (FullPath, mode);
293 public UnixFileSystemInfo CreateLink (string path)
295 int r = Syscall.link (FullName, path);
296 UnixMarshal.ThrowExceptionForLastErrorIf (r);
297 return Create (path);
300 public UnixSymbolicLinkInfo CreateSymbolicLink (string path)
302 int r = Syscall.symlink (FullName, path);
303 UnixMarshal.ThrowExceptionForLastErrorIf (r);
304 return new UnixSymbolicLinkInfo (path);
307 public abstract void Delete ();
309 [CLSCompliant (false)]
310 [Obsolete ("Use GetConfigurationValue (Mono.Unix.Native.PathconfName)")]
311 public long GetConfigurationValue (PathConf name)
313 long r = Syscall.pathconf (FullPath, name);
314 if (r == -1 && Syscall.GetLastError() != (Error) 0)
315 UnixMarshal.ThrowExceptionForLastError ();
319 [CLSCompliant (false)]
320 public long GetConfigurationValue (Native.PathconfName name)
322 long r = Native.Syscall.pathconf (FullPath, name);
323 if (r == -1 && Syscall.GetLastError() != (Error) 0)
324 UnixMarshal.ThrowExceptionForLastError ();
328 public void Refresh ()
333 internal void Refresh (bool force)
337 int r = GetFileStatus (FullPath, out this.stat);
341 protected virtual int GetFileStatus (string path, out Native.Stat stat)
343 return Native.Syscall.stat (path, out stat);
346 public void SetLength (long length)
350 r = Syscall.truncate (FullPath, length);
351 } while (UnixMarshal.ShouldRetrySyscall (r));
352 UnixMarshal.ThrowExceptionForLastErrorIf (r);
355 [CLSCompliant (false)]
356 [Obsolete ("Use Protection setter")]
357 public void SetPermissions (FilePermissions perms)
359 int r = Syscall.chmod (FullPath, perms);
360 UnixMarshal.ThrowExceptionForLastErrorIf (r);
363 [CLSCompliant (false)]
364 [Obsolete ("Use SetOwner (long, long)")]
365 public virtual void SetOwner (uint owner, uint group)
367 int r = Syscall.chown (FullPath, owner, group);
368 UnixMarshal.ThrowExceptionForLastErrorIf (r);
371 public virtual void SetOwner (long owner, long group)
373 uint _owner = Convert.ToUInt32 (owner);
374 uint _group = Convert.ToUInt32 (group);
375 int r = Syscall.chown (FullPath, _owner, _group);
376 UnixMarshal.ThrowExceptionForLastErrorIf (r);
379 public void SetOwner (string owner)
381 Passwd pw = Syscall.getpwnam (owner);
383 throw new ArgumentException (Locale.GetText ("invalid username"), "owner");
384 uint uid = pw.pw_uid;
385 uint gid = pw.pw_gid;
389 public void SetOwner (string owner, string group)
391 uint uid = UnixUser.GetUserId (owner);
392 uint gid = UnixGroup.GetGroupId (group);
397 public override string ToString ()
402 public Native.Stat ToStat ()
407 internal static UnixFileSystemInfo Create (string path)
410 int r = Native.Syscall.lstat (path, out stat);
411 UnixMarshal.ThrowExceptionForLastErrorIf (r);
413 if (IsType (stat.st_mode, Native.FilePermissions.S_IFDIR))
414 return new UnixDirectoryInfo (path, stat);
415 else if (IsType (stat.st_mode, Native.FilePermissions.S_IFLNK))
416 return new UnixSymbolicLinkInfo (path, stat);
417 return new UnixFileInfo (path, stat);