Module Name:    src
Committed By:   rillig
Date:           Sat Nov  7 12:47:16 UTC 2020

Modified Files:
        src/usr.bin/make: arch.c

Log Message:
make(1): fix archive handling

It's no wonder that nobody is using the archive handling of make.  The
archives created by GNU binutils cannot be processed using make since the
format of the archive names has changed.  GNU binutils appends a slash to
the member names.  Support that format from now on.

Add more debugging output in ArchFindMember.  Since nobody uses this part
of make, it doesn't hurt that the debug output is now very verbose.

In Arch_Touch and Arch_TouchLib, move the snprintf to where it belongs.
There's no point modifying a local variable just to throw it away
afterwards.


To generate a diff of this commit:
cvs rdiff -u -r1.158 -r1.159 src/usr.bin/make/arch.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/make/arch.c
diff -u src/usr.bin/make/arch.c:1.158 src/usr.bin/make/arch.c:1.159
--- src/usr.bin/make/arch.c:1.158	Sat Nov  7 12:34:49 2020
+++ src/usr.bin/make/arch.c	Sat Nov  7 12:47:16 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: arch.c,v 1.158 2020/11/07 12:34:49 rillig Exp $	*/
+/*	$NetBSD: arch.c,v 1.159 2020/11/07 12:47:16 rillig Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -125,7 +125,7 @@
 #include "config.h"
 
 /*	"@(#)arch.c	8.2 (Berkeley) 1/2/94"	*/
-MAKE_RCSID("$NetBSD: arch.c,v 1.158 2020/11/07 12:34:49 rillig Exp $");
+MAKE_RCSID("$NetBSD: arch.c,v 1.159 2020/11/07 12:47:16 rillig Exp $");
 
 #ifdef TARGET_MACHINE
 #undef MAKE_MACHINE
@@ -689,7 +689,16 @@ ArchiveMember_HasName(const struct ar_hd
 	return namelen == ar_name_len;
 
     /* hdr->ar_name is space-padded to the right. */
-    return ar_name[namelen] == ' ';
+    if (ar_name[namelen] == ' ')
+	return TRUE;
+
+    /* In archives created by GNU binutils 2.27, the member names end with
+     * a slash. */
+    if (ar_name[namelen] == '/' &&
+	(namelen == ar_name_len || ar_name[namelen + 1] == ' '))
+	return TRUE;
+
+    return FALSE;
 }
 
 /* Locate a member of an archive, given the path of the archive and the path
@@ -756,6 +765,11 @@ ArchFindMember(const char *archive, cons
 	    return NULL;
 	}
 
+	DEBUG5(ARCH, "Reading archive %s member %.*s mtime %.*s\n",
+	       archive,
+	       (int)sizeof out_arh->ar_name, out_arh->ar_name,
+	       (int)sizeof out_arh->ar_date, out_arh->ar_date);
+
 	if (ArchiveMember_HasName(out_arh, member, len)) {
 	    /*
 	     * To make life easier for callers that want to update the
@@ -845,45 +859,41 @@ ArchFindMember(const char *archive, cons
 void
 Arch_Touch(GNode *gn)
 {
-    FILE *arch;
+    FILE *f;
     struct ar_hdr arh;
 
-    arch = ArchFindMember(GNode_VarArchive(gn), GNode_VarMember(gn),
-			  &arh, "r+");
-
-    snprintf(arh.ar_date, sizeof arh.ar_date, "%-12ld", (long)now);
-
-    if (arch != NULL) {
-	(void)fwrite(&arh, sizeof arh, 1, arch);
-	fclose(arch);
-    }
+    f = ArchFindMember(GNode_VarArchive(gn), GNode_VarMember(gn), &arh, "r+");
+    if (f == NULL)
+	return;
+
+    snprintf(arh.ar_date, sizeof arh.ar_date, "%-ld", (unsigned long)now);
+    (void)fwrite(&arh, sizeof arh, 1, f);
+    fclose(f);			/* TODO: handle errors */
 }
 
 /* Given a node which represents a library, touch the thing, making sure that
- * the table of contents also is touched.
+ * the table of contents is also touched.
  *
  * Both the modification time of the library and of the RANLIBMAG member are
  * set to 'now'. */
 void
-Arch_TouchLib(GNode *gn)
+Arch_TouchLib(GNode *gn MAKE_ATTR_UNUSED)
 {
 #ifdef RANLIBMAG
-    FILE *arch;
+    FILE *f;
     struct ar_hdr arh;		/* Header describing table of contents */
     struct utimbuf times;
 
-    arch = ArchFindMember(gn->path, RANLIBMAG, &arh, "r+");
-    snprintf(arh.ar_date, sizeof arh.ar_date, "%-12ld", (long) now);
-
-    if (arch != NULL) {
-	(void)fwrite(&arh, sizeof arh, 1, arch);
-	fclose(arch);
+    f = ArchFindMember(gn->path, RANLIBMAG, &arh, "r+");
+    if (f == NULL)
+	return;
+
+    snprintf(arh.ar_date, sizeof arh.ar_date, "%-ld", (unsigned long)now);
+    (void)fwrite(&arh, sizeof arh, 1, f);
+    fclose(f);			/* TODO: handle errors */
 
-	times.actime = times.modtime = now;
-	utime(gn->path, &times);
-    }
-#else
-    (void)gn;
+    times.actime = times.modtime = now;
+    utime(gn->path, &times);	/* TODO: handle errors */
 #endif
 }
 

Reply via email to