2008-09-30 Michael Hutchinson <mhutchinson@novell.com>
[mono-project.git] / mcs / class / Mono.Posix / Mono.Unix / UnixDirectoryInfo.cs
blob5cc6183edc15796aa1c991673daaa86b366d5d30
1 //
2 // Mono.Unix/UnixDirectoryInfo.cs
3 //
4 // Authors:
5 // Jonathan Pryor (jonpryor@vt.edu)
6 //
7 // (C) 2004-2006 Jonathan Pryor
8 //
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:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
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.
29 using System;
30 using System.Collections;
31 using System.IO;
32 using System.Text;
33 using System.Text.RegularExpressions;
34 using Mono.Unix;
36 namespace Mono.Unix {
38 public sealed class UnixDirectoryInfo : UnixFileSystemInfo
40 public UnixDirectoryInfo (string path)
41 : base (path)
45 internal UnixDirectoryInfo (string path, Native.Stat stat)
46 : base (path, stat)
50 public override string Name {
51 get {
52 string r = UnixPath.GetFileName (FullPath);
53 if (r == null || r.Length == 0)
54 return FullPath;
55 return r;
59 public UnixDirectoryInfo Parent {
60 get {
61 if (FullPath == "/")
62 return this;
63 string dirname = UnixPath.GetDirectoryName (FullPath);
64 if (dirname == "")
65 throw new InvalidOperationException ("Do not know parent directory for path `" + FullPath + "'");
66 return new UnixDirectoryInfo (dirname);
70 public UnixDirectoryInfo Root {
71 get {
72 string root = UnixPath.GetPathRoot (FullPath);
73 if (root == null)
74 return null;
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);
84 base.Refresh ();
87 public void Create (FileAccessPermissions mode)
89 Create ((Native.FilePermissions) mode);
92 public void Create ()
94 Mono.Unix.Native.FilePermissions mode =
95 Mono.Unix.Native.FilePermissions.ACCESSPERMS;
96 Create (mode);
99 public override void Delete ()
101 Delete (false);
104 public void Delete (bool recursive)
106 if (recursive) {
107 foreach (UnixFileSystemInfo e in GetFileSystemEntries ()) {
108 UnixDirectoryInfo d = e as UnixDirectoryInfo;
109 if (d != null)
110 d.Delete (true);
111 else
112 e.Delete ();
115 int r = Native.Syscall.rmdir (FullPath);
116 UnixMarshal.ThrowExceptionForLastErrorIf (r);
117 base.Refresh ();
120 public Native.Dirent[] GetEntries ()
122 IntPtr dirp = Native.Syscall.opendir (FullPath);
123 if (dirp == IntPtr.Zero)
124 UnixMarshal.ThrowExceptionForLastError ();
126 bool complete = false;
127 try {
128 Native.Dirent[] entries = GetEntries (dirp);
129 complete = true;
130 return entries;
132 finally {
133 int r = Native.Syscall.closedir (dirp);
134 // don't throw an exception if an exception is in progress
135 if (complete)
136 UnixMarshal.ThrowExceptionForLastErrorIf (r);
140 private static Native.Dirent[] GetEntries (IntPtr dirp)
142 ArrayList entries = new ArrayList ();
144 int r;
145 IntPtr result;
146 do {
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 != "..")
152 entries.Add (d);
153 } while (r == 0 && result != IntPtr.Zero);
154 if (r != 0)
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 ();
166 try {
167 return GetEntries (dirp, regex);
169 finally {
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 ();
179 int r;
180 IntPtr result;
181 do {
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 != "..")
187 entries.Add (d);
189 } while (r == 0 && result != IntPtr.Zero);
190 if (r != 0)
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));
214 return entries;
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;
233 do {
234 buf.Capacity *= 2;
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);
250 // vim: noexpandtab