2 // Mono.Unix/UnixDirectoryInfo.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.
30 using System
.Collections
;
33 using System
.Text
.RegularExpressions
;
38 public sealed class UnixDirectoryInfo
: UnixFileSystemInfo
40 public UnixDirectoryInfo (string path
)
45 internal UnixDirectoryInfo (string path
, Native
.Stat stat
)
50 public override string Name
{
52 string r
= UnixPath
.GetFileName (FullPath
);
53 if (r
== null || r
.Length
== 0)
59 public UnixDirectoryInfo Parent
{
63 string dirname
= UnixPath
.GetDirectoryName (FullPath
);
65 throw new InvalidOperationException ("Do not know parent directory for path `" + FullPath
+ "'");
66 return new UnixDirectoryInfo (dirname
);
70 public UnixDirectoryInfo Root
{
72 string root
= UnixPath
.GetPathRoot (FullPath
);
75 return new UnixDirectoryInfo (root
);
79 [CLSCompliant (false)]
80 public void Create (Mono
.Unix
.Native
.FilePermissions mode
)
82 int r
= Mono
.Unix
.Native
.Syscall
.mkdir (FullPath
, mode
);
83 UnixMarshal
.ThrowExceptionForLastErrorIf (r
);
87 public void Create (FileAccessPermissions mode
)
89 Create ((Native
.FilePermissions
) mode
);
94 Mono
.Unix
.Native
.FilePermissions mode
=
95 Mono
.Unix
.Native
.FilePermissions
.ACCESSPERMS
;
99 public override void Delete ()
104 public void Delete (bool recursive
)
107 foreach (UnixFileSystemInfo e
in GetFileSystemEntries ()) {
108 UnixDirectoryInfo d
= e
as UnixDirectoryInfo
;
115 int r
= Native
.Syscall
.rmdir (FullPath
);
116 UnixMarshal
.ThrowExceptionForLastErrorIf (r
);
120 public Native
.Dirent
[] GetEntries ()
122 IntPtr dirp
= Native
.Syscall
.opendir (FullPath
);
123 if (dirp
== IntPtr
.Zero
)
124 UnixMarshal
.ThrowExceptionForLastError ();
126 bool complete
= false;
128 Native
.Dirent
[] entries
= GetEntries (dirp
);
133 int r
= Native
.Syscall
.closedir (dirp
);
134 // don't throw an exception if an exception is in progress
136 UnixMarshal
.ThrowExceptionForLastErrorIf (r
);
140 private static Native
.Dirent
[] GetEntries (IntPtr dirp
)
142 ArrayList entries
= new ArrayList ();
147 Native
.Dirent d
= new Native
.Dirent ();
148 r
= Native
.Syscall
.readdir_r (dirp
, d
, out result
);
149 if (r
== 0 && result
!= IntPtr
.Zero
)
150 // don't include current & parent dirs
151 if (d
.d_name
!= "." && d
.d_name
!= "..")
153 } while (r
== 0 && result
!= IntPtr
.Zero
);
155 UnixMarshal
.ThrowExceptionForLastErrorIf (r
);
157 return (Native
.Dirent
[]) entries
.ToArray (typeof(Native
.Dirent
));
160 public Native
.Dirent
[] GetEntries (Regex regex
)
162 IntPtr dirp
= Native
.Syscall
.opendir (FullPath
);
163 if (dirp
== IntPtr
.Zero
)
164 UnixMarshal
.ThrowExceptionForLastError ();
167 return GetEntries (dirp
, regex
);
170 int r
= Native
.Syscall
.closedir (dirp
);
171 UnixMarshal
.ThrowExceptionForLastErrorIf (r
);
175 private static Native
.Dirent
[] GetEntries (IntPtr dirp
, Regex regex
)
177 ArrayList entries
= new ArrayList ();
182 Native
.Dirent d
= new Native
.Dirent ();
183 r
= Native
.Syscall
.readdir_r (dirp
, d
, out result
);
184 if (r
== 0 && result
!= IntPtr
.Zero
&& regex
.Match (d
.d_name
).Success
) {
185 // don't include current & parent dirs
186 if (d
.d_name
!= "." && d
.d_name
!= "..")
189 } while (r
== 0 && result
!= IntPtr
.Zero
);
191 UnixMarshal
.ThrowExceptionForLastError ();
193 return (Native
.Dirent
[]) entries
.ToArray (typeof(Native
.Dirent
));
196 public Native
.Dirent
[] GetEntries (string regex
)
198 Regex re
= new Regex (regex
);
199 return GetEntries (re
);
202 public UnixFileSystemInfo
[] GetFileSystemEntries ()
204 Native
.Dirent
[] dentries
= GetEntries ();
205 return GetFileSystemEntries (dentries
);
208 private UnixFileSystemInfo
[] GetFileSystemEntries (Native
.Dirent
[] dentries
)
210 UnixFileSystemInfo
[] entries
= new UnixFileSystemInfo
[dentries
.Length
];
211 for (int i
= 0; i
!= entries
.Length
; ++i
)
212 entries
[i
] = UnixFileSystemInfo
.GetFileSystemEntry (
213 UnixPath
.Combine (FullPath
, dentries
[i
].d_name
));
217 public UnixFileSystemInfo
[] GetFileSystemEntries (Regex regex
)
219 Native
.Dirent
[] dentries
= GetEntries (regex
);
220 return GetFileSystemEntries (dentries
);
223 public UnixFileSystemInfo
[] GetFileSystemEntries (string regex
)
225 Regex re
= new Regex (regex
);
226 return GetFileSystemEntries (re
);
229 public static string GetCurrentDirectory ()
231 StringBuilder buf
= new StringBuilder (16);
232 IntPtr r
= IntPtr
.Zero
;
235 r
= Native
.Syscall
.getcwd (buf
, (ulong) buf
.Capacity
);
236 } while (r
== IntPtr
.Zero
&& Native
.Syscall
.GetLastError() == Native
.Errno
.ERANGE
);
237 if (r
== IntPtr
.Zero
)
238 UnixMarshal
.ThrowExceptionForLastError ();
239 return buf
.ToString ();
242 public static void SetCurrentDirectory (string path
)
244 int r
= Native
.Syscall
.chdir (path
);
245 UnixMarshal
.ThrowExceptionForLastErrorIf (r
);