From ba0c36cfcf84efbac6f89e27238e04bb57e9cd45 Mon Sep 17 00:00:00 2001
From: Ron Yorston <rmy@pobox.com>
Date: Wed, 4 Mar 2015 09:07:57 +0000
Subject: 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.
---
 archival/ar.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

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)
 {
 	struct stat st;
 	archive_handle_t *out_handle;
+	char *temp_fn = NULL;
 
 	xfstat(handle->src_fd, &st, handle->ar__name);
 
@@ -183,8 +184,14 @@ static int write_ar_archive(archive_handle_t *handle)
 	 */
 	if (st.st_size != 0) {
 		out_handle = init_handle();
+#if !ENABLE_PLATFORM_MINGW32
 		xunlink(handle->ar__name);
 		out_handle->src_fd = xopen(handle->ar__name, O_WRONLY | O_CREAT | O_TRUNC);
+#else
+		/* can't unlink open file, create temporary output file */
+		temp_fn = xasprintf("%sXXXXXX", handle->ar__name);
+		out_handle->src_fd = xmkstemp(temp_fn);
+#endif
 		out_handle->accept = handle->accept;
 	} else {
 		out_handle = handle;
@@ -206,12 +213,19 @@ static int write_ar_archive(archive_handle_t *handle)
 		continue;
 
 	/* optional, since we exit right after we return */
-	if (ENABLE_FEATURE_CLEAN_UP) {
+	if (ENABLE_FEATURE_CLEAN_UP || ENABLE_PLATFORM_MINGW32) {
 		close(handle->src_fd);
 		if (out_handle->src_fd != handle->src_fd)
 			close(out_handle->src_fd);
 	}
 
+#if ENABLE_PLATFORM_MINGW32
+	if ( temp_fn != NULL ) {
+		xrename(temp_fn, handle->ar__name);
+		free(temp_fn);
+	}
+#endif
+
 	return EXIT_SUCCESS;
 }
 #endif /* FEATURE_AR_CREATE */
-- 
cgit v1.2.3-55-g6feb