31dc350c0554d516ff71ea56584db4ef1cfda7b8
[platform/upstream/glib.git] / glib / gstdio.c
1 /* gstdio.c - wrappers for C library functions
2  *
3  * Copyright 2004 Tor Lillqvist
4  *
5  * GLib is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU Lesser General Public License as
7  * published by the Free Software Foundation; either version 2 of the
8  * License, or (at your option) any later version.
9  *
10  * GLib is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with GLib; see the file COPYING.LIB.  If not,
17  * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #include "config.h"
22 #include "galias.h"
23
24 #include "glib.h"
25
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <fcntl.h>
29
30 #ifdef HAVE_UNISTD_H
31 #include <unistd.h>
32 #endif
33
34 #ifdef G_OS_WIN32
35 #include <errno.h>
36 #include <wchar.h>
37 #include <direct.h>
38 #include <io.h>
39 #endif
40
41 #include "gstdio.h"
42
43 #if !defined (G_OS_UNIX) && !defined (G_OS_WIN32)
44 #error Please port this to your operating system
45 #endif
46
47
48 /**
49  * g_open:
50  * @filename: a pathname in the GLib file name encoding
51  * @flags: as in open()
52  * @mode: as in open()
53  *
54  * A wrapper for the POSIX open() function. The open() function is
55  * used to convert a pathname into a file descriptor. Note that on
56  * POSIX systems file descriptors are implemented by the operating
57  * system. On Windows, it's the C library that implements open() and
58  * file descriptors. The actual Windows API for opening files is
59  * something different.
60  *
61  * See the C library manual for more details about open().
62  *
63  * Returns: a new file descriptor, or -1 if an error occurred. The
64  * return value can be used exactly like the return value from open().
65  * 
66  * Since: 2.6
67  */
68 int
69 g_open (const gchar *filename,
70         int          flags,
71         int          mode)
72 {
73 #ifdef G_OS_WIN32
74   if (G_WIN32_HAVE_WIDECHAR_API ())
75     {
76       wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
77       int retval = _wopen (wfilename, flags, mode);
78       int save_errno = errno;
79       
80       g_free (wfilename);
81
82       errno = save_errno;
83       return retval;
84     }
85   else
86     {    
87       gchar *cp_filename = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL);
88       int retval = open (cp_filename, flags, mode);
89       int save_errno = errno;
90
91       g_free (cp_filename);
92
93       errno = save_errno;
94       return retval;
95     }
96 #else
97   return open (filename, flags, mode);
98 #endif
99 }
100
101 /**
102  * g_rename:
103  * @oldfilename: a pathname in the GLib file name encoding
104  * @newfilename: a pathname in the GLib file name encoding
105  *
106  * A wrapper for the POSIX rename() function. The rename() function 
107  * renames a file, moving it between directories if required.
108  * 
109  * See your C library manual for more details about how rename() works
110  * on your system. Note in particular that on Windows, it is in
111  * general not possible to rename a file if a file with the new name
112  * already exists. Also it is not possible in general to rename an
113  * open file.
114  *
115  * Returns: 0 if the renaming succeeded, -1 if an error occurred
116  * 
117  * Since: 2.6
118  */
119 int
120 g_rename (const gchar *oldfilename,
121           const gchar *newfilename)
122 {
123 #ifdef G_OS_WIN32
124   if (G_WIN32_HAVE_WIDECHAR_API ())
125     {
126       wchar_t *woldfilename = g_utf8_to_utf16 (oldfilename, -1, NULL, NULL, NULL);
127       wchar_t *wnewfilename = g_utf8_to_utf16 (newfilename, -1, NULL, NULL, NULL);
128       int retval = _wrename (woldfilename, wnewfilename);
129       int save_errno = errno;
130       
131       g_free (woldfilename);
132       g_free (wnewfilename);
133       
134       errno = save_errno;
135       return retval;
136     }
137   else
138     {
139       gchar *cp_oldfilename = g_locale_from_utf8 (oldfilename, -1, NULL, NULL, NULL);
140       gchar *cp_newfilename = g_locale_from_utf8 (newfilename, -1, NULL, NULL, NULL);
141       int retval = rename (cp_oldfilename, cp_newfilename);
142       int save_errno = errno;
143
144       g_free (cp_oldfilename);
145       g_free (cp_newfilename);
146
147       errno = save_errno;
148       return retval;
149     }
150 #else
151   return rename (oldfilename, newfilename);
152 #endif
153 }
154
155 /**
156  * g_mkdir: 
157  * @filename: a pathname in the GLib file name encoding
158  * @mode: permissions to use for the newly created directory
159  *
160  * A wrapper for the POSIX mkdir() function. The mkdir() function 
161  * attempts to create a directory with the given name and permissions.
162  * 
163  * See the C library manual for more details about mkdir().
164  *
165  * Returns: 0 if the directory was successfully created, -1 if an error 
166  *    occurred
167  * 
168  * Since: 2.6
169  */
170 int
171 g_mkdir (const gchar *filename,
172          int          mode)
173 {
174 #ifdef G_OS_WIN32
175   if (G_WIN32_HAVE_WIDECHAR_API ())
176     {
177       wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
178       int retval = _wmkdir (wfilename);
179       int save_errno = errno;
180
181       g_free (wfilename);
182       
183       errno = save_errno;
184       return retval;
185     }
186   else
187     {
188       gchar *cp_filename = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL);
189       int retval = mkdir (cp_filename);
190       int save_errno = errno;
191
192       g_free (cp_filename);
193
194       errno = save_errno;
195       return retval;
196     }
197 #else
198   return mkdir (filename, mode);
199 #endif
200 }
201
202 /**
203  * g_stat: 
204  * @filename: a pathname in the GLib file name encoding
205  * @buf: a pointer to a <structname>stat</structname> struct, which
206  *    will be filled with the file information
207  *
208  * A wrapper for the POSIX stat() function. The stat() function 
209  * returns information about a file.
210  * 
211  * See the C library manual for more details about stat().
212  *
213  * Returns: 0 if the information was successfully retrieved, -1 if an error 
214  *    occurred
215  * 
216  * Since: 2.6
217  */
218 int
219 g_stat (const gchar *filename,
220         struct stat *buf)
221 {
222 #ifdef G_OS_WIN32
223   if (G_WIN32_HAVE_WIDECHAR_API ())
224     {
225       wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
226       int retval = _wstat (wfilename, (struct _stat *) buf);
227       int save_errno = errno;
228
229       g_free (wfilename);
230
231       errno = save_errno;
232       return retval;
233     }
234   else
235     {
236       gchar *cp_filename = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL);
237       int retval = stat (cp_filename, buf);
238       int save_errno = errno;
239
240       g_free (cp_filename);
241
242       errno = save_errno;
243       return retval;
244     }
245 #else
246   return stat (filename, buf);
247 #endif
248 }
249
250 /**
251  * g_lstat: 
252  * @filename: a pathname in the GLib file name encoding
253  * @buf: a pointer to a <structname>stat</structname> struct, which
254  *    will be filled with the file information
255  *
256  * A wrapper for the POSIX lstat() function. The lstat() function is
257  * like stat() except that in the case of symbolic links, it returns
258  * information about the symbolic link itself and not the file that it
259  * refers to. If the system does not support symbolic links g_lstat()
260  * is identical to g_stat().
261  * 
262  * See the C library manual for more details about lstat().
263  *
264  * Returns: 0 if the information was successfully retrieved, -1 if an error 
265  *    occurred
266  * 
267  * Since: 2.6
268  */
269 int
270 g_lstat (const gchar *filename,
271          struct stat *buf)
272 {
273 #ifdef HAVE_LSTAT
274   /* This can't be Win32, so don't do the widechar dance. */
275   return lstat (filename, buf);
276 #else
277   return g_stat (filename, buf);
278 #endif
279 }
280
281 /**
282  * g_unlink:
283  * @filename: a pathname in the GLib file name encoding
284  *
285  * A wrapper for the POSIX unlink() function. The unlink() function 
286  * deletes a name from the filesystem. If this was the last link to the 
287  * file and no processes have it opened, the diskspace occupied by the
288  * file is freed.
289  * 
290  * See your C library manual for more details about unlink(). Note
291  * that on Windows, it is in general not possible to delete files that
292  * are open to some process, or mapped into memory.
293  *
294  * Returns: 0 if the name was successfully deleted, -1 if an error 
295  *    occurred
296  * 
297  * Since: 2.6
298  */
299 int
300 g_unlink (const gchar *filename)
301 {
302 #ifdef G_OS_WIN32
303   if (G_WIN32_HAVE_WIDECHAR_API ())
304     {
305       wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
306       int retval = _wunlink (wfilename);
307       int save_errno = errno;
308
309       g_free (wfilename);
310
311       errno = save_errno;
312       return retval;
313     }
314   else
315     {
316       gchar *cp_filename = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL);
317       int retval = unlink (cp_filename);
318       int save_errno = errno;
319
320       g_free (cp_filename);
321
322       errno = save_errno;
323       return retval;
324     }
325 #else
326   return unlink (filename);
327 #endif
328 }
329
330 /**
331  * g_remove:
332  * @filename: a pathname in the GLib file name encoding
333  *
334  * A wrapper for the POSIX remove() function. The remove() function
335  * deletes a name from the filesystem.
336  * 
337  * See your C library manual for more details about how remove() works
338  * on your system. On Unix, remove() removes also directories, as it
339  * calls unlink() for files and rmdir() for directories. On Windows,
340  * although remove() in the C library only works for files, this
341  * function tries first remove() and then if that fails rmdir(), and
342  * thus works for both files and directories. Note however, that on
343  * Windows, it is in general not possible to remove a file that is
344  * open to some process, or mapped into memory.
345  *
346  * Returns: 0 if the file was successfully removed, -1 if an error 
347  *    occurred
348  * 
349  * Since: 2.6
350  */
351 int
352 g_remove (const gchar *filename)
353 {
354 #ifdef G_OS_WIN32
355   if (G_WIN32_HAVE_WIDECHAR_API ())
356     {
357       wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
358       int retval;
359       int save_errno;
360
361       retval = _wremove (wfilename);
362       if (retval == -1)
363         retval = _wrmdir (wfilename);
364       save_errno = errno;
365
366       g_free (wfilename);
367
368       errno = save_errno;
369       return retval;
370     }
371   else
372     {
373       gchar *cp_filename = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL);
374       int retval;
375       int save_errno;
376       
377       retval = remove (cp_filename);
378       if (retval == -1)
379         retval = rmdir (cp_filename);
380       save_errno = errno;
381
382       g_free (cp_filename);
383
384       errno = save_errno;
385       return retval;
386     }
387 #else
388   return remove (filename);
389 #endif
390 }
391
392 /**
393  * g_rmdir:
394  * @filename: a pathname in the GLib file name encoding
395  *
396  * A wrapper for the POSIX rmdir() function. The rmdir() function
397  * deletes a directory from the filesystem.
398  * 
399  * See your C library manual for more details about how rmdir() works
400  * on your system.
401  *
402  * Returns: 0 if the directory was successfully removed, -1 if an error 
403  *    occurred
404  * 
405  * Since: 2.6
406  */
407 int
408 g_rmdir (const gchar *filename)
409 {
410 #ifdef G_OS_WIN32
411   if (G_WIN32_HAVE_WIDECHAR_API ())
412     {
413       wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
414       int retval = _wrmdir (wfilename);
415       int save_errno = errno;
416
417       g_free (wfilename);
418
419       errno = save_errno;
420       return retval;
421     }
422   else
423     {
424       gchar *cp_filename = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL);
425       int retval = rmdir (cp_filename);
426       int save_errno = errno;
427
428       g_free (cp_filename);
429
430       errno = save_errno;
431       return retval;
432     }
433 #else
434   return rmdir (filename);
435 #endif
436 }
437
438 /**
439  * g_fopen:
440  * @filename: a pathname in the GLib file name encoding
441  * @mode: a string describing the mode in which the file should be 
442  *   opened
443  *
444  * A wrapper for the POSIX fopen() function. The fopen() function opens
445  * a file and associates a new stream with it. 
446  * 
447  * See the C library manual for more details about fopen().
448  *
449  * Returns: A <typename>FILE</typename> pointer if the file was successfully
450  *    opened, or %NULL if an error occurred
451  * 
452  * Since: 2.6
453  */
454 FILE *
455 g_fopen (const gchar *filename,
456          const gchar *mode)
457 {
458 #ifdef G_OS_WIN32
459   if (G_WIN32_HAVE_WIDECHAR_API ())
460     {
461       wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
462       wchar_t *wmode = g_utf8_to_utf16 (mode, -1, NULL, NULL, NULL);
463       FILE *retval = _wfopen (wfilename, wmode);
464       int save_errno = errno;
465
466       g_free (wfilename);
467       g_free (wmode);
468
469       errno = save_errno;
470       return retval;
471     }
472   else
473     {
474       gchar *cp_filename = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL);
475       FILE *retval = fopen (cp_filename, mode);
476       int save_errno = errno;
477
478       g_free (cp_filename);
479
480       errno = save_errno;
481       return retval;
482     }
483 #else
484   return fopen (filename, mode);
485 #endif
486 }
487
488 /**
489  * g_freopen:
490  * @filename: a pathname in the GLib file name encoding
491  * @mode: a string describing the mode in which the file should be 
492  *   opened
493  * @stream: an existing stream which will be reused, or %NULL
494  *
495  * A wrapper for the POSIX freopen() function. The freopen() function
496  * opens a file and associates it with an existing stream.
497  * 
498  * See the C library manual for more details about freopen().
499  *
500  * Returns: A <typename>FILE</typename> pointer if the file was successfully
501  *    opened, or %NULL if an error occurred.
502  * 
503  * Since: 2.6
504  */
505 FILE *
506 g_freopen (const gchar *filename,
507            const gchar *mode,
508            FILE        *stream)
509 {
510 #ifdef G_OS_WIN32
511   if (G_WIN32_HAVE_WIDECHAR_API ())
512     {
513       wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
514       wchar_t *wmode = g_utf8_to_utf16 (mode, -1, NULL, NULL, NULL);
515       FILE *retval = _wfreopen (wfilename, wmode, stream);
516       int save_errno = errno;
517
518       g_free (wfilename);
519       g_free (wmode);
520
521       errno = save_errno;
522       return retval;
523     }
524   else
525     {
526       gchar *cp_filename = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL);
527       FILE *retval = freopen (cp_filename, mode, stream);
528       int save_errno = errno;
529
530       g_free (cp_filename);
531
532       errno = save_errno;
533       return retval;
534     }
535 #else
536   return freopen (filename, mode, stream);
537 #endif
538 }