From 5f1f828a6321b8db9c618f2098620e44c66f96b1 Mon Sep 17 00:00:00 2001 From: Kai Wang Date: Thu, 31 Jan 2008 08:11:01 +0000 Subject: [PATCH] Add hook routine archive_write_ar_finish() which writes the 'ar' global header if nothing else has been written before the closing of the archive. This will change the behaviour when creating archives without members, i.e., instead of generating a 0-size archive file, an archive with just the global header (8 bytes in total) will be created and it is indeed a valid archive by the definition of libarchive, thus subsequent operation on this archive will be accepted. This especially solves the failure caused by following sequence: (several ports do) % ar cru libfoo.a # without specifying obj files % ranlib libfoo.a Reviewed by: kientzle, jkoshy Approved by: kientzle Approved by: jkoshy (mentor) Reported by: erwin MFC after: 1 month --- lib/libarchive/archive_write_set_format_ar.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/lib/libarchive/archive_write_set_format_ar.c b/lib/libarchive/archive_write_set_format_ar.c index 9599070e225a..6a223c3ae787 100644 --- a/lib/libarchive/archive_write_set_format_ar.c +++ b/lib/libarchive/archive_write_set_format_ar.c @@ -75,6 +75,7 @@ static int archive_write_ar_header(struct archive_write *, static ssize_t archive_write_ar_data(struct archive_write *, const void *buff, size_t s); static int archive_write_ar_destroy(struct archive_write *); +static int archive_write_ar_finish(struct archive_write *); static int archive_write_ar_finish_entry(struct archive_write *); static const char *ar_basename(const char *path); static int format_octal(int64_t v, char *p, int s); @@ -126,7 +127,7 @@ archive_write_set_format_ar(struct archive_write *a) a->format_write_header = archive_write_ar_header; a->format_write_data = archive_write_ar_data; - a->format_finish = NULL; + a->format_finish = archive_write_ar_finish; a->format_destroy = archive_write_ar_destroy; a->format_finish_entry = archive_write_ar_finish_entry; return (ARCHIVE_OK); @@ -397,6 +398,23 @@ archive_write_ar_destroy(struct archive_write *a) return (ARCHIVE_OK); } +static int +archive_write_ar_finish(struct archive_write *a) +{ + int ret; + + /* + * If we haven't written anything yet, we need to write + * the ar global header now to make it a valid ar archive. + */ + if (a->archive.file_position == 0) { + ret = (a->compressor.write)(a, "!\n", 8); + return (ret); + } + + return (ARCHIVE_OK); +} + static int archive_write_ar_finish_entry(struct archive_write *a) {