mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-25 15:06:14 +01:00
Straighten up the GFileType vs symlinks on Windows situation
On Windows NTFS symlinks are implemented as reparse points, which are special kinds of files *or directories*. A directory symlink should link to a directory. A file symlink should link to a file. Mismatching (such as a file symlink pointing to a directory) produces symlinks that simply do not function. Therefore GFileType file vs directory vs symlink distinction is too simplistic to correctly represent a NTFS filesystem object type. Since we can't turn back time and choose a better way of representing file types, make GFileType reflect the file vs directory type on Windows, meaning that all FS objects are either files or directories (or shortcuts, which are also files), but never symlinks. A test for symlinkiness will have to be made via GFileInfo - it tracks symlinkiness separately from file/directory/whatever.
This commit is contained in:
parent
c2a5537845
commit
19608e36d2
@ -76,6 +76,7 @@ typedef struct _GFileInfoClass GFileInfoClass;
|
||||
* A key in the "standard" namespace for checking if the file is a symlink.
|
||||
* Typically the actual type is something else, if we followed the symlink
|
||||
* to get the type.
|
||||
* On Windows NTFS mountpoints are considered to be symlinks as well.
|
||||
* Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BOOLEAN.
|
||||
**/
|
||||
#define G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK "standard::is-symlink" /* boolean */
|
||||
|
@ -361,6 +361,15 @@ typedef enum {
|
||||
* @G_FILE_TYPE_MOUNTABLE: File is a mountable location.
|
||||
*
|
||||
* Indicates the file's on-disk type.
|
||||
*
|
||||
* On Windows systems a file will never have %G_FILE_TYPE_SYMBOLIC_LINK type;
|
||||
* use #GFileInfo and %G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK to determine
|
||||
* whether a file is a symlink or not. This is due to the fact that NTFS does
|
||||
* not have a single filesystem object type for symbolic links - it has
|
||||
* files that symlink to files, and directories that symlink to directories.
|
||||
* #GFileType enumeration cannot precisely represent this important distinction,
|
||||
* which is why all Windows symlinks will continue to be reported as
|
||||
* %G_FILE_TYPE_REGULAR or %G_FILE_TYPE_DIRECTORY.
|
||||
**/
|
||||
typedef enum {
|
||||
G_FILE_TYPE_UNKNOWN = 0,
|
||||
|
@ -957,8 +957,8 @@ set_info_from_stat (GFileInfo *info,
|
||||
else if (S_ISLNK (statbuf->st_mode))
|
||||
file_type = G_FILE_TYPE_SYMBOLIC_LINK;
|
||||
#elif defined (G_OS_WIN32)
|
||||
if (statbuf->reparse_tag == IO_REPARSE_TAG_SYMLINK ||
|
||||
statbuf->reparse_tag == IO_REPARSE_TAG_MOUNT_POINT)
|
||||
else if (statbuf->reparse_tag == IO_REPARSE_TAG_SYMLINK ||
|
||||
statbuf->reparse_tag == IO_REPARSE_TAG_MOUNT_POINT)
|
||||
file_type = G_FILE_TYPE_SYMBOLIC_LINK;
|
||||
#endif
|
||||
|
||||
|
@ -291,10 +291,10 @@ test_internal_enhanced_stdio (void)
|
||||
ft_programdata = g_file_info_get_file_type (fi_programdata);
|
||||
ft_commondata = g_file_info_get_file_type (fi_commondata);
|
||||
|
||||
g_assert_cmpint (ft_allusers, ==, G_FILE_TYPE_SYMBOLIC_LINK);
|
||||
g_assert_cmpint (ft_allusers, ==, G_FILE_TYPE_DIRECTORY);
|
||||
g_assert_cmpint (ft_allusers_target, ==, G_FILE_TYPE_DIRECTORY);
|
||||
g_assert_cmpint (ft_programdata, ==, G_FILE_TYPE_DIRECTORY);
|
||||
g_assert_cmpint (ft_commondata, ==, G_FILE_TYPE_SYMBOLIC_LINK);
|
||||
g_assert_cmpint (ft_commondata, ==, G_FILE_TYPE_DIRECTORY);
|
||||
|
||||
allusers_is_symlink = g_file_info_get_attribute_boolean (fi_allusers, G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK);
|
||||
allusers_reparse_tag = g_file_info_get_attribute_uint32 (fi_allusers, G_FILE_ATTRIBUTE_DOS_REPARSE_POINT_TAG);
|
||||
|
Loading…
Reference in New Issue
Block a user