Mercurial > hg > octave-kai > gnulib-hg
annotate lib/copy-file.c @ 16271:a9b070c205b2
copy-file: Refactor.
* lib/copy-file.c: Include quote.h.
(copy_file_preserving): Call qcopy_acl instead of copy_acl. Emit error
message here.
* modules/copy-file (Depends-on): Add quote.
author | Bruno Haible <bruno@clisp.org> |
---|---|
date | Wed, 11 Jan 2012 02:01:45 +0100 |
parents | 8250f2777afc |
children | 8e1f4b31c39f |
rev | line source |
---|---|
4266 | 1 /* Copying of files. |
16201
8250f2777afc
maint: update all copyright year number ranges
Jim Meyering <meyering@redhat.com>
parents:
14079
diff
changeset
|
2 Copyright (C) 2001-2003, 2006-2007, 2009-2012 Free Software Foundation, Inc. |
4266 | 3 Written by Bruno Haible <haible@clisp.cons.org>, 2001. |
4 | |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8196
diff
changeset
|
5 This program is free software: you can redistribute it and/or modify |
4266 | 6 it under the terms of the GNU General Public License as published by |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8196
diff
changeset
|
7 the Free Software Foundation; either version 3 of the License, or |
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8196
diff
changeset
|
8 (at your option) any later version. |
4266 | 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 | |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8196
diff
changeset
|
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
4266 | 17 |
18 | |
7304
1c4ed7637c24
Include <config.h> unconditionally.
Bruno Haible <bruno@clisp.org>
parents:
6751
diff
changeset
|
19 #include <config.h> |
4266 | 20 |
21 /* Specification. */ | |
22 #include "copy-file.h" | |
23 | |
24 #include <errno.h> | |
25 #include <fcntl.h> | |
4310
17ce7ef2789c
Include <stddef.h>, for size_t.
Bruno Haible <bruno@clisp.org>
parents:
4308
diff
changeset
|
26 #include <stddef.h> |
8196
5166dec344af
exit.h is replaced with stdlib.h.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
27 #include <stdlib.h> |
4266 | 28 #include <sys/stat.h> |
6751
1b0092424a44
Include <unistd.h> unconditionally.
Bruno Haible <bruno@clisp.org>
parents:
6259
diff
changeset
|
29 #include <unistd.h> |
4266 | 30 |
31 #if HAVE_UTIME || HAVE_UTIMES | |
32 # if HAVE_UTIME_H | |
33 # include <utime.h> | |
34 # else | |
35 # include <sys/utime.h> | |
36 # endif | |
37 #endif | |
38 | |
39 #include "error.h" | |
40 #include "safe-read.h" | |
41 #include "full-write.h" | |
7742
4a26effdff28
Preserve ACLs while copying.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
42 #include "acl.h" |
4266 | 43 #include "binary-io.h" |
16271 | 44 #include "quote.h" |
4266 | 45 #include "gettext.h" |
12198
e8fbc5424b99
digests, copy-file: increase the IO buffer size from 4KiB to 32KiB
Pádraig Brady <P@draigBrady.com>
parents:
9309
diff
changeset
|
46 #include "xalloc.h" |
4266 | 47 |
48 #define _(str) gettext (str) | |
49 | |
7863 | 50 /* The results of open() in this file are not used with fchdir, |
51 therefore save some unnecessary work in fchdir.c. */ | |
52 #undef open | |
53 #undef close | |
54 | |
12198
e8fbc5424b99
digests, copy-file: increase the IO buffer size from 4KiB to 32KiB
Pádraig Brady <P@draigBrady.com>
parents:
9309
diff
changeset
|
55 enum { IO_SIZE = 32 * 1024 }; |
7863 | 56 |
4266 | 57 void |
58 copy_file_preserving (const char *src_filename, const char *dest_filename) | |
59 { | |
60 int src_fd; | |
61 struct stat statbuf; | |
62 int mode; | |
63 int dest_fd; | |
12198
e8fbc5424b99
digests, copy-file: increase the IO buffer size from 4KiB to 32KiB
Pádraig Brady <P@draigBrady.com>
parents:
9309
diff
changeset
|
64 char *buf = xmalloc (IO_SIZE); |
4266 | 65 |
66 src_fd = open (src_filename, O_RDONLY | O_BINARY); | |
67 if (src_fd < 0 || fstat (src_fd, &statbuf) < 0) | |
68 error (EXIT_FAILURE, errno, _("error while opening \"%s\" for reading"), | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12198
diff
changeset
|
69 src_filename); |
4266 | 70 |
71 mode = statbuf.st_mode & 07777; | |
72 | |
73 dest_fd = open (dest_filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0600); | |
74 if (dest_fd < 0) | |
75 error (EXIT_FAILURE, errno, _("cannot open backup file \"%s\" for writing"), | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12198
diff
changeset
|
76 dest_filename); |
4266 | 77 |
78 /* Copy the file contents. */ | |
79 for (;;) | |
80 { | |
12198
e8fbc5424b99
digests, copy-file: increase the IO buffer size from 4KiB to 32KiB
Pádraig Brady <P@draigBrady.com>
parents:
9309
diff
changeset
|
81 size_t n_read = safe_read (src_fd, buf, IO_SIZE); |
4266 | 82 if (n_read == SAFE_READ_ERROR) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12198
diff
changeset
|
83 error (EXIT_FAILURE, errno, _("error reading \"%s\""), src_filename); |
4266 | 84 if (n_read == 0) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12198
diff
changeset
|
85 break; |
4266 | 86 |
87 if (full_write (dest_fd, buf, n_read) < n_read) | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12198
diff
changeset
|
88 error (EXIT_FAILURE, errno, _("error writing \"%s\""), dest_filename); |
4266 | 89 } |
90 | |
12198
e8fbc5424b99
digests, copy-file: increase the IO buffer size from 4KiB to 32KiB
Pádraig Brady <P@draigBrady.com>
parents:
9309
diff
changeset
|
91 free (buf); |
e8fbc5424b99
digests, copy-file: increase the IO buffer size from 4KiB to 32KiB
Pádraig Brady <P@draigBrady.com>
parents:
9309
diff
changeset
|
92 |
7742
4a26effdff28
Preserve ACLs while copying.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
93 #if !USE_ACL |
4266 | 94 if (close (dest_fd) < 0) |
95 error (EXIT_FAILURE, errno, _("error writing \"%s\""), dest_filename); | |
96 if (close (src_fd) < 0) | |
97 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
|
98 #endif |
4266 | 99 |
100 /* Preserve the access and modification times. */ | |
101 #if HAVE_UTIME | |
102 { | |
103 struct utimbuf ut; | |
104 | |
105 ut.actime = statbuf.st_atime; | |
106 ut.modtime = statbuf.st_mtime; | |
107 utime (dest_filename, &ut); | |
108 } | |
109 #elif HAVE_UTIMES | |
110 { | |
111 struct timeval ut[2]; | |
112 | |
113 ut[0].tv_sec = statbuf.st_atime; ut[0].tv_usec = 0; | |
114 ut[1].tv_sec = statbuf.st_mtime; ut[1].tv_usec = 0; | |
115 utimes (dest_filename, &ut); | |
116 } | |
117 #endif | |
118 | |
4268 | 119 #if HAVE_CHOWN |
4266 | 120 /* Preserve the owner and group. */ |
121 chown (dest_filename, statbuf.st_uid, statbuf.st_gid); | |
4268 | 122 #endif |
4266 | 123 |
124 /* Preserve the access permissions. */ | |
7742
4a26effdff28
Preserve ACLs while copying.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
125 #if USE_ACL |
16271 | 126 switch (qcopy_acl (src_filename, src_fd, dest_filename, dest_fd, mode)) |
127 { | |
128 case -2: | |
129 error (EXIT_FAILURE, errno, "%s", quote (src_filename)); | |
130 case -1: | |
131 error (EXIT_FAILURE, errno, _("preserving permissions for %s"), | |
132 quote (dest_filename)); | |
133 } | |
7742
4a26effdff28
Preserve ACLs while copying.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
134 #else |
4266 | 135 chmod (dest_filename, mode); |
7742
4a26effdff28
Preserve ACLs while copying.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
136 #endif |
4a26effdff28
Preserve ACLs while copying.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
137 |
4a26effdff28
Preserve ACLs while copying.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
138 #if USE_ACL |
4a26effdff28
Preserve ACLs while copying.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
139 if (close (dest_fd) < 0) |
4a26effdff28
Preserve ACLs while copying.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
140 error (EXIT_FAILURE, errno, _("error writing \"%s\""), dest_filename); |
4a26effdff28
Preserve ACLs while copying.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
141 if (close (src_fd) < 0) |
4a26effdff28
Preserve ACLs while copying.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
142 error (EXIT_FAILURE, errno, _("error after reading \"%s\""), src_filename); |
4a26effdff28
Preserve ACLs while copying.
Bruno Haible <bruno@clisp.org>
parents:
7304
diff
changeset
|
143 #endif |
4266 | 144 } |