Mercurial > hg > octave-lojdl > gnulib-hg
annotate lib/copy-file.c @ 8196:5166dec344af
exit.h is replaced with stdlib.h.
author | Bruno Haible <bruno@clisp.org> |
---|---|
date | Sun, 18 Feb 2007 21:08:06 +0000 |
parents | cb2590895141 |
children | bbbbbf4cd1c5 |
rev | line source |
---|---|
4266 | 1 /* Copying of files. |
8196
5166dec344af
exit.h is replaced with stdlib.h.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
2 Copyright (C) 2001-2003, 2006-2007 Free Software Foundation, Inc. |
4266 | 3 Written by Bruno Haible <haible@clisp.cons.org>, 2001. |
4 | |
5 This program is free software; you can redistribute it and/or modify | |
6 it under the terms of the GNU General Public License as published by | |
7 the Free Software Foundation; either version 2, or (at your option) | |
8 any later version. | |
9 | |
10 This program is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 GNU General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU General Public License | |
16 along with this program; if not, write to the Free Software Foundation, | |
5848
a48fb0e98c8c
*** empty log message ***
Paul Eggert <eggert@cs.ucla.edu>
parents:
4310
diff
changeset
|
17 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ |
4266 | 18 |
19 | |
7304
1c4ed7637c24
Include <config.h> unconditionally.
Bruno Haible <bruno@clisp.org>
parents:
6751
diff
changeset
|
20 #include <config.h> |
4266 | 21 |
22 /* Specification. */ | |
23 #include "copy-file.h" | |
24 | |
25 #include <errno.h> | |
26 #include <fcntl.h> | |
4310
17ce7ef2789c
Include <stddef.h>, for size_t.
Bruno Haible <bruno@clisp.org>
parents:
4308
diff
changeset
|
27 #include <stddef.h> |
8196
5166dec344af
exit.h is replaced with stdlib.h.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
28 #include <stdlib.h> |
4266 | 29 #include <sys/stat.h> |
6751
1b0092424a44
Include <unistd.h> unconditionally.
Bruno Haible <bruno@clisp.org>
parents:
6259
diff
changeset
|
30 #include <unistd.h> |
4266 | 31 |
32 #if HAVE_UTIME || HAVE_UTIMES | |
33 # if HAVE_UTIME_H | |
34 # include <utime.h> | |
35 # else | |
36 # include <sys/utime.h> | |
37 # endif | |
38 #endif | |
39 | |
40 #include "error.h" | |
41 #include "safe-read.h" | |
42 #include "full-write.h" | |
7742
4a26effdff28
Preserve ACLs while copying.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
43 #include "acl.h" |
4266 | 44 #include "binary-io.h" |
45 #include "gettext.h" | |
46 | |
47 #define _(str) gettext (str) | |
48 | |
7863 | 49 /* The results of open() in this file are not used with fchdir, |
50 therefore save some unnecessary work in fchdir.c. */ | |
51 #undef open | |
52 #undef close | |
53 | |
54 | |
4266 | 55 void |
56 copy_file_preserving (const char *src_filename, const char *dest_filename) | |
57 { | |
58 int src_fd; | |
59 struct stat statbuf; | |
60 int mode; | |
61 int dest_fd; | |
62 char buf[4096]; | |
4308
38cad811ac67
(copy_file_preserving): Declare buf_size to be of type size_t, not int.
Jim Meyering <jim@meyering.net>
parents:
4268
diff
changeset
|
63 const size_t buf_size = sizeof (buf); |
4266 | 64 |
65 src_fd = open (src_filename, O_RDONLY | O_BINARY); | |
66 if (src_fd < 0 || fstat (src_fd, &statbuf) < 0) | |
67 error (EXIT_FAILURE, errno, _("error while opening \"%s\" for reading"), | |
68 src_filename); | |
69 | |
70 mode = statbuf.st_mode & 07777; | |
71 | |
72 dest_fd = open (dest_filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0600); | |
73 if (dest_fd < 0) | |
74 error (EXIT_FAILURE, errno, _("cannot open backup file \"%s\" for writing"), | |
75 dest_filename); | |
76 | |
77 /* Copy the file contents. */ | |
78 for (;;) | |
79 { | |
80 size_t n_read = safe_read (src_fd, buf, buf_size); | |
81 if (n_read == SAFE_READ_ERROR) | |
82 error (EXIT_FAILURE, errno, _("error reading \"%s\""), src_filename); | |
83 if (n_read == 0) | |
84 break; | |
85 | |
86 if (full_write (dest_fd, buf, n_read) < n_read) | |
87 error (EXIT_FAILURE, errno, _("error writing \"%s\""), dest_filename); | |
88 } | |
89 | |
7742
4a26effdff28
Preserve ACLs while copying.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
90 #if !USE_ACL |
4266 | 91 if (close (dest_fd) < 0) |
92 error (EXIT_FAILURE, errno, _("error writing \"%s\""), dest_filename); | |
93 if (close (src_fd) < 0) | |
94 error (EXIT_FAILURE, errno, _("error after reading \"%s\""), src_filename); | |
7742
4a26effdff28
Preserve ACLs while copying.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
95 #endif |
4266 | 96 |
97 /* Preserve the access and modification times. */ | |
98 #if HAVE_UTIME | |
99 { | |
100 struct utimbuf ut; | |
101 | |
102 ut.actime = statbuf.st_atime; | |
103 ut.modtime = statbuf.st_mtime; | |
104 utime (dest_filename, &ut); | |
105 } | |
106 #elif HAVE_UTIMES | |
107 { | |
108 struct timeval ut[2]; | |
109 | |
110 ut[0].tv_sec = statbuf.st_atime; ut[0].tv_usec = 0; | |
111 ut[1].tv_sec = statbuf.st_mtime; ut[1].tv_usec = 0; | |
112 utimes (dest_filename, &ut); | |
113 } | |
114 #endif | |
115 | |
4268 | 116 #if HAVE_CHOWN |
4266 | 117 /* Preserve the owner and group. */ |
118 chown (dest_filename, statbuf.st_uid, statbuf.st_gid); | |
4268 | 119 #endif |
4266 | 120 |
121 /* Preserve the access permissions. */ | |
7742
4a26effdff28
Preserve ACLs while copying.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
122 #if USE_ACL |
4a26effdff28
Preserve ACLs while copying.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
123 if (copy_acl (src_filename, src_fd, dest_filename, dest_fd, mode)) |
4a26effdff28
Preserve ACLs while copying.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
124 exit (EXIT_FAILURE); |
4a26effdff28
Preserve ACLs while copying.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
125 #else |
4266 | 126 chmod (dest_filename, mode); |
7742
4a26effdff28
Preserve ACLs while copying.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
127 #endif |
4a26effdff28
Preserve ACLs while copying.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
128 |
4a26effdff28
Preserve ACLs while copying.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
129 #if USE_ACL |
4a26effdff28
Preserve ACLs while copying.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
130 if (close (dest_fd) < 0) |
4a26effdff28
Preserve ACLs while copying.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
131 error (EXIT_FAILURE, errno, _("error writing \"%s\""), dest_filename); |
4a26effdff28
Preserve ACLs while copying.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
132 if (close (src_fd) < 0) |
4a26effdff28
Preserve ACLs while copying.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
133 error (EXIT_FAILURE, errno, _("error after reading \"%s\""), src_filename); |
4a26effdff28
Preserve ACLs while copying.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
134 #endif |
4266 | 135 } |