Beispiel #1
0
bool tr_sys_path_get_info(char const* path, int flags, tr_sys_path_info* info, tr_error** error)
{
    TR_ASSERT(path != NULL);
    TR_ASSERT(info != NULL);

    bool ret = false;
    wchar_t* wide_path = path_to_native_path(path);

    if ((flags & TR_SYS_PATH_NO_FOLLOW) == 0)
    {
        HANDLE handle = INVALID_HANDLE_VALUE;

        if (wide_path != NULL)
        {
            handle = CreateFileW(wide_path, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
        }

        if (handle != INVALID_HANDLE_VALUE)
        {
            tr_error* my_error = NULL;
            ret = tr_sys_file_get_info(handle, info, &my_error);

            if (!ret)
            {
                tr_error_propagate(error, &my_error);
            }

            CloseHandle(handle);
        }
        else
        {
            set_system_error(error, GetLastError());
        }
    }
    else
    {
        WIN32_FILE_ATTRIBUTE_DATA attributes;

        if (wide_path != NULL)
        {
            ret = GetFileAttributesExW(wide_path, GetFileExInfoStandard, &attributes);
        }

        if (ret)
        {
            stat_to_sys_path_info(attributes.dwFileAttributes, attributes.nFileSizeLow, attributes.nFileSizeHigh,
                &attributes.ftLastWriteTime, info);
        }
        else
        {
            set_system_error(error, GetLastError());
        }
    }

    tr_free(wide_path);

    return ret;
}
Beispiel #2
0
static int
test_get_info (void)
{
  char * const test_dir = create_test_dir (__FUNCTION__);
  tr_sys_path_info info;
  tr_sys_file_t fd;
  tr_error * err = NULL;
  char * path1, * path2;
  time_t t;

  path1 = tr_buildPath (test_dir, "a", NULL);
  path2 = tr_buildPath (test_dir, "b", NULL);

  /* Can't get info of non-existent file/directory */
  check (!tr_sys_path_get_info (path1, 0, &info, &err));
  check (err != NULL);
  tr_error_clear (&err);

  t = time (NULL);
  libtest_create_file_with_string_contents (path1, "test");

  /* Good file info */
  clear_path_info (&info);
  check (tr_sys_path_get_info (path1, 0, &info, &err));
  check (err == NULL);
  check_int_eq (TR_SYS_PATH_IS_FILE, info.type);
  check_int_eq (4, info.size);
  check (info.last_modified_at >= t && info.last_modified_at <= time (NULL));

  /* Good file info (by handle) */
  fd = tr_sys_file_open (path1, TR_SYS_FILE_READ, 0, NULL);
  clear_path_info (&info);
  check (tr_sys_file_get_info (fd, &info, &err));
  check (err == NULL);
  check_int_eq (TR_SYS_PATH_IS_FILE, info.type);
  check_int_eq (4, info.size);
  check (info.last_modified_at >= t && info.last_modified_at <= time (NULL));
  tr_sys_file_close (fd, NULL);

  tr_sys_path_remove (path1, NULL);

  /* Good directory info */
  t = time (NULL);
  tr_sys_dir_create (path1, 0, 0777, NULL);
  clear_path_info (&info);
  check (tr_sys_path_get_info (path1, 0, &info, &err));
  check (err == NULL);
  check_int_eq (TR_SYS_PATH_IS_DIRECTORY, info.type);
  check (info.size != (uint64_t) -1);
  check (info.last_modified_at >= t && info.last_modified_at <= time (NULL));
  tr_sys_path_remove (path1, NULL);

  if (create_symlink (path1, path2, false))
    {
      /* Can't get info of non-existent file/directory */
      check (!tr_sys_path_get_info (path1, 0, &info, &err));
      check (err != NULL);
      tr_error_clear (&err);

      t = time (NULL);
      libtest_create_file_with_string_contents (path2, "test");

      /* Good file info */
      clear_path_info (&info);
      check (tr_sys_path_get_info (path1, 0, &info, &err));
      check (err == NULL);
      check_int_eq (TR_SYS_PATH_IS_FILE, info.type);
      check_int_eq (4, info.size);
      check (info.last_modified_at >= t && info.last_modified_at <= time (NULL));

      /* Good file info (by handle) */
      fd = tr_sys_file_open (path1, TR_SYS_FILE_READ, 0, NULL);
      clear_path_info (&info);
      check (tr_sys_file_get_info (fd, &info, &err));
      check (err == NULL);
      check_int_eq (TR_SYS_PATH_IS_FILE, info.type);
      check_int_eq (4, info.size);
      check (info.last_modified_at >= t && info.last_modified_at <= time (NULL));
      tr_sys_file_close (fd, NULL);

      tr_sys_path_remove (path2, NULL);

      /* Good directory info */
      t = time (NULL);
      tr_sys_dir_create (path2, 0, 0777, NULL);
      clear_path_info (&info);
      check (tr_sys_path_get_info (path1, 0, &info, &err));
      check (err == NULL);
      check_int_eq (TR_SYS_PATH_IS_DIRECTORY, info.type);
      check (info.size != (uint64_t) -1);
      check (info.last_modified_at >= t && info.last_modified_at <= time (NULL));

      tr_sys_path_remove (path2, NULL);
      tr_sys_path_remove (path1, NULL);
    }
  else
    {
      fprintf (stderr, "WARNING: [%s] unable to run symlink tests\n", __FUNCTION__);
    }

  tr_free (path2);
  tr_free (path1);

  tr_free (test_dir);
  return 0;
}