Mercurial > hg > octave-kai > gnulib-hg
comparison lib/copy-file.c @ 16273:d50152d6b5d2
copy-file: add error-code-returning variant.
* lib/copy-file.h (GL_COPY_ERR_*): New enumeration items.
(qcopy_file_preserving): New declaration.
* lib/copy-file.c (qcopy_file_preserving): Renamed from
copy_file_preserving. Change return type to 'int'. Don't emit an error
message here.
(copy_file_preserving): New function.
* tests/test-copy-file.c: Include <stdlib.h>.
(main): Test qcopy_file_preserving if the environment variable
NO_STDERR_OUTPUT is set.
* tests/test-copy-file-1.sh: Invoke test-copy-file.sh a second time,
with NO_STDERR_OUTPUT
* tests/test-copy-file-2.sh: Likewise.
author | Reuben Thomas <rrt@sc3d.org> |
---|---|
date | Thu, 12 Jan 2012 03:04:49 +0100 |
parents | 8e1f4b31c39f |
children | e542fd46ad6f |
comparison
equal
deleted
inserted
replaced
16272:8e1f4b31c39f | 16273:d50152d6b5d2 |
---|---|
52 #undef open | 52 #undef open |
53 #undef close | 53 #undef close |
54 | 54 |
55 enum { IO_SIZE = 32 * 1024 }; | 55 enum { IO_SIZE = 32 * 1024 }; |
56 | 56 |
57 void | 57 int |
58 copy_file_preserving (const char *src_filename, const char *dest_filename) | 58 qcopy_file_preserving (const char *src_filename, const char *dest_filename) |
59 { | 59 { |
60 int err = 0; | |
60 int src_fd; | 61 int src_fd; |
61 struct stat statbuf; | 62 struct stat statbuf; |
62 int mode; | 63 int mode; |
63 int dest_fd; | 64 int dest_fd; |
64 char *buf = xmalloc (IO_SIZE); | 65 char *buf = xmalloc (IO_SIZE); |
65 | 66 |
66 src_fd = open (src_filename, O_RDONLY | O_BINARY); | 67 src_fd = open (src_filename, O_RDONLY | O_BINARY); |
67 if (src_fd < 0 || fstat (src_fd, &statbuf) < 0) | 68 if (src_fd < 0) |
68 error (EXIT_FAILURE, errno, _("error while opening %s for reading"), | 69 { |
69 quote (src_filename)); | 70 err = GL_COPY_ERR_OPEN_READ; |
71 goto error; | |
72 } | |
73 if (fstat (src_fd, &statbuf) < 0) | |
74 { | |
75 err = GL_COPY_ERR_OPEN_READ; | |
76 goto error_src; | |
77 } | |
70 | 78 |
71 mode = statbuf.st_mode & 07777; | 79 mode = statbuf.st_mode & 07777; |
72 | 80 |
73 dest_fd = open (dest_filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0600); | 81 dest_fd = open (dest_filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0600); |
74 if (dest_fd < 0) | 82 if (dest_fd < 0) |
75 error (EXIT_FAILURE, errno, _("cannot open backup file %s for writing"), | 83 { |
76 quote (dest_filename)); | 84 err = GL_COPY_ERR_OPEN_BACKUP_WRITE; |
85 goto error_src; | |
86 } | |
77 | 87 |
78 /* Copy the file contents. */ | 88 /* Copy the file contents. */ |
79 for (;;) | 89 for (;;) |
80 { | 90 { |
81 size_t n_read = safe_read (src_fd, buf, IO_SIZE); | 91 size_t n_read = safe_read (src_fd, buf, IO_SIZE); |
82 if (n_read == SAFE_READ_ERROR) | 92 if (n_read == SAFE_READ_ERROR) |
83 error (EXIT_FAILURE, errno, _("error reading %s"), | 93 { |
84 quote (src_filename)); | 94 err = GL_COPY_ERR_READ; |
95 goto error_src_dest; | |
96 } | |
85 if (n_read == 0) | 97 if (n_read == 0) |
86 break; | 98 break; |
87 | 99 |
88 if (full_write (dest_fd, buf, n_read) < n_read) | 100 if (full_write (dest_fd, buf, n_read) < n_read) |
89 error (EXIT_FAILURE, errno, _("error writing %s"), | 101 { |
90 quote (est_filename)); | 102 err = GL_COPY_ERR_WRITE; |
103 goto error_src_dest; | |
104 } | |
91 } | 105 } |
92 | 106 |
93 free (buf); | 107 free (buf); |
94 | 108 |
95 #if !USE_ACL | 109 #if !USE_ACL |
96 if (close (dest_fd) < 0) | 110 if (close (dest_fd) < 0) |
97 error (EXIT_FAILURE, errno, _("error writing %s"), quote (dest_filename)); | 111 { |
112 err = GL_COPY_ERR_WRITE; | |
113 goto error_src; | |
114 } | |
98 if (close (src_fd) < 0) | 115 if (close (src_fd) < 0) |
99 error (EXIT_FAILURE, errno, _("error after reading %s"), | 116 { |
100 quote (src_filename)); | 117 err = GL_COPY_ERR_AFTER_READ; |
118 goto error; | |
119 } | |
101 #endif | 120 #endif |
102 | 121 |
103 /* Preserve the access and modification times. */ | 122 /* Preserve the access and modification times. */ |
104 #if HAVE_UTIME | 123 #if HAVE_UTIME |
105 { | 124 { |
127 /* Preserve the access permissions. */ | 146 /* Preserve the access permissions. */ |
128 #if USE_ACL | 147 #if USE_ACL |
129 switch (qcopy_acl (src_filename, src_fd, dest_filename, dest_fd, mode)) | 148 switch (qcopy_acl (src_filename, src_fd, dest_filename, dest_fd, mode)) |
130 { | 149 { |
131 case -2: | 150 case -2: |
151 err = GL_COPY_ERR_GET_ACL; | |
152 goto error_src_dest; | |
153 case -1: | |
154 err = GL_COPY_ERR_SET_ACL; | |
155 goto error_src_dest; | |
156 } | |
157 #else | |
158 chmod (dest_filename, mode); | |
159 #endif | |
160 | |
161 #if USE_ACL | |
162 if (close (dest_fd) < 0) | |
163 { | |
164 err = GL_COPY_ERR_WRITE; | |
165 goto error_src; | |
166 } | |
167 if (close (src_fd) < 0) | |
168 { | |
169 err = GL_COPY_ERR_AFTER_READ; | |
170 goto error; | |
171 } | |
172 #endif | |
173 | |
174 return 0; | |
175 | |
176 error_src_dest: | |
177 close (dest_fd); | |
178 error_src: | |
179 close (src_fd); | |
180 error: | |
181 return err; | |
182 } | |
183 | |
184 void | |
185 copy_file_preserving (const char *src_filename, const char *dest_filename) | |
186 { | |
187 switch (qcopy_file_preserving (src_filename, dest_filename)) | |
188 { | |
189 case 0: | |
190 return; | |
191 | |
192 case GL_COPY_ERR_OPEN_READ: | |
193 error (EXIT_FAILURE, errno, _("error while opening %s for reading"), | |
194 quote (src_filename)); | |
195 | |
196 case GL_COPY_ERR_OPEN_BACKUP_WRITE: | |
197 error (EXIT_FAILURE, errno, _("cannot open backup file %s for writing"), | |
198 quote (dest_filename)); | |
199 | |
200 case GL_COPY_ERR_READ: | |
201 error (EXIT_FAILURE, errno, _("error reading %s"), | |
202 quote (src_filename)); | |
203 | |
204 case GL_COPY_ERR_WRITE: | |
205 error (EXIT_FAILURE, errno, _("error writing %s"), | |
206 quote (dest_filename)); | |
207 | |
208 case GL_COPY_ERR_AFTER_READ: | |
209 error (EXIT_FAILURE, errno, _("error after reading %s"), | |
210 quote (src_filename)); | |
211 | |
212 case GL_COPY_ERR_GET_ACL: | |
132 error (EXIT_FAILURE, errno, "%s", quote (src_filename)); | 213 error (EXIT_FAILURE, errno, "%s", quote (src_filename)); |
133 case -1: | 214 |
215 case GL_COPY_ERR_SET_ACL: | |
134 error (EXIT_FAILURE, errno, _("preserving permissions for %s"), | 216 error (EXIT_FAILURE, errno, _("preserving permissions for %s"), |
135 quote (dest_filename)); | 217 quote (dest_filename)); |
136 } | 218 |
137 #else | 219 default: |
138 chmod (dest_filename, mode); | 220 abort (); |
139 #endif | 221 } |
140 | |
141 #if USE_ACL | |
142 if (close (dest_fd) < 0) | |
143 error (EXIT_FAILURE, errno, _("error writing %s"), quote (dest_filename)); | |
144 if (close (src_fd) < 0) | |
145 error (EXIT_FAILURE, errno, _("error after reading %s"), | |
146 quote (src_filename)); | |
147 #endif | |
148 } | 222 } |