[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: copy_file_preserving variant that doesn't exit on error?
From: |
Reuben Thomas |
Subject: |
Re: copy_file_preserving variant that doesn't exit on error? |
Date: |
Tue, 2 Aug 2011 02:16:42 +0100 |
On 24 July 2011 21:05, Reuben Thomas <address@hidden> wrote:
> I just came across the copy-file module, which does exactly what I
> want (it is even geared to making backup files), but (unfortunately
> for use in an interactive program) exits on error.
Just to move this along a bit, I attach a patch which changes
copy_file_preserving to return error codes instead of calling error.
Obviously, I don't expect this to be applied to gnulib, but as per my
original message, I'd like to know if a version of
copy_file_preserving along these lines is thought to be a good idea
for interactive use (I need it for creating backup files in GNU Zile),
and how I might produce a patch that provides an error-returning
variant without duplicating all the code.
diff --git a/lib/copy-file.h b/lib/copy-file.h
index cb8b1f7..b0c29e0 100644
--- a/lib/copy-file.h
+++ b/lib/copy-file.h
@@ -26,7 +26,7 @@ extern "C" {
Modification times, owner, group and access permissions are preserved as
far as possible.
Exit upon failure. */
-extern void copy_file_preserving (const char *src_filename, const
char *dest_filename);
+extern int copy_file_preserving (const char *src_filename, const char
*dest_filename);
#ifdef __cplusplus
diff --git a/lib/copy-file.c b/lib/copy-file.c
index f9cd9c0..b5b8447 100644
--- a/lib/copy-file.c
+++ b/lib/copy-file.c
@@ -53,7 +53,7 @@
enum { IO_SIZE = 32 * 1024 };
-void
+int
copy_file_preserving (const char *src_filename, const char *dest_filename)
{
int src_fd;
@@ -63,37 +63,37 @@ copy_file_preserving (const char *src_filename,
const char *dest_filename)
char *buf = xmalloc (IO_SIZE);
src_fd = open (src_filename, O_RDONLY | O_BINARY);
- if (src_fd < 0 || fstat (src_fd, &statbuf) < 0)
- error (EXIT_FAILURE, errno, _("error while opening \"%s\" for reading"),
- src_filename);
+ if (src_fd < 0)
+ return -1;
+ if (fstat (src_fd, &statbuf) < 0)
+ goto error_exit_2;
mode = statbuf.st_mode & 07777;
dest_fd = open (dest_filename, O_WRONLY | O_CREAT | O_TRUNC |
O_BINARY, 0600);
if (dest_fd < 0)
- error (EXIT_FAILURE, errno, _("cannot open backup file \"%s\" for
writing"),
- dest_filename);
+ return -1;
/* Copy the file contents. */
for (;;)
{
size_t n_read = safe_read (src_fd, buf, IO_SIZE);
if (n_read == SAFE_READ_ERROR)
- error (EXIT_FAILURE, errno, _("error reading \"%s\""), src_filename);
+ goto error_exit;
if (n_read == 0)
break;
if (full_write (dest_fd, buf, n_read) < n_read)
- error (EXIT_FAILURE, errno, _("error writing \"%s\""), dest_filename);
+ goto error_exit;
}
free (buf);
#if !USE_ACL
if (close (dest_fd) < 0)
- error (EXIT_FAILURE, errno, _("error writing \"%s\""), dest_filename);
+ goto error_exit_2;
if (close (src_fd) < 0)
- error (EXIT_FAILURE, errno, _("error after reading \"%s\""), src_filename);
+ return -1;
#endif
/* Preserve the access and modification times. */
@@ -123,15 +123,23 @@ copy_file_preserving (const char *src_filename,
const char *dest_filename)
/* Preserve the access permissions. */
#if USE_ACL
if (copy_acl (src_filename, src_fd, dest_filename, dest_fd, mode))
- exit (EXIT_FAILURE);
+ goto error_exit;
#else
chmod (dest_filename, mode);
#endif
#if USE_ACL
if (close (dest_fd) < 0)
- error (EXIT_FAILURE, errno, _("error writing \"%s\""), dest_filename);
+ goto error_exit_2;
if (close (src_fd) < 0)
- error (EXIT_FAILURE, errno, _("error after reading \"%s\""), src_filename);
+ return -1;
#endif
+
+ return 0;
+
+ error_exit:
+ close (dest_fd);
+ error_exit_2:
+ close (src_fd);
+ return -1;
}
- Re: copy_file_preserving variant that doesn't exit on error?,
Reuben Thomas <=