Subject: Re: make: print real reason for exec failure
To: None <tech-toolchain@netbsd.org>
From: Simon J. Gerraty <sjg@quick.com.au>
List: tech-toolchain
Date: 05/29/2001 02:15:45
>> In article <200105290015.RAA11306@zen.quick.com.au>,
>> Simon J. Gerraty <sjg@quick.com.au> wrote:
>> >>Below are some of the changes I've recently made to bmake (autoconf'd
>> >>version of netbsd make), that I think would be useful to add to our
>> >>make.
>> >
>> >While I'm at it, below is another change that might be useful:
>> >
>> > [ using perror() to print a nice error message ]
>> 
>> This change will lead to problems. You cannot use stdio on a child of
>> vfork!

Good point - though I've not noticed any in the months I've run this, 
probably because spitting out that error is typically one of the last 
things done.

>You could call strerror() and then write() to spit out the string to
>work around this.

Yep, would sure beat "not found".  Ok, patch below avoids stdio.

Index: compat.c
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/make/compat.c,v
retrieving revision 1.32
diff -u -p -r1.32 compat.c
--- compat.c	2001/04/06 11:13:46	1.32
+++ compat.c	2001/05/29 09:13:14
@@ -68,6 +68,7 @@ __RCSID("$NetBSD: compat.c,v 1.32 2001/0
 #include    <sys/types.h>
 #include    <sys/stat.h>
 #include    <sys/wait.h>
+#include    <sys/uio.h>
 #include    <ctype.h>
 #include    <errno.h>
 #include    <signal.h>
@@ -283,9 +284,19 @@ CompatRunCommand (cmdp, gnp)
     if (cpid == 0) {
 	Check_Cwd(av);
 	if (local) {
+	    struct iovec iov[4];
+	    
 	    execvp(av[0], av);
-	    (void) write (2, av[0], strlen (av[0]));
-	    (void) write (2, ": not found\n", sizeof(": not found"));
+	    iov[0].iov_base = av[0];
+	    iov[0].iov_len = strlen(av[0]);
+	    iov[1].iov_base = ": ";
+	    iov[1].iov_len = 2;
+	    if ((iov[2].iov_base = strerror(errno)) == NULL)
+		    iov[2].iov_base = "not found";
+	    iov[2].iov_len = strlen(iov[2].iov_base);
+	    iov[3].iov_base = "\n";
+	    iov[3].iov_len = 1;
+	    (void) writev (2, iov, 4);
 	} else {
 	    (void)execv(av[0], av);
 	}