summaryrefslogtreecommitdiff
path: root/usr.bin/head
diff options
context:
space:
mode:
authorScott Soule Cheloha <cheloha@cvs.openbsd.org>2022-02-07 17:19:58 +0000
committerScott Soule Cheloha <cheloha@cvs.openbsd.org>2022-02-07 17:19:58 +0000
commit983088b9d99f2964ea472bed9c58dfda3de63247 (patch)
treefe53a257797ddd8b5a28fcace15db27e3080c4fd /usr.bin/head
parent1ee4139ad810c28017b8910a383b47002ebe28ce (diff)
head(1): check for stdio errors
- Output errors are terminal. - Input errors yield a warning and cause head(1) to fail gracefully. Tweaked by millert@. Thread: https://marc.info/?l=openbsd-tech&m=164419238123928&w=2 ok millert@
Diffstat (limited to 'usr.bin/head')
-rw-r--r--usr.bin/head/head.c35
1 files changed, 24 insertions, 11 deletions
diff --git a/usr.bin/head/head.c b/usr.bin/head/head.c
index 90b07a078ab..73670621524 100644
--- a/usr.bin/head/head.c
+++ b/usr.bin/head/head.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: head.c,v 1.23 2022/01/29 00:19:04 cheloha Exp $ */
+/* $OpenBSD: head.c,v 1.24 2022/02/07 17:19:57 cheloha Exp $ */
/*
* Copyright (c) 1980, 1987 Regents of the University of California.
@@ -96,30 +96,43 @@ main(int argc, char *argv[])
int
head_file(const char *path, long count, int need_header)
{
+ const char *name;
FILE *fp;
- int ch;
+ int ch, status = 0;
static int first = 1;
if (path != NULL) {
- fp = fopen(path, "r");
+ name = path;
+ fp = fopen(name, "r");
if (fp == NULL) {
- warn("%s", path);
+ warn("%s", name);
return 1;
}
if (need_header) {
- printf("%s==> %s <==\n", first ? "" : "\n", path);
+ printf("%s==> %s <==\n", first ? "" : "\n", name);
+ if (ferror(stdout))
+ err(1, "stdout");
first = 0;
}
- } else
+ } else {
+ name = "stdin";
fp = stdin;
+ }
+
+ while ((ch = getc(fp)) != EOF) {
+ if (putchar(ch) == EOF)
+ err(1, "stdout");
+ if (ch == '\n' && --count == 0)
+ break;
+ }
+ if (ferror(fp)) {
+ warn("%s", name);
+ status = 1;
+ }
- for (; count > 0 && !feof(fp); --count)
- while ((ch = getc(fp)) != EOF)
- if (putchar(ch) == '\n')
- break;
fclose(fp);
- return 0;
+ return status;
}