Subject: more user-friendly error message for /bin/sh?
To: None <tech-userlevel@NetBSD.org>
From: Roland Illig <rillig@NetBSD.org>
List: tech-userlevel
Date: 01/16/2007 20:57:30
This is a multi-part message in MIME format.
--------------000708070203000104070403
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit

Currently, I can do this:

$ /bin/sh /bin/cat
/bin/cat: 1: Syntax error: "(" unexpected

What about the following error message, which says what's really the 
problem:?

$ ./sh /bin/cat
./sh: Cannot execute ELF binary /bin/cat

(I just hope no one says they really have shell scripts starting with 
the ELF magic code, and that they need those bytes at the start of the 
script. ;))

Roland

--------------000708070203000104070403
Content-Type: text/plain;
 name="sh.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="sh.patch"

Index: input.c
===================================================================
RCS file: /cvsroot/src/bin/sh/input.c,v
retrieving revision 1.39
diff -u -p -r1.39 input.c
--- input.c	7 Aug 2003 09:05:32 -0000	1.39
+++ input.c	16 Jan 2007 19:57:01 -0000
@@ -384,12 +384,28 @@ popstring(void)
 void
 setinputfile(const char *fname, int push)
 {
+	unsigned char magic[4];
 	int fd;
 	int fd2;
 
 	INTOFF;
 	if ((fd = open(fname, O_RDONLY)) < 0)
 		error("Can't open %s", fname);
+
+	/* Since the message "Syntax error: "(" unexpected" is not very
+	 * helpful, we check if the file starts with the ELF magic to
+	 * avoid that message. The first lseek tries to make sure that
+	 * we can later rewind the file.
+	 */
+	if (lseek(fd, 0, SEEK_SET) == 0) {
+		if (read(fd, magic, 4) == 4) {
+			if (memcmp(magic, "\177ELF", 4) == 0)
+				error("Cannot execute ELF binary %s", fname);
+		}
+		if (lseek(fd, 0, SEEK_SET) != 0)
+			error("Cannot rewind the file %s", fname);
+	}
+
 	if (fd < 10) {
 		fd2 = copyfd(fd, 10);
 		close(fd);

--------------000708070203000104070403--