Don't call g_path_skip_root() unless the path is absolute.
[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 <windows.h>
37 #include <errno.h>
38 #include <wchar.h>
39 #include <direct.h>
40 #include <io.h>
41 #endif
42
43 #include "gstdio.h"
44
45 #include "galias.h"
46
47 #if !defined (G_OS_UNIX) && !defined (G_OS_WIN32) && !defined (G_OS_BEOS)
48 #error Please port this to your operating system
49 #endif
50
51
52 /**
53  * g_access:
54  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
55  * @mode: as in access()
56  *
57  * A wrapper for the POSIX access() function. This function is used to
58  * test a pathname for one or several of read, write or execute
59  * permissions, or just existence. On Windows, the underlying access()
60  * function in the C library only checks the READONLY attribute, and
61  * does not look at the ACL at all. Software that needs to handle file
62  * permissions on Windows more exactly should use the Win32 API.
63  *
64  * See the C library manual for more details about access().
65  *
66  * Returns: zero if the pathname refers to an existing file system
67  * object that has all the tested permissions, or -1 otherwise or on
68  * error.
69  * 
70  * Since: 2.8
71  */
72 int
73 g_access (const gchar *filename,
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 = _waccess (wfilename, 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 = access (cp_filename, mode);
110       save_errno = errno;
111
112       g_free (cp_filename);
113
114       errno = save_errno;
115       return retval;
116     }
117 #else
118   return access (filename, mode);
119 #endif
120 }
121
122 /**
123  * g_chmod:
124  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
125  * @mode: as in chmod()
126  *
127  * A wrapper for the POSIX chmod() function. The chmod() function is
128  * used to set the permissions of a file system object. Note that on
129  * Windows the file protection mechanism is not at all POSIX-like, and
130  * the underlying chmod() function in the C library just sets or
131  * clears the READONLY attribute. It does not touch any ACL. Software
132  * that needs to manage file permissions on Windows exactly should
133  * use the Win32 API.
134  *
135  * See the C library manual for more details about chmod().
136  *
137  * Returns: zero if the operation succeeded, -1 on error.
138  * 
139  * Since: 2.8
140  */
141 int
142 g_chmod (const gchar *filename,
143          int          mode)
144 {
145 #ifdef G_OS_WIN32
146   if (G_WIN32_HAVE_WIDECHAR_API ())
147     {
148       wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
149       int retval;
150       int save_errno;
151       
152       if (wfilename == NULL)
153         {
154           errno = EINVAL;
155           return -1;
156         }
157
158       retval = _wchmod (wfilename, mode);
159       save_errno = errno;
160
161       g_free (wfilename);
162
163       errno = save_errno;
164       return retval;
165     }
166   else
167     {    
168       gchar *cp_filename = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL);
169       int retval;
170       int save_errno;
171
172       if (cp_filename == NULL)
173         {
174           errno = EINVAL;
175           return -1;
176         }
177
178       retval = chmod (cp_filename, mode);
179       save_errno = errno;
180
181       g_free (cp_filename);
182
183       errno = save_errno;
184       return retval;
185     }
186 #else
187   return chmod (filename, mode);
188 #endif
189 }
190
191 /**
192  * g_open:
193  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
194  * @flags: as in open()
195  * @mode: as in open()
196  *
197  * A wrapper for the POSIX open() function. The open() function is
198  * used to convert a pathname into a file descriptor. Note that on
199  * POSIX systems file descriptors are implemented by the operating
200  * system. On Windows, it's the C library that implements open() and
201  * file descriptors. The actual Windows API for opening files is
202  * something different.
203  *
204  * See the C library manual for more details about open().
205  *
206  * Returns: a new file descriptor, or -1 if an error occurred. The
207  * return value can be used exactly like the return value from open().
208  * 
209  * Since: 2.6
210  */
211 int
212 g_open (const gchar *filename,
213         int          flags,
214         int          mode)
215 {
216 #ifdef G_OS_WIN32
217   if (G_WIN32_HAVE_WIDECHAR_API ())
218     {
219       wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
220       int retval;
221       int save_errno;
222       
223       if (wfilename == NULL)
224         {
225           errno = EINVAL;
226           return -1;
227         }
228
229       retval = _wopen (wfilename, flags, mode);
230       save_errno = errno;
231
232       g_free (wfilename);
233
234       errno = save_errno;
235       return retval;
236     }
237   else
238     {    
239       gchar *cp_filename = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL);
240       int retval;
241       int save_errno;
242
243       if (cp_filename == NULL)
244         {
245           errno = EINVAL;
246           return -1;
247         }
248
249       retval = open (cp_filename, flags, mode);
250       save_errno = errno;
251
252       g_free (cp_filename);
253
254       errno = save_errno;
255       return retval;
256     }
257 #else
258   return open (filename, flags, mode);
259 #endif
260 }
261
262 /**
263  * g_creat:
264  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
265  * @mode: as in creat()
266  *
267  * A wrapper for the POSIX creat() function. The creat() function is
268  * used to convert a pathname into a file descriptor, creating a file
269  * if necessar. Note that on POSIX systems file descriptors are
270  * implemented by the operating system. On Windows, it's the C library
271  * that implements creat() and file descriptors. The actual Windows
272  * API for opening files is something different.
273  *
274  * See the C library manual for more details about creat().
275  *
276  * Returns: a new file descriptor, or -1 if an error occurred. The
277  * return value can be used exactly like the return value from creat().
278  * 
279  * Since: 2.8
280  */
281 int
282 g_creat (const gchar *filename,
283          int          mode)
284 {
285 #ifdef G_OS_WIN32
286   if (G_WIN32_HAVE_WIDECHAR_API ())
287     {
288       wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
289       int retval;
290       int save_errno;
291       
292       if (wfilename == NULL)
293         {
294           errno = EINVAL;
295           return -1;
296         }
297
298       retval = _wcreat (wfilename, mode);
299       save_errno = errno;
300
301       g_free (wfilename);
302
303       errno = save_errno;
304       return retval;
305     }
306   else
307     {    
308       gchar *cp_filename = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL);
309       int retval;
310       int save_errno;
311
312       if (cp_filename == NULL)
313         {
314           errno = EINVAL;
315           return -1;
316         }
317
318       retval = creat (cp_filename, mode);
319       save_errno = errno;
320
321       g_free (cp_filename);
322
323       errno = save_errno;
324       return retval;
325     }
326 #else
327   return creat (filename, mode);
328 #endif
329 }
330
331 /**
332  * g_rename:
333  * @oldfilename: a pathname in the GLib file name encoding (UTF-8 on Windows)
334  * @newfilename: a pathname in the GLib file name encoding
335  *
336  * A wrapper for the POSIX rename() function. The rename() function 
337  * renames a file, moving it between directories if required.
338  * 
339  * See your C library manual for more details about how rename() works
340  * on your system. Note in particular that on Win9x it is not possible
341  * to rename a file if a file with the new name already exists. Also
342  * it is not possible in general on Windows to rename an open file.
343  *
344  * Returns: 0 if the renaming succeeded, -1 if an error occurred
345  * 
346  * Since: 2.6
347  */
348 int
349 g_rename (const gchar *oldfilename,
350           const gchar *newfilename)
351 {
352 #ifdef G_OS_WIN32
353   if (G_WIN32_HAVE_WIDECHAR_API ())
354     {
355       wchar_t *woldfilename = g_utf8_to_utf16 (oldfilename, -1, NULL, NULL, NULL);
356       wchar_t *wnewfilename;
357       int retval;
358       int save_errno;
359
360       if (woldfilename == NULL)
361         {
362           errno = EINVAL;
363           return -1;
364         }
365
366       wnewfilename = g_utf8_to_utf16 (newfilename, -1, NULL, NULL, NULL);
367
368       if (wnewfilename == NULL)
369         {
370           g_free (woldfilename);
371           errno = EINVAL;
372           return -1;
373         }
374
375       if (MoveFileExW (woldfilename, wnewfilename, MOVEFILE_REPLACE_EXISTING))
376         retval = 0;
377       else
378         {
379           retval = -1;
380           switch (GetLastError ())
381             {
382 #define CASE(a,b) case ERROR_##a: save_errno = b; break
383             CASE (FILE_NOT_FOUND, ENOENT);
384             CASE (PATH_NOT_FOUND, ENOENT);
385             CASE (ACCESS_DENIED, EACCES);
386             CASE (NOT_SAME_DEVICE, EXDEV);
387             CASE (LOCK_VIOLATION, EACCES);
388             CASE (SHARING_VIOLATION, EACCES);
389             CASE (FILE_EXISTS, EEXIST);
390             CASE (ALREADY_EXISTS, EEXIST);
391 #undef CASE
392             default: save_errno = EIO;
393             }
394         }
395
396       g_free (woldfilename);
397       g_free (wnewfilename);
398       
399       errno = save_errno;
400       return retval;
401     }
402   else
403     {
404       gchar *cp_oldfilename = g_locale_from_utf8 (oldfilename, -1, NULL, NULL, NULL);
405       gchar *cp_newfilename;
406       int retval;
407       int save_errno;
408
409       if (cp_oldfilename == NULL)
410         {
411           errno = EINVAL;
412           return -1;
413         }
414
415       cp_newfilename = g_locale_from_utf8 (newfilename, -1, NULL, NULL, NULL);
416
417       if (cp_newfilename == NULL)
418         {
419           g_free (cp_oldfilename);
420           errno = EINVAL;
421           return -1;
422         }
423         
424       retval = rename (cp_oldfilename, cp_newfilename);
425       save_errno = errno;
426
427       g_free (cp_oldfilename);
428       g_free (cp_newfilename);
429
430       errno = save_errno;
431       return retval;
432     }
433 #else
434   return rename (oldfilename, newfilename);
435 #endif
436 }
437
438 /**
439  * g_mkdir: 
440  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
441  * @mode: permissions to use for the newly created directory
442  *
443  * A wrapper for the POSIX mkdir() function. The mkdir() function 
444  * attempts to create a directory with the given name and permissions.
445  * 
446  * See the C library manual for more details about mkdir().
447  *
448  * Returns: 0 if the directory was successfully created, -1 if an error 
449  *    occurred
450  * 
451  * Since: 2.6
452  */
453 int
454 g_mkdir (const gchar *filename,
455          int          mode)
456 {
457 #ifdef G_OS_WIN32
458   if (G_WIN32_HAVE_WIDECHAR_API ())
459     {
460       wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
461       int retval;
462       int save_errno;
463
464       if (wfilename == NULL)
465         {
466           errno = EINVAL;
467           return -1;
468         }
469
470       retval = _wmkdir (wfilename);
471       save_errno = errno;
472
473       g_free (wfilename);
474       
475       errno = save_errno;
476       return retval;
477     }
478   else
479     {
480       gchar *cp_filename = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL);
481       int retval;
482       int save_errno;
483
484       if (cp_filename == NULL)
485         {
486           errno = EINVAL;
487           return -1;
488         }
489
490       retval = mkdir (cp_filename);
491       save_errno = errno;
492
493       g_free (cp_filename);
494
495       errno = save_errno;
496       return retval;
497     }
498 #else
499   return mkdir (filename, mode);
500 #endif
501 }
502
503 /**
504  * g_chdir: 
505  * @path: a pathname in the GLib file name encoding (UTF-8 on Windows)
506  *
507  * A wrapper for the POSIX chdir() function. The function changes the
508  * current directory of the process to @path.
509  * 
510  * See your C library manual for more details about chdir().
511  *
512  * Returns: 0 on success, -1 if an error occurred.
513  * 
514  * Since: 2.8
515  */
516 int
517 g_chdir (const gchar *path)
518 {
519 #ifdef G_OS_WIN32
520   if (G_WIN32_HAVE_WIDECHAR_API ())
521     {
522       wchar_t *wpath = g_utf8_to_utf16 (path, -1, NULL, NULL, NULL);
523       int retval;
524       int save_errno;
525
526       if (wpath == NULL)
527         {
528           errno = EINVAL;
529           return -1;
530         }
531
532       retval = _wchdir (wpath);
533       save_errno = errno;
534
535       g_free (wpath);
536       
537       errno = save_errno;
538       return retval;
539     }
540   else
541     {
542       gchar *cp_path = g_locale_from_utf8 (path, -1, NULL, NULL, NULL);
543       int retval;
544       int save_errno;
545
546       if (cp_path == NULL)
547         {
548           errno = EINVAL;
549           return -1;
550         }
551
552       retval = chdir (cp_path);
553       save_errno = errno;
554
555       g_free (cp_path);
556
557       errno = save_errno;
558       return retval;
559     }
560 #else
561   return chdir (path);
562 #endif
563 }
564
565 /**
566  * g_stat: 
567  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
568  * @buf: a pointer to a <structname>stat</structname> struct, which
569  *    will be filled with the file information
570  *
571  * A wrapper for the POSIX stat() function. The stat() function 
572  * returns information about a file.
573  * 
574  * See the C library manual for more details about stat().
575  *
576  * Returns: 0 if the information was successfully retrieved, -1 if an error 
577  *    occurred
578  * 
579  * Since: 2.6
580  */
581 int
582 g_stat (const gchar *filename,
583         struct stat *buf)
584 {
585 #ifdef G_OS_WIN32
586   if (G_WIN32_HAVE_WIDECHAR_API ())
587     {
588       wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
589       int retval;
590       int save_errno;
591       int len;
592
593       if (wfilename == NULL)
594         {
595           errno = EINVAL;
596           return -1;
597         }
598
599       len = wcslen (wfilename);
600       while (len > 0 && G_IS_DIR_SEPARATOR (wfilename[len-1]))
601         len--;
602       if (len > 0 &&
603           (!g_path_is_absolute (filename) || len > g_path_skip_root (filename) - filename))
604         wfilename[len] = '\0';
605
606       retval = _wstat (wfilename, (struct _stat *) buf);
607       save_errno = errno;
608
609       g_free (wfilename);
610
611       errno = save_errno;
612       return retval;
613     }
614   else
615     {
616       gchar *cp_filename = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL);
617       int retval;
618       int save_errno;
619       int len;
620
621       if (cp_filename == NULL)
622         {
623           errno = EINVAL;
624           return -1;
625         }
626
627       len = strlen (cp_filename);
628       while (len > 0 && G_IS_DIR_SEPARATOR (cp_filename[len-1]))
629         len--;
630       if (len > 0 &&
631           (!g_path_is_absolute (filename) || len > g_path_skip_root (filename) - filename))
632         cp_filename[len] = '\0';
633       
634       retval = stat (cp_filename, buf);
635       save_errno = errno;
636
637       g_free (cp_filename);
638
639       errno = save_errno;
640       return retval;
641     }
642 #else
643   return stat (filename, buf);
644 #endif
645 }
646
647 /**
648  * g_lstat: 
649  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
650  * @buf: a pointer to a <structname>stat</structname> struct, which
651  *    will be filled with the file information
652  *
653  * A wrapper for the POSIX lstat() function. The lstat() function is
654  * like stat() except that in the case of symbolic links, it returns
655  * information about the symbolic link itself and not the file that it
656  * refers to. If the system does not support symbolic links g_lstat()
657  * is identical to g_stat().
658  * 
659  * See the C library manual for more details about lstat().
660  *
661  * Returns: 0 if the information was successfully retrieved, -1 if an error 
662  *    occurred
663  * 
664  * Since: 2.6
665  */
666 int
667 g_lstat (const gchar *filename,
668          struct stat *buf)
669 {
670 #ifdef HAVE_LSTAT
671   /* This can't be Win32, so don't do the widechar dance. */
672   return lstat (filename, buf);
673 #else
674   return g_stat (filename, buf);
675 #endif
676 }
677
678 /**
679  * g_unlink:
680  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
681  *
682  * A wrapper for the POSIX unlink() function. The unlink() function 
683  * deletes a name from the filesystem. If this was the last link to the 
684  * file and no processes have it opened, the diskspace occupied by the
685  * file is freed.
686  * 
687  * See your C library manual for more details about unlink(). Note
688  * that on Windows, it is in general not possible to delete files that
689  * are open to some process, or mapped into memory.
690  *
691  * Returns: 0 if the name was successfully deleted, -1 if an error 
692  *    occurred
693  * 
694  * Since: 2.6
695  */
696 int
697 g_unlink (const gchar *filename)
698 {
699 #ifdef G_OS_WIN32
700   if (G_WIN32_HAVE_WIDECHAR_API ())
701     {
702       wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
703       int retval;
704       int save_errno;
705
706       if (wfilename == NULL)
707         {
708           errno = EINVAL;
709           return -1;
710         }
711
712       retval = _wunlink (wfilename);
713       save_errno = errno;
714
715       g_free (wfilename);
716
717       errno = save_errno;
718       return retval;
719     }
720   else
721     {
722       gchar *cp_filename = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL);
723       int retval;
724       int save_errno;
725
726       if (cp_filename == NULL)
727         {
728           errno = EINVAL;
729           return -1;
730         }
731
732       retval = unlink (cp_filename);
733       save_errno = errno;
734
735       g_free (cp_filename);
736
737       errno = save_errno;
738       return retval;
739     }
740 #else
741   return unlink (filename);
742 #endif
743 }
744
745 /**
746  * g_remove:
747  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
748  *
749  * A wrapper for the POSIX remove() function. The remove() function
750  * deletes a name from the filesystem.
751  * 
752  * See your C library manual for more details about how remove() works
753  * on your system. On Unix, remove() removes also directories, as it
754  * calls unlink() for files and rmdir() for directories. On Windows,
755  * although remove() in the C library only works for files, this
756  * function tries first remove() and then if that fails rmdir(), and
757  * thus works for both files and directories. Note however, that on
758  * Windows, it is in general not possible to remove a file that is
759  * open to some process, or mapped into memory.
760  *
761  * Returns: 0 if the file was successfully removed, -1 if an error 
762  *    occurred
763  * 
764  * Since: 2.6
765  */
766 int
767 g_remove (const gchar *filename)
768 {
769 #ifdef G_OS_WIN32
770   if (G_WIN32_HAVE_WIDECHAR_API ())
771     {
772       wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
773       int retval;
774       int save_errno;
775
776       if (wfilename == NULL)
777         {
778           errno = EINVAL;
779           return -1;
780         }
781
782       retval = _wremove (wfilename);
783       if (retval == -1)
784         retval = _wrmdir (wfilename);
785       save_errno = errno;
786
787       g_free (wfilename);
788
789       errno = save_errno;
790       return retval;
791     }
792   else
793     {
794       gchar *cp_filename = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL);
795       int retval;
796       int save_errno;
797       
798       if (cp_filename == NULL)
799         {
800           errno = EINVAL;
801           return -1;
802         }
803
804       retval = remove (cp_filename);
805       if (retval == -1)
806         retval = rmdir (cp_filename);
807       save_errno = errno;
808
809       g_free (cp_filename);
810
811       errno = save_errno;
812       return retval;
813     }
814 #else
815   return remove (filename);
816 #endif
817 }
818
819 /**
820  * g_rmdir:
821  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
822  *
823  * A wrapper for the POSIX rmdir() function. The rmdir() function
824  * deletes a directory from the filesystem.
825  * 
826  * See your C library manual for more details about how rmdir() works
827  * on your system.
828  *
829  * Returns: 0 if the directory was successfully removed, -1 if an error 
830  *    occurred
831  * 
832  * Since: 2.6
833  */
834 int
835 g_rmdir (const gchar *filename)
836 {
837 #ifdef G_OS_WIN32
838   if (G_WIN32_HAVE_WIDECHAR_API ())
839     {
840       wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
841       int retval;
842       int save_errno;
843
844       if (wfilename == NULL)
845         {
846           errno = EINVAL;
847           return -1;
848         }
849       
850       retval = _wrmdir (wfilename);
851       save_errno = errno;
852
853       g_free (wfilename);
854
855       errno = save_errno;
856       return retval;
857     }
858   else
859     {
860       gchar *cp_filename = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL);
861       int retval;
862       int save_errno;
863
864       if (cp_filename == NULL)
865         {
866           errno = EINVAL;
867           return -1;
868         }
869
870       retval = rmdir (cp_filename);
871       save_errno = errno;
872
873       g_free (cp_filename);
874
875       errno = save_errno;
876       return retval;
877     }
878 #else
879   return rmdir (filename);
880 #endif
881 }
882
883 /**
884  * g_fopen:
885  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
886  * @mode: a string describing the mode in which the file should be 
887  *   opened
888  *
889  * A wrapper for the POSIX fopen() function. The fopen() function opens
890  * a file and associates a new stream with it. 
891  * 
892  * See the C library manual for more details about fopen().
893  *
894  * Returns: A <type>FILE</type> pointer if the file was successfully
895  *    opened, or %NULL if an error occurred
896  * 
897  * Since: 2.6
898  */
899 FILE *
900 g_fopen (const gchar *filename,
901          const gchar *mode)
902 {
903 #ifdef G_OS_WIN32
904   if (G_WIN32_HAVE_WIDECHAR_API ())
905     {
906       wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
907       wchar_t *wmode;
908       FILE *retval;
909       int save_errno;
910
911       if (wfilename == NULL)
912         {
913           errno = EINVAL;
914           return NULL;
915         }
916
917       wmode = g_utf8_to_utf16 (mode, -1, NULL, NULL, NULL);
918
919       if (wmode == NULL)
920         {
921           g_free (wfilename);
922           errno = EINVAL;
923           return NULL;
924         }
925         
926       retval = _wfopen (wfilename, wmode);
927       save_errno = errno;
928
929       g_free (wfilename);
930       g_free (wmode);
931
932       errno = save_errno;
933       return retval;
934     }
935   else
936     {
937       gchar *cp_filename = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL);
938       FILE *retval;
939       int save_errno;
940
941       if (cp_filename == NULL)
942         {
943           errno = EINVAL;
944           return NULL;
945         }
946
947       retval = fopen (cp_filename, mode);
948       save_errno = errno;
949
950       g_free (cp_filename);
951
952       errno = save_errno;
953       return retval;
954     }
955 #else
956   return fopen (filename, mode);
957 #endif
958 }
959
960 /**
961  * g_freopen:
962  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
963  * @mode: a string describing the mode in which the file should be 
964  *   opened
965  * @stream: an existing stream which will be reused, or %NULL
966  *
967  * A wrapper for the POSIX freopen() function. The freopen() function
968  * opens a file and associates it with an existing stream.
969  * 
970  * See the C library manual for more details about freopen().
971  *
972  * Returns: A <type>FILE</type> pointer if the file was successfully
973  *    opened, or %NULL if an error occurred.
974  * 
975  * Since: 2.6
976  */
977 FILE *
978 g_freopen (const gchar *filename,
979            const gchar *mode,
980            FILE        *stream)
981 {
982 #ifdef G_OS_WIN32
983   if (G_WIN32_HAVE_WIDECHAR_API ())
984     {
985       wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
986       wchar_t *wmode;
987       FILE *retval;
988       int save_errno;
989
990       if (wfilename == NULL)
991         {
992           errno = EINVAL;
993           return NULL;
994         }
995       
996       wmode = g_utf8_to_utf16 (mode, -1, NULL, NULL, NULL);
997
998       if (wmode == NULL)
999         {
1000           g_free (wfilename);
1001           errno = EINVAL;
1002           return NULL;
1003         }
1004       
1005       retval = _wfreopen (wfilename, wmode, stream);
1006       save_errno = errno;
1007
1008       g_free (wfilename);
1009       g_free (wmode);
1010
1011       errno = save_errno;
1012       return retval;
1013     }
1014   else
1015     {
1016       gchar *cp_filename = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL);
1017       FILE *retval;
1018       int save_errno;
1019
1020       if (cp_filename == NULL)
1021         {
1022           errno = EINVAL;
1023           return NULL;
1024         }
1025
1026       retval = freopen (cp_filename, mode, stream);
1027       save_errno = errno;
1028
1029       g_free (cp_filename);
1030
1031       errno = save_errno;
1032       return retval;
1033     }
1034 #else
1035   return freopen (filename, mode, stream);
1036 #endif
1037 }
1038
1039 #define __G_STDIO_C__
1040 #include "galiasdef.c"