diff options
Diffstat (limited to 'gio/glocalfileinfo.c')
-rw-r--r-- | gio/glocalfileinfo.c | 97 |
1 files changed, 55 insertions, 42 deletions
diff --git a/gio/glocalfileinfo.c b/gio/glocalfileinfo.c index 35853cc2d..fad80d37c 100644 --- a/gio/glocalfileinfo.c +++ b/gio/glocalfileinfo.c @@ -53,6 +53,7 @@ #endif /* HAVE_XATTR */ #include <glib/gstdio.h> +#include <glib/gstdioprivate.h> #include <gfileattribute-priv.h> #include <gfileinfo-priv.h> #include <gvfs.h> @@ -60,9 +61,10 @@ #ifdef G_OS_UNIX #include <unistd.h> #include "glib-unix.h" -#include "glib-private.h" #endif +#include "glib-private.h" + #include "thumbnail-verify.h" #ifdef G_OS_WIN32 @@ -136,9 +138,15 @@ _g_local_file_info_create_etag (GLocalFileStat *statbuf) static char * _g_local_file_info_create_file_id (GLocalFileStat *statbuf) { + guint64 ino; +#ifdef G_OS_WIN32 + ino = statbuf->file_index; +#else + ino = statbuf->st_ino; +#endif return g_strdup_printf ("l%" G_GUINT64_FORMAT ":%" G_GUINT64_FORMAT, (guint64) statbuf->st_dev, - (guint64) statbuf->st_ino); + ino); } static char * @@ -148,13 +156,12 @@ _g_local_file_info_create_fs_id (GLocalFileStat *statbuf) (guint64) statbuf->st_dev); } - -#ifdef S_ISLNK +#if defined (S_ISLNK) || defined (G_OS_WIN32) static gchar * read_link (const gchar *full_name) { -#ifdef HAVE_READLINK +#if defined (HAVE_READLINK) || defined (G_OS_WIN32) gchar *buffer; guint size; @@ -165,7 +172,11 @@ read_link (const gchar *full_name) { int read_size; +#ifndef G_OS_WIN32 read_size = readlink (full_name, buffer, size); +#else + read_size = GLIB_PRIVATE_CALL (g_win32_readlink_utf8) (full_name, buffer, size); +#endif if (read_size < 0) { g_free (buffer); @@ -184,7 +195,7 @@ read_link (const gchar *full_name) #endif } -#endif /* S_ISLNK */ +#endif /* S_ISLNK || G_OS_WIN32 */ #ifdef HAVE_SELINUX /* Get the SELinux security context */ @@ -938,6 +949,9 @@ set_info_from_stat (GFileInfo *info, #ifdef S_ISLNK 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) + file_type = G_FILE_TYPE_SYMBOLIC_LINK; #endif g_file_info_set_file_type (info, file_type); @@ -960,7 +974,11 @@ set_info_from_stat (GFileInfo *info, #if defined (HAVE_STRUCT_STAT_ST_BLOCKS) _g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_UNIX_BLOCKS, statbuf->st_blocks); _g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_STANDARD_ALLOCATED_SIZE, - statbuf->st_blocks * G_GUINT64_CONSTANT (512)); + statbuf->st_blocks * G_GUINT64_CONSTANT (512)); +#elif defined (G_OS_WIN32) + _g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_STANDARD_ALLOCATED_SIZE, + statbuf->allocated_size); + #endif _g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_MODIFIED, statbuf->st_mtime); @@ -1711,13 +1729,12 @@ _g_local_file_info_get (const char *basename, GLocalFileStat statbuf; #ifdef S_ISLNK struct stat statbuf2; +#elif defined (G_OS_WIN32) + GWin32PrivateStat statbuf2; #endif int res; gboolean stat_ok; gboolean is_symlink, symlink_broken; -#ifdef G_OS_WIN32 - DWORD dos_attributes; -#endif char *symlink_target; GVfs *vfs; GVfsClass *class; @@ -1739,28 +1756,7 @@ _g_local_file_info_get (const char *basename, #ifndef G_OS_WIN32 res = g_lstat (path, &statbuf); #else - { - wchar_t *wpath = g_utf8_to_utf16 (path, -1, NULL, NULL, error); - int len; - - if (wpath == NULL) - { - g_object_unref (info); - return NULL; - } - - len = wcslen (wpath); - while (len > 0 && G_IS_DIR_SEPARATOR (wpath[len-1])) - len--; - if (len > 0 && - (!g_path_is_absolute (path) || len > g_path_skip_root (path) - path)) - wpath[len] = '\0'; - - res = _wstati64 (wpath, &statbuf); - dos_attributes = GetFileAttributesW (wpath); - - g_free (wpath); - } + res = GLIB_PRIVATE_CALL (g_win32_lstat_utf8) (path, &statbuf); #endif if (res == -1) @@ -1791,11 +1787,14 @@ _g_local_file_info_get (const char *basename, #ifdef S_ISLNK is_symlink = stat_ok && S_ISLNK (statbuf.st_mode); +#elif defined (G_OS_WIN32) + /* glib already checked the FILE_ATTRIBUTE_REPARSE_POINT for us */ + is_symlink = stat_ok && statbuf.reparse_tag == IO_REPARSE_TAG_SYMLINK; #else is_symlink = FALSE; #endif symlink_broken = FALSE; -#ifdef S_ISLNK + if (is_symlink) { g_file_info_set_is_symlink (info, TRUE); @@ -1803,7 +1802,11 @@ _g_local_file_info_get (const char *basename, /* Unless NOFOLLOW was set we default to following symlinks */ if (!(flags & G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS)) { +#ifndef G_OS_WIN32 res = stat (path, &statbuf2); +#else + res = GLIB_PRIVATE_CALL (g_win32_stat_utf8) (path, &statbuf2); +#endif /* Report broken links as symlinks */ if (res != -1) @@ -1815,7 +1818,6 @@ _g_local_file_info_get (const char *basename, symlink_broken = TRUE; } } -#endif if (stat_ok) set_info_from_stat (info, &statbuf, attribute_matcher); @@ -1839,27 +1841,28 @@ _g_local_file_info_get (const char *basename, (stat_ok && S_ISREG (statbuf.st_mode))) _g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_STANDARD_IS_BACKUP, TRUE); #else - if (dos_attributes & FILE_ATTRIBUTE_HIDDEN) + if (statbuf.attributes & FILE_ATTRIBUTE_HIDDEN) g_file_info_set_is_hidden (info, TRUE); - if (dos_attributes & FILE_ATTRIBUTE_ARCHIVE) + if (statbuf.attributes & FILE_ATTRIBUTE_ARCHIVE) _g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_DOS_IS_ARCHIVE, TRUE); - if (dos_attributes & FILE_ATTRIBUTE_SYSTEM) + if (statbuf.attributes & FILE_ATTRIBUTE_SYSTEM) _g_file_info_set_attribute_boolean_by_id (info, G_FILE_ATTRIBUTE_ID_DOS_IS_SYSTEM, TRUE); #endif symlink_target = NULL; -#ifdef S_ISLNK if (is_symlink) { +#if defined (S_ISLNK) || defined (G_OS_WIN32) symlink_target = read_link (path); +#endif if (symlink_target && _g_file_attribute_matcher_matches_id (attribute_matcher, G_FILE_ATTRIBUTE_ID_STANDARD_SYMLINK_TARGET)) g_file_info_set_symlink_target (info, symlink_target); } -#endif + if (_g_file_attribute_matcher_matches_id (attribute_matcher, G_FILE_ATTRIBUTE_ID_STANDARD_CONTENT_TYPE) || _g_file_attribute_matcher_matches_id (attribute_matcher, @@ -2014,7 +2017,7 @@ _g_local_file_info_get_from_fd (int fd, GFileInfo *info; #ifdef G_OS_WIN32 -#define FSTAT _fstati64 +#define FSTAT GLIB_PRIVATE_CALL (g_win32_fstat) #else #define FSTAT fstat #endif @@ -2148,16 +2151,26 @@ set_unix_mode (char *filename, if (!get_uint32 (value, &val, error)) return FALSE; -#ifdef HAVE_SYMLINK +#if defined (HAVE_SYMLINK) || defined (G_OS_WIN32) if (flags & G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS) { #ifdef HAVE_LCHMOD res = lchmod (filename, val); #else + gboolean is_symlink; +#ifndef G_OS_WIN32 struct stat statbuf; /* Calling chmod on a symlink changes permissions on the symlink. * We don't want to do this, so we need to check for a symlink */ res = g_lstat (filename, &statbuf); - if (res == 0 && S_ISLNK (statbuf.st_mode)) + is_symlink = (res == 0 && S_ISLNK (statbuf.st_mode)); +#else + /* FIXME: implement lchmod for W32, should be doable */ + GWin32PrivateStat statbuf; + + res = GLIB_PRIVATE_CALL (g_win32_lstat_utf8) (filename, &statbuf); + is_symlink = (res == 0 && statbuf.reparse_tag == IO_REPARSE_TAG_SYMLINK); +#endif + if (is_symlink) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, |