2004-11-18 Lluis Sanchez Gual <lluis@novell.com>
[mono.git] / mcs / class / Mono.Posix / Mono.Unix / UnixDirectoryInfo.cs
1 //
2 // Mono.Unix/UnixDirectoryInfo.cs
3 //
4 // Authors:
5 //   Jonathan Pryor (jonpryor@vt.edu)
6 //
7 // (C) 2004 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 class UnixDirectoryInfo : UnixFileSystemInfo
39         {
40                 public UnixDirectoryInfo (string path)
41                         : base (path)
42                 {
43                 }
44
45                 internal UnixDirectoryInfo (string path, Stat stat)
46                         : base (path, stat)
47                 {
48                 }
49
50                 public void Create (FilePermissions mode)
51                 {
52                         int r = Syscall.mkdir (Path, mode);
53                         UnixMarshal.ThrowExceptionForLastErrorIf (r);
54                         base.Refresh ();
55                 }
56
57                 public void Create ()
58                 {
59                         FilePermissions mode = FilePermissions.ACCESSPERMS;
60                         Create (mode);
61                 }
62
63                 public override void Delete ()
64                 {
65                         Delete (false);
66                 }
67
68                 public void Delete (bool recursive)
69                 {
70                         if (recursive) {
71                                 foreach (UnixFileSystemInfo e in GetFileSystemEntries ()) {
72                                         UnixDirectoryInfo d = e as UnixDirectoryInfo;
73                                         if (d != null)
74                                                 d.Delete (true);
75                                         else
76                                                 e.Delete ();
77                                 }
78                         }
79                         int r = Syscall.rmdir (Path);
80                         UnixMarshal.ThrowExceptionForLastErrorIf (r);
81                         base.Refresh ();
82                 }
83
84                 public Dirent[] GetEntries ()
85                 {
86                         IntPtr dirp = Syscall.opendir (Path);
87                         if (dirp == IntPtr.Zero)
88                                 UnixMarshal.ThrowExceptionForLastError ();
89
90                         bool complete = false;
91                         try {
92                                 Dirent[] entries = GetEntries (dirp);
93                                 complete = true;
94                                 return entries;
95                         }
96                         finally {
97                                 int r = Syscall.closedir (dirp);
98                                 // don't throw an exception if an exception is in progress
99                                 if (complete)
100                                         UnixMarshal.ThrowExceptionForLastErrorIf (r);
101                         }
102                 }
103
104                 private static Dirent[] GetEntries (IntPtr dirp)
105                 {
106                         ArrayList entries = new ArrayList ();
107
108                         int r;
109                         IntPtr result;
110                         do {
111                                 Dirent d = new Dirent ();
112                                 r = Syscall.readdir_r (dirp, d, out result);
113                                 if (r == 0 && result != IntPtr.Zero)
114                                         // don't include current & parent dirs
115                                         if (d.d_name != "." && d.d_name != "..")
116                                                 entries.Add (d);
117                         } while  (r == 0 && result != IntPtr.Zero);
118                         if (r != 0)
119                                 UnixMarshal.ThrowExceptionForLastErrorIf (r);
120
121                         return (Dirent[]) entries.ToArray (typeof(Dirent));
122                 }
123
124                 public Dirent[] GetEntries (Regex regex)
125                 {
126                         IntPtr dirp = Syscall.opendir (Path);
127                         if (dirp == IntPtr.Zero)
128                                 UnixMarshal.ThrowExceptionForLastError ();
129
130                         try {
131                                 return GetEntries (dirp, regex);
132                         }
133                         finally {
134                                 int r = Syscall.closedir (dirp);
135                                 UnixMarshal.ThrowExceptionForLastErrorIf (r);
136                         }
137                 }
138
139                 private static Dirent[] GetEntries (IntPtr dirp, Regex regex)
140                 {
141                         ArrayList entries = new ArrayList ();
142
143                         int r;
144                         IntPtr result;
145                         do {
146                                 Dirent d = new Dirent ();
147                                 r = Syscall.readdir_r (dirp, d, out result);
148                                 if (r == 0 && result != IntPtr.Zero && regex.Match (d.d_name).Success) {
149                                         // don't include current & parent dirs
150                                         if (d.d_name != "." && d.d_name != "..")
151                                                 entries.Add (d);
152                                 }
153                         } while  (r == 0 && result != IntPtr.Zero);
154                         if (r != 0)
155                                 UnixMarshal.ThrowExceptionForLastError ();
156
157                         return (Dirent[]) entries.ToArray (typeof(Dirent));
158                 }
159
160                 public Dirent[] GetEntries (string regex)
161                 {
162                         Regex re = new Regex (regex);
163                         return GetEntries (re);
164                 }
165
166                 public UnixFileSystemInfo[] GetFileSystemEntries ()
167                 {
168                         Dirent[] dentries = GetEntries ();
169                         return GetFileSystemEntries (dentries);
170                 }
171
172                 private UnixFileSystemInfo[] GetFileSystemEntries (Dirent[] dentries)
173                 {
174                         UnixFileSystemInfo[] entries = new UnixFileSystemInfo[dentries.Length];
175                         for (int i = 0; i != entries.Length; ++i)
176                                 entries [i] = UnixFileSystemInfo.Create (dentries[i].d_name);
177                         return entries;
178                 }
179
180                 public UnixFileSystemInfo[] GetFileSystemEntries (Regex regex)
181                 {
182                         Dirent[] dentries = GetEntries (regex);
183                         return GetFileSystemEntries (dentries);
184                 }
185
186                 public UnixFileSystemInfo[] GetFileSystemEntries (string regex)
187                 {
188                         Regex re = new Regex (regex);
189                         return GetFileSystemEntries (re);
190                 }
191         }
192 }
193
194 // vim: noexpandtab