43ad2c34748463bb052b8e5e314d3ab7e671b0e5
[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;
78       int save_errno;
79       
80       if (wfilename == NULL)
81         {
82           errno = EINVAL;
83           return -1;
84         }
85
86       retval = _wopen (wfilename, flags, mode);
87       save_errno = errno;
88
89       g_free (wfilename);
90
91       errno = save_errno;
92       return retval;
93     }
94   else
95     {    
96       gchar *cp_filename = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL);
97       int retval;
98       int save_errno;
99
100       if (cp_filename == NULL)
101         {
102           errno = EINVAL;
103           return -1;
104         }
105
106       retval = open (cp_filename, flags, mode);
107       save_errno = errno;
108
109       g_free (cp_filename);
110
111       errno = save_errno;
112       return retval;
113     }
114 #else
115   return open (filename, flags, mode);
116 #endif
117 }
118
119 /**
120  * g_rename:
121  * @oldfilename: a pathname in the GLib file name encoding
122  * @newfilename: a pathname in the GLib file name encoding
123  *
124  * A wrapper for the POSIX rename() function. The rename() function 
125  * renames a file, moving it between directories if required.
126  * 
127  * See your C library manual for more details about how rename() works
128  * on your system. Note in particular that on Windows, it is in
129  * general not possible to rename a file if a file with the new name
130  * already exists. Also it is not possible in general to rename an
131  * open file.
132  *
133  * Returns: 0 if the renaming succeeded, -1 if an error occurred
134  * 
135  * Since: 2.6
136  */
137 int
138 g_rename (const gchar *oldfilename,
139           const gchar *newfilename)
140 {
141 #ifdef G_OS_WIN32
142   if (G_WIN32_HAVE_WIDECHAR_API ())
143     {
144       wchar_t *woldfilename = g_utf8_to_utf16 (oldfilename, -1, NULL, NULL, NULL);
145       wchar_t *wnewfilename;
146       int retval;
147       int save_errno;
148
149       if (woldfilename == NULL)
150         {
151           errno = EINVAL;
152           return -1;
153         }
154
155       wnewfilename = g_utf8_to_utf16 (newfilename, -1, NULL, NULL, NULL);
156
157       if (wnewfilename == NULL)
158         {
159           g_free (woldfilename);
160           errno = EINVAL;
161           return -1;
162         }
163
164       retval = _wrename (woldfilename, wnewfilename);
165       save_errno = errno;
166
167       g_free (woldfilename);
168       g_free (wnewfilename);
169       
170       errno = save_errno;
171       return retval;
172     }
173   else
174     {
175       gchar *cp_oldfilename = g_locale_from_utf8 (oldfilename, -1, NULL, NULL, NULL);
176       gchar *cp_newfilename;
177       int retval;
178       int save_errno;
179
180       if (cp_oldfilename == NULL)
181         {
182           errno = EINVAL;
183           return -1;
184         }
185
186       cp_newfilename = g_locale_from_utf8 (newfilename, -1, NULL, NULL, NULL);
187
188       if (cp_newfilename == NULL)
189         {
190           g_free (cp_oldfilename);
191           errno = EINVAL;
192           return -1;
193         }
194         
195       retval = rename (cp_oldfilename, cp_newfilename);
196       save_errno = errno;
197
198       g_free (cp_oldfilename);
199       g_free (cp_newfilename);
200
201       errno = save_errno;
202       return retval;
203     }
204 #else
205   return rename (oldfilename, newfilename);
206 #endif
207 }
208
209 /**
210  * g_mkdir: 
211  * @filename: a pathname in the GLib file name encoding
212  * @mode: permissions to use for the newly created directory
213  *
214  * A wrapper for the POSIX mkdir() function. The mkdir() function 
215  * attempts to create a directory with the given name and permissions.
216  * 
217  * See the C library manual for more details about mkdir().
218  *
219  * Returns: 0 if the directory was successfully created, -1 if an error 
220  *    occurred
221  * 
222  * Since: 2.6
223  */
224 int
225 g_mkdir (const gchar *filename,
226          int          mode)
227 {
228 #ifdef G_OS_WIN32
229   if (G_WIN32_HAVE_WIDECHAR_API ())
230     {
231       wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
232       int retval;
233       int save_errno;
234
235       if (wfilename == NULL)
236         {
237           errno = EINVAL;
238           return -1;
239         }
240
241       retval = _wmkdir (wfilename);
242       save_errno = errno;
243
244       g_free (wfilename);
245       
246       errno = save_errno;
247       return retval;
248     }
249   else
250     {
251       gchar *cp_filename = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL);
252       int retval;
253       int save_errno;
254
255       if (cp_filename == NULL)
256         {
257           errno = EINVAL;
258           return -1;
259         }
260
261       retval = mkdir (cp_filename);
262       save_errno = errno;
263
264       g_free (cp_filename);
265
266       errno = save_errno;
267       return retval;
268     }
269 #else
270   return mkdir (filename, mode);
271 #endif
272 }
273
274 /**
275  * g_stat: 
276  * @filename: a pathname in the GLib file name encoding
277  * @buf: a pointer to a <structname>stat</structname> struct, which
278  *    will be filled with the file information
279  *
280  * A wrapper for the POSIX stat() function. The stat() function 
281  * returns information about a file.
282  * 
283  * See the C library manual for more details about stat().
284  *
285  * Returns: 0 if the information was successfully retrieved, -1 if an error 
286  *    occurred
287  * 
288  * Since: 2.6
289  */
290 int
291 g_stat (const gchar *filename,
292         struct stat *buf)
293 {
294 #ifdef G_OS_WIN32
295   if (G_WIN32_HAVE_WIDECHAR_API ())
296     {
297       wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
298       int retval;
299       int save_errno;
300
301       if (wfilename == NULL)
302         {
303           errno = EINVAL;
304           return -1;
305         }
306
307       retval = _wstat (wfilename, (struct _stat *) buf);
308       save_errno = errno;
309
310       g_free (wfilename);
311
312       errno = save_errno;
313       return retval;
314     }
315   else
316     {
317       gchar *cp_filename = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL);
318       int retval;
319       int save_errno;
320
321       if (cp_filename == NULL)
322         {
323           errno = EINVAL;
324           return -1;
325         }
326
327       retval = stat (cp_filename, buf);
328       save_errno = errno;
329
330       g_free (cp_filename);
331
332       errno = save_errno;
333       return retval;
334     }
335 #else
336   return stat (filename, buf);
337 #endif
338 }
339
340 /**
341  * g_lstat: 
342  * @filename: a pathname in the GLib file name encoding
343  * @buf: a pointer to a <structname>stat</structname> struct, which
344  *    will be filled with the file information
345  *
346  * A wrapper for the POSIX lstat() function. The lstat() function is
347  * like stat() except that in the case of symbolic links, it returns
348  * information about the symbolic link itself and not the file that it
349  * refers to. If the system does not support symbolic links g_lstat()
350  * is identical to g_stat().
351  * 
352  * See the C library manual for more details about lstat().
353  *
354  * Returns: 0 if the information was successfully retrieved, -1 if an error 
355  *    occurred
356  * 
357  * Since: 2.6
358  */
359 int
360 g_lstat (const gchar *filename,
361          struct stat *buf)
362 {
363 #ifdef HAVE_LSTAT
364   /* This can't be Win32, so don't do the widechar dance. */
365   return lstat (filename, buf);
366 #else
367   return g_stat (filename, buf);
368 #endif
369 }
370
371 /**
372  * g_unlink:
373  * @filename: a pathname in the GLib file name encoding
374  *
375  * A wrapper for the POSIX unlink() function. The unlink() function 
376  * deletes a name from the filesystem. If this was the last link to the 
377  * file and no processes have it opened, the diskspace occupied by the
378  * file is freed.
379  * 
380  * See your C library manual for more details about unlink(). Note
381  * that on Windows, it is in general not possible to delete files that
382  * are open to some process, or mapped into memory.
383  *
384  * Returns: 0 if the name was successfully deleted, -1 if an error 
385  *    occurred
386  * 
387  * Since: 2.6
388  */
389 int
390 g_unlink (const gchar *filename)
391 {
392 #ifdef G_OS_WIN32
393   if (G_WIN32_HAVE_WIDECHAR_API ())
394     {
395       wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
396       int retval;
397       int save_errno;
398
399       if (wfilename == NULL)
400         {
401           errno = EINVAL;
402           return -1;
403         }
404
405       retval = _wunlink (wfilename);
406       save_errno = errno;
407
408       g_free (wfilename);
409
410       errno = save_errno;
411       return retval;
412     }
413   else
414     {
415       gchar *cp_filename = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL);
416       int retval;
417       int save_errno;
418
419       if (cp_filename == NULL)
420         {
421           errno = EINVAL;
422           return -1;
423         }
424
425       retval = unlink (cp_filename);
426       save_errno = errno;
427
428       g_free (cp_filename);
429
430       errno = save_errno;
431       return retval;
432     }
433 #else
434   return unlink (filename);
435 #endif
436 }
437
438 /**
439  * g_remove:
440  * @filename: a pathname in the GLib file name encoding
441  *
442  * A wrapper for the POSIX remove() function. The remove() function
443  * deletes a name from the filesystem.
444  * 
445  * See your C library manual for more details about how remove() works
446  * on your system. On Unix, remove() removes also directories, as it
447  * calls unlink() for files and rmdir() for directories. On Windows,
448  * although remove() in the C library only works for files, this
449  * function tries first remove() and then if that fails rmdir(), and
450  * thus works for both files and directories. Note however, that on
451  * Windows, it is in general not possible to remove a file that is
452  * open to some process, or mapped into memory.
453  *
454  * Returns: 0 if the file was successfully removed, -1 if an error 
455  *    occurred
456  * 
457  * Since: 2.6
458  */
459 int
460 g_remove (const gchar *filename)
461 {
462 #ifdef G_OS_WIN32
463   if (G_WIN32_HAVE_WIDECHAR_API ())
464     {
465       wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
466       int retval;
467       int save_errno;
468
469       if (wfilename == NULL)
470         {
471           errno = EINVAL;
472           return -1;
473         }
474
475       retval = _wremove (wfilename);
476       if (retval == -1)
477         retval = _wrmdir (wfilename);
478       save_errno = errno;
479
480       g_free (wfilename);
481
482       errno = save_errno;
483       return retval;
484     }
485   else
486     {
487       gchar *cp_filename = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL);
488       int retval;
489       int save_errno;
490       
491       if (cp_filename == NULL)
492         {
493           errno = EINVAL;
494           return -1;
495         }
496
497       retval = remove (cp_filename);
498       if (retval == -1)
499         retval = rmdir (cp_filename);
500       save_errno = errno;
501
502       g_free (cp_filename);
503
504       errno = save_errno;
505       return retval;
506     }
507 #else
508   return remove (filename);
509 #endif
510 }
511
512 /**
513  * g_rmdir:
514  * @filename: a pathname in the GLib file name encoding
515  *
516  * A wrapper for the POSIX rmdir() function. The rmdir() function
517  * deletes a directory from the filesystem.
518  * 
519  * See your C library manual for more details about how rmdir() works
520  * on your system.
521  *
522  * Returns: 0 if the directory was successfully removed, -1 if an error 
523  *    occurred
524  * 
525  * Since: 2.6
526  */
527 int
528 g_rmdir (const gchar *filename)
529 {
530 #ifdef G_OS_WIN32
531   if (G_WIN32_HAVE_WIDECHAR_API ())
532     {
533       wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
534       int retval;
535       int save_errno;
536
537       if (wfilename == NULL)
538         {
539           errno = EINVAL;
540           return -1;
541         }
542       
543       retval = _wrmdir (wfilename);
544       save_errno = errno;
545
546       g_free (wfilename);
547
548       errno = save_errno;
549       return retval;
550     }
551   else
552     {
553       gchar *cp_filename = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL);
554       int retval;
555       int save_errno;
556
557       if (cp_filename == NULL)
558         {
559           errno = EINVAL;
560           return -1;
561         }
562
563       retval = rmdir (cp_filename);
564       save_errno = errno;
565
566       g_free (cp_filename);
567
568       errno = save_errno;
569       return retval;
570     }
571 #else
572   return rmdir (filename);
573 #endif
574 }
575
576 /**
577  * g_fopen:
578  * @filename: a pathname in the GLib file name encoding
579  * @mode: a string describing the mode in which the file should be 
580  *   opened
581  *
582  * A wrapper for the POSIX fopen() function. The fopen() function opens
583  * a file and associates a new stream with it. 
584  * 
585  * See the C library manual for more details about fopen().
586  *
587  * Returns: A <typename>FILE</typename> pointer if the file was successfully
588  *    opened, or %NULL if an error occurred
589  * 
590  * Since: 2.6
591  */
592 FILE *
593 g_fopen (const gchar *filename,
594          const gchar *mode)
595 {
596 #ifdef G_OS_WIN32
597   if (G_WIN32_HAVE_WIDECHAR_API ())
598     {
599       wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
600       wchar_t *wmode;
601       FILE *retval;
602       int save_errno;
603
604       if (wfilename == NULL)
605         {
606           errno = EINVAL;
607           return NULL;
608         }
609
610       wmode = g_utf8_to_utf16 (mode, -1, NULL, NULL, NULL);
611
612       if (wmode == NULL)
613         {
614           g_free (wfilename);
615           errno = EINVAL;
616           return NULL;
617         }
618         
619       retval = _wfopen (wfilename, wmode);
620       save_errno = errno;
621
622       g_free (wfilename);
623       g_free (wmode);
624
625       errno = save_errno;
626       return retval;
627     }
628   else
629     {
630       gchar *cp_filename = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL);
631       FILE *retval;
632       int save_errno;
633
634       if (cp_filename == NULL)
635         {
636           errno = EINVAL;
637           return NULL;
638         }
639
640       retval = fopen (cp_filename, mode);
641       save_errno = errno;
642
643       g_free (cp_filename);
644
645       errno = save_errno;
646       return retval;
647     }
648 #else
649   return fopen (filename, mode);
650 #endif
651 }
652
653 /**
654  * g_freopen:
655  * @filename: a pathname in the GLib file name encoding
656  * @mode: a string describing the mode in which the file should be 
657  *   opened
658  * @stream: an existing stream which will be reused, or %NULL
659  *
660  * A wrapper for the POSIX freopen() function. The freopen() function
661  * opens a file and associates it with an existing stream.
662  * 
663  * See the C library manual for more details about freopen().
664  *
665  * Returns: A <typename>FILE</typename> pointer if the file was successfully
666  *    opened, or %NULL if an error occurred.
667  * 
668  * Since: 2.6
669  */
670 FILE *
671 g_freopen (const gchar *filename,
672            const gchar *mode,
673            FILE        *stream)
674 {
675 #ifdef G_OS_WIN32
676   if (G_WIN32_HAVE_WIDECHAR_API ())
677     {
678       wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
679       wchar_t *wmode;
680       FILE *retval;
681       int save_errno;
682
683       if (wfilename == NULL)
684         {
685           errno = EINVAL;
686           return NULL;
687         }
688       
689       wmode = g_utf8_to_utf16 (mode, -1, NULL, NULL, NULL);
690
691       if (wmode == NULL)
692         {
693           g_free (wfilename);
694           errno = EINVAL;
695           return NULL;
696         }
697       
698       retval = _wfreopen (wfilename, wmode, stream);
699       save_errno = errno;
700
701       g_free (wfilename);
702       g_free (wmode);
703
704       errno = save_errno;
705       return retval;
706     }
707   else
708     {
709       gchar *cp_filename = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL);
710       FILE *retval;
711       int save_errno;
712
713       if (cp_filename == NULL)
714         {
715           errno = EINVAL;
716           return NULL;
717         }
718
719       retval = freopen (cp_filename, mode, stream);
720       save_errno = errno;
721
722       g_free (cp_filename);
723
724       errno = save_errno;
725       return retval;
726     }
727 #else
728   return freopen (filename, mode, stream);
729 #endif
730 }