glib r6697 - trunk/gio



Author: tml
Date: Wed Mar 12 18:33:59 2008
New Revision: 6697
URL: http://svn.gnome.org/viewvc/glib?rev=6697&view=rev

Log:
2008-03-12  Tor Lillqvist  <tml novell com>

	* glocalfileinfo.h: Introduce a macro GLocalFileStat that is the
	normal struct stat on Unix but struct _stati64 on Windows to have
	access to 64-bit file size information. Use that instead of struct
	stat in the functions declared here in this private header.

	* glocalfileinfo.c: Corresponding changes. Move some G_OS_WIN32,
	S_ISLNK and HAVE_UTIMES ifdefs and add some more to avoid compiler
	warnings about unused functions and variables. Don't set
	meaningless attributes like inode numbers on Windows.



Modified:
   trunk/gio/ChangeLog
   trunk/gio/glocalfileinfo.c
   trunk/gio/glocalfileinfo.h

Modified: trunk/gio/glocalfileinfo.c
==============================================================================
--- trunk/gio/glocalfileinfo.c	(original)
+++ trunk/gio/glocalfileinfo.c	Wed Mar 12 18:33:59 2008
@@ -99,20 +99,24 @@
 	guint32 bits[2];
 	unsigned char in[64];
 };
+
 #ifndef G_OS_WIN32
+
 typedef struct {
   char *user_name;
   char *real_name;
 } UidData;
-#endif
+
 G_LOCK_DEFINE_STATIC (uid_cache);
 static GHashTable *uid_cache = NULL;
 
 G_LOCK_DEFINE_STATIC (gid_cache);
 static GHashTable *gid_cache = NULL;
 
+#endif  /* !G_OS_WIN32 */
+
 char *
-_g_local_file_info_create_etag (struct stat *statbuf)
+_g_local_file_info_create_etag (GLocalFileStat *statbuf)
 {
   GTimeVal tv;
   
@@ -129,7 +133,7 @@
 }
 
 static char *
-_g_local_file_info_create_file_id (struct stat *statbuf)
+_g_local_file_info_create_file_id (GLocalFileStat *statbuf)
 {
   return g_strdup_printf ("l%" G_GUINT64_FORMAT ":%" G_GUINT64_FORMAT,
 			  (guint64) statbuf->st_dev, 
@@ -137,13 +141,15 @@
 }
 
 static char *
-_g_local_file_info_create_fs_id (struct stat *statbuf)
+_g_local_file_info_create_fs_id (GLocalFileStat *statbuf)
 {
   return g_strdup_printf ("l%" G_GUINT64_FORMAT,
 			  (guint64) statbuf->st_dev);
 }
 
 
+#ifdef S_ISLNK
+
 static gchar *
 read_link (const gchar *full_name)
 {
@@ -177,6 +183,8 @@
 #endif
 }
 
+#endif  /* S_ISLNK */
+
 /* Get the SELinux security context */
 static void
 get_selinux_context (const char            *path,
@@ -776,6 +784,9 @@
 				    GFileAttributeMatcher *attribute_matcher,
 				    GLocalParentFileInfo  *parent_info)
 {
+  /* Use plain struct stat for now as long as we only look at the
+   * S_ISVTX bit which doesn't exist on Win32 anyway.
+   */
   struct stat statbuf;
   int res;
   
@@ -789,6 +800,11 @@
       g_file_attribute_matcher_matches (attribute_matcher, G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH) ||
       g_file_attribute_matcher_matches (attribute_matcher, G_FILE_ATTRIBUTE_UNIX_IS_MOUNTPOINT))
     {
+      /* FIXME: Windows: The underlying _waccess() call in the C
+       * library is mostly pointless as it only looks at the READONLY
+       * FAT-style attribute of the file, it doesn't check the ACL at
+       * all.
+       */
       parent_info->writable = (g_access (dir, W_OK) == 0);
       
       res = g_stat (dir, &statbuf);
@@ -819,9 +835,10 @@
 get_access_rights (GFileAttributeMatcher *attribute_matcher,
 		   GFileInfo             *info,
 		   const gchar           *path,
-		   struct stat           *statbuf,
+		   GLocalFileStat        *statbuf,
 		   GLocalParentFileInfo  *parent_info)
 {
+  /* FIXME: Windows: The underlyin _waccess() is mostly pointless */
   if (g_file_attribute_matcher_matches (attribute_matcher,
 					G_FILE_ATTRIBUTE_ACCESS_CAN_READ))
     g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_READ,
@@ -876,7 +893,7 @@
 
 static void
 set_info_from_stat (GFileInfo             *info, 
-                    struct stat           *statbuf,
+                    GLocalFileStat        *statbuf,
 		    GFileAttributeMatcher *attribute_matcher)
 {
   GFileType file_type;
@@ -906,12 +923,16 @@
   g_file_info_set_size (info, statbuf->st_size);
 
   g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_DEVICE, statbuf->st_dev);
+#ifndef G_OS_WIN32
+  /* Pointless setting these on Windows even if they exist in the struct */
   g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_UNIX_INODE, statbuf->st_ino);
-  g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_MODE, statbuf->st_mode);
   g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_NLINK, statbuf->st_nlink);
   g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_UID, statbuf->st_uid);
   g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_GID, statbuf->st_gid);
   g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_RDEV, statbuf->st_rdev);
+#endif
+  /* FIXME: st_mode is mostly pointless on Windows, too. Set the attribute or not? */
+  g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_MODE, statbuf->st_mode);
 #if defined (HAVE_STRUCT_STAT_ST_BLKSIZE)
   g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_BLOCK_SIZE, statbuf->st_blksize);
 #endif
@@ -965,6 +986,8 @@
     }
 }
 
+#ifndef G_OS_WIN32
+
 static char *
 make_valid_utf8 (const char *name)
 {
@@ -1019,7 +1042,7 @@
   
   return utf8_string;
 }
-#ifndef G_OS_WIN32
+
 static void
 uid_data_free (UidData *data)
 {
@@ -1166,12 +1189,13 @@
   G_UNLOCK (gid_cache);
   return res;
 }
+
 #endif /* !G_OS_WIN32 */
 
 static char *
 get_content_type (const char          *basename,
 		  const char          *path,
-		  struct stat         *statbuf,
+		  GLocalFileStat      *statbuf,
 		  gboolean             is_symlink,
 		  gboolean             symlink_broken,
 		  GFileQueryInfoFlags  flags,
@@ -1375,10 +1399,15 @@
 			GError                **error)
 {
   GFileInfo *info;
-  struct stat statbuf;
+  GLocalFileStat statbuf;
+#ifdef S_ISLNK
   struct stat statbuf2;
+#endif
   int res;
   gboolean is_symlink, symlink_broken;
+#ifdef G_OS_WIN32
+  DWORD dos_attributes;
+#endif
 
   info = g_file_info_new ();
 
@@ -1391,7 +1420,33 @@
   if (attribute_matcher == NULL)
     return info;
 
+#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);
+  }
+#endif
+
   if (res == -1)
     {
       int errsv = errno;
@@ -1412,6 +1467,7 @@
 #endif
   symlink_broken = FALSE;
   
+#ifdef S_ISLNK
   if (is_symlink)
     {
       g_file_info_set_is_symlink (info, TRUE);
@@ -1428,15 +1484,28 @@
 	    symlink_broken = TRUE;
 	}
     }
+#endif
 
   set_info_from_stat (info, &statbuf, attribute_matcher);
   
+#ifndef G_OS_WIN32
   if (basename != NULL && basename[0] == '.')
     g_file_info_set_is_hidden (info, TRUE);
 
   if (basename != NULL && basename[strlen (basename) -1] == '~')
     g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_STANDARD_IS_BACKUP, TRUE);
+#else
+  if (dos_attributes & FILE_ATTRIBUTE_HIDDEN)
+    g_file_info_set_is_hidden (info, TRUE);
+
+  if (dos_attributes & FILE_ATTRIBUTE_ARCHIVE)
+    g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_DOS_IS_ARCHIVE, TRUE);
+
+  if (dos_attributes & FILE_ATTRIBUTE_SYSTEM)
+    g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_DOS_IS_SYSTEM, TRUE);
+#endif
 
+#ifdef S_ISLNK
   if (is_symlink &&
       g_file_attribute_matcher_matches (attribute_matcher,
 					G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET))
@@ -1445,6 +1514,7 @@
       g_file_info_set_symlink_target (info, link);
       g_free (link);
     }
+#endif
 
   if (g_file_attribute_matcher_matches (attribute_matcher,
 					G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME))
@@ -1605,11 +1675,17 @@
 				char    *attributes,
 				GError **error)
 {
-  struct stat stat_buf;
+  GLocalFileStat stat_buf;
   GFileAttributeMatcher *matcher;
   GFileInfo *info;
   
-  if (fstat (fd, &stat_buf) == -1)
+#ifdef G_OS_WIN32
+#define FSTAT _fstati64
+#else
+#define FSTAT fstat
+#endif
+
+  if (FSTAT (fd, &stat_buf) == -1)
     {
       int errsv = errno;
 
@@ -1669,6 +1745,7 @@
   return TRUE;
 }
 
+#ifdef HAVE_UTIMES
 static gboolean
 get_uint64 (const GFileAttributeValue  *value,
 	    guint64                    *val_out,
@@ -1685,6 +1762,7 @@
   
   return TRUE;
 }
+#endif
 
 #if defined(HAVE_SYMLINK)
 static gboolean
@@ -1844,6 +1922,7 @@
 }
 #endif
 
+#ifdef HAVE_UTIMES
 static int
 lazy_stat (char        *filename, 
            struct stat *statbuf, 
@@ -1863,7 +1942,6 @@
 }
 
 
-#ifdef HAVE_UTIMES
 static gboolean
 set_mtime_atime (char                       *filename,
 		 const GFileAttributeValue  *mtime_value,
@@ -2006,9 +2084,16 @@
 				    GCancellable         *cancellable,
 				    GError              **error)
 {
-  GFileAttributeValue *value, *uid, *gid;
+  GFileAttributeValue *value;
+#ifdef HAVE_CHOWN
+  GFileAttributeValue *uid, *gid;
+#endif
+#ifdef HAVE_UTIMES
   GFileAttributeValue *mtime, *mtime_usec, *atime, *atime_usec;
+#endif
+#if defined (HAVE_CHOWN) && defined (HAVE_UTIMES)
   GFileAttributeStatus status;
+#endif
   gboolean res;
   
   /* Handles setting multiple specified data in a single set, and takes care

Modified: trunk/gio/glocalfileinfo.h
==============================================================================
--- trunk/gio/glocalfileinfo.h	(original)
+++ trunk/gio/glocalfileinfo.h	Wed Mar 12 18:33:59 2008
@@ -40,6 +40,13 @@
   dev_t device;
 } GLocalParentFileInfo;
 
+#ifdef G_OS_WIN32
+/* We want 64-bit file size support */
+#define GLocalFileStat struct _stati64
+#else
+#define GLocalFileStat struct stat
+#endif
+
 gboolean   _g_local_file_has_trash_dir        (const char *dirname,
 					       dev_t dir_dev);
 void       _g_local_file_info_get_parent_info (const char                 *dir,
@@ -54,7 +61,7 @@
 GFileInfo *_g_local_file_info_get_from_fd     (int                         fd,
 					       char                       *attributes,
 					       GError                    **error);
-char *     _g_local_file_info_create_etag     (struct stat                *statbuf);
+char *     _g_local_file_info_create_etag     (GLocalFileStat             *statbuf);
 gboolean   _g_local_file_info_set_attribute   (char                       *filename,
 					       const char                 *attribute,
 					       GFileAttributeType          type,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]