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