Subject: bin/4870: head(1) exits immediately, if arguments don't exist
To: None <gnats-bugs@gnats.netbsd.org>
From: NAKAJIMA Yoshihiro <nakayosh@kcn.or.jp>
List: netbsd-bugs
Date: 01/22/1998 23:28:26
>Number:         4870
>Category:       bin
>Synopsis:       head(1) exits immediately, if arguments don't exist
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Jan 22 06:35:01 1998
>Last-Modified:
>Originator:     NAKAJIMA Yoshihiro
>Organization:
>Release:        NetBSD-current 98/01/17
>Environment:
System: NetBSD asura 1.3B NetBSD 1.3B (ASURA) #1: Mon Jan 19 21:09:50 JST 1998 nakayosh@asura:/usr/src/sys/arch/i386/compile/ASURA i386


>Description:

If the first argument doesn't exist, head(1) exits immediately before
examining the latter arguments. And exit status is zero. Like this:

: % ls foo bar
: ls: foo: No such file or directory
: bar
: % head foo bar
: head: foo: No such file or directory: Bad file descriptor
: % echo $status
: 0

4.4BSD-Lite2's head(1) uses built-in err(), whose first argument is the
fatal error flag:

: void
: err(int fatal, const char *fmt, ...)
: {
<snip>
:         if (fatal)
:                 exit(1);
<snip>
: }

In other hand, NetBSD's err(3)'s first argument is the exit status.

>How-To-Repeat:

See above.

>Fix:

diff -u src/usr.bin/head/head.c.orig src/usr.bin/head/head.c
--- src/usr.bin/head/head.c.orig	Sun Oct 19 23:18:46 1997
+++ src/usr.bin/head/head.c	Thu Jan 22 21:30:32 1998
@@ -68,7 +68,7 @@
 void usage __P((void));
 int main __P((int, char *[]));
 
-int eval;
+int eval = 0;
 
 int
 main(argc, argv)
@@ -87,7 +87,7 @@
 		case 'n':
 			linecnt = strtol(optarg, &ep, 10);
 			if (*ep || linecnt <= 0)
-				err(1, "illegal line count -- %s", optarg);
+				errx(1, "illegal line count -- %s", optarg);
 			break;
 
 		case '?':
@@ -100,7 +100,8 @@
 	if (*argv)
 		for (first = 1; *argv; ++argv) {
 			if ((fp = fopen(*argv, "r")) == NULL) {
-				err(0, "%s: %s", *argv, strerror(errno));
+				warn("%s", *argv);
+				eval = 1;
 				continue;
 			}
 			if (argc > 1) {
@@ -126,7 +127,7 @@
 	while (cnt--)
 		while ((ch = getc(fp)) != EOF) {
 			if (putchar(ch) == EOF)
-				err(1, "stdout: %s", strerror(errno));
+				err(1, "stdout");
 			if (ch == '\n')
 				break;
 		}
@@ -143,7 +144,11 @@
 		if (ap[0] != '-' || ap[1] == '-' || !isdigit(ap[1]))
 			return;
 		if ((ap = malloc(strlen(*argv) + 2)) == NULL)
-			err(1, "%s", strerror(errno));
+#ifdef __GNUC__
+			err(1, "%s", "");
+#else
+			err(1, NULL);
+#endif
 		ap[0] = '-';
 		ap[1] = 'n';
 		(void)strcpy(ap + 2, *argv + 1);

>Audit-Trail:
>Unformatted: