54c21646adf33d3ce3a7cf7e08496e782e149557
[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 #include <sys/utime.h>
42 #else
43 #include <utime.h>
44 #endif
45
46 #include "gstdio.h"
47
48
49 #if !defined (G_OS_UNIX) && !defined (G_OS_WIN32) && !defined (G_OS_BEOS)
50 #error Please port this to your operating system
51 #endif
52
53 #if defined (_MSC_VER) && !defined(_WIN64)
54 #undef _wstat
55 #define _wstat _wstat32
56 #endif
57
58 /**
59  * g_access:
60  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
61  * @mode: as in access()
62  *
63  * A wrapper for the POSIX access() function. This function is used to
64  * test a pathname for one or several of read, write or execute
65  * permissions, or just existence.
66  *
67  * On Windows, the file protection mechanism is not at all POSIX-like,
68  * and the underlying function in the C library only checks the
69  * FAT-style READONLY attribute, and does not look at the ACL of a
70  * file at all. This function is this in practise almost useless on
71  * Windows. Software that needs to handle file permissions on Windows
72  * more exactly should use the Win32 API.
73  *
74  * See your C library manual for more details about access().
75  *
76  * Returns: zero if the pathname refers to an existing file system
77  * object that has all the tested permissions, or -1 otherwise or on
78  * error.
79  * 
80  * Since: 2.8
81  */
82 int
83 g_access (const gchar *filename,
84           int          mode)
85 {
86 #ifdef G_OS_WIN32
87   wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
88   int retval;
89   int save_errno;
90     
91   if (wfilename == NULL)
92     {
93       errno = EINVAL;
94       return -1;
95     }
96
97 #ifndef X_OK
98 #define X_OK 1
99 #endif
100
101   retval = _waccess (wfilename, mode & ~X_OK);
102   save_errno = errno;
103
104   g_free (wfilename);
105
106   errno = save_errno;
107   return retval;
108 #else
109   return access (filename, mode);
110 #endif
111 }
112
113 /**
114  * g_chmod:
115  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
116  * @mode: as in chmod()
117  *
118  * A wrapper for the POSIX chmod() function. The chmod() function is
119  * used to set the permissions of a file system object.
120  * 
121  * On Windows the file protection mechanism is not at all POSIX-like,
122  * and the underlying chmod() function in the C library just sets or
123  * clears the FAT-style READONLY attribute. It does not touch any
124  * ACL. Software that needs to manage file permissions on Windows
125  * exactly should use the Win32 API.
126  *
127  * See your C library manual for more details about chmod().
128  *
129  * Returns: zero if the operation succeeded, -1 on error.
130  * 
131  * Since: 2.8
132  */
133 int
134 g_chmod (const gchar *filename,
135          int          mode)
136 {
137 #ifdef G_OS_WIN32
138   wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
139   int retval;
140   int save_errno;
141     
142   if (wfilename == NULL)
143     {
144       errno = EINVAL;
145       return -1;
146     }
147
148   retval = _wchmod (wfilename, mode);
149   save_errno = errno;
150
151   g_free (wfilename);
152
153   errno = save_errno;
154   return retval;
155 #else
156   return chmod (filename, mode);
157 #endif
158 }
159 /**
160  * g_open:
161  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
162  * @flags: as in open()
163  * @mode: as in open()
164  *
165  * A wrapper for the POSIX open() function. The open() function is
166  * used to convert a pathname into a file descriptor.
167  *
168  * On POSIX systems file descriptors are implemented by the operating
169  * system. On Windows, it's the C library that implements open() and
170  * file descriptors. The actual Win32 API for opening files is quite
171  * different, see MSDN documentation for CreateFile(). The Win32 API
172  * uses file handles, which are more randomish integers, not small
173  * integers like file descriptors.
174  *
175  * Because file descriptors are specific to the C library on Windows,
176  * the file descriptor returned by this function makes sense only to
177  * functions in the same C library. Thus if the GLib-using code uses a
178  * different C library than GLib does, the file descriptor returned by
179  * this function cannot be passed to C library functions like write()
180  * or read().
181  *
182  * See your C library manual for more details about open().
183  *
184  * Returns: a new file descriptor, or -1 if an error occurred. The
185  * return value can be used exactly like the return value from open().
186  * 
187  * Since: 2.6
188  */
189 int
190 g_open (const gchar *filename,
191         int          flags,
192         int          mode)
193 {
194 #ifdef G_OS_WIN32
195   wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
196   int retval;
197   int save_errno;
198     
199   if (wfilename == NULL)
200     {
201       errno = EINVAL;
202       return -1;
203     }
204
205   retval = _wopen (wfilename, flags, mode);
206   save_errno = errno;
207
208   g_free (wfilename);
209
210   errno = save_errno;
211   return retval;
212 #else
213   return open (filename, flags, mode);
214 #endif
215 }
216
217 /**
218  * g_creat:
219  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
220  * @mode: as in creat()
221  *
222  * A wrapper for the POSIX creat() function. The creat() function is
223  * used to convert a pathname into a file descriptor, creating a file
224  * if necessary.
225
226  * On POSIX systems file descriptors are implemented by the operating
227  * system. On Windows, it's the C library that implements creat() and
228  * file descriptors. The actual Windows API for opening files is
229  * different, see MSDN documentation for CreateFile(). The Win32 API
230  * uses file handles, which are more randomish integers, not small
231  * integers like file descriptors.
232  *
233  * Because file descriptors are specific to the C library on Windows,
234  * the file descriptor returned by this function makes sense only to
235  * functions in the same C library. Thus if the GLib-using code uses a
236  * different C library than GLib does, the file descriptor returned by
237  * this function cannot be passed to C library functions like write()
238  * or read().
239  *
240  * See your C library manual for more details about creat().
241  *
242  * Returns: a new file descriptor, or -1 if an error occurred. The
243  * return value can be used exactly like the return value from creat().
244  * 
245  * Since: 2.8
246  */
247 int
248 g_creat (const gchar *filename,
249          int          mode)
250 {
251 #ifdef G_OS_WIN32
252   wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
253   int retval;
254   int save_errno;
255     
256   if (wfilename == NULL)
257     {
258       errno = EINVAL;
259       return -1;
260     }
261
262   retval = _wcreat (wfilename, mode);
263   save_errno = errno;
264
265   g_free (wfilename);
266
267   errno = save_errno;
268   return retval;
269 #else
270   return creat (filename, mode);
271 #endif
272 }
273
274 /**
275  * g_rename:
276  * @oldfilename: a pathname in the GLib file name encoding (UTF-8 on Windows)
277  * @newfilename: a pathname in the GLib file name encoding
278  *
279  * A wrapper for the POSIX rename() function. The rename() function 
280  * renames a file, moving it between directories if required.
281  * 
282  * See your C library manual for more details about how rename() works
283  * on your system. It is not possible in general on Windows to rename
284  * a file that is open to some process.
285  *
286  * Returns: 0 if the renaming succeeded, -1 if an error occurred
287  * 
288  * Since: 2.6
289  */
290 int
291 g_rename (const gchar *oldfilename,
292           const gchar *newfilename)
293 {
294 #ifdef G_OS_WIN32
295   wchar_t *woldfilename = g_utf8_to_utf16 (oldfilename, -1, NULL, NULL, NULL);
296   wchar_t *wnewfilename;
297   int retval;
298   int save_errno = 0;
299
300   if (woldfilename == NULL)
301     {
302       errno = EINVAL;
303       return -1;
304     }
305
306   wnewfilename = g_utf8_to_utf16 (newfilename, -1, NULL, NULL, NULL);
307
308   if (wnewfilename == NULL)
309     {
310       g_free (woldfilename);
311       errno = EINVAL;
312       return -1;
313     }
314
315   if (MoveFileExW (woldfilename, wnewfilename, MOVEFILE_REPLACE_EXISTING))
316     retval = 0;
317   else
318     {
319       retval = -1;
320       switch (GetLastError ())
321         {
322 #define CASE(a,b) case ERROR_##a: save_errno = b; break
323           CASE (FILE_NOT_FOUND, ENOENT);
324           CASE (PATH_NOT_FOUND, ENOENT);
325           CASE (ACCESS_DENIED, EACCES);
326           CASE (NOT_SAME_DEVICE, EXDEV);
327           CASE (LOCK_VIOLATION, EACCES);
328           CASE (SHARING_VIOLATION, EACCES);
329           CASE (FILE_EXISTS, EEXIST);
330           CASE (ALREADY_EXISTS, EEXIST);
331 #undef CASE
332         default: save_errno = EIO;
333         }
334     }
335
336   g_free (woldfilename);
337   g_free (wnewfilename);
338     
339   errno = save_errno;
340   return retval;
341 #else
342   return rename (oldfilename, newfilename);
343 #endif
344 }
345
346 /**
347  * g_mkdir: 
348  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
349  * @mode: permissions to use for the newly created directory
350  *
351  * A wrapper for the POSIX mkdir() function. The mkdir() function 
352  * attempts to create a directory with the given name and permissions.
353  * The mode argument is ignored on Windows.
354  * 
355  * See your C library manual for more details about mkdir().
356  *
357  * Returns: 0 if the directory was successfully created, -1 if an error 
358  *    occurred
359  * 
360  * Since: 2.6
361  */
362 int
363 g_mkdir (const gchar *filename,
364          int          mode)
365 {
366 #ifdef G_OS_WIN32
367   wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
368   int retval;
369   int save_errno;
370
371   if (wfilename == NULL)
372     {
373       errno = EINVAL;
374       return -1;
375     }
376
377   retval = _wmkdir (wfilename);
378   save_errno = errno;
379
380   g_free (wfilename);
381     
382   errno = save_errno;
383   return retval;
384 #else
385   return mkdir (filename, mode);
386 #endif
387 }
388
389 /**
390  * g_chdir: 
391  * @path: a pathname in the GLib file name encoding (UTF-8 on Windows)
392  *
393  * A wrapper for the POSIX chdir() function. The function changes the
394  * current directory of the process to @path.
395  * 
396  * See your C library manual for more details about chdir().
397  *
398  * Returns: 0 on success, -1 if an error occurred.
399  * 
400  * Since: 2.8
401  */
402 int
403 g_chdir (const gchar *path)
404 {
405 #ifdef G_OS_WIN32
406   wchar_t *wpath = g_utf8_to_utf16 (path, -1, NULL, NULL, NULL);
407   int retval;
408   int save_errno;
409
410   if (wpath == NULL)
411     {
412       errno = EINVAL;
413       return -1;
414     }
415
416   retval = _wchdir (wpath);
417   save_errno = errno;
418
419   g_free (wpath);
420     
421   errno = save_errno;
422   return retval;
423 #else
424   return chdir (path);
425 #endif
426 }
427
428 /**
429  * g_stat: 
430  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
431  * @buf: a pointer to a <structname>stat</structname> struct, which
432  *    will be filled with the file information
433  *
434  * A wrapper for the POSIX stat() function. The stat() function
435  * returns information about a file. On Windows the stat() function in
436  * the C library checks only the FAT-style READONLY attribute and does
437  * not look at the ACL at all. Thus on Windows the protection bits in
438  * the st_mode field are a fabrication of little use.
439  * 
440  * On Windows the Microsoft C libraries have several variants of the
441  * <structname>stat</structname> struct and stat() function with names
442  * like "_stat", "_stat32", "_stat32i64" and "_stat64i32". The one
443  * used here is for 32-bit code the one with 32-bit size and time
444  * fields, specifically called "_stat32".
445  *
446  * In Microsoft's compiler, by default "struct stat" means one with
447  * 64-bit time fields while in MinGW "struct stat" is the legacy one
448  * with 32-bit fields. To hopefully clear up this messs, the gstdio.h
449  * header defines a type GStatBuf which is the appropriate struct type
450  * depending on the platform and/or compiler being used. On POSIX it
451  * is just "struct stat", but note that even on POSIX platforms,
452  * "stat" might be a macro.
453  *
454  * See your C library manual for more details about stat().
455  *
456  * Returns: 0 if the information was successfully retrieved, -1 if an error 
457  *    occurred
458  * 
459  * Since: 2.6
460  */
461 int
462 g_stat (const gchar *filename,
463         GStatBuf    *buf)
464 {
465 #ifdef G_OS_WIN32
466   wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
467   int retval;
468   int save_errno;
469   int len;
470
471   if (wfilename == NULL)
472     {
473       errno = EINVAL;
474       return -1;
475     }
476
477   len = wcslen (wfilename);
478   while (len > 0 && G_IS_DIR_SEPARATOR (wfilename[len-1]))
479     len--;
480   if (len > 0 &&
481       (!g_path_is_absolute (filename) || len > g_path_skip_root (filename) - filename))
482     wfilename[len] = '\0';
483
484   retval = _wstat (wfilename, buf);
485   save_errno = errno;
486
487   g_free (wfilename);
488
489   errno = save_errno;
490   return retval;
491 #else
492   return stat (filename, buf);
493 #endif
494 }
495
496 /**
497  * g_lstat: 
498  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
499  * @buf: a pointer to a <structname>stat</structname> struct, which
500  *    will be filled with the file information
501  *
502  * A wrapper for the POSIX lstat() function. The lstat() function is
503  * like stat() except that in the case of symbolic links, it returns
504  * information about the symbolic link itself and not the file that it
505  * refers to. If the system does not support symbolic links g_lstat()
506  * is identical to g_stat().
507  * 
508  * See your C library manual for more details about lstat().
509  *
510  * Returns: 0 if the information was successfully retrieved, -1 if an error 
511  *    occurred
512  * 
513  * Since: 2.6
514  */
515 int
516 g_lstat (const gchar *filename,
517          GStatBuf    *buf)
518 {
519 #ifdef HAVE_LSTAT
520   /* This can't be Win32, so don't do the widechar dance. */
521   return lstat (filename, buf);
522 #else
523   return g_stat (filename, buf);
524 #endif
525 }
526
527 /**
528  * g_unlink:
529  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
530  *
531  * A wrapper for the POSIX unlink() function. The unlink() function 
532  * deletes a name from the filesystem. If this was the last link to the 
533  * file and no processes have it opened, the diskspace occupied by the
534  * file is freed.
535  * 
536  * See your C library manual for more details about unlink(). Note
537  * that on Windows, it is in general not possible to delete files that
538  * are open to some process, or mapped into memory.
539  *
540  * Returns: 0 if the name was successfully deleted, -1 if an error 
541  *    occurred
542  * 
543  * Since: 2.6
544  */
545 int
546 g_unlink (const gchar *filename)
547 {
548 #ifdef G_OS_WIN32
549   wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
550   int retval;
551   int save_errno;
552
553   if (wfilename == NULL)
554     {
555       errno = EINVAL;
556       return -1;
557     }
558
559   retval = _wunlink (wfilename);
560   save_errno = errno;
561
562   g_free (wfilename);
563
564   errno = save_errno;
565   return retval;
566 #else
567   return unlink (filename);
568 #endif
569 }
570
571 /**
572  * g_remove:
573  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
574  *
575  * A wrapper for the POSIX remove() function. The remove() function
576  * deletes a name from the filesystem.
577  * 
578  * See your C library manual for more details about how remove() works
579  * on your system. On Unix, remove() removes also directories, as it
580  * calls unlink() for files and rmdir() for directories. On Windows,
581  * although remove() in the C library only works for files, this
582  * function tries first remove() and then if that fails rmdir(), and
583  * thus works for both files and directories. Note however, that on
584  * Windows, it is in general not possible to remove a file that is
585  * open to some process, or mapped into memory.
586  *
587  * If this function fails on Windows you can't infer too much from the
588  * errno value. rmdir() is tried regardless of what caused remove() to
589  * fail. Any errno value set by remove() will be overwritten by that
590  * set by rmdir().
591  *
592  * Returns: 0 if the file was successfully removed, -1 if an error 
593  *    occurred
594  * 
595  * Since: 2.6
596  */
597 int
598 g_remove (const gchar *filename)
599 {
600 #ifdef G_OS_WIN32
601   wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
602   int retval;
603   int save_errno;
604
605   if (wfilename == NULL)
606     {
607       errno = EINVAL;
608       return -1;
609     }
610
611   retval = _wremove (wfilename);
612   if (retval == -1)
613     retval = _wrmdir (wfilename);
614   save_errno = errno;
615
616   g_free (wfilename);
617
618   errno = save_errno;
619   return retval;
620 #else
621   return remove (filename);
622 #endif
623 }
624
625 /**
626  * g_rmdir:
627  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
628  *
629  * A wrapper for the POSIX rmdir() function. The rmdir() function
630  * deletes a directory from the filesystem.
631  * 
632  * See your C library manual for more details about how rmdir() works
633  * on your system.
634  *
635  * Returns: 0 if the directory was successfully removed, -1 if an error 
636  *    occurred
637  * 
638  * Since: 2.6
639  */
640 int
641 g_rmdir (const gchar *filename)
642 {
643 #ifdef G_OS_WIN32
644   wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
645   int retval;
646   int save_errno;
647
648   if (wfilename == NULL)
649     {
650       errno = EINVAL;
651       return -1;
652     }
653   
654   retval = _wrmdir (wfilename);
655   save_errno = errno;
656
657   g_free (wfilename);
658
659   errno = save_errno;
660   return retval;
661 #else
662   return rmdir (filename);
663 #endif
664 }
665
666 /**
667  * g_fopen:
668  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
669  * @mode: a string describing the mode in which the file should be 
670  *   opened
671  *
672  * A wrapper for the stdio fopen() function. The fopen() function
673  * opens a file and associates a new stream with it.
674  * 
675  * Because file descriptors are specific to the C library on Windows,
676  * and a file descriptor is partof the <type>FILE</type> struct, the
677  * <type>FILE</type> pointer returned by this function makes sense
678  * only to functions in the same C library. Thus if the GLib-using
679  * code uses a different C library than GLib does, the
680  * <type>FILE</type> pointer returned by this function cannot be
681  * passed to C library functions like fprintf() or fread().
682  *
683  * See your C library manual for more details about fopen().
684  *
685  * Returns: A <type>FILE</type> pointer if the file was successfully
686  *    opened, or %NULL if an error occurred
687  * 
688  * Since: 2.6
689  */
690 FILE *
691 g_fopen (const gchar *filename,
692          const gchar *mode)
693 {
694 #ifdef G_OS_WIN32
695   wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
696   wchar_t *wmode;
697   FILE *retval;
698   int save_errno;
699
700   if (wfilename == NULL)
701     {
702       errno = EINVAL;
703       return NULL;
704     }
705
706   wmode = g_utf8_to_utf16 (mode, -1, NULL, NULL, NULL);
707
708   if (wmode == NULL)
709     {
710       g_free (wfilename);
711       errno = EINVAL;
712       return NULL;
713     }
714
715   retval = _wfopen (wfilename, wmode);
716   save_errno = errno;
717
718   g_free (wfilename);
719   g_free (wmode);
720
721   errno = save_errno;
722   return retval;
723 #else
724   return fopen (filename, mode);
725 #endif
726 }
727
728 /**
729  * g_freopen:
730  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
731  * @mode: a string describing the mode in which the file should be 
732  *   opened
733  * @stream: an existing stream which will be reused, or %NULL
734  *
735  * A wrapper for the POSIX freopen() function. The freopen() function
736  * opens a file and associates it with an existing stream.
737  * 
738  * See your C library manual for more details about freopen().
739  *
740  * Returns: A <type>FILE</type> pointer if the file was successfully
741  *    opened, or %NULL if an error occurred.
742  * 
743  * Since: 2.6
744  */
745 FILE *
746 g_freopen (const gchar *filename,
747            const gchar *mode,
748            FILE        *stream)
749 {
750 #ifdef G_OS_WIN32
751   wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
752   wchar_t *wmode;
753   FILE *retval;
754   int save_errno;
755
756   if (wfilename == NULL)
757     {
758       errno = EINVAL;
759       return NULL;
760     }
761   
762   wmode = g_utf8_to_utf16 (mode, -1, NULL, NULL, NULL);
763
764   if (wmode == NULL)
765     {
766       g_free (wfilename);
767       errno = EINVAL;
768       return NULL;
769     }
770   
771   retval = _wfreopen (wfilename, wmode, stream);
772   save_errno = errno;
773
774   g_free (wfilename);
775   g_free (wmode);
776
777   errno = save_errno;
778   return retval;
779 #else
780   return freopen (filename, mode, stream);
781 #endif
782 }
783
784 /**
785  * g_utime:
786  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
787  * @utb: a pointer to a struct utimbuf.
788  *
789  * A wrapper for the POSIX utime() function. The utime() function
790  * sets the access and modification timestamps of a file.
791  * 
792  * See your C library manual for more details about how utime() works
793  * on your system.
794  *
795  * Returns: 0 if the operation was successful, -1 if an error 
796  *    occurred
797  * 
798  * Since: 2.18
799  */
800 int
801 g_utime (const gchar    *filename,
802          struct utimbuf *utb)
803 {
804 #ifdef G_OS_WIN32
805   wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
806   int retval;
807   int save_errno;
808
809   if (wfilename == NULL)
810     {
811       errno = EINVAL;
812       return -1;
813     }
814   
815   retval = _wutime (wfilename, (struct _utimbuf*) utb);
816   save_errno = errno;
817
818   g_free (wfilename);
819
820   errno = save_errno;
821   return retval;
822 #else
823   return utime (filename, utb);
824 #endif
825 }