Example #1
0
static bool
preallocate_file_sparse (tr_sys_file_t fd, uint64_t length, tr_error ** error)
{
  tr_error * my_error = NULL;

  if (length == 0)
    return true;

  if (tr_sys_file_preallocate (fd, length, TR_SYS_FILE_PREALLOC_SPARSE, &my_error))
    return true;

  dbgmsg ("Preallocating (sparse, normal) failed (%d): %s", my_error->code, my_error->message);

  if (!TR_ERROR_IS_ENOSPC (my_error->code))
    {
      const char zero = '\0';

      tr_error_clear (&my_error);

      /* fallback: the old-style seek-and-write */
      if (tr_sys_file_write_at (fd, &zero, 1, length - 1, NULL, &my_error) &&
          tr_sys_file_truncate (fd, length, &my_error))
        return true;

      dbgmsg ("Preallocating (sparse, fallback) failed (%d): %s", my_error->code, my_error->message);
    }

  tr_error_propagate (error, &my_error);
  return false;
}
Example #2
0
static int
test_error_set (void)
{
  tr_error * err = NULL;

  tr_error_prefix (&err, "error: ");
  check (err == NULL);

  tr_error_set (&err, 1, "error: %s (%d)", "oops", 2);
  check (err != NULL);
  check_int_eq (1, err->code);
  check_streq ("error: oops (2)", err->message);
  tr_error_clear (&err);
  check (err == NULL);

  tr_error_set_literal (&err, 2, "oops");
  check (err != NULL);
  check_int_eq (2, err->code);
  check_streq ("oops", err->message);

  tr_error_prefix (&err, "error: ");
  check (err != NULL);
  check_int_eq (2, err->code);
  check_streq ("error: oops", err->message);

  tr_error_free (err);

  return 0;
}
Example #3
0
static int
test_path_xname (const struct xname_test_data * data,
                 size_t                         data_size,
                 char *                      (* func) (const char *, tr_error **))
{
  for (size_t i = 0; i < data_size; ++i)
    {
      tr_error * err = NULL;
      char * name = func (data[i].input, &err);

      if (data[i].output != NULL)
        {
          check (name != NULL);
          check (err == NULL);
          check_streq (data[i].output, name);
          tr_free (name);
        }
      else
        {
          check (name == NULL);
          check (err != NULL);
          tr_error_clear (&err);
        }
    }

  return 0;
}
Example #4
0
static void
create_temp_path (char      * path_template,
                  void     (* callback) (const char * path, void * param, tr_error ** error),
                  void      * callback_param,
                  tr_error ** error)
{
  char * path;
  size_t path_size;
  int attempt;
  tr_error * my_error = NULL;

  assert (path_template != NULL);
  assert (callback != NULL);

  path = tr_strdup (path_template);
  path_size = strlen (path);

  assert (path_size > 0);

  for (attempt = 0; attempt < 100; ++attempt)
    {
      size_t i = path_size;

      while (i > 0 && path_template[i - 1] == 'X')
        {
          const int c = tr_rand_int (26 + 26 + 10);
          path[i - 1] = c < 26 ? c + 'A' : (c < 26 + 26 ? (c - 26) + 'a' : (c - 26 - 26) + '0');
          --i;
        }

      assert (path_size >= i + 6);

      tr_error_clear (&my_error);

      (*callback) (path, callback_param, &my_error);

      if (my_error == NULL)
        break;
    }

  if (my_error != NULL)
    tr_error_propagate(error, &my_error);
  else
    memcpy (path_template, path, path_size);

  tr_free (path);
}
Example #5
0
bool
gtr_file_trash_or_remove (const char * filename, tr_error ** error)
{
  GFile * file;
  gboolean trashed = FALSE;
  bool result = true;

  g_return_val_if_fail (filename && *filename, false);

  file = g_file_new_for_path (filename);

  if (gtr_pref_flag_get (TR_KEY_trash_can_enabled))
    {
      GError * err = NULL;
      trashed = g_file_trash (file, NULL, &err);
      if (err)
        {
          g_message ("Unable to trash file \"%s\": %s", filename, err->message);
          tr_error_set_literal (error, err->code, err->message);
          g_clear_error (&err);
        }
    }

  if (!trashed)
    {
      GError * err = NULL;
      g_file_delete (file, NULL, &err);
      if (err)
        {
          g_message ("Unable to delete file \"%s\": %s", filename, err->message);
          tr_error_clear (error);
          tr_error_set_literal (error, err->code, err->message);
          g_clear_error (&err);
          result = false;
        }
    }

  g_object_unref (G_OBJECT (file));
  return result;
}
Example #6
0
static bool
preallocate_file_full (tr_sys_file_t fd, uint64_t length, tr_error ** error)
{
  tr_error * my_error = NULL;

  if (length == 0)
    return true;

  if (tr_sys_file_preallocate (fd, length, 0, &my_error))
    return true;

  dbgmsg ("Preallocating (full, normal) failed (%d): %s", my_error->code, my_error->message);

  if (!TR_ERROR_IS_ENOSPC (my_error->code))
    {
      uint8_t buf[4096];
      bool success = true;

      memset (buf, 0, sizeof (buf));
      tr_error_clear (&my_error);

      /* fallback: the old-fashioned way */
      while (success && length > 0)
        {
          const uint64_t thisPass = MIN (length, sizeof (buf));
          uint64_t bytes_written;
          success = tr_sys_file_write (fd, buf, thisPass, &bytes_written, &my_error);
          length -= bytes_written;
        }

      if (success)
        return true;

      dbgmsg ("Preallocating (full, fallback) failed (%d): %s", my_error->code, my_error->message);
    }

  tr_error_propagate (error, &my_error);
  return false;
}
Example #7
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;
}