Example #1
0
static int
test_error_propagate (void)
{
  tr_error * err = NULL;
  tr_error * err2 = NULL;

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

  tr_error_propagate (&err2, &err);
  check (err2 != NULL);
  check_int_eq (1, err2->code);
  check_streq ("oops", err2->message);
  check (err == NULL);

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

  tr_error_propagate (NULL, &err);
  check (err == NULL);

  tr_error_free (err2);

  return 0;
}
Example #2
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 #3
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;
}
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
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 #6
0
static bool
create_path (const char  * path_in,
             int           permissions,
             tr_error   ** error)
{
  char * p;
  char * pp;
  bool done;
  int tmperr;
  int rv;
  struct stat sb;
  char * path;

  /* make a temporary copy of path */
  path = tr_strdup (path_in);

  /* walk past the root */
  p = path;
  while (*p == TR_PATH_DELIMITER)
    ++p;

  pp = p;
  done = false;
  while ((p = strchr (pp, TR_PATH_DELIMITER)) || (p = strchr (pp, '\0')))
    {
      if (!*p)
        done = true;
      else
        *p = '\0';

      tmperr = errno;
      rv = stat (path, &sb);
      errno = tmperr;
      if (rv)
        {
          tr_error * my_error = NULL;

          /* Folder doesn't exist yet */
          if (!tr_sys_dir_create (path, 0, permissions, &my_error))
            {
              tr_logAddError (_ ("Couldn't create \"%1$s\": %2$s"), path, my_error->message);
              tr_free (path);
              tr_error_propagate (error, &my_error);
              return false;
            }
        }
      else if ((sb.st_mode & S_IFMT) != S_IFDIR)
        {
          /* Node exists but isn't a folder */
          char * const buf = tr_strdup_printf (_ ("File \"%s\" is in the way"), path);
          tr_logAddError (_ ("Couldn't create \"%1$s\": %2$s"), path_in, buf);
          tr_free (buf);
          tr_free (path);
          set_system_error (error, ENOTDIR);
          return false;
        }

      if (done)
        break;

      *p = TR_PATH_DELIMITER;
      p++;
      pp = p;
    }

  tr_free (path);
  return true;
}