New module copy-file.
authorBruno Haible <bruno@clisp.org>
Fri, 28 Mar 2003 21:53:34 +0000 (21:53 +0000)
committerBruno Haible <bruno@clisp.org>
Fri, 28 Mar 2003 21:53:34 +0000 (21:53 +0000)
ChangeLog
lib/ChangeLog
lib/copy-file.c [new file with mode: 0644]
lib/copy-file.h [new file with mode: 0644]
m4/ChangeLog
m4/copy-file.m4 [new file with mode: 0644]
modules/copy-file [new file with mode: 0644]

index 45120a1..645f24e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2003-03-28  Bruno Haible  <bruno@clisp.org>
+
+       * modules/copy-file: New file.
+       * MODULES.html.sh (func_all_modules): Add it.
+
 2003-02-20  Bruno Haible  <bruno@clisp.org>
 
        * MODULES.html.sh (func_all_modules): Add poll.
index b7c7b98..57dc361 100644 (file)
@@ -1,3 +1,8 @@
+2003-03-28  Bruno Haible  <bruno@clisp.org>
+
+       * copy-file.h: New file, from GNU gettext.
+       * copy-file.c: New file, from GNU gettext.
+
 2003-03-18  Jim Meyering  <jim@meyering.net>
 
        * quote.c (quote_n): Fix typo in comment.
diff --git a/lib/copy-file.c b/lib/copy-file.c
new file mode 100644 (file)
index 0000000..a03047b
--- /dev/null
@@ -0,0 +1,116 @@
+/* Copying of files.
+   Copyright (C) 2001-2003 Free Software Foundation, Inc.
+   Written by Bruno Haible <haible@clisp.cons.org>, 2001.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+/* Specification.  */
+#include "copy-file.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#if HAVE_UTIME || HAVE_UTIMES
+# if HAVE_UTIME_H
+#  include <utime.h>
+# else
+#  include <sys/utime.h>
+# endif
+#endif
+
+#include "error.h"
+#include "safe-read.h"
+#include "full-write.h"
+#include "binary-io.h"
+#include "exit.h"
+#include "gettext.h"
+
+#define _(str) gettext (str)
+
+void
+copy_file_preserving (const char *src_filename, const char *dest_filename)
+{
+  int src_fd;
+  struct stat statbuf;
+  int mode;
+  int dest_fd;
+  char buf[4096];
+  const int buf_size = sizeof (buf);
+
+  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);
+
+  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);
+
+  /* Copy the file contents.  */
+  for (;;)
+    {
+      size_t n_read = safe_read (src_fd, buf, buf_size);
+      if (n_read == SAFE_READ_ERROR)
+       error (EXIT_FAILURE, errno, _("error reading \"%s\""), src_filename);
+      if (n_read == 0)
+       break;
+
+      if (full_write (dest_fd, buf, n_read) < n_read)
+       error (EXIT_FAILURE, errno, _("error writing \"%s\""), dest_filename);
+    }
+
+  if (close (dest_fd) < 0)
+    error (EXIT_FAILURE, errno, _("error writing \"%s\""), dest_filename);
+  if (close (src_fd) < 0)
+    error (EXIT_FAILURE, errno, _("error after reading \"%s\""), src_filename);
+
+  /* Preserve the access and modification times.  */
+#if HAVE_UTIME
+  {
+    struct utimbuf ut;
+
+    ut.actime = statbuf.st_atime;
+    ut.modtime = statbuf.st_mtime;
+    utime (dest_filename, &ut);
+  }
+#elif HAVE_UTIMES
+  {
+    struct timeval ut[2];
+
+    ut[0].tv_sec = statbuf.st_atime; ut[0].tv_usec = 0;
+    ut[1].tv_sec = statbuf.st_mtime; ut[1].tv_usec = 0;
+    utimes (dest_filename, &ut);
+  }
+#endif
+
+  /* Preserve the owner and group.  */
+  chown (dest_filename, statbuf.st_uid, statbuf.st_gid);
+
+  /* Preserve the access permissions.  */
+  chmod (dest_filename, mode);
+}
diff --git a/lib/copy-file.h b/lib/copy-file.h
new file mode 100644 (file)
index 0000000..3efda34
--- /dev/null
@@ -0,0 +1,24 @@
+/* Copying of files.
+   Copyright (C) 2001-2003 Free Software Foundation, Inc.
+   Written by Bruno Haible <haible@clisp.cons.org>, 2001.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+/* Copy a regular file: from src_filename to dest_filename.
+   The destination file is assumed to be a backup file.
+   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);
index b312a27..2ad1e19 100644 (file)
@@ -1,3 +1,7 @@
+2003-03-28  Bruno Haible  <bruno@clisp.org>
+
+       * copy-file.m4: New file.
+
 2003-03-18  Bruno Haible  <bruno@clisp.org>
 
        * onceonly.m4: Use m4_defn instead of defn, for better error checking.
diff --git a/m4/copy-file.m4 b/m4/copy-file.m4
new file mode 100644 (file)
index 0000000..8bc1536
--- /dev/null
@@ -0,0 +1,13 @@
+# copy-file.m4 serial 1
+dnl Copyright (C) 2003 Free Software Foundation, Inc.
+dnl This file is free software, distributed under the terms of the GNU
+dnl General Public License.  As a special exception to the GNU General
+dnl Public License, this file may be distributed as part of a program
+dnl that contains a configuration script generated by Autoconf, under
+dnl the same distribution terms as the rest of that program.
+
+AC_DEFUN([gl_COPY_FILE],
+[
+  AC_CHECK_HEADERS_ONCE(unistd.h utime.h)
+  AC_CHECK_FUNCS(utime utimes)
+])
diff --git a/modules/copy-file b/modules/copy-file
new file mode 100644 (file)
index 0000000..99fc3bf
--- /dev/null
@@ -0,0 +1,28 @@
+Description:
+Copying of files.
+
+Files:
+lib/copy-file.h
+lib/copy-file.c
+m4/copy-file.m4
+
+Depends-on:
+error
+safe-read
+full-write
+binary-io
+exit
+gettext
+
+configure.ac:
+gl_COPY_FILE
+
+Makefile.am:
+lib_SOURCES += copy-file.h copy-file.c
+
+Include:
+"copy-file.h"
+
+Maintainer:
+Bruno Haible
+