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. 27 // 28 29 using System; 30 using System.Collections; 31 using System.IO; 32 using System.Text; 33 using System.Text.RegularExpressions; 34 using Mono.Unix; 35 36 namespace Mono.Unix { 37 38 public sealed class UnixDirectoryInfo : UnixFileSystemInfo 39 { UnixDirectoryInfo(string path)40 public UnixDirectoryInfo (string path) 41 : base (path) 42 { 43 } 44 UnixDirectoryInfo(string path, Native.Stat stat)45 internal UnixDirectoryInfo (string path, Native.Stat stat) 46 : base (path, stat) 47 { 48 } 49 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; 56 } 57 } 58 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); 67 } 68 } 69 70 public UnixDirectoryInfo Root { 71 get { 72 string root = UnixPath.GetPathRoot (FullPath); 73 if (root == null) 74 return null; 75 return new UnixDirectoryInfo (root); 76 } 77 } 78 79 [CLSCompliant (false)] Create(Mono.Unix.Native.FilePermissions mode)80 public void Create (Mono.Unix.Native.FilePermissions mode) 81 { 82 int r = Mono.Unix.Native.Syscall.mkdir (FullPath, mode); 83 UnixMarshal.ThrowExceptionForLastErrorIf (r); 84 base.Refresh (); 85 } 86 Create(FileAccessPermissions mode)87 public void Create (FileAccessPermissions mode) 88 { 89 Create ((Native.FilePermissions) mode); 90 } 91 Create()92 public void Create () 93 { 94 Mono.Unix.Native.FilePermissions mode = 95 Mono.Unix.Native.FilePermissions.ACCESSPERMS; 96 Create (mode); 97 } 98 Delete()99 public override void Delete () 100 { 101 Delete (false); 102 } 103 Delete(bool recursive)104 public void Delete (bool recursive) 105 { 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 (); 113 } 114 } 115 int r = Native.Syscall.rmdir (FullPath); 116 UnixMarshal.ThrowExceptionForLastErrorIf (r); 117 base.Refresh (); 118 } 119 GetEntries()120 public Native.Dirent[] GetEntries () 121 { 122 IntPtr dirp = Native.Syscall.opendir (FullPath); 123 if (dirp == IntPtr.Zero) 124 UnixMarshal.ThrowExceptionForLastError (); 125 126 bool complete = false; 127 try { 128 Native.Dirent[] entries = GetEntries (dirp); 129 complete = true; 130 return entries; 131 } 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); 137 } 138 } 139 GetEntries(IntPtr dirp)140 private static Native.Dirent[] GetEntries (IntPtr dirp) 141 { 142 ArrayList entries = new ArrayList (); 143 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); 156 157 return (Native.Dirent[]) entries.ToArray (typeof(Native.Dirent)); 158 } 159 GetEntries(Regex regex)160 public Native.Dirent[] GetEntries (Regex regex) 161 { 162 IntPtr dirp = Native.Syscall.opendir (FullPath); 163 if (dirp == IntPtr.Zero) 164 UnixMarshal.ThrowExceptionForLastError (); 165 166 try { 167 return GetEntries (dirp, regex); 168 } 169 finally { 170 int r = Native.Syscall.closedir (dirp); 171 UnixMarshal.ThrowExceptionForLastErrorIf (r); 172 } 173 } 174 GetEntries(IntPtr dirp, Regex regex)175 private static Native.Dirent[] GetEntries (IntPtr dirp, Regex regex) 176 { 177 ArrayList entries = new ArrayList (); 178 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); 188 } 189 } while (r == 0 && result != IntPtr.Zero); 190 if (r != 0) 191 UnixMarshal.ThrowExceptionForLastError (); 192 193 return (Native.Dirent[]) entries.ToArray (typeof(Native.Dirent)); 194 } 195 GetEntries(string regex)196 public Native.Dirent[] GetEntries (string regex) 197 { 198 Regex re = new Regex (regex); 199 return GetEntries (re); 200 } 201 GetFileSystemEntries()202 public UnixFileSystemInfo[] GetFileSystemEntries () 203 { 204 Native.Dirent[] dentries = GetEntries (); 205 return GetFileSystemEntries (dentries); 206 } 207 GetFileSystemEntries(Native.Dirent[] dentries)208 private UnixFileSystemInfo[] GetFileSystemEntries (Native.Dirent[] dentries) 209 { 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; 215 } 216 GetFileSystemEntries(Regex regex)217 public UnixFileSystemInfo[] GetFileSystemEntries (Regex regex) 218 { 219 Native.Dirent[] dentries = GetEntries (regex); 220 return GetFileSystemEntries (dentries); 221 } 222 GetFileSystemEntries(string regex)223 public UnixFileSystemInfo[] GetFileSystemEntries (string regex) 224 { 225 Regex re = new Regex (regex); 226 return GetFileSystemEntries (re); 227 } 228 GetCurrentDirectory()229 public static string GetCurrentDirectory () 230 { 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 (); 240 } 241 SetCurrentDirectory(string path)242 public static void SetCurrentDirectory (string path) 243 { 244 int r = Native.Syscall.chdir (path); 245 UnixMarshal.ThrowExceptionForLastErrorIf (r); 246 } 247 } 248 } 249 250 // vim: noexpandtab 251