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 return (FileTypes
) (stat
.st_mode
& Native
.FilePermissions
.S_IFMT
);
125 // no set as chmod(2) won't accept changing the file type.
128 public FileAccessPermissions FileAccessPermissions
{
131 int perms
= (int) stat
.st_mode
;
132 return (FileAccessPermissions
) (perms
& (int) FileAccessPermissions
.AllPermissions
);
136 int perms
= (int) stat
.st_mode
;
137 perms
&= (int) ~FileAccessPermissions
.AllPermissions
;
138 perms
|= (int) value;
139 Protection
= (Native
.FilePermissions
) perms
;
143 public FileSpecialAttributes FileSpecialAttributes
{
146 int attrs
= (int) stat
.st_mode
;
147 return (FileSpecialAttributes
) (attrs
& (int) AllSpecialAttributes
);
151 int perms
= (int) stat
.st_mode
;
152 perms
&= (int) ~AllSpecialAttributes
;
153 perms
|= (int) value;
154 Protection
= (Native
.FilePermissions
) perms
;
158 public long LinkCount
{
159 get {AssertValid (); return Convert.ToInt64 (stat.st_nlink);}
162 public UnixUserInfo OwnerUser
{
163 get {AssertValid (); return new UnixUserInfo (stat.st_uid);}
166 public long OwnerUserId
{
167 get {AssertValid (); return stat.st_uid;}
170 public UnixGroupInfo OwnerGroup
{
171 get {AssertValid (); return new UnixGroupInfo (stat.st_gid);}
174 public long OwnerGroupId
{
175 get {AssertValid (); return stat.st_gid;}
178 public long DeviceType
{
179 get {AssertValid (); return Convert.ToInt64 (stat.st_rdev);}
183 get {AssertValid (); return (long) stat.st_size;}
186 public long BlockSize
{
187 get {AssertValid (); return (long) stat.st_blksize;}
190 public long BlocksAllocated
{
191 get {AssertValid (); return (long) stat.st_blocks;}
194 public DateTime LastAccessTime
{
195 get {AssertValid (); return Native.NativeConvert.ToDateTime (stat.st_atime);}
198 public DateTime LastAccessTimeUtc
{
199 get {return LastAccessTime.ToUniversalTime ();}
202 public DateTime LastWriteTime
{
203 get {AssertValid (); return Native.NativeConvert.ToDateTime (stat.st_mtime);}
206 public DateTime LastWriteTimeUtc
{
207 get {return LastWriteTime.ToUniversalTime ();}
210 public DateTime LastStatusChangeTime
{
211 get {AssertValid (); return Native.NativeConvert.ToDateTime (stat.st_ctime);}
214 public DateTime LastStatusChangeTimeUtc
{
215 get {return LastStatusChangeTime.ToUniversalTime ();}
218 public bool IsDirectory
{
219 get {AssertValid (); return IsFileType (stat.st_mode, Native.FilePermissions.S_IFDIR);}
222 public bool IsCharacterDevice
{
223 get {AssertValid (); return IsFileType (stat.st_mode, Native.FilePermissions.S_IFCHR);}
226 public bool IsBlockDevice
{
227 get {AssertValid (); return IsFileType (stat.st_mode, Native.FilePermissions.S_IFBLK);}
230 public bool IsRegularFile
{
231 get {AssertValid (); return IsFileType (stat.st_mode, Native.FilePermissions.S_IFREG);}
235 get {AssertValid (); return IsFileType (stat.st_mode, Native.FilePermissions.S_IFIFO);}
238 public bool IsSymbolicLink
{
239 get {AssertValid (); return IsFileType (stat.st_mode, Native.FilePermissions.S_IFLNK);}
242 public bool IsSocket
{
243 get {AssertValid (); return IsFileType (stat.st_mode, Native.FilePermissions.S_IFSOCK);}
246 public bool IsSetUser
{
247 get {AssertValid (); return IsSet (stat.st_mode, Native.FilePermissions.S_ISUID);}
250 public bool IsSetGroup
{
251 get {AssertValid (); return IsSet (stat.st_mode, Native.FilePermissions.S_ISGID);}
254 public bool IsSticky
{
255 get {AssertValid (); return IsSet (stat.st_mode, Native.FilePermissions.S_ISVTX);}
258 internal static bool IsFileType (Native
.FilePermissions mode
, Native
.FilePermissions type
)
260 return (mode
& Native
.FilePermissions
.S_IFMT
) == type
;
263 internal static bool IsSet (Native
.FilePermissions mode
, Native
.FilePermissions type
)
265 return (mode
& type
) == type
;
268 [CLSCompliant (false)]
269 public bool CanAccess (Native
.AccessModes mode
)
271 int r
= Native
.Syscall
.access (FullPath
, mode
);
275 public UnixFileSystemInfo
CreateLink (string path
)
277 int r
= Native
.Syscall
.link (FullName
, path
);
278 UnixMarshal
.ThrowExceptionForLastErrorIf (r
);
279 return GetFileSystemEntry (path
);
282 public UnixSymbolicLinkInfo
CreateSymbolicLink (string path
)
284 int r
= Native
.Syscall
.symlink (FullName
, path
);
285 UnixMarshal
.ThrowExceptionForLastErrorIf (r
);
286 return new UnixSymbolicLinkInfo (path
);
289 public abstract void Delete ();
291 [CLSCompliant (false)]
292 public long GetConfigurationValue (Native
.PathconfName name
)
294 long r
= Native
.Syscall
.pathconf (FullPath
, name
);
295 if (r
== -1 && Native
.Stdlib
.GetLastError() != (Native
.Errno
) 0)
296 UnixMarshal
.ThrowExceptionForLastError ();
300 public void Refresh ()
305 internal void Refresh (bool force
)
309 valid
= GetFileStatus (FullPath
, out this.stat
);
312 protected virtual bool GetFileStatus (string path
, out Native
.Stat stat
)
314 return Native
.Syscall
.stat (path
, out stat
) == 0;
317 public void SetLength (long length
)
321 r
= Native
.Syscall
.truncate (FullPath
, length
);
322 } while (UnixMarshal
.ShouldRetrySyscall (r
));
323 UnixMarshal
.ThrowExceptionForLastErrorIf (r
);
326 public virtual void SetOwner (long owner
, long group)
328 uint _owner
= Convert
.ToUInt32 (owner
);
329 uint _group
= Convert
.ToUInt32 (group);
330 int r
= Native
.Syscall
.chown (FullPath
, _owner
, _group
);
331 UnixMarshal
.ThrowExceptionForLastErrorIf (r
);
334 public void SetOwner (string owner
)
336 Native
.Passwd pw
= Native
.Syscall
.getpwnam (owner
);
338 throw new ArgumentException (Locale
.GetText ("invalid username"), "owner");
339 uint uid
= pw
.pw_uid
;
340 uint gid
= pw
.pw_gid
;
341 SetOwner ((long) uid
, (long) gid
);
344 public void SetOwner (string owner
, string group)
348 uid
= new UnixUserInfo (owner
).UserId
;
351 gid
= new UnixGroupInfo (group).GroupId
;
356 public void SetOwner (UnixUserInfo owner
)
367 public void SetOwner (UnixUserInfo owner
, UnixGroupInfo
group)
378 public override string ToString ()
383 public Native
.Stat
ToStat ()
389 public static UnixFileSystemInfo
GetFileSystemEntry (string path
)
392 int r
= Native
.Syscall
.lstat (path
, out stat
);
393 if (r
== -1 && Native
.Stdlib
.GetLastError() == Native
.Errno
.ENOENT
) {
394 return new UnixFileInfo (path
);
396 UnixMarshal
.ThrowExceptionForLastErrorIf (r
);
398 if (IsFileType (stat
.st_mode
, Native
.FilePermissions
.S_IFDIR
))
399 return new UnixDirectoryInfo (path
, stat
);
400 else if (IsFileType (stat
.st_mode
, Native
.FilePermissions
.S_IFLNK
))
401 return new UnixSymbolicLinkInfo (path
, stat
);
402 return new UnixFileInfo (path
, stat
);