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