Fix tr_moveFile error reporting

Remove unused `renamed` argument.
Use tr_error instead of errno to report errors to support Win32 file
wrappers which do not map Windows error codes to POSIX ones.
Return bool instead of int (0/-1).

Uncomment tr_error_prefix and tr_error_propagate_prefixed functions.
This commit is contained in:
Mike Gelfand
2014-12-10 18:37:58 +00:00
parent a3fdd5f029
commit 4fe156a255
6 changed files with 63 additions and 47 deletions

View File

@@ -16,12 +16,16 @@
#define TR_ERROR_IS_ENOSPC(code) ((code) == ERROR_DISK_FULL) #define TR_ERROR_IS_ENOSPC(code) ((code) == ERROR_DISK_FULL)
#define TR_ERROR_EINVAL ERROR_INVALID_PARAMETER
#else /* _WIN32 */ #else /* _WIN32 */
#include <errno.h> #include <errno.h>
#define TR_ERROR_IS_ENOSPC(code) ((code) == ENOSPC) #define TR_ERROR_IS_ENOSPC(code) ((code) == ENOSPC)
#define TR_ERROR_EINVAL EINVAL
#endif /* _WIN32 */ #endif /* _WIN32 */
#endif /* TR_ERROR_TYPES_H */ #endif /* TR_ERROR_TYPES_H */

View File

@@ -135,8 +135,6 @@ tr_error_clear (tr_error ** error)
*error = NULL; *error = NULL;
} }
#if 0
static void static void
error_prefix_valist (tr_error ** error, error_prefix_valist (tr_error ** error,
const char * prefix_format, const char * prefix_format,
@@ -194,5 +192,3 @@ tr_error_propagate_prefixed (tr_error ** new_error,
error_prefix_valist (new_error, prefix_format, args); error_prefix_valist (new_error, prefix_format, args);
va_end (args); va_end (args);
} }
#endif /* 0 */

View File

@@ -134,8 +134,6 @@ void tr_error_propagate (tr_error ** new_error,
*/ */
void tr_error_clear (tr_error ** error); void tr_error_clear (tr_error ** error);
#if 0
/** /**
* @brief Prefix message of exising error object. * @brief Prefix message of exising error object.
* *
@@ -167,8 +165,6 @@ void tr_error_propagate_prefixed (tr_error ** new_error,
const char * prefix_format, const char * prefix_format,
...) TR_GNUC_PRINTF (3, 4); ...) TR_GNUC_PRINTF (3, 4);
#endif /* 0 */
/** @} */ /** @} */
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -3094,14 +3094,15 @@ setLocation (void * vdata)
if (do_move && !tr_sys_path_is_same (oldpath, newpath, NULL)) if (do_move && !tr_sys_path_is_same (oldpath, newpath, NULL))
{ {
bool renamed = false; tr_error * error = NULL;
errno = 0;
tr_logAddTorInfo (tor, "moving \"%s\" to \"%s\"", oldpath, newpath); tr_logAddTorInfo (tor, "moving \"%s\" to \"%s\"", oldpath, newpath);
if (tr_moveFile (oldpath, newpath, &renamed)) if (!tr_moveFile (oldpath, newpath, &error))
{ {
err = true; err = true;
tr_logAddTorErr (tor, "error moving \"%s\" to \"%s\": %s", tr_logAddTorErr (tor, "error moving \"%s\" to \"%s\": %s",
oldpath, newpath, tr_strerror (errno)); oldpath, newpath, error->message);
tr_error_free (error);
} }
} }

View File

@@ -46,6 +46,7 @@
#include "transmission.h" #include "transmission.h"
#include "error.h" #include "error.h"
#include "error-types.h"
#include "file.h" #include "file.h"
#include "ConvertUTF.h" #include "ConvertUTF.h"
#include "list.h" #include "list.h"
@@ -1410,67 +1411,72 @@ tr_strratio (char * buf, size_t buflen, double ratio, const char * infinity)
**** ****
***/ ***/
int bool
tr_moveFile (const char * oldpath, const char * newpath, bool * renamed) tr_moveFile (const char * oldpath, const char * newpath, tr_error ** error)
{ {
tr_sys_file_t in; tr_sys_file_t in;
tr_sys_file_t out; tr_sys_file_t out;
char * buf; char * buf = NULL;
tr_sys_path_info info; tr_sys_path_info info;
uint64_t bytesLeft; uint64_t bytesLeft;
const size_t buflen = 1024 * 128; /* 128 KiB buffer */ const size_t buflen = 1024 * 128; /* 128 KiB buffer */
tr_error * error = NULL;
/* make sure the old file exists */ /* make sure the old file exists */
if (!tr_sys_path_get_info (oldpath, 0, &info, &error)) if (!tr_sys_path_get_info (oldpath, 0, &info, error))
{ {
const int err = error->code; tr_error_prefix (error, "Unable to get information on old file: ");
tr_error_free (error); return false;
errno = err;
return -1;
} }
if (info.type != TR_SYS_PATH_IS_FILE) if (info.type != TR_SYS_PATH_IS_FILE)
{ {
errno = ENOENT; tr_error_set_literal (error, TR_ERROR_EINVAL, "Old path does not point to a file.");
return -1; return false;
} }
bytesLeft = info.size;
/* make sure the target directory exists */ /* make sure the target directory exists */
{ {
char * newdir = tr_sys_path_dirname (newpath, NULL); char * newdir = tr_sys_path_dirname (newpath, NULL);
const bool i = tr_sys_dir_create (newdir, TR_SYS_DIR_CREATE_PARENTS, 0777, &error); const bool i = tr_sys_dir_create (newdir, TR_SYS_DIR_CREATE_PARENTS, 0777, error);
tr_free (newdir); tr_free (newdir);
if (!i) if (!i)
{ {
const int err = error->code; tr_error_prefix (error, "Unable to create directory for new file: ");
tr_error_free (error); return false;
errno = err;
return -1;
} }
} }
/* they might be on the same filesystem... */ /* they might be on the same filesystem... */
{ if (tr_sys_path_rename (oldpath, newpath, NULL))
const bool i = tr_sys_path_rename (oldpath, newpath, NULL); return true;
if (renamed != NULL)
*renamed = i;
if (i)
return 0;
}
/* copy the file */ /* copy the file */
in = tr_sys_file_open (oldpath, TR_SYS_FILE_READ | TR_SYS_FILE_SEQUENTIAL, 0, NULL); in = tr_sys_file_open (oldpath, TR_SYS_FILE_READ | TR_SYS_FILE_SEQUENTIAL, 0, error);
out = tr_sys_file_open (newpath, TR_SYS_FILE_WRITE | TR_SYS_FILE_CREATE | TR_SYS_FILE_TRUNCATE, 0666, NULL); if (in == TR_BAD_SYS_FILE)
{
tr_error_prefix (error, "Unable to open old file: ");
return false;
}
out = tr_sys_file_open (newpath, TR_SYS_FILE_WRITE | TR_SYS_FILE_CREATE | TR_SYS_FILE_TRUNCATE, 0666, error);
if (out == TR_BAD_SYS_FILE)
{
tr_error_prefix (error, "Unable to open new file: ");
tr_sys_file_close (in, NULL);
return false;
}
buf = tr_valloc (buflen); buf = tr_valloc (buflen);
bytesLeft = info.size;
while (bytesLeft > 0) while (bytesLeft > 0)
{ {
const uint64_t bytesThisPass = MIN (bytesLeft, buflen); const uint64_t bytesThisPass = MIN (bytesLeft, buflen);
uint64_t numRead, bytesWritten; uint64_t numRead, bytesWritten;
if (!tr_sys_file_read (in, buf, bytesThisPass, &numRead, NULL)) if (!tr_sys_file_read (in, buf, bytesThisPass, &numRead, error))
break; break;
if (!tr_sys_file_write (out, buf, numRead, &bytesWritten, NULL)) if (!tr_sys_file_write (out, buf, numRead, &bytesWritten, error))
break; break;
assert (numRead == bytesWritten);
assert (bytesWritten <= bytesLeft);
bytesLeft -= bytesWritten; bytesLeft -= bytesWritten;
} }
@@ -1478,11 +1484,23 @@ tr_moveFile (const char * oldpath, const char * newpath, bool * renamed)
tr_free (buf); tr_free (buf);
tr_sys_file_close (out, NULL); tr_sys_file_close (out, NULL);
tr_sys_file_close (in, NULL); tr_sys_file_close (in, NULL);
if (bytesLeft != 0)
return -1;
tr_sys_path_remove (oldpath, NULL); if (bytesLeft != 0)
return 0; {
tr_error_prefix (error, "Unable to read/write: ");
return false;
}
{
tr_error * my_error = NULL;
if (!tr_sys_path_remove (oldpath, &my_error))
{
tr_logAddError ("Unable to remove file at old path: %s", my_error->message);
tr_error_free (my_error);
}
}
return true;
} }
/*** /***

View File

@@ -15,6 +15,7 @@
#include <stddef.h> /* size_t */ #include <stddef.h> /* size_t */
#include <time.h> /* time_t */ #include <time.h> /* time_t */
#include "error.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@@ -396,10 +397,10 @@ int tr_gettimeofday (struct timeval * tv);
/** /**
* @brief move a file * @brief move a file
* @return 0 on success; otherwise, return -1 and set errno * @return `True` on success, `false` otherwise (with `error` set accordingly).
*/ */
int tr_moveFile (const char * oldpath, const char * newpath, bool tr_moveFile (const char * oldpath, const char * newpath,
bool * renamed) TR_GNUC_NONNULL (1,2); tr_error ** error) TR_GNUC_NONNULL (1,2);
/** @brief convenience function to remove an item from an array */ /** @brief convenience function to remove an item from an array */
void tr_removeElementFromArray (void * array, void tr_removeElementFromArray (void * array,