aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2015-03-04 09:07:57 +0000
committerRon Yorston <rmy@pobox.com>2015-03-04 09:07:57 +0000
commitba0c36cfcf84efbac6f89e27238e04bb57e9cd45 (patch)
tree1ca31bc62b664b50a4b0fae8996e4abff2c9143e
parent939a8e932851124e05f14df53a925b185054b5ae (diff)
downloadbusybox-w32-ba0c36cfcf84efbac6f89e27238e04bb57e9cd45.tar.gz
busybox-w32-ba0c36cfcf84efbac6f89e27238e04bb57e9cd45.tar.bz2
busybox-w32-ba0c36cfcf84efbac6f89e27238e04bb57e9cd45.zip
ar: fix modification of existing archives
When modifying an existing archive the code opens the old file, unlinks it and creates a new file with the same name. This doesn't work on Windows where it isn't possible to unlink an open file. Instead we create a temporary file for output and change it's name when we're done.
-rw-r--r--archival/ar.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/archival/ar.c b/archival/ar.c
index f86c52d9b..89e6a1207 100644
--- a/archival/ar.c
+++ b/archival/ar.c
@@ -175,6 +175,7 @@ static int write_ar_archive(archive_handle_t *handle)
175{ 175{
176 struct stat st; 176 struct stat st;
177 archive_handle_t *out_handle; 177 archive_handle_t *out_handle;
178 char *temp_fn = NULL;
178 179
179 xfstat(handle->src_fd, &st, handle->ar__name); 180 xfstat(handle->src_fd, &st, handle->ar__name);
180 181
@@ -183,8 +184,14 @@ static int write_ar_archive(archive_handle_t *handle)
183 */ 184 */
184 if (st.st_size != 0) { 185 if (st.st_size != 0) {
185 out_handle = init_handle(); 186 out_handle = init_handle();
187#if !ENABLE_PLATFORM_MINGW32
186 xunlink(handle->ar__name); 188 xunlink(handle->ar__name);
187 out_handle->src_fd = xopen(handle->ar__name, O_WRONLY | O_CREAT | O_TRUNC); 189 out_handle->src_fd = xopen(handle->ar__name, O_WRONLY | O_CREAT | O_TRUNC);
190#else
191 /* can't unlink open file, create temporary output file */
192 temp_fn = xasprintf("%sXXXXXX", handle->ar__name);
193 out_handle->src_fd = xmkstemp(temp_fn);
194#endif
188 out_handle->accept = handle->accept; 195 out_handle->accept = handle->accept;
189 } else { 196 } else {
190 out_handle = handle; 197 out_handle = handle;
@@ -206,12 +213,19 @@ static int write_ar_archive(archive_handle_t *handle)
206 continue; 213 continue;
207 214
208 /* optional, since we exit right after we return */ 215 /* optional, since we exit right after we return */
209 if (ENABLE_FEATURE_CLEAN_UP) { 216 if (ENABLE_FEATURE_CLEAN_UP || ENABLE_PLATFORM_MINGW32) {
210 close(handle->src_fd); 217 close(handle->src_fd);
211 if (out_handle->src_fd != handle->src_fd) 218 if (out_handle->src_fd != handle->src_fd)
212 close(out_handle->src_fd); 219 close(out_handle->src_fd);
213 } 220 }
214 221
222#if ENABLE_PLATFORM_MINGW32
223 if ( temp_fn != NULL ) {
224 xrename(temp_fn, handle->ar__name);
225 free(temp_fn);
226 }
227#endif
228
215 return EXIT_SUCCESS; 229 return EXIT_SUCCESS;
216} 230}
217#endif /* FEATURE_AR_CREATE */ 231#endif /* FEATURE_AR_CREATE */