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