nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /* GLIB - Library of useful routines for C programming |
2 | * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald |
||
3 | * |
||
4 | * gdir.c: Simplified wrapper around the DIRENT functions. |
||
5 | * |
||
6 | * Copyright 2001 Hans Breuer |
||
7 | * Copyright 2004 Tor Lillqvist |
||
8 | * |
||
9 | * This library is free software; you can redistribute it and/or |
||
10 | * modify it under the terms of the GNU Lesser General Public |
||
11 | * License as published by the Free Software Foundation; either |
||
12 | * version 2 of the License, or (at your option) any later version. |
||
13 | * |
||
14 | * This library is distributed in the hope that it will be useful, |
||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||
17 | * Lesser General Public License for more details. |
||
18 | * |
||
19 | * You should have received a copy of the GNU Lesser General Public |
||
20 | * License along with this library; if not, see <http://www.gnu.org/licenses/>. |
||
21 | */ |
||
22 | |||
23 | #include "config.h" |
||
24 | |||
25 | #include <errno.h> |
||
26 | #include <string.h> |
||
27 | #include <stdio.h> |
||
28 | #include <sys/stat.h> |
||
29 | |||
30 | #ifdef HAVE_DIRENT_H |
||
31 | #include <sys/types.h> |
||
32 | #include <dirent.h> |
||
33 | #endif |
||
34 | |||
35 | #include "gdir.h" |
||
36 | |||
37 | #include "gconvert.h" |
||
38 | #include "gfileutils.h" |
||
39 | #include "gstrfuncs.h" |
||
40 | #include "gtestutils.h" |
||
41 | #include "glibintl.h" |
||
42 | |||
43 | #if defined (_MSC_VER) && !defined (HAVE_DIRENT_H) |
||
44 | #include "../build/win32/dirent/dirent.h" |
||
45 | #include "../build/win32/dirent/wdirent.c" |
||
46 | #endif |
||
47 | |||
48 | #include "glib-private.h" /* g_dir_open_with_errno, g_dir_new_from_dirp */ |
||
49 | |||
50 | /** |
||
51 | * GDir: |
||
52 | * |
||
53 | * An opaque structure representing an opened directory. |
||
54 | */ |
||
55 | |||
56 | struct _GDir |
||
57 | { |
||
58 | #ifdef G_OS_WIN32 |
||
59 | _WDIR *wdirp; |
||
60 | #else |
||
61 | DIR *dirp; |
||
62 | #endif |
||
63 | #ifdef G_OS_WIN32 |
||
64 | gchar utf8_buf[FILENAME_MAX*4]; |
||
65 | #endif |
||
66 | }; |
||
67 | |||
68 | /*< private > |
||
69 | * g_dir_open_with_errno: |
||
70 | * @path: the path to the directory you are interested in. |
||
71 | * @flags: Currently must be set to 0. Reserved for future use. |
||
72 | * |
||
73 | * Opens a directory for reading. |
||
74 | * |
||
75 | * This function is equivalent to g_dir_open() except in the error case, |
||
76 | * errno will be set accordingly. |
||
77 | * |
||
78 | * This is useful if you want to construct your own error message. |
||
79 | * |
||
80 | * Returns: a newly allocated #GDir on success, or %NULL on failure, |
||
81 | * with errno set accordingly. |
||
82 | * |
||
83 | * Since: 2.38 |
||
84 | */ |
||
85 | GDir * |
||
86 | g_dir_open_with_errno (const gchar *path, |
||
87 | guint flags) |
||
88 | { |
||
89 | GDir dir; |
||
90 | #ifdef G_OS_WIN32 |
||
91 | gint saved_errno; |
||
92 | wchar_t *wpath; |
||
93 | #endif |
||
94 | |||
95 | g_return_val_if_fail (path != NULL, NULL); |
||
96 | |||
97 | #ifdef G_OS_WIN32 |
||
98 | wpath = g_utf8_to_utf16 (path, -1, NULL, NULL, NULL); |
||
99 | |||
100 | g_return_val_if_fail (wpath != NULL, NULL); |
||
101 | |||
102 | dir.wdirp = _wopendir (wpath); |
||
103 | saved_errno = errno; |
||
104 | g_free (wpath); |
||
105 | errno = saved_errno; |
||
106 | |||
107 | if (dir.wdirp == NULL) |
||
108 | return NULL; |
||
109 | #else |
||
110 | dir.dirp = opendir (path); |
||
111 | |||
112 | if (dir.dirp == NULL) |
||
113 | return NULL; |
||
114 | #endif |
||
115 | |||
116 | return g_memdup (&dir, sizeof dir); |
||
117 | } |
||
118 | |||
119 | /** |
||
120 | * g_dir_open: |
||
121 | * @path: the path to the directory you are interested in. On Unix |
||
122 | * in the on-disk encoding. On Windows in UTF-8 |
||
123 | * @flags: Currently must be set to 0. Reserved for future use. |
||
124 | * @error: return location for a #GError, or %NULL. |
||
125 | * If non-%NULL, an error will be set if and only if |
||
126 | * g_dir_open() fails. |
||
127 | * |
||
128 | * Opens a directory for reading. The names of the files in the |
||
129 | * directory can then be retrieved using g_dir_read_name(). Note |
||
130 | * that the ordering is not defined. |
||
131 | * |
||
132 | * Returns: a newly allocated #GDir on success, %NULL on failure. |
||
133 | * If non-%NULL, you must free the result with g_dir_close() |
||
134 | * when you are finished with it. |
||
135 | **/ |
||
136 | GDir * |
||
137 | g_dir_open (const gchar *path, |
||
138 | guint flags, |
||
139 | GError **error) |
||
140 | { |
||
141 | gint saved_errno; |
||
142 | GDir *dir; |
||
143 | |||
144 | dir = g_dir_open_with_errno (path, flags); |
||
145 | |||
146 | if (dir == NULL) |
||
147 | { |
||
148 | gchar *utf8_path; |
||
149 | |||
150 | saved_errno = errno; |
||
151 | |||
152 | utf8_path = g_filename_to_utf8 (path, -1, NULL, NULL, NULL); |
||
153 | |||
154 | g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (saved_errno), |
||
155 | _("Error opening directory '%s': %s"), utf8_path, g_strerror (saved_errno)); |
||
156 | g_free (utf8_path); |
||
157 | } |
||
158 | |||
159 | return dir; |
||
160 | } |
||
161 | |||
162 | #if defined (G_OS_WIN32) && !defined (_WIN64) |
||
163 | |||
164 | /* The above function actually is called g_dir_open_utf8, and it's |
||
165 | * that what applications compiled with this GLib version will |
||
166 | * use. |
||
167 | */ |
||
168 | |||
169 | #undef g_dir_open |
||
170 | |||
171 | /* Binary compatibility version. Not for newly compiled code. */ |
||
172 | |||
173 | GDir * |
||
174 | g_dir_open (const gchar *path, |
||
175 | guint flags, |
||
176 | GError **error) |
||
177 | { |
||
178 | gchar *utf8_path = g_locale_to_utf8 (path, -1, NULL, NULL, error); |
||
179 | GDir *retval; |
||
180 | |||
181 | if (utf8_path == NULL) |
||
182 | return NULL; |
||
183 | |||
184 | retval = g_dir_open_utf8 (utf8_path, flags, error); |
||
185 | |||
186 | g_free (utf8_path); |
||
187 | |||
188 | return retval; |
||
189 | } |
||
190 | #endif |
||
191 | |||
192 | /*< private > |
||
193 | * g_dir_new_from_dirp: |
||
194 | * @dirp: a #DIR* created by opendir() or fdopendir() |
||
195 | * |
||
196 | * Creates a #GDir object from the DIR object that is created using |
||
197 | * opendir() or fdopendir(). The created #GDir assumes ownership of the |
||
198 | * passed-in #DIR pointer. |
||
199 | * |
||
200 | * @dirp must not be %NULL. |
||
201 | * |
||
202 | * This function never fails. |
||
203 | * |
||
204 | * Returns: a newly allocated #GDir, which should be closed using |
||
205 | * g_dir_close(). |
||
206 | * |
||
207 | * Since: 2.38 |
||
208 | **/ |
||
209 | GDir * |
||
210 | g_dir_new_from_dirp (gpointer dirp) |
||
211 | { |
||
212 | #ifdef G_OS_UNIX |
||
213 | GDir *dir; |
||
214 | |||
215 | g_return_val_if_fail (dirp != NULL, NULL); |
||
216 | |||
217 | dir = g_new (GDir, 1); |
||
218 | dir->dirp = dirp; |
||
219 | |||
220 | return dir; |
||
221 | #else |
||
222 | g_assert_not_reached (); |
||
223 | #endif |
||
224 | } |
||
225 | |||
226 | /** |
||
227 | * g_dir_read_name: |
||
228 | * @dir: a #GDir* created by g_dir_open() |
||
229 | * |
||
230 | * Retrieves the name of another entry in the directory, or %NULL. |
||
231 | * The order of entries returned from this function is not defined, |
||
232 | * and may vary by file system or other operating-system dependent |
||
233 | * factors. |
||
234 | * |
||
235 | * %NULL may also be returned in case of errors. On Unix, you can |
||
236 | * check `errno` to find out if %NULL was returned because of an error. |
||
237 | * |
||
238 | * On Unix, the '.' and '..' entries are omitted, and the returned |
||
239 | * name is in the on-disk encoding. |
||
240 | * |
||
241 | * On Windows, as is true of all GLib functions which operate on |
||
242 | * filenames, the returned name is in UTF-8. |
||
243 | * |
||
244 | * Returns: The entry's name or %NULL if there are no |
||
245 | * more entries. The return value is owned by GLib and |
||
246 | * must not be modified or freed. |
||
247 | **/ |
||
248 | const gchar * |
||
249 | g_dir_read_name (GDir *dir) |
||
250 | { |
||
251 | #ifdef G_OS_WIN32 |
||
252 | gchar *utf8_name; |
||
253 | struct _wdirent *wentry; |
||
254 | #else |
||
255 | struct dirent *entry; |
||
256 | #endif |
||
257 | |||
258 | g_return_val_if_fail (dir != NULL, NULL); |
||
259 | |||
260 | #ifdef G_OS_WIN32 |
||
261 | while (1) |
||
262 | { |
||
263 | wentry = _wreaddir (dir->wdirp); |
||
264 | while (wentry |
||
265 | && (0 == wcscmp (wentry->d_name, L".") || |
||
266 | |||
267 | wentry = _wreaddir (dir->wdirp); |
||
268 | |||
269 | if (wentry == NULL) |
||
270 | return NULL; |
||
271 | |||
272 | utf8_name = g_utf16_to_utf8 (wentry->d_name, -1, NULL, NULL, NULL); |
||
273 | |||
274 | if (utf8_name == NULL) |
||
275 | continue; /* Huh, impossible? Skip it anyway */ |
||
276 | |||
277 | strcpy (dir->utf8_buf, utf8_name); |
||
278 | g_free (utf8_name); |
||
279 | |||
280 | return dir->utf8_buf; |
||
281 | } |
||
282 | #else |
||
283 | entry = readdir (dir->dirp); |
||
284 | while (entry |
||
285 | && (0 == strcmp (entry->d_name, ".") || |
||
286 | |||
287 | entry = readdir (dir->dirp); |
||
288 | |||
289 | if (entry) |
||
290 | return entry->d_name; |
||
291 | else |
||
292 | return NULL; |
||
293 | #endif |
||
294 | } |
||
295 | |||
296 | #if defined (G_OS_WIN32) && !defined (_WIN64) |
||
297 | |||
298 | /* Ditto for g_dir_read_name */ |
||
299 | |||
300 | #undef g_dir_read_name |
||
301 | |||
302 | /* Binary compatibility version. Not for newly compiled code. */ |
||
303 | |||
304 | const gchar * |
||
305 | g_dir_read_name (GDir *dir) |
||
306 | { |
||
307 | while (1) |
||
308 | { |
||
309 | const gchar *utf8_name = g_dir_read_name_utf8 (dir); |
||
310 | gchar *retval; |
||
311 | |||
312 | if (utf8_name == NULL) |
||
313 | return NULL; |
||
314 | |||
315 | retval = g_locale_from_utf8 (utf8_name, -1, NULL, NULL, NULL); |
||
316 | |||
317 | if (retval != NULL) |
||
318 | { |
||
319 | strcpy (dir->utf8_buf, retval); |
||
320 | g_free (retval); |
||
321 | |||
322 | return dir->utf8_buf; |
||
323 | } |
||
324 | } |
||
325 | } |
||
326 | |||
327 | #endif |
||
328 | |||
329 | /** |
||
330 | * g_dir_rewind: |
||
331 | * @dir: a #GDir* created by g_dir_open() |
||
332 | * |
||
333 | * Resets the given directory. The next call to g_dir_read_name() |
||
334 | * will return the first entry again. |
||
335 | **/ |
||
336 | void |
||
337 | g_dir_rewind (GDir *dir) |
||
338 | { |
||
339 | g_return_if_fail (dir != NULL); |
||
340 | |||
341 | #ifdef G_OS_WIN32 |
||
342 | _wrewinddir (dir->wdirp); |
||
343 | #else |
||
344 | rewinddir (dir->dirp); |
||
345 | #endif |
||
346 | } |
||
347 | |||
348 | /** |
||
349 | * g_dir_close: |
||
350 | * @dir: a #GDir* created by g_dir_open() |
||
351 | * |
||
352 | * Closes the directory and deallocates all related resources. |
||
353 | **/ |
||
354 | void |
||
355 | g_dir_close (GDir *dir) |
||
356 | { |
||
357 | g_return_if_fail (dir != NULL); |
||
358 | |||
359 | #ifdef G_OS_WIN32 |
||
360 | _wclosedir (dir->wdirp); |
||
361 | #else |
||
362 | closedir (dir->dirp); |
||
363 | #endif |
||
364 | g_free (dir); |
||
365 | } |