1 /* gstdio.c - wrappers for C library functions
3 * Copyright 2004 Tor Lillqvist
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library 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.
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this library; if not, see <http://www.gnu.org/licenses/>.
20 #include "glibconfig.h"
22 #define G_STDIO_NO_WRAP_ON_UNIX
24 #include <sys/types.h>
38 #include <sys/utime.h>
45 #include "gstdioprivate.h"
47 #if !defined (G_OS_UNIX) && !defined (G_OS_WIN32)
48 #error Please port this to your operating system
51 #if defined (_MSC_VER) && !defined(_WIN64)
53 #define _wstat _wstat32
56 #if defined (G_OS_WIN32)
58 /* We can't include Windows DDK and Windows SDK simultaneously,
59 * so let's copy this here from MinGW-w64 DDK.
60 * The structure is ultimately documented here:
61 * https://msdn.microsoft.com/en-us/library/ff552012(v=vs.85).aspx
63 typedef struct _REPARSE_DATA_BUFFER
66 USHORT ReparseDataLength
;
72 USHORT SubstituteNameOffset
;
73 USHORT SubstituteNameLength
;
74 USHORT PrintNameOffset
;
75 USHORT PrintNameLength
;
78 } SymbolicLinkReparseBuffer
;
81 USHORT SubstituteNameOffset
;
82 USHORT SubstituteNameLength
;
83 USHORT PrintNameOffset
;
84 USHORT PrintNameLength
;
86 } MountPointReparseBuffer
;
90 } GenericReparseBuffer
;
92 } REPARSE_DATA_BUFFER
, *PREPARSE_DATA_BUFFER
;
95 w32_error_to_errno (DWORD error_code
)
99 case ERROR_ACCESS_DENIED
:
102 case ERROR_INVALID_HANDLE
:
105 case ERROR_INVALID_FUNCTION
:
108 case ERROR_FILE_NOT_FOUND
:
111 case ERROR_PATH_NOT_FOUND
:
112 return ENOENT
; /* or ELOOP, or ENAMETOOLONG */
114 case ERROR_NOT_ENOUGH_MEMORY
:
115 case ERROR_OUTOFMEMORY
:
125 _g_win32_stat_utf16_no_trailing_slashes (const gunichar2
*filename
,
127 GWin32PrivateStat
*buf
,
128 gboolean for_symlink
)
131 gboolean succeeded_so_far
;
133 struct __stat64 statbuf
;
134 BY_HANDLE_FILE_INFORMATION handle_info
;
135 FILE_STANDARD_INFO std_info
;
136 WIN32_FIND_DATAW finddata
;
137 DWORD immediate_attributes
;
138 gboolean is_symlink
= FALSE
;
139 gboolean is_directory
;
141 wchar_t *filename_target
= NULL
;
146 immediate_attributes
= GetFileAttributesW (filename
);
148 if (immediate_attributes
== INVALID_FILE_ATTRIBUTES
)
150 error_code
= GetLastError ();
151 errno
= w32_error_to_errno (error_code
);
156 is_symlink
= (immediate_attributes
& FILE_ATTRIBUTE_REPARSE_POINT
) == FILE_ATTRIBUTE_REPARSE_POINT
;
157 is_directory
= (immediate_attributes
& FILE_ATTRIBUTE_DIRECTORY
) == FILE_ATTRIBUTE_DIRECTORY
;
159 open_flags
= FILE_ATTRIBUTE_NORMAL
;
161 if (for_symlink
&& is_symlink
)
162 open_flags
|= FILE_FLAG_OPEN_REPARSE_POINT
;
165 open_flags
|= FILE_FLAG_BACKUP_SEMANTICS
;
167 file_handle
= CreateFileW (filename
, FILE_READ_ATTRIBUTES
,
168 FILE_SHARE_READ
, NULL
, OPEN_EXISTING
,
172 if (file_handle
== INVALID_HANDLE_VALUE
)
174 error_code
= GetLastError ();
175 errno
= w32_error_to_errno (error_code
);
181 file_handle
= (HANDLE
) _get_osfhandle (fd
);
183 if (file_handle
== INVALID_HANDLE_VALUE
)
187 succeeded_so_far
= GetFileInformationByHandle (file_handle
,
189 error_code
= GetLastError ();
191 if (succeeded_so_far
)
193 succeeded_so_far
= GetFileInformationByHandleEx (file_handle
,
197 error_code
= GetLastError ();
200 if (!succeeded_so_far
)
202 CloseHandle (file_handle
);
203 errno
= w32_error_to_errno (error_code
);
207 /* It's tempting to use GetFileInformationByHandleEx(FileAttributeTagInfo),
208 * but it always reports that the ReparseTag is 0.
212 HANDLE tmp
= FindFirstFileW (filename
,
215 if (tmp
== INVALID_HANDLE_VALUE
)
217 error_code
= GetLastError ();
218 errno
= w32_error_to_errno (error_code
);
219 CloseHandle (file_handle
);
225 if (is_symlink
&& !for_symlink
)
227 /* If filename is a symlink, _wstat64 obtains information about
228 * the symlink (except that st_size will be 0).
229 * To get information about the target we need to resolve
230 * the symlink first. And we need _wstat64() to get st_dev,
231 * it's a bother to try finding it ourselves.
233 DWORD filename_target_len
;
236 /* Just in case, give it a real memory location instead of NULL */
237 new_len
= GetFinalPathNameByHandleW (file_handle
,
238 (wchar_t *) &filename_target_len
,
240 FILE_NAME_NORMALIZED
);
242 #define SANE_LIMIT 1024 * 10
243 if (new_len
>= SANE_LIMIT
)
247 error_code
= ERROR_BUFFER_OVERFLOW
;
249 else if (new_len
== 0)
251 error_code
= GetLastError ();
256 const wchar_t *extended_prefix
= L
"\\\\?\\";
257 const gsize extended_prefix_len
= wcslen (extended_prefix
);
258 const gsize extended_prefix_len_bytes
= sizeof (wchar_t) * extended_prefix_len
;
260 /* Pretend that new_len doesn't count the terminating NUL char,
261 * and ask for a bit more space than is needed.
263 filename_target_len
= new_len
+ 5;
264 filename_target
= g_malloc (filename_target_len
* sizeof (wchar_t));
266 new_len
= GetFinalPathNameByHandleW (file_handle
,
269 FILE_NAME_NORMALIZED
);
271 /* filename_target_len is already larger than needed,
272 * new_len should be smaller than that, even if the size
273 * is off by 1 for some reason.
275 if (new_len
>= filename_target_len
- 1)
278 error_code
= ERROR_BUFFER_OVERFLOW
;
279 g_clear_pointer (&filename_target
, g_free
);
281 /* GetFinalPathNameByHandle() is documented to return extended paths,
282 * strip the extended prefix.
284 else if (new_len
> extended_prefix_len
&&
285 memcmp (filename_target
, extended_prefix
, extended_prefix_len_bytes
) == 0)
287 new_len
-= extended_prefix_len
;
288 memmove (filename_target
,
289 filename_target
+ extended_prefix_len
,
290 (new_len
+ 1) * sizeof (wchar_t));
295 succeeded_so_far
= FALSE
;
298 CloseHandle (file_handle
);
300 /* else if fd >= 0 the file_handle was obtained via _get_osfhandle()
301 * and must not be closed, it is owned by fd.
304 if (!succeeded_so_far
)
306 errno
= w32_error_to_errno (error_code
);
311 result
= _wstat64 (filename_target
!= NULL
? filename_target
: filename
, &statbuf
);
313 result
= _fstat64 (fd
, &statbuf
);
319 g_free (filename_target
);
325 g_free (filename_target
);
327 buf
->st_dev
= statbuf
.st_dev
;
328 buf
->st_mode
= statbuf
.st_mode
;
329 buf
->volume_serial
= handle_info
.dwVolumeSerialNumber
;
330 buf
->file_index
= (((guint64
) handle_info
.nFileIndexHigh
) << 32) | handle_info
.nFileIndexLow
;
331 /* Note that immediate_attributes is for the symlink
332 * (if it's a symlink), while handle_info contains info
333 * about the symlink or the target, depending on the flags
336 buf
->attributes
= handle_info
.dwFileAttributes
;
337 buf
->st_nlink
= handle_info
.nNumberOfLinks
;
338 buf
->st_size
= (((guint64
) handle_info
.nFileSizeHigh
) << 32) | handle_info
.nFileSizeLow
;
339 buf
->allocated_size
= std_info
.AllocationSize
.QuadPart
;
341 if (fd
< 0 && buf
->attributes
& FILE_ATTRIBUTE_REPARSE_POINT
)
342 buf
->reparse_tag
= finddata
.dwReserved0
;
344 buf
->reparse_tag
= 0;
346 buf
->st_ctime
= statbuf
.st_ctime
;
347 buf
->st_atime
= statbuf
.st_atime
;
348 buf
->st_mtime
= statbuf
.st_mtime
;
354 _g_win32_stat_utf8 (const gchar
*filename
,
355 GWin32PrivateStat
*buf
,
356 gboolean for_symlink
)
362 len
= strlen (filename
);
364 while (len
> 0 && G_IS_DIR_SEPARATOR (filename
[len
- 1]))
368 (g_path_is_absolute (filename
) && len
<= g_path_skip_root (filename
) - filename
))
369 len
= strlen (filename
);
371 wfilename
= g_utf8_to_utf16 (filename
, len
, NULL
, NULL
, NULL
);
373 if (wfilename
== NULL
)
379 result
= _g_win32_stat_utf16_no_trailing_slashes (wfilename
, -1, buf
, for_symlink
);
387 g_win32_stat_utf8 (const gchar
*filename
,
388 GWin32PrivateStat
*buf
)
390 return _g_win32_stat_utf8 (filename
, buf
, FALSE
);
394 g_win32_lstat_utf8 (const gchar
*filename
,
395 GWin32PrivateStat
*buf
)
397 return _g_win32_stat_utf8 (filename
, buf
, TRUE
);
401 g_win32_fstat (int fd
,
402 GWin32PrivateStat
*buf
)
404 return _g_win32_stat_utf16_no_trailing_slashes (NULL
, fd
, buf
, FALSE
);
408 _g_win32_readlink_utf16_raw (const gunichar2
*filename
,
412 DWORD returned_bytes
;
413 BYTE returned_data
[MAXIMUM_REPARSE_DATA_BUFFER_SIZE
]; /* This is 16k, by the way */
416 REPARSE_DATA_BUFFER
*rep_buf
;
420 if (buf_size
> G_MAXSIZE
/ sizeof (wchar_t))
422 /* "buf_size * sizeof (wchar_t)" overflows */
427 if ((attributes
= GetFileAttributesW (filename
)) == 0)
429 error_code
= GetLastError ();
430 errno
= w32_error_to_errno (error_code
);
434 if ((attributes
& FILE_ATTRIBUTE_REPARSE_POINT
) == 0)
440 /* To read symlink target we need to open the file as a reparse
441 * point and use DeviceIoControl() on it.
443 h
= CreateFileW (filename
,
444 FILE_READ_ATTRIBUTES
| SYNCHRONIZE
| GENERIC_READ
,
445 FILE_SHARE_READ
, NULL
, OPEN_EXISTING
,
446 FILE_ATTRIBUTE_NORMAL
447 | FILE_FLAG_OPEN_REPARSE_POINT
448 | (attributes
& FILE_ATTRIBUTE_DIRECTORY
? FILE_FLAG_BACKUP_SEMANTICS
: 0),
451 if (h
== INVALID_HANDLE_VALUE
)
453 error_code
= GetLastError ();
454 errno
= w32_error_to_errno (error_code
);
458 if (!DeviceIoControl (h
, FSCTL_GET_REPARSE_POINT
, NULL
, 0,
459 returned_data
, MAXIMUM_REPARSE_DATA_BUFFER_SIZE
,
460 &returned_bytes
, NULL
))
462 error_code
= GetLastError ();
463 errno
= w32_error_to_errno (error_code
);
468 rep_buf
= (REPARSE_DATA_BUFFER
*) returned_data
;
471 if (rep_buf
->ReparseTag
== IO_REPARSE_TAG_SYMLINK
)
473 to_copy
= rep_buf
->SymbolicLinkReparseBuffer
.SubstituteNameLength
;
475 if (to_copy
> buf_size
* sizeof (wchar_t))
476 to_copy
= buf_size
* sizeof (wchar_t);
479 &((BYTE
*) rep_buf
->SymbolicLinkReparseBuffer
.PathBuffer
)[rep_buf
->SymbolicLinkReparseBuffer
.SubstituteNameOffset
],
482 else if (rep_buf
->ReparseTag
== IO_REPARSE_TAG_MOUNT_POINT
)
484 to_copy
= rep_buf
->MountPointReparseBuffer
.SubstituteNameLength
;
486 if (to_copy
> buf_size
* sizeof (wchar_t))
487 to_copy
= buf_size
* sizeof (wchar_t);
490 &((BYTE
*) rep_buf
->MountPointReparseBuffer
.PathBuffer
)[rep_buf
->MountPointReparseBuffer
.SubstituteNameOffset
],
500 _g_win32_readlink_utf16 (const gunichar2
*filename
,
504 const wchar_t *ntobjm_prefix
= L
"\\??\\";
505 const gsize ntobjm_prefix_len_unichar2
= wcslen (ntobjm_prefix
);
506 const gsize ntobjm_prefix_len_bytes
= sizeof (gunichar2
) * ntobjm_prefix_len_unichar2
;
507 int result
= _g_win32_readlink_utf16_raw (filename
, buf
, buf_size
);
512 /* Ensure that output is a multiple of sizeof (gunichar2),
513 * cutting any trailing partial gunichar2, if present.
515 result
-= result
% sizeof (gunichar2
);
520 /* DeviceIoControl () tends to return filenames as NT Object Manager
521 * names , i.e. "\\??\\C:\\foo\\bar".
522 * Remove the leading 4-byte \??\ prefix, as glib (as well as many W32 API
523 * functions) is unprepared to deal with it.
525 if (result
> ntobjm_prefix_len_bytes
&&
526 memcmp (buf
, ntobjm_prefix
, ntobjm_prefix_len_bytes
) == 0)
528 result
-= ntobjm_prefix_len_bytes
;
529 memmove (buf
, buf
+ ntobjm_prefix_len_unichar2
, result
);
536 g_win32_readlink_utf8 (const gchar
*filename
,
543 wfilename
= g_utf8_to_utf16 (filename
, -1, NULL
, NULL
, NULL
);
545 if (wfilename
== NULL
)
551 result
= _g_win32_readlink_utf16 (wfilename
, (gunichar2
*) buf
, buf_size
);
558 gchar
*tmp
= g_utf16_to_utf8 ((const gunichar2
*) buf
,
559 result
/ sizeof (gunichar2
),
570 if (tmp_len
> buf_size
- 1)
571 tmp_len
= buf_size
- 1;
573 memcpy (buf
, tmp
, tmp_len
);
574 /* readlink() doesn't NUL-terminate, but we do.
575 * To be compliant, however, we return the
576 * number of bytes without the NUL-terminator.
590 * @filename: (type filename): a pathname in the GLib file name encoding
592 * @mode: as in access()
594 * A wrapper for the POSIX access() function. This function is used to
595 * test a pathname for one or several of read, write or execute
596 * permissions, or just existence.
598 * On Windows, the file protection mechanism is not at all POSIX-like,
599 * and the underlying function in the C library only checks the
600 * FAT-style READONLY attribute, and does not look at the ACL of a
601 * file at all. This function is this in practise almost useless on
602 * Windows. Software that needs to handle file permissions on Windows
603 * more exactly should use the Win32 API.
605 * See your C library manual for more details about access().
607 * Returns: zero if the pathname refers to an existing file system
608 * object that has all the tested permissions, or -1 otherwise
614 g_access (const gchar
*filename
,
618 wchar_t *wfilename
= g_utf8_to_utf16 (filename
, -1, NULL
, NULL
, NULL
);
622 if (wfilename
== NULL
)
632 retval
= _waccess (wfilename
, mode
& ~X_OK
);
640 return access (filename
, mode
);
646 * @filename: (type filename): a pathname in the GLib file name encoding
648 * @mode: as in chmod()
650 * A wrapper for the POSIX chmod() function. The chmod() function is
651 * used to set the permissions of a file system object.
653 * On Windows the file protection mechanism is not at all POSIX-like,
654 * and the underlying chmod() function in the C library just sets or
655 * clears the FAT-style READONLY attribute. It does not touch any
656 * ACL. Software that needs to manage file permissions on Windows
657 * exactly should use the Win32 API.
659 * See your C library manual for more details about chmod().
661 * Returns: 0 if the operation succeeded, -1 on error
666 g_chmod (const gchar
*filename
,
670 wchar_t *wfilename
= g_utf8_to_utf16 (filename
, -1, NULL
, NULL
, NULL
);
674 if (wfilename
== NULL
)
680 retval
= _wchmod (wfilename
, mode
);
688 return chmod (filename
, mode
);
693 * @filename: (type filename): a pathname in the GLib file name encoding
695 * @flags: as in open()
696 * @mode: as in open()
698 * A wrapper for the POSIX open() function. The open() function is
699 * used to convert a pathname into a file descriptor.
701 * On POSIX systems file descriptors are implemented by the operating
702 * system. On Windows, it's the C library that implements open() and
703 * file descriptors. The actual Win32 API for opening files is quite
704 * different, see MSDN documentation for CreateFile(). The Win32 API
705 * uses file handles, which are more randomish integers, not small
706 * integers like file descriptors.
708 * Because file descriptors are specific to the C library on Windows,
709 * the file descriptor returned by this function makes sense only to
710 * functions in the same C library. Thus if the GLib-using code uses a
711 * different C library than GLib does, the file descriptor returned by
712 * this function cannot be passed to C library functions like write()
715 * See your C library manual for more details about open().
717 * Returns: a new file descriptor, or -1 if an error occurred.
718 * The return value can be used exactly like the return value
724 g_open (const gchar
*filename
,
729 wchar_t *wfilename
= g_utf8_to_utf16 (filename
, -1, NULL
, NULL
, NULL
);
733 if (wfilename
== NULL
)
739 retval
= _wopen (wfilename
, flags
, mode
);
749 fd
= open (filename
, flags
, mode
);
750 while (G_UNLIKELY (fd
== -1 && errno
== EINTR
));
757 * @filename: (type filename): a pathname in the GLib file name encoding
759 * @mode: as in creat()
761 * A wrapper for the POSIX creat() function. The creat() function is
762 * used to convert a pathname into a file descriptor, creating a file
765 * On POSIX systems file descriptors are implemented by the operating
766 * system. On Windows, it's the C library that implements creat() and
767 * file descriptors. The actual Windows API for opening files is
768 * different, see MSDN documentation for CreateFile(). The Win32 API
769 * uses file handles, which are more randomish integers, not small
770 * integers like file descriptors.
772 * Because file descriptors are specific to the C library on Windows,
773 * the file descriptor returned by this function makes sense only to
774 * functions in the same C library. Thus if the GLib-using code uses a
775 * different C library than GLib does, the file descriptor returned by
776 * this function cannot be passed to C library functions like write()
779 * See your C library manual for more details about creat().
781 * Returns: a new file descriptor, or -1 if an error occurred.
782 * The return value can be used exactly like the return value
788 g_creat (const gchar
*filename
,
792 wchar_t *wfilename
= g_utf8_to_utf16 (filename
, -1, NULL
, NULL
, NULL
);
796 if (wfilename
== NULL
)
802 retval
= _wcreat (wfilename
, mode
);
810 return creat (filename
, mode
);
816 * @oldfilename: (type filename): a pathname in the GLib file name encoding
818 * @newfilename: (type filename): a pathname in the GLib file name encoding
820 * A wrapper for the POSIX rename() function. The rename() function
821 * renames a file, moving it between directories if required.
823 * See your C library manual for more details about how rename() works
824 * on your system. It is not possible in general on Windows to rename
825 * a file that is open to some process.
827 * Returns: 0 if the renaming succeeded, -1 if an error occurred
832 g_rename (const gchar
*oldfilename
,
833 const gchar
*newfilename
)
836 wchar_t *woldfilename
= g_utf8_to_utf16 (oldfilename
, -1, NULL
, NULL
, NULL
);
837 wchar_t *wnewfilename
;
841 if (woldfilename
== NULL
)
847 wnewfilename
= g_utf8_to_utf16 (newfilename
, -1, NULL
, NULL
, NULL
);
849 if (wnewfilename
== NULL
)
851 g_free (woldfilename
);
856 if (MoveFileExW (woldfilename
, wnewfilename
, MOVEFILE_REPLACE_EXISTING
))
861 switch (GetLastError ())
863 #define CASE(a,b) case ERROR_##a: save_errno = b; break
864 CASE (FILE_NOT_FOUND
, ENOENT
);
865 CASE (PATH_NOT_FOUND
, ENOENT
);
866 CASE (ACCESS_DENIED
, EACCES
);
867 CASE (NOT_SAME_DEVICE
, EXDEV
);
868 CASE (LOCK_VIOLATION
, EACCES
);
869 CASE (SHARING_VIOLATION
, EACCES
);
870 CASE (FILE_EXISTS
, EEXIST
);
871 CASE (ALREADY_EXISTS
, EEXIST
);
873 default: save_errno
= EIO
;
877 g_free (woldfilename
);
878 g_free (wnewfilename
);
883 return rename (oldfilename
, newfilename
);
889 * @filename: (type filename): a pathname in the GLib file name encoding
891 * @mode: permissions to use for the newly created directory
893 * A wrapper for the POSIX mkdir() function. The mkdir() function
894 * attempts to create a directory with the given name and permissions.
895 * The mode argument is ignored on Windows.
897 * See your C library manual for more details about mkdir().
899 * Returns: 0 if the directory was successfully created, -1 if an error
905 g_mkdir (const gchar
*filename
,
909 wchar_t *wfilename
= g_utf8_to_utf16 (filename
, -1, NULL
, NULL
, NULL
);
913 if (wfilename
== NULL
)
919 retval
= _wmkdir (wfilename
);
927 return mkdir (filename
, mode
);
933 * @path: (type filename): a pathname in the GLib file name encoding
936 * A wrapper for the POSIX chdir() function. The function changes the
937 * current directory of the process to @path.
939 * See your C library manual for more details about chdir().
941 * Returns: 0 on success, -1 if an error occurred.
946 g_chdir (const gchar
*path
)
949 wchar_t *wpath
= g_utf8_to_utf16 (path
, -1, NULL
, NULL
, NULL
);
959 retval
= _wchdir (wpath
);
974 * A type corresponding to the appropriate struct type for the stat()
975 * system call, depending on the platform and/or compiler being used.
977 * See g_stat() for more information.
981 * @filename: (type filename): a pathname in the GLib file name encoding
983 * @buf: a pointer to a stat struct, which will be filled with the file
986 * A wrapper for the POSIX stat() function. The stat() function
987 * returns information about a file. On Windows the stat() function in
988 * the C library checks only the FAT-style READONLY attribute and does
989 * not look at the ACL at all. Thus on Windows the protection bits in
990 * the @st_mode field are a fabrication of little use.
992 * On Windows the Microsoft C libraries have several variants of the
993 * stat struct and stat() function with names like _stat(), _stat32(),
994 * _stat32i64() and _stat64i32(). The one used here is for 32-bit code
995 * the one with 32-bit size and time fields, specifically called _stat32().
997 * In Microsoft's compiler, by default struct stat means one with
998 * 64-bit time fields while in MinGW struct stat is the legacy one
999 * with 32-bit fields. To hopefully clear up this messs, the gstdio.h
1000 * header defines a type #GStatBuf which is the appropriate struct type
1001 * depending on the platform and/or compiler being used. On POSIX it
1002 * is just struct stat, but note that even on POSIX platforms, stat()
1005 * See your C library manual for more details about stat().
1007 * Returns: 0 if the information was successfully retrieved,
1008 * -1 if an error occurred
1013 g_stat (const gchar
*filename
,
1017 GWin32PrivateStat w32_buf
;
1018 int retval
= g_win32_stat_utf8 (filename
, &w32_buf
);
1020 buf
->st_dev
= w32_buf
.st_dev
;
1021 buf
->st_ino
= w32_buf
.st_ino
;
1022 buf
->st_mode
= w32_buf
.st_mode
;
1023 buf
->st_nlink
= w32_buf
.st_nlink
;
1024 buf
->st_uid
= w32_buf
.st_uid
;
1025 buf
->st_gid
= w32_buf
.st_gid
;
1026 buf
->st_rdev
= w32_buf
.st_dev
;
1027 buf
->st_size
= w32_buf
.st_size
;
1028 buf
->st_atime
= w32_buf
.st_atime
;
1029 buf
->st_mtime
= w32_buf
.st_mtime
;
1030 buf
->st_ctime
= w32_buf
.st_ctime
;
1034 return stat (filename
, buf
);
1040 * @filename: (type filename): a pathname in the GLib file name encoding
1041 * (UTF-8 on Windows)
1042 * @buf: a pointer to a stat struct, which will be filled with the file
1045 * A wrapper for the POSIX lstat() function. The lstat() function is
1046 * like stat() except that in the case of symbolic links, it returns
1047 * information about the symbolic link itself and not the file that it
1048 * refers to. If the system does not support symbolic links g_lstat()
1049 * is identical to g_stat().
1051 * See your C library manual for more details about lstat().
1053 * Returns: 0 if the information was successfully retrieved,
1054 * -1 if an error occurred
1059 g_lstat (const gchar
*filename
,
1063 /* This can't be Win32, so don't do the widechar dance. */
1064 return lstat (filename
, buf
);
1065 #elif defined (G_OS_WIN32)
1066 GWin32PrivateStat w32_buf
;
1067 int retval
= g_win32_lstat_utf8 (filename
, &w32_buf
);
1069 buf
->st_dev
= w32_buf
.st_dev
;
1070 buf
->st_ino
= w32_buf
.st_ino
;
1071 buf
->st_mode
= w32_buf
.st_mode
;
1072 buf
->st_nlink
= w32_buf
.st_nlink
;
1073 buf
->st_uid
= w32_buf
.st_uid
;
1074 buf
->st_gid
= w32_buf
.st_gid
;
1075 buf
->st_rdev
= w32_buf
.st_dev
;
1076 buf
->st_size
= w32_buf
.st_size
;
1077 buf
->st_atime
= w32_buf
.st_atime
;
1078 buf
->st_mtime
= w32_buf
.st_mtime
;
1079 buf
->st_ctime
= w32_buf
.st_ctime
;
1083 return g_stat (filename
, buf
);
1089 * @filename: (type filename): a pathname in the GLib file name encoding
1090 * (UTF-8 on Windows)
1092 * A wrapper for the POSIX unlink() function. The unlink() function
1093 * deletes a name from the filesystem. If this was the last link to the
1094 * file and no processes have it opened, the diskspace occupied by the
1097 * See your C library manual for more details about unlink(). Note
1098 * that on Windows, it is in general not possible to delete files that
1099 * are open to some process, or mapped into memory.
1101 * Returns: 0 if the name was successfully deleted, -1 if an error
1107 g_unlink (const gchar
*filename
)
1110 wchar_t *wfilename
= g_utf8_to_utf16 (filename
, -1, NULL
, NULL
, NULL
);
1114 if (wfilename
== NULL
)
1120 retval
= _wunlink (wfilename
);
1128 return unlink (filename
);
1134 * @filename: (type filename): a pathname in the GLib file name encoding
1135 * (UTF-8 on Windows)
1137 * A wrapper for the POSIX remove() function. The remove() function
1138 * deletes a name from the filesystem.
1140 * See your C library manual for more details about how remove() works
1141 * on your system. On Unix, remove() removes also directories, as it
1142 * calls unlink() for files and rmdir() for directories. On Windows,
1143 * although remove() in the C library only works for files, this
1144 * function tries first remove() and then if that fails rmdir(), and
1145 * thus works for both files and directories. Note however, that on
1146 * Windows, it is in general not possible to remove a file that is
1147 * open to some process, or mapped into memory.
1149 * If this function fails on Windows you can't infer too much from the
1150 * errno value. rmdir() is tried regardless of what caused remove() to
1151 * fail. Any errno value set by remove() will be overwritten by that
1154 * Returns: 0 if the file was successfully removed, -1 if an error
1160 g_remove (const gchar
*filename
)
1163 wchar_t *wfilename
= g_utf8_to_utf16 (filename
, -1, NULL
, NULL
, NULL
);
1167 if (wfilename
== NULL
)
1173 retval
= _wremove (wfilename
);
1175 retval
= _wrmdir (wfilename
);
1183 return remove (filename
);
1189 * @filename: (type filename): a pathname in the GLib file name encoding
1190 * (UTF-8 on Windows)
1192 * A wrapper for the POSIX rmdir() function. The rmdir() function
1193 * deletes a directory from the filesystem.
1195 * See your C library manual for more details about how rmdir() works
1198 * Returns: 0 if the directory was successfully removed, -1 if an error
1204 g_rmdir (const gchar
*filename
)
1207 wchar_t *wfilename
= g_utf8_to_utf16 (filename
, -1, NULL
, NULL
, NULL
);
1211 if (wfilename
== NULL
)
1217 retval
= _wrmdir (wfilename
);
1225 return rmdir (filename
);
1231 * @filename: (type filename): a pathname in the GLib file name encoding
1232 * (UTF-8 on Windows)
1233 * @mode: a string describing the mode in which the file should be opened
1235 * A wrapper for the stdio fopen() function. The fopen() function
1236 * opens a file and associates a new stream with it.
1238 * Because file descriptors are specific to the C library on Windows,
1239 * and a file descriptor is part of the FILE struct, the FILE* returned
1240 * by this function makes sense only to functions in the same C library.
1241 * Thus if the GLib-using code uses a different C library than GLib does,
1242 * the FILE* returned by this function cannot be passed to C library
1243 * functions like fprintf() or fread().
1245 * See your C library manual for more details about fopen().
1247 * Returns: A FILE* if the file was successfully opened, or %NULL if
1253 g_fopen (const gchar
*filename
,
1257 wchar_t *wfilename
= g_utf8_to_utf16 (filename
, -1, NULL
, NULL
, NULL
);
1262 if (wfilename
== NULL
)
1268 wmode
= g_utf8_to_utf16 (mode
, -1, NULL
, NULL
, NULL
);
1277 retval
= _wfopen (wfilename
, wmode
);
1286 return fopen (filename
, mode
);
1292 * @filename: (type filename): a pathname in the GLib file name encoding
1293 * (UTF-8 on Windows)
1294 * @mode: a string describing the mode in which the file should be opened
1295 * @stream: (nullable): an existing stream which will be reused, or %NULL
1297 * A wrapper for the POSIX freopen() function. The freopen() function
1298 * opens a file and associates it with an existing stream.
1300 * See your C library manual for more details about freopen().
1302 * Returns: A FILE* if the file was successfully opened, or %NULL if
1303 * an error occurred.
1308 g_freopen (const gchar
*filename
,
1313 wchar_t *wfilename
= g_utf8_to_utf16 (filename
, -1, NULL
, NULL
, NULL
);
1318 if (wfilename
== NULL
)
1324 wmode
= g_utf8_to_utf16 (mode
, -1, NULL
, NULL
, NULL
);
1333 retval
= _wfreopen (wfilename
, wmode
, stream
);
1342 return freopen (filename
, mode
, stream
);
1348 * @filename: (type filename): a pathname in the GLib file name encoding
1349 * (UTF-8 on Windows)
1350 * @utb: a pointer to a struct utimbuf.
1352 * A wrapper for the POSIX utime() function. The utime() function
1353 * sets the access and modification timestamps of a file.
1355 * See your C library manual for more details about how utime() works
1358 * Returns: 0 if the operation was successful, -1 if an error occurred
1363 g_utime (const gchar
*filename
,
1364 struct utimbuf
*utb
)
1367 wchar_t *wfilename
= g_utf8_to_utf16 (filename
, -1, NULL
, NULL
, NULL
);
1371 if (wfilename
== NULL
)
1377 retval
= _wutime (wfilename
, (struct _utimbuf
*) utb
);
1385 return utime (filename
, utb
);
1391 * @fd: A file descriptor
1394 * This wraps the close() call; in case of error, %errno will be
1395 * preserved, but the error will also be stored as a #GError in @error.
1397 * Besides using #GError, there is another major reason to prefer this
1398 * function over the call provided by the system; on Unix, it will
1399 * attempt to correctly handle %EINTR, which has platform-specific
1402 * Returns: %TRUE on success, %FALSE if there was an error.
1412 /* Just ignore EINTR for now; a retry loop is the wrong thing to do
1413 * on Linux at least. Anyone who wants to add a conditional check
1414 * for e.g. HP-UX is welcome to do so later...
1416 * http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
1417 * https://bugzilla.gnome.org/show_bug.cgi?id=682819
1418 * http://utcc.utoronto.ca/~cks/space/blog/unix/CloseEINTR
1419 * https://sites.google.com/site/michaelsafyan/software-engineering/checkforeintrwheninvokingclosethinkagain
1421 if (G_UNLIKELY (res
== -1 && errno
== EINTR
))
1426 g_set_error_literal (error
, G_FILE_ERROR
,
1427 g_file_error_from_errno (errsv
),
1428 g_strerror (errsv
));