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