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_EINVAL ERROR_INVALID_PARAMETER
#else /* _WIN32 */
#include <errno.h>
#define TR_ERROR_IS_ENOSPC(code) ((code) == ENOSPC)
#define TR_ERROR_EINVAL EINVAL
#endif /* _WIN32 */
#endif /* TR_ERROR_TYPES_H */

View File

@@ -135,8 +135,6 @@ tr_error_clear (tr_error ** error)
*error = NULL;
}
#if 0
static void
error_prefix_valist (tr_error ** error,
const char * prefix_format,
@@ -194,5 +192,3 @@ tr_error_propagate_prefixed (tr_error ** new_error,
error_prefix_valist (new_error, prefix_format, 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);
#if 0
/**
* @brief Prefix message of exising error object.
*
@@ -167,8 +165,6 @@ void tr_error_propagate_prefixed (tr_error ** new_error,
const char * prefix_format,
...) TR_GNUC_PRINTF (3, 4);
#endif /* 0 */
/** @} */
#ifdef __cplusplus

View File

@@ -3094,14 +3094,15 @@ setLocation (void * vdata)
if (do_move && !tr_sys_path_is_same (oldpath, newpath, NULL))
{
bool renamed = false;
errno = 0;
tr_error * error = NULL;
tr_logAddTorInfo (tor, "moving \"%s\" to \"%s\"", oldpath, newpath);
if (tr_moveFile (oldpath, newpath, &renamed))
if (!tr_moveFile (oldpath, newpath, &error))
{
err = true;
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 "error.h"
#include "error-types.h"
#include "file.h"
#include "ConvertUTF.h"
#include "list.h"
@@ -1410,67 +1411,72 @@ tr_strratio (char * buf, size_t buflen, double ratio, const char * infinity)
****
***/
int
tr_moveFile (const char * oldpath, const char * newpath, bool * renamed)
bool
tr_moveFile (const char * oldpath, const char * newpath, tr_error ** error)
{
tr_sys_file_t in;
tr_sys_file_t out;
char * buf;
char * buf = NULL;
tr_sys_path_info info;
uint64_t bytesLeft;
const size_t buflen = 1024 * 128; /* 128 KiB buffer */
tr_error * error = NULL;
/* 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_free (error);
errno = err;
return -1;
tr_error_prefix (error, "Unable to get information on old file: ");
return false;
}
if (info.type != TR_SYS_PATH_IS_FILE)
{
errno = ENOENT;
return -1;
tr_error_set_literal (error, TR_ERROR_EINVAL, "Old path does not point to a file.");
return false;
}
bytesLeft = info.size;
/* make sure the target directory exists */
{
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);
if (!i)
{
const int err = error->code;
tr_error_free (error);
errno = err;
return -1;
tr_error_prefix (error, "Unable to create directory for new file: ");
return false;
}
}
/* they might be on the same filesystem... */
{
const bool i = tr_sys_path_rename (oldpath, newpath, NULL);
if (renamed != NULL)
*renamed = i;
if (i)
return 0;
}
if (tr_sys_path_rename (oldpath, newpath, NULL))
return true;
/* copy the file */
in = tr_sys_file_open (oldpath, TR_SYS_FILE_READ | TR_SYS_FILE_SEQUENTIAL, 0, NULL);
out = tr_sys_file_open (newpath, TR_SYS_FILE_WRITE | TR_SYS_FILE_CREATE | TR_SYS_FILE_TRUNCATE, 0666, NULL);
in = tr_sys_file_open (oldpath, TR_SYS_FILE_READ | TR_SYS_FILE_SEQUENTIAL, 0, error);
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);
bytesLeft = info.size;
while (bytesLeft > 0)
{
const uint64_t bytesThisPass = MIN (bytesLeft, buflen);
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;
if (!tr_sys_file_write (out, buf, numRead, &bytesWritten, NULL))
if (!tr_sys_file_write (out, buf, numRead, &bytesWritten, error))
break;
assert (numRead == bytesWritten);
assert (bytesWritten <= bytesLeft);
bytesLeft -= bytesWritten;
}
@@ -1478,11 +1484,23 @@ tr_moveFile (const char * oldpath, const char * newpath, bool * renamed)
tr_free (buf);
tr_sys_file_close (out, NULL);
tr_sys_file_close (in, NULL);
if (bytesLeft != 0)
return -1;
tr_sys_path_remove (oldpath, NULL);
return 0;
if (bytesLeft != 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 <time.h> /* time_t */
#include "error.h"
#ifdef __cplusplus
extern "C" {
@@ -396,10 +397,10 @@ int tr_gettimeofday (struct timeval * tv);
/**
* @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 * renamed) TR_GNUC_NONNULL (1,2);
bool tr_moveFile (const char * oldpath, const char * newpath,
tr_error ** error) TR_GNUC_NONNULL (1,2);
/** @brief convenience function to remove an item from an array */
void tr_removeElementFromArray (void * array,