From cd7a1a4ec867c031982522d0c13ca598f0c380f6 Mon Sep 17 00:00:00 2001 From: cheloha Date: Sat, 29 Jan 2022 00:19:04 +0000 Subject: [PATCH] head(1): refactor main loop The main loop here is horribly obfuscated. In particular, the path through the loop to exit(3) is very complex. Refactor the open/read/write/close portions of the loop out of main() into a separate function, head_file(). The result is a lot easier to understand at a glance. In particular, the path to the end of main() is now dead simple. Thread: https://marc.info/?l=openbsd-tech&m=164325900400701&w=2 ok millert@ --- usr.bin/head/head.c | 72 ++++++++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 30 deletions(-) diff --git a/usr.bin/head/head.c b/usr.bin/head/head.c index f0c10cd2666..90b07a078ab 100644 --- a/usr.bin/head/head.c +++ b/usr.bin/head/head.c @@ -1,4 +1,4 @@ -/* $OpenBSD: head.c,v 1.22 2021/10/10 15:57:25 cheloha Exp $ */ +/* $OpenBSD: head.c,v 1.23 2022/01/29 00:19:04 cheloha Exp $ */ /* * Copyright (c) 1980, 1987 Regents of the University of California. @@ -37,6 +37,7 @@ #include #include +int head_file(const char *, long, int); static void usage(void); /* @@ -49,9 +50,7 @@ int main(int argc, char *argv[]) { const char *errstr; - FILE *fp; - long cnt; - int ch, firsttime; + int ch; long linecnt = 10; int status = 0; @@ -81,33 +80,46 @@ main(int argc, char *argv[]) } argc -= optind, argv += optind; - for (firsttime = 1; ; firsttime = 0) { - if (!*argv) { - if (!firsttime) - exit(status); - fp = stdin; - if (pledge("stdio", NULL) == -1) - err(1, "pledge"); - } else { - if ((fp = fopen(*argv, "r")) == NULL) { - warn("%s", *argv++); - status = 1; - continue; - } - if (argc > 1) { - if (!firsttime) - putchar('\n'); - printf("==> %s <==\n", *argv); - } - ++argv; - } - for (cnt = linecnt; cnt && !feof(fp); --cnt) - while ((ch = getc(fp)) != EOF) - if (putchar(ch) == '\n') - break; - fclose(fp); + if (argc == 0) { + if (pledge("stdio", NULL) == -1) + err(1, "pledge"); + + status = head_file(NULL, linecnt, 0); + } else { + for (; *argv != NULL; argv++) + status |= head_file(*argv, linecnt, argc > 1); } - /*NOTREACHED*/ + + return status; +} + +int +head_file(const char *path, long count, int need_header) +{ + FILE *fp; + int ch; + static int first = 1; + + if (path != NULL) { + fp = fopen(path, "r"); + if (fp == NULL) { + warn("%s", path); + return 1; + } + if (need_header) { + printf("%s==> %s <==\n", first ? "" : "\n", path); + first = 0; + } + } else + fp = stdin; + + for (; count > 0 && !feof(fp); --count) + while ((ch = getc(fp)) != EOF) + if (putchar(ch) == '\n') + break; + fclose(fp); + + return 0; } -- 2.20.1