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