Blame gio/tests/g-file-info.c

Packit ae235b
/* GLib testing framework examples and tests
Packit ae235b
 * Copyright (C) 2008 Red Hat, Inc.
Packit ae235b
 * Authors: Tomas Bzatek <tbzatek@redhat.com>
Packit ae235b
 *
Packit ae235b
 * This work is provided "as is"; redistribution and modification
Packit ae235b
 * in whole or in part, in any medium, physical or electronic is
Packit ae235b
 * permitted without restriction.
Packit ae235b
 *
Packit ae235b
 * This work is distributed in the hope that it will be useful,
Packit ae235b
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit ae235b
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Packit ae235b
 *
Packit ae235b
 * In no event shall the authors or contributors be liable for any
Packit ae235b
 * direct, indirect, incidental, special, exemplary, or consequential
Packit ae235b
 * damages (including, but not limited to, procurement of substitute
Packit ae235b
 * goods or services; loss of use, data, or profits; or business
Packit ae235b
 * interruption) however caused and on any theory of liability, whether
Packit ae235b
 * in contract, strict liability, or tort (including negligence or
Packit ae235b
 * otherwise) arising in any way out of the use of this software, even
Packit ae235b
 * if advised of the possibility of such damage.
Packit ae235b
 */
Packit ae235b
Packit ae235b
#include "config.h"
Packit ae235b
Packit ae235b
#include <glib/glib.h>
Packit ae235b
#include <gio/gio.h>
Packit ae235b
#include <stdlib.h>
Packit ae235b
#include <string.h>
Packit ae235b
#ifdef G_OS_WIN32
Packit ae235b
#include <stdio.h>
Packit ae235b
#include <glib/gstdio.h>
Packit ae235b
#include <Windows.h>
Packit ae235b
#include <Shlobj.h>
Packit ae235b
#endif
Packit ae235b
Packit ae235b
#define TEST_NAME			"Prilis zlutoucky kun"
Packit ae235b
#define TEST_DISPLAY_NAME	        "UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88"
Packit ae235b
#define TEST_SIZE			0xFFFFFFF0
Packit ae235b
Packit ae235b
static void
Packit ae235b
test_assigned_values (GFileInfo *info)
Packit ae235b
{
Packit ae235b
  const char *name, *display_name, *mistake;
Packit ae235b
  guint64 size;
Packit ae235b
  GFileType type;
Packit ae235b
  
Packit ae235b
  /*  Test for attributes presence */
Packit ae235b
  g_assert (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_NAME) == TRUE);
Packit ae235b
  g_assert (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME) == TRUE);
Packit ae235b
  g_assert (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SIZE) == TRUE);
Packit ae235b
  g_assert (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_COPY_NAME) == FALSE);
Packit ae235b
	
Packit ae235b
  /*  Retrieve data back and compare */
Packit ae235b
  
Packit ae235b
  name = g_file_info_get_attribute_byte_string (info, G_FILE_ATTRIBUTE_STANDARD_NAME);
Packit ae235b
  display_name = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME);
Packit ae235b
  mistake = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_COPY_NAME);
Packit ae235b
  size = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_STANDARD_SIZE);
Packit ae235b
  type = g_file_info_get_file_type (info);
Packit ae235b
  
Packit ae235b
  g_assert_cmpstr (name, ==, TEST_NAME);
Packit ae235b
  g_assert_cmpstr (display_name, ==, TEST_DISPLAY_NAME);
Packit ae235b
  g_assert (mistake == NULL);
Packit ae235b
  g_assert_cmpint (size, ==, TEST_SIZE);
Packit ae235b
  g_assert_cmpstr (name, ==, g_file_info_get_name (info));
Packit ae235b
  g_assert_cmpstr (display_name, ==, g_file_info_get_display_name (info));
Packit ae235b
  g_assert_cmpint (size, ==, g_file_info_get_size (info)	);
Packit ae235b
  g_assert_cmpint (type, ==, G_FILE_TYPE_DIRECTORY);
Packit ae235b
}
Packit ae235b
Packit ae235b
Packit ae235b
Packit ae235b
static void
Packit ae235b
test_g_file_info (void)
Packit ae235b
{
Packit ae235b
  GFileInfo *info;
Packit ae235b
  GFileInfo *info_dup;
Packit ae235b
  GFileInfo *info_copy;
Packit ae235b
  char **attr_list;
Packit ae235b
  GFileAttributeMatcher *matcher;
Packit ae235b
  
Packit ae235b
  info = g_file_info_new ();
Packit ae235b
  
Packit ae235b
  /*  Test for empty instance */
Packit ae235b
  attr_list = g_file_info_list_attributes (info, NULL);
Packit ae235b
  g_assert (attr_list != NULL);
Packit ae235b
  g_assert (*attr_list == NULL);
Packit ae235b
  g_strfreev (attr_list);
Packit ae235b
Packit ae235b
  g_file_info_set_attribute_byte_string (info, G_FILE_ATTRIBUTE_STANDARD_NAME, TEST_NAME);
Packit ae235b
  g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, TEST_DISPLAY_NAME);
Packit ae235b
  g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_STANDARD_SIZE, TEST_SIZE);
Packit ae235b
  g_file_info_set_file_type (info, G_FILE_TYPE_DIRECTORY);
Packit ae235b
	
Packit ae235b
  /*  The attr list should not be empty now */
Packit ae235b
  attr_list = g_file_info_list_attributes (info, NULL);
Packit ae235b
  g_assert (attr_list != NULL);
Packit ae235b
  g_assert (*attr_list != NULL);
Packit ae235b
  g_strfreev (attr_list);
Packit ae235b
Packit ae235b
  test_assigned_values (info);
Packit ae235b
	
Packit ae235b
  /*  Test dups */
Packit ae235b
  info_dup = g_file_info_dup (info);
Packit ae235b
  g_assert (info_dup != NULL);
Packit ae235b
  test_assigned_values (info_dup);
Packit ae235b
  
Packit ae235b
  info_copy = g_file_info_new ();
Packit ae235b
  g_file_info_copy_into (info_dup, info_copy);
Packit ae235b
  g_assert (info_copy != NULL);
Packit ae235b
  test_assigned_values (info_copy);
Packit ae235b
Packit ae235b
  /*  Test remove attribute */
Packit ae235b
  g_assert (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER) == FALSE);
Packit ae235b
  g_file_info_set_attribute_int32 (info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER, 10);
Packit ae235b
  g_assert (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER) == TRUE);
Packit ae235b
Packit ae235b
  g_assert (g_file_info_get_attribute_type (info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER) == G_FILE_ATTRIBUTE_TYPE_INT32);
Packit ae235b
  g_assert (g_file_info_get_attribute_status (info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER) != G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING);
Packit ae235b
Packit ae235b
  g_file_info_remove_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER);
Packit ae235b
  g_assert (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER) == FALSE);
Packit ae235b
  g_assert (g_file_info_get_attribute_type (info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER) == G_FILE_ATTRIBUTE_TYPE_INVALID);
Packit ae235b
Packit ae235b
  matcher = g_file_attribute_matcher_new (G_FILE_ATTRIBUTE_STANDARD_NAME ","
Packit ae235b
                                          G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME);
Packit ae235b
Packit ae235b
  g_assert (g_file_attribute_matcher_matches (matcher, G_FILE_ATTRIBUTE_STANDARD_NAME) == TRUE);
Packit ae235b
  g_assert (g_file_attribute_matcher_matches_only (matcher, G_FILE_ATTRIBUTE_STANDARD_NAME) == FALSE);
Packit ae235b
  g_assert (g_file_attribute_matcher_matches (matcher, G_FILE_ATTRIBUTE_STANDARD_SIZE) == FALSE);
Packit ae235b
Packit ae235b
  g_file_info_set_attribute_mask (info, matcher);
Packit ae235b
  g_file_attribute_matcher_unref (matcher);
Packit ae235b
Packit ae235b
  g_assert (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SIZE) == FALSE);
Packit ae235b
  g_assert (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_NAME) == TRUE);
Packit ae235b
Packit ae235b
  g_object_unref (info);
Packit ae235b
  g_object_unref (info_dup);
Packit ae235b
  g_object_unref (info_copy);
Packit ae235b
}
Packit ae235b
Packit ae235b
#ifdef G_OS_WIN32
Packit ae235b
static void
Packit ae235b
test_internal_enhanced_stdio (void)
Packit ae235b
{
Packit ae235b
  char *p0, *p1, *ps;
Packit ae235b
  gboolean try_sparse;
Packit ae235b
  gchar *tmp_dir_root;
Packit ae235b
  wchar_t *tmp_dir_root_w;
Packit ae235b
  gchar *c;
Packit ae235b
  DWORD fsflags;
Packit ae235b
  FILE *f;
Packit ae235b
  SYSTEMTIME st;
Packit ae235b
  FILETIME ft;
Packit ae235b
  HANDLE h;
Packit ae235b
  GStatBuf statbuf_p0, statbuf_p1, statbuf_ps;
Packit ae235b
  GFile *gf_p0, *gf_p1, *gf_ps;
Packit ae235b
  GFileInfo *fi_p0, *fi_p1, *fi_ps;
Packit ae235b
  guint64 size_p0, alsize_p0, size_ps, alsize_ps;
Packit ae235b
  const gchar *id_p0;
Packit ae235b
  const gchar *id_p1;
Packit ae235b
  volatile guint64 time_p0;
Packit ae235b
  gchar *tmp_dir;
Packit ae235b
  wchar_t *programdata_dir_w;
Packit ae235b
  wchar_t *users_dir_w;
Packit ae235b
  static const GUID folder_id_programdata = 
Packit ae235b
    { 0x62AB5D82, 0xFDC1, 0x4DC3, { 0xA9, 0xDD, 0x07, 0x0D, 0x1D, 0x49, 0x5D, 0x97 } };
Packit ae235b
  static const GUID folder_id_users = 
Packit ae235b
    { 0x0762D272, 0xC50A, 0x4BB0, { 0xA3, 0x82, 0x69, 0x7D, 0xCD, 0x72, 0x9B, 0x80 } };
Packit ae235b
Packit ae235b
  programdata_dir_w = NULL;
Packit ae235b
  SHGetKnownFolderPath (&folder_id_programdata, 0, NULL, &programdata_dir_w);
Packit ae235b
Packit ae235b
  users_dir_w = NULL;
Packit ae235b
  SHGetKnownFolderPath (&folder_id_users, 0, NULL, &users_dir_w);
Packit ae235b
Packit ae235b
  if (programdata_dir_w != NULL && users_dir_w != NULL)
Packit ae235b
    {
Packit ae235b
      gchar *programdata;
Packit ae235b
      gchar *users_dir;
Packit ae235b
      gchar *allusers;
Packit ae235b
      GFile *gf_programdata, *gf_allusers;
Packit ae235b
      GFileInfo *fi_programdata, *fi_allusers, *fi_allusers_target;
Packit ae235b
      GFileType ft_allusers;
Packit ae235b
      GFileType ft_allusers_target;
Packit ae235b
      GFileType ft_programdata;
Packit ae235b
      gboolean allusers_is_symlink;
Packit ae235b
      const gchar *id_allusers;
Packit ae235b
      const gchar *id_allusers_target;
Packit ae235b
      const gchar *id_programdata;
Packit ae235b
      const gchar *allusers_target;
Packit ae235b
Packit ae235b
      /* C:/ProgramData */
Packit ae235b
      programdata = g_utf16_to_utf8 (programdata_dir_w, -1, NULL, NULL, NULL);
Packit ae235b
      g_assert_nonnull (programdata);
Packit ae235b
      /* C:/Users */
Packit ae235b
      users_dir = g_utf16_to_utf8 (users_dir_w, -1, NULL, NULL, NULL);
Packit ae235b
      g_assert_nonnull (users_dir);
Packit ae235b
      /* "C:/Users/All Users" is a known directory symlink
Packit ae235b
       * for "C:/ProgramData".
Packit ae235b
       */
Packit ae235b
      allusers = g_build_filename (users_dir, "All Users", NULL);
Packit ae235b
      g_assert_nonnull (allusers);
Packit ae235b
Packit ae235b
      /* We don't test g_stat() and g_lstat() on these directories,
Packit ae235b
       * because it is pointless - there's no way to tell that these
Packit ae235b
       * functions behave correctly in this case
Packit ae235b
       * (st_ino is useless, so we can't tell apart g_stat() and g_lstat()
Packit ae235b
       *  results; st_mode is also useless as it does not support S_ISLNK;
Packit ae235b
       *  and these directories have no interesting properties other
Packit ae235b
       *  than [not] being symlinks).
Packit ae235b
       */
Packit ae235b
      gf_programdata = g_file_new_for_path (programdata);
Packit ae235b
      gf_allusers = g_file_new_for_path (allusers);
Packit ae235b
Packit ae235b
      fi_programdata = g_file_query_info (gf_programdata,
Packit ae235b
                                          G_FILE_ATTRIBUTE_ID_FILE ","
Packit ae235b
                                          G_FILE_ATTRIBUTE_STANDARD_TYPE,
Packit ae235b
                                          G_FILE_QUERY_INFO_NONE,
Packit ae235b
                                          NULL, NULL);
Packit ae235b
Packit ae235b
      fi_allusers_target = g_file_query_info (gf_allusers,
Packit ae235b
                                              G_FILE_ATTRIBUTE_ID_FILE ","
Packit ae235b
                                              G_FILE_ATTRIBUTE_STANDARD_TYPE,
Packit ae235b
                                              G_FILE_QUERY_INFO_NONE,
Packit ae235b
                                              NULL, NULL);
Packit ae235b
Packit ae235b
      fi_allusers = g_file_query_info (gf_allusers,
Packit ae235b
                                       G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET ","
Packit ae235b
                                       G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK ","
Packit ae235b
                                       G_FILE_ATTRIBUTE_ID_FILE ","
Packit ae235b
                                       G_FILE_ATTRIBUTE_STANDARD_TYPE,
Packit ae235b
                                       G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
Packit ae235b
                                       NULL, NULL);
Packit ae235b
Packit ae235b
      g_assert (g_file_info_has_attribute (fi_programdata, G_FILE_ATTRIBUTE_ID_FILE));
Packit ae235b
      g_assert (g_file_info_has_attribute (fi_programdata, G_FILE_ATTRIBUTE_STANDARD_TYPE));
Packit ae235b
Packit ae235b
      g_assert (g_file_info_has_attribute (fi_allusers_target, G_FILE_ATTRIBUTE_ID_FILE));
Packit ae235b
      g_assert (g_file_info_has_attribute (fi_allusers_target, G_FILE_ATTRIBUTE_STANDARD_TYPE));
Packit ae235b
Packit ae235b
      g_assert (g_file_info_has_attribute (fi_allusers, G_FILE_ATTRIBUTE_ID_FILE));
Packit ae235b
      g_assert (g_file_info_has_attribute (fi_allusers, G_FILE_ATTRIBUTE_STANDARD_TYPE));
Packit ae235b
      g_assert (g_file_info_has_attribute (fi_allusers, G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK));
Packit ae235b
      g_assert (g_file_info_has_attribute (fi_allusers, G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET));
Packit ae235b
Packit ae235b
      ft_allusers = g_file_info_get_file_type (fi_allusers);
Packit ae235b
      ft_allusers_target = g_file_info_get_file_type (fi_allusers_target);
Packit ae235b
      ft_programdata = g_file_info_get_file_type (fi_programdata);
Packit ae235b
Packit ae235b
      g_assert (ft_allusers == G_FILE_TYPE_SYMBOLIC_LINK);
Packit ae235b
      g_assert (ft_allusers_target == G_FILE_TYPE_DIRECTORY);
Packit ae235b
      g_assert (ft_programdata == G_FILE_TYPE_DIRECTORY);
Packit ae235b
Packit ae235b
      allusers_is_symlink = g_file_info_get_attribute_boolean (fi_allusers, G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK);
Packit ae235b
Packit ae235b
      g_assert_true (allusers_is_symlink);
Packit ae235b
Packit ae235b
      id_allusers = g_file_info_get_attribute_string (fi_allusers, G_FILE_ATTRIBUTE_ID_FILE);
Packit ae235b
      id_allusers_target = g_file_info_get_attribute_string (fi_allusers_target, G_FILE_ATTRIBUTE_ID_FILE);
Packit ae235b
      id_programdata = g_file_info_get_attribute_string (fi_programdata, G_FILE_ATTRIBUTE_ID_FILE);
Packit ae235b
Packit ae235b
      g_assert_cmpstr (id_allusers_target, ==, id_programdata);
Packit ae235b
      g_assert_cmpstr (id_allusers, !=, id_programdata);
Packit ae235b
Packit ae235b
      allusers_target = g_file_info_get_symlink_target (fi_allusers);
Packit ae235b
Packit ae235b
      g_assert_true (g_str_has_suffix (allusers_target, "ProgramData"));
Packit ae235b
Packit ae235b
      g_object_unref (fi_allusers);
Packit ae235b
      g_object_unref (fi_allusers_target);
Packit ae235b
      g_object_unref (fi_programdata);
Packit ae235b
      g_object_unref (gf_allusers);
Packit ae235b
      g_object_unref (gf_programdata);
Packit ae235b
Packit ae235b
      g_free (allusers);
Packit ae235b
      g_free (users_dir);
Packit ae235b
      g_free (programdata);
Packit ae235b
    }
Packit ae235b
Packit ae235b
  if (programdata_dir_w)
Packit ae235b
    CoTaskMemFree (programdata_dir_w);
Packit ae235b
Packit ae235b
  if (users_dir_w)
Packit ae235b
    CoTaskMemFree (users_dir_w);
Packit ae235b
Packit ae235b
  tmp_dir = g_dir_make_tmp ("glib_stdio_testXXXXXX", NULL);
Packit ae235b
  g_assert_nonnull (tmp_dir);
Packit ae235b
Packit ae235b
  /* Technically, this isn't necessary - we already assume NTFS, because of
Packit ae235b
   * symlink support, and NTFS also supports sparse files. Still, given
Packit ae235b
   * the amount of unusual I/O APIs called in this test, checking for
Packit ae235b
   * sparse file support of the filesystem where temp directory is
Packit ae235b
   * doesn't seem to be out of place.
Packit ae235b
   */
Packit ae235b
  try_sparse = FALSE;
Packit ae235b
  tmp_dir_root = g_strdup (tmp_dir);
Packit ae235b
  /* We need "C:\\" or "C:/", with a trailing [back]slash */
Packit ae235b
  for (c = tmp_dir_root; c && c[0] && c[1]; c++)
Packit ae235b
    if (c[0] == ':')
Packit ae235b
      {
Packit ae235b
        c[2] = '\0';
Packit ae235b
        break;
Packit ae235b
      }
Packit ae235b
  tmp_dir_root_w = g_utf8_to_utf16 (tmp_dir_root, -1, NULL, NULL, NULL);
Packit ae235b
  g_assert_nonnull (tmp_dir_root_w);
Packit ae235b
  g_free (tmp_dir_root);
Packit ae235b
  g_assert_true (GetVolumeInformationW (tmp_dir_root_w, NULL, 0, NULL, NULL, &fsflags, NULL, 0));
Packit ae235b
  g_free (tmp_dir_root_w);
Packit ae235b
  try_sparse = (fsflags & FILE_SUPPORTS_SPARSE_FILES) == FILE_SUPPORTS_SPARSE_FILES;
Packit ae235b
Packit ae235b
  p0 = g_build_filename (tmp_dir, "zool", NULL);
Packit ae235b
  p1 = g_build_filename (tmp_dir, "looz", NULL);
Packit ae235b
  ps = g_build_filename (tmp_dir, "sparse", NULL);
Packit ae235b
Packit ae235b
  if (try_sparse)
Packit ae235b
    {
Packit ae235b
      FILE_SET_SPARSE_BUFFER ssb;
Packit ae235b
      FILE_ZERO_DATA_INFORMATION zdi;
Packit ae235b
Packit ae235b
      g_remove (ps);
Packit ae235b
Packit ae235b
      f = g_fopen (ps, "wb");
Packit ae235b
      g_assert_nonnull (f);
Packit ae235b
Packit ae235b
      h = (HANDLE) _get_osfhandle (fileno (f));
Packit ae235b
      g_assert (h != INVALID_HANDLE_VALUE);
Packit ae235b
Packit ae235b
      ssb.SetSparse = TRUE;
Packit ae235b
      g_assert_true (DeviceIoControl (h,
Packit ae235b
                     FSCTL_SET_SPARSE,
Packit ae235b
                     &ssb, sizeof (ssb),
Packit ae235b
                     NULL, 0, NULL, NULL));
Packit ae235b
Packit ae235b
      /* Make it a sparse file that starts with 4GBs of zeros */
Packit ae235b
      zdi.FileOffset.QuadPart = 0;
Packit ae235b
      zdi.BeyondFinalZero.QuadPart = 0xFFFFFFFFULL + 1;
Packit ae235b
      g_assert_true (DeviceIoControl (h,
Packit ae235b
                     FSCTL_SET_ZERO_DATA,
Packit ae235b
                     &zdi, sizeof (zdi),
Packit ae235b
                     NULL, 0, NULL, NULL));
Packit ae235b
Packit ae235b
      /* Let's not keep this seemingly 4GB monster around
Packit ae235b
       * longer than we absolutely need to. Do all operations
Packit ae235b
       * without assertions, then remove the file immediately.
Packit ae235b
       */
Packit ae235b
      _fseeki64 (f, 0xFFFFFFFFULL, SEEK_SET);
Packit ae235b
      fprintf (f, "Hello 4GB World!");
Packit ae235b
      fflush (f);
Packit ae235b
      fclose (f);
Packit ae235b
Packit ae235b
      memset (&statbuf_ps, 0, sizeof (statbuf_ps));
Packit ae235b
Packit ae235b
      g_stat (ps, &statbuf_ps);
Packit ae235b
Packit ae235b
      gf_ps = g_file_new_for_path (ps);
Packit ae235b
Packit ae235b
      fi_ps = g_file_query_info (gf_ps,
Packit ae235b
                                 G_FILE_ATTRIBUTE_STANDARD_SIZE ","
Packit ae235b
                                 G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE,
Packit ae235b
                                 G_FILE_QUERY_INFO_NONE,
Packit ae235b
                                 NULL, NULL);
Packit ae235b
Packit ae235b
      g_remove (ps);
Packit ae235b
Packit ae235b
      g_assert (g_file_info_has_attribute (fi_ps, G_FILE_ATTRIBUTE_STANDARD_SIZE));
Packit ae235b
      g_assert (g_file_info_has_attribute (fi_ps, G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE));
Packit ae235b
Packit ae235b
      size_ps = g_file_info_get_attribute_uint64 (fi_ps, G_FILE_ATTRIBUTE_STANDARD_SIZE);
Packit ae235b
      alsize_ps = g_file_info_get_attribute_uint64 (fi_ps, G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE);
Packit ae235b
Packit ae235b
      /* allocated size should small (usually - size of the FS cluster,
Packit ae235b
       * let's assume it's less than 1 gigabyte),
Packit ae235b
       * size should be more than 4 gigabytes,
Packit ae235b
       * st_size should not exceed its 0xFFFFFFFF 32-bit limit,
Packit ae235b
       * and should be nonzero (this also detects a failed g_stat() earlier).
Packit ae235b
       */
Packit ae235b
      g_assert_cmpuint (alsize_ps, <, 0x40000000);
Packit ae235b
      g_assert_cmpuint (size_ps, >, G_GUINT64_CONSTANT (0xFFFFFFFF));
Packit ae235b
      g_assert_cmpuint (statbuf_ps.st_size, >, 0);
Packit ae235b
      g_assert_cmpuint (statbuf_ps.st_size, <=, 0xFFFFFFFF);
Packit ae235b
Packit ae235b
      g_object_unref (fi_ps);
Packit ae235b
      g_object_unref (gf_ps);
Packit ae235b
    }
Packit ae235b
Packit ae235b
  /* Wa-a-ay past 02/07/2106 @ 6:28am (UTC),
Packit ae235b
   * which is the date corresponding to 0xFFFFFFFF + 1.
Packit ae235b
   * This is easier to check than Y2038 (0x80000000 + 1),
Packit ae235b
   * since there's no need to worry about signedness this way.
Packit ae235b
   */
Packit ae235b
  st.wYear = 2106;
Packit ae235b
  st.wMonth = 2;
Packit ae235b
  st.wDay = 9;
Packit ae235b
  st.wHour = 0;
Packit ae235b
  st.wMinute = 0;
Packit ae235b
  st.wSecond = 0;
Packit ae235b
  st.wMilliseconds = 0;
Packit ae235b
Packit ae235b
  g_assert_true (SystemTimeToFileTime (&st, &ft));
Packit ae235b
Packit ae235b
  f = g_fopen (p0, "w");
Packit ae235b
  g_assert_nonnull (f);
Packit ae235b
Packit ae235b
  h = (HANDLE) _get_osfhandle (fileno (f));
Packit ae235b
  g_assert (h != INVALID_HANDLE_VALUE);
Packit ae235b
Packit ae235b
  fprintf (f, "1");
Packit ae235b
  fflush (f);
Packit ae235b
Packit ae235b
  g_assert_true (SetFileTime (h, &ft, &ft, &ft));
Packit ae235b
Packit ae235b
  fclose (f);
Packit ae235b
Packit ae235b
  f = g_fopen (p1, "w");
Packit ae235b
  g_assert_nonnull (f);
Packit ae235b
Packit ae235b
  fclose (f);
Packit ae235b
Packit ae235b
  memset (&statbuf_p0, 0, sizeof (statbuf_p0));
Packit ae235b
  memset (&statbuf_p1, 0, sizeof (statbuf_p1));
Packit ae235b
Packit ae235b
  g_assert_cmpint (g_stat (p0, &statbuf_p0), ==, 0);
Packit ae235b
  g_assert_cmpint (g_stat (p1, &statbuf_p1), ==, 0);
Packit ae235b
Packit ae235b
  gf_p0 = g_file_new_for_path (p0);
Packit ae235b
  gf_p1 = g_file_new_for_path (p1);
Packit ae235b
Packit ae235b
  fi_p0 = g_file_query_info (gf_p0,
Packit ae235b
                             G_FILE_ATTRIBUTE_STANDARD_SIZE ","
Packit ae235b
                             G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE ","
Packit ae235b
                             G_FILE_ATTRIBUTE_ID_FILE ","
Packit ae235b
                             G_FILE_ATTRIBUTE_TIME_MODIFIED,
Packit ae235b
                             G_FILE_QUERY_INFO_NONE,
Packit ae235b
                             NULL, NULL);
Packit ae235b
Packit ae235b
  fi_p1 = g_file_query_info (gf_p1,
Packit ae235b
                             G_FILE_ATTRIBUTE_STANDARD_SIZE ","
Packit ae235b
                             G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE ","
Packit ae235b
                             G_FILE_ATTRIBUTE_ID_FILE ","
Packit ae235b
                             G_FILE_ATTRIBUTE_TIME_MODIFIED,
Packit ae235b
                             G_FILE_QUERY_INFO_NONE,
Packit ae235b
                             NULL, NULL);
Packit ae235b
Packit ae235b
  g_assert (g_file_info_has_attribute (fi_p0, G_FILE_ATTRIBUTE_STANDARD_SIZE));
Packit ae235b
  g_assert (g_file_info_has_attribute (fi_p0, G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE));
Packit ae235b
  g_assert (g_file_info_has_attribute (fi_p0, G_FILE_ATTRIBUTE_ID_FILE));
Packit ae235b
  g_assert (g_file_info_has_attribute (fi_p0, G_FILE_ATTRIBUTE_TIME_MODIFIED));
Packit ae235b
Packit ae235b
  g_assert (g_file_info_has_attribute (fi_p1, G_FILE_ATTRIBUTE_STANDARD_SIZE));
Packit ae235b
  g_assert (g_file_info_has_attribute (fi_p1, G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE));
Packit ae235b
  g_assert (g_file_info_has_attribute (fi_p1, G_FILE_ATTRIBUTE_ID_FILE));
Packit ae235b
  g_assert (g_file_info_has_attribute (fi_p1, G_FILE_ATTRIBUTE_TIME_MODIFIED));
Packit ae235b
Packit ae235b
  size_p0 = g_file_info_get_attribute_uint64 (fi_p0, G_FILE_ATTRIBUTE_STANDARD_SIZE);
Packit ae235b
  alsize_p0 = g_file_info_get_attribute_uint64 (fi_p0, G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE);
Packit ae235b
Packit ae235b
  /* size should be 1, allocated size should be something else
Packit ae235b
   * (could be 0 or the size of the FS cluster, but never 1).
Packit ae235b
   */
Packit ae235b
  g_assert_cmpuint (size_p0, ==, statbuf_p0.st_size);
Packit ae235b
  g_assert_cmpuint (size_p0, ==, 1);
Packit ae235b
  g_assert_cmpuint (alsize_p0, !=, size_p0);
Packit ae235b
Packit ae235b
  id_p0 = g_file_info_get_attribute_string (fi_p0, G_FILE_ATTRIBUTE_ID_FILE);
Packit ae235b
  id_p1 = g_file_info_get_attribute_string (fi_p1, G_FILE_ATTRIBUTE_ID_FILE);
Packit ae235b
Packit ae235b
  /* st_ino from W32 stat() is useless for file identification.
Packit ae235b
   * It will be either 0, or it will be the same for both files.
Packit ae235b
   */
Packit ae235b
  g_assert (statbuf_p0.st_ino == statbuf_p1.st_ino);
Packit ae235b
  g_assert_cmpstr (id_p0, !=, id_p1);
Packit ae235b
Packit ae235b
  time_p0 = g_file_info_get_attribute_uint64 (fi_p0, G_FILE_ATTRIBUTE_TIME_MODIFIED);
Packit ae235b
Packit ae235b
  /* Check that GFileInfo doesn't suffer from Y2106 problem.
Packit ae235b
   * Don't check stat(), as its contents may vary depending on
Packit ae235b
   * the host platform architecture
Packit ae235b
   * (time fields are 32-bit on 32-bit Windows,
Packit ae235b
   *  and 64-bit on 64-bit Windows, usually),
Packit ae235b
   * so it *can* pass this test in some cases.
Packit ae235b
   */
Packit ae235b
  g_assert (time_p0 > G_GUINT64_CONSTANT (0xFFFFFFFF));
Packit ae235b
Packit ae235b
  g_object_unref (fi_p0);
Packit ae235b
  g_object_unref (fi_p1);
Packit ae235b
  g_object_unref (gf_p0);
Packit ae235b
  g_object_unref (gf_p1);
Packit ae235b
  g_remove (p0);
Packit ae235b
  g_remove (p1);
Packit ae235b
  g_free (p0);
Packit ae235b
  g_free (p1);
Packit ae235b
  g_rmdir (tmp_dir);
Packit ae235b
}
Packit ae235b
#endif
Packit ae235b
Packit ae235b
Packit ae235b
int
Packit ae235b
main (int   argc,
Packit ae235b
      char *argv[])
Packit ae235b
{
Packit ae235b
  g_test_init (&argc, &argv, NULL);
Packit ae235b
Packit ae235b
  g_test_add_func ("/g-file-info/test_g_file_info", test_g_file_info);
Packit ae235b
#ifdef G_OS_WIN32
Packit ae235b
  g_test_add_func ("/g-file-info/internal-enhanced-stdio", test_internal_enhanced_stdio);
Packit ae235b
#endif
Packit ae235b
  
Packit ae235b
  return g_test_run();
Packit ae235b
}