The branch stable/13 has been updated by emaste:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=d71103026de3ad27e6a16ecf91823540620c6024

commit d71103026de3ad27e6a16ecf91823540620c6024
Author:     Ed Maste <ema...@freebsd.org>
AuthorDate: 2021-08-03 18:30:06 +0000
Commit:     Ed Maste <ema...@freebsd.org>
CommitDate: 2021-10-09 00:28:31 +0000

    ar: provide error exit status upon failure
    
    Previously ar and ranlib returned with exit status 0 (success) in the
    case of a missing file or other error.  Update to use error handling
    similar to that added by ELF Tool Chain after that project forked
    FreeBSD's ar.
    
    PR:             PR257599 [exp-run]
    Reported by:    Shawn Webb, gehmehgeh (on HardenedBSD IRC)
    Reviewed by:    markj
    Obtained from:  elftoolchain
    MFC after:      2 months
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D31402
    
    (cherry picked from commit 38911b3c2c7dbb9a097b44856472ebbbedde71fc)
---
 usr.bin/ar/acplex.l  |  4 ++--
 usr.bin/ar/acpyacc.y |  6 ++---
 usr.bin/ar/ar.c      | 62 ++++++++++++++++++++++++++++------------------------
 usr.bin/ar/ar.h      | 20 ++++++++---------
 usr.bin/ar/read.c    | 36 +++++++++++++++++++-----------
 usr.bin/ar/write.c   | 49 ++++++++++++++++++++++++-----------------
 6 files changed, 100 insertions(+), 77 deletions(-)

diff --git a/usr.bin/ar/acplex.l b/usr.bin/ar/acplex.l
index f9b7deba0dda..8eb47e6a8d0e 100644
--- a/usr.bin/ar/acplex.l
+++ b/usr.bin/ar/acplex.l
@@ -33,8 +33,8 @@ __FBSDID("$FreeBSD$");
 #include <err.h>
 #include <errno.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
-#include <sysexits.h>
 
 #include "y.tab.h"
 
@@ -72,7 +72,7 @@ SAVE|save             { return (SAVE); }
 [-_A-Za-z0-9/:$.\\]+   {
        yylval.str = strdup(yytext);
        if (yylval.str == NULL)
-               errc(EX_SOFTWARE, errno, "strdup failed");
+               errc(EXIT_FAILURE, errno, "strdup failed");
        return (FNAME);
 }
 
diff --git a/usr.bin/ar/acpyacc.y b/usr.bin/ar/acpyacc.y
index 113b3818bff1..5d4eb9fb6b37 100644
--- a/usr.bin/ar/acpyacc.y
+++ b/usr.bin/ar/acpyacc.y
@@ -191,7 +191,7 @@ directory_cmd
        ;
 
 end_cmd
-       : END { arscp_end(EX_OK); }
+       : END { arscp_end(EXIT_SUCCESS); }
        ;
 
 extract_cmd
@@ -655,9 +655,9 @@ ar_mode_script(struct bsdar *ar)
        interactive = isatty(fileno(stdin));
        while(yyparse()) {
                if (!interactive)
-                       arscp_end(1);
+                       arscp_end(EXIT_FAILURE);
        }
 
        /* Script ends without END */
-       arscp_end(EX_OK);
+       arscp_end(EXIT_SUCCESS);
 }
diff --git a/usr.bin/ar/ar.c b/usr.bin/ar/ar.c
index 8e02471e1623..b131163342a6 100644
--- a/usr.bin/ar/ar.c
+++ b/usr.bin/ar/ar.c
@@ -72,7 +72,6 @@ __FBSDID("$FreeBSD$");
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <sysexits.h>
 
 #include "ar.h"
 
@@ -102,10 +101,11 @@ main(int argc, char **argv)
        struct bsdar    *bsdar, bsdar_storage;
        char            *p;
        size_t           len;
-       int              i, opt, Dflag, Uflag;
+       int              exitcode, i, opt, Dflag, Uflag;
 
        bsdar = &bsdar_storage;
        memset(bsdar, 0, sizeof(*bsdar));
+       exitcode = EXIT_SUCCESS;
        Dflag = 0;
        Uflag = 0;
 
@@ -151,9 +151,10 @@ main(int argc, char **argv)
                        bsdar->options |= AR_D;
                bsdar->options |= AR_S;
                while ((bsdar->filename = *argv++) != NULL)
-                       ar_mode_s(bsdar);
+                       if (ar_mode_s(bsdar))
+                               exitcode = EXIT_FAILURE;
 
-               exit(EX_OK);
+               exit(exitcode);
        } else {
                if (argc < 2)
                        bsdar_usage();
@@ -161,7 +162,7 @@ main(int argc, char **argv)
                if (*argv[1] != '-') {
                        len = strlen(argv[1]) + 2;
                        if ((p = malloc(len)) == NULL)
-                               bsdar_errc(bsdar, EX_SOFTWARE, errno,
+                               bsdar_errc(bsdar, EXIT_FAILURE, errno,
                                    "malloc failed");
                        *p = '-';
                        (void)strlcpy(p + 1, argv[1], len - 1);
@@ -262,23 +263,23 @@ main(int argc, char **argv)
                bsdar_usage();
 
        if (bsdar->options & AR_A && bsdar->options & AR_B)
-               bsdar_errc(bsdar, EX_USAGE, 0,
+               bsdar_errc(bsdar, EXIT_FAILURE, 0,
                    "only one of -a and -[bi] options allowed");
 
        if (bsdar->options & AR_J && bsdar->options & AR_Z)
-               bsdar_errc(bsdar, EX_USAGE, 0,
+               bsdar_errc(bsdar, EXIT_FAILURE, 0,
                    "only one of -j and -z options allowed");
 
        if (bsdar->options & AR_S && bsdar->options & AR_SS)
-               bsdar_errc(bsdar, EX_USAGE, 0,
+               bsdar_errc(bsdar, EXIT_FAILURE, 0,
                    "only one of -s and -S options allowed");
 
        if (bsdar->options & (AR_A | AR_B)) {
                if (*argv == NULL)
-                       bsdar_errc(bsdar, EX_USAGE, 0,
+                       bsdar_errc(bsdar, EXIT_FAILURE, 0,
                            "no position operand specified");
                if ((bsdar->posarg = basename(*argv)) == NULL)
-                       bsdar_errc(bsdar, EX_SOFTWARE, errno,
+                       bsdar_errc(bsdar, EXIT_FAILURE, errno,
                            "basename failed");
                argc--;
                argv++;
@@ -310,7 +311,7 @@ main(int argc, char **argv)
 
        if (bsdar->mode == 'M') {
                ar_mode_script(bsdar);
-               exit(EX_OK);
+               exit(EXIT_SUCCESS);
        }
 
        if ((bsdar->filename = *argv) == NULL)
@@ -321,44 +322,47 @@ main(int argc, char **argv)
 
        if ((!bsdar->mode || strchr("ptx", bsdar->mode)) &&
            bsdar->options & AR_S) {
-               ar_mode_s(bsdar);
+               exitcode = ar_mode_s(bsdar);
                if (!bsdar->mode)
-                       exit(EX_OK);
+                       exit(exitcode);
        }
 
        switch(bsdar->mode) {
        case 'd':
-               ar_mode_d(bsdar);
+               exitcode = ar_mode_d(bsdar);
                break;
        case 'm':
-               ar_mode_m(bsdar);
+               exitcode = ar_mode_m(bsdar);
                break;
        case 'p':
-               ar_mode_p(bsdar);
+               exitcode = ar_mode_p(bsdar);
                break;
        case 'q':
-               ar_mode_q(bsdar);
+               exitcode = ar_mode_q(bsdar);
                break;
        case 'r':
-               ar_mode_r(bsdar);
+               exitcode = ar_mode_r(bsdar);
                break;
        case 't':
-               ar_mode_t(bsdar);
+               exitcode = ar_mode_t(bsdar);
                break;
        case 'x':
-               ar_mode_x(bsdar);
+               exitcode = ar_mode_x(bsdar);
                break;
        default:
                bsdar_usage();
                /* NOTREACHED */
        }
 
-       for (i = 0; i < bsdar->argc; i++)
-               if (bsdar->argv[i] != NULL)
+       for (i = 0; i < bsdar->argc; i++) {
+               if (bsdar->argv[i] != NULL) {
                        bsdar_warnc(bsdar, 0, "%s: not found in archive",
                            bsdar->argv[i]);
+                       exitcode = EXIT_FAILURE;
+               }
+       }
 
-       exit(EX_OK);
+       exit(exitcode);
 }
 
 static void
@@ -366,7 +370,7 @@ set_mode(struct bsdar *bsdar, char opt)
 {
 
        if (bsdar->mode != '\0' && bsdar->mode != opt)
-               bsdar_errc(bsdar, EX_USAGE, 0,
+               bsdar_errc(bsdar, EXIT_FAILURE, 0,
                    "Can't specify both -%c and -%c", opt, bsdar->mode);
        bsdar->mode = opt;
 }
@@ -376,7 +380,7 @@ only_mode(struct bsdar *bsdar, const char *opt, const char 
*valid_modes)
 {
 
        if (strchr(valid_modes, bsdar->mode) == NULL)
-               bsdar_errc(bsdar, EX_USAGE, 0,
+               bsdar_errc(bsdar, EXIT_FAILURE, 0,
                    "Option %s is not permitted in mode -%c", opt, bsdar->mode);
 }
 
@@ -395,7 +399,7 @@ bsdar_usage(void)
        (void)fprintf(stderr, "\tar -t [-Tv] archive [file ...]\n");
        (void)fprintf(stderr, "\tar -x [-CTouv] archive [file ...]\n");
        (void)fprintf(stderr, "\tar -V\n");
-       exit(EX_USAGE);
+       exit(EXIT_FAILURE);
 }
 
 static void
@@ -404,19 +408,19 @@ ranlib_usage(void)
 
        (void)fprintf(stderr, "usage:   ranlib [-DtU] archive ...\n");
        (void)fprintf(stderr, "\tranlib -V\n");
-       exit(EX_USAGE);
+       exit(EXIT_FAILURE);
 }
 
 static void
 bsdar_version(void)
 {
        (void)printf("BSD ar %s - %s\n", BSDAR_VERSION, 
archive_version_string());
-       exit(EX_OK);
+       exit(EXIT_SUCCESS);
 }
 
 static void
 ranlib_version(void)
 {
        (void)printf("ranlib %s - %s\n", BSDAR_VERSION, 
archive_version_string());
-       exit(EX_OK);
+       exit(EXIT_SUCCESS);
 }
diff --git a/usr.bin/ar/ar.h b/usr.bin/ar/ar.h
index 733724748221..21b3a669a943 100644
--- a/usr.bin/ar/ar.h
+++ b/usr.bin/ar/ar.h
@@ -54,7 +54,7 @@
  */
 #define        AC(CALL) do {                                                   
\
        if ((CALL))                                                     \
-               bsdar_errc(bsdar, EX_SOFTWARE, archive_errno(a), "%s",  \
+               bsdar_errc(bsdar, EXIT_FAILURE, archive_errno(a), "%s", \
                    archive_error_string(a));                           \
 } while (0)
 
@@ -117,13 +117,13 @@ struct bsdar {
 void   bsdar_errc(struct bsdar *, int _eval, int _code,
            const char *fmt, ...) __dead2;
 void   bsdar_warnc(struct bsdar *, int _code, const char *fmt, ...);
-void   ar_mode_d(struct bsdar *bsdar);
-void   ar_mode_m(struct bsdar *bsdar);
-void   ar_mode_p(struct bsdar *bsdar);
-void   ar_mode_q(struct bsdar *bsdar);
-void   ar_mode_r(struct bsdar *bsdar);
-void   ar_mode_s(struct bsdar *bsdar);
-void   ar_mode_t(struct bsdar *bsdar);
-void   ar_mode_x(struct bsdar *bsdar);
-void   ar_mode_A(struct bsdar *bsdar);
+int    ar_mode_d(struct bsdar *bsdar);
+int    ar_mode_m(struct bsdar *bsdar);
+int    ar_mode_p(struct bsdar *bsdar);
+int    ar_mode_q(struct bsdar *bsdar);
+int    ar_mode_r(struct bsdar *bsdar);
+int    ar_mode_s(struct bsdar *bsdar);
+int    ar_mode_t(struct bsdar *bsdar);
+int    ar_mode_x(struct bsdar *bsdar);
+int    ar_mode_A(struct bsdar *bsdar);
 void   ar_mode_script(struct bsdar *ar);
diff --git a/usr.bin/ar/read.c b/usr.bin/ar/read.c
index 7791fc155850..04130b859c32 100644
--- a/usr.bin/ar/read.c
+++ b/usr.bin/ar/read.c
@@ -37,38 +37,38 @@ __FBSDID("$FreeBSD$");
 #include <errno.h>
 #include <libgen.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
-#include <sysexits.h>
 
 #include "ar.h"
 
-static void read_archive(struct bsdar *bsdar, char mode);
+static int read_archive(struct bsdar *bsdar, char mode);
 
-void
+int
 ar_mode_p(struct bsdar *bsdar)
 {
 
-       read_archive(bsdar, 'p');
+       return (read_archive(bsdar, 'p'));
 }
 
-void
+int
 ar_mode_t(struct bsdar *bsdar)
 {
 
-       read_archive(bsdar, 't');
+       return (read_archive(bsdar, 't'));
 }
 
-void
+int
 ar_mode_x(struct bsdar *bsdar)
 {
 
-       read_archive(bsdar, 'x');
+       return (read_archive(bsdar, 'x'));
 }
 
 /*
  * Handle read modes: 'x', 't' and 'p'.
  */
-static void
+static int
 read_archive(struct bsdar *bsdar, char mode)
 {
        struct archive           *a;
@@ -85,13 +85,15 @@ read_archive(struct bsdar *bsdar, char mode)
        char                    **av;
        char                      buf[25];
        char                      find;
-       int                       flags, r, i;
+       int                       exitcode, flags, r, i;
 
        if ((a = archive_read_new()) == NULL)
-               bsdar_errc(bsdar, EX_SOFTWARE, 0, "archive_read_new failed");
+               bsdar_errc(bsdar, EXIT_FAILURE, 0, "archive_read_new failed");
        archive_read_support_format_ar(a);
        AC(archive_read_open_filename(a, bsdar->filename, DEF_BLKSZ));
 
+       exitcode = EXIT_SUCCESS;
+
        for (;;) {
                r = archive_read_next_header(a, &entry);
                if (r == ARCHIVE_WARN || r == ARCHIVE_RETRY ||
@@ -120,7 +122,7 @@ read_archive(struct bsdar *bsdar, char mode)
                                if (*av == NULL)
                                        continue;
                                if ((bname = basename(*av)) == NULL)
-                                       bsdar_errc(bsdar, EX_SOFTWARE, errno,
+                                       bsdar_errc(bsdar, EXIT_FAILURE, errno,
                                            "basename failed");
                                if (strcmp(bname, name) != 0)
                                        continue;
@@ -206,11 +208,19 @@ read_archive(struct bsdar *bsdar, char mode)
                                r = archive_read_extract(a, entry, flags);
                        }
 
-                       if (r)
+                       if (r) {
                                bsdar_warnc(bsdar, archive_errno(a), "%s",
                                    archive_error_string(a));
+                               exitcode = EXIT_FAILURE;
+                       }
                }
        }
+
+       if (r == ARCHIVE_FATAL)
+               exitcode = EXIT_FAILURE;
+
        AC(archive_read_close(a));
        AC(archive_read_free(a));
+
+       return (exitcode);
 }
diff --git a/usr.bin/ar/write.c b/usr.bin/ar/write.c
index f515b2b4eb1e..676a30f923b7 100644
--- a/usr.bin/ar/write.c
+++ b/usr.bin/ar/write.c
@@ -67,52 +67,52 @@ static void insert_obj(struct bsdar *bsdar, struct ar_obj 
*obj,
 static void    prefault_buffer(const char *buf, size_t s);
 static void    read_objs(struct bsdar *bsdar, const char *archive,
                    int checkargv);
-static void    write_archive(struct bsdar *bsdar, char mode);
+static int     write_archive(struct bsdar *bsdar, char mode);
 static void    write_cleanup(struct bsdar *bsdar);
 static void    write_data(struct bsdar *bsdar, struct archive *a,
                    const void *buf, size_t s);
 static void    write_objs(struct bsdar *bsdar);
 
-void
+int
 ar_mode_d(struct bsdar *bsdar)
 {
 
-       write_archive(bsdar, 'd');
+       return (write_archive(bsdar, 'd'));
 }
 
-void
+int
 ar_mode_m(struct bsdar *bsdar)
 {
 
-       write_archive(bsdar, 'm');
+       return (write_archive(bsdar, 'm'));
 }
 
-void
+int
 ar_mode_q(struct bsdar *bsdar)
 {
 
-       write_archive(bsdar, 'q');
+       return (write_archive(bsdar, 'q'));
 }
 
-void
+int
 ar_mode_r(struct bsdar *bsdar)
 {
 
-       write_archive(bsdar, 'r');
+       return (write_archive(bsdar, 'r'));
 }
 
-void
+int
 ar_mode_s(struct bsdar *bsdar)
 {
 
-       write_archive(bsdar, 's');
+       return (write_archive(bsdar, 's'));
 }
 
-void
+int
 ar_mode_A(struct bsdar *bsdar)
 {
 
-       write_archive(bsdar, 'A');
+       return (write_archive(bsdar, 'A'));
 }
 
 /*
@@ -378,16 +378,17 @@ read_objs(struct bsdar *bsdar, const char *archive, int 
checkargv)
 /*
  * Determine the constitution of resulting archive.
  */
-static void
+static int
 write_archive(struct bsdar *bsdar, char mode)
 {
        struct ar_obj            *nobj, *obj, *obj_temp, *pos;
        struct stat               sb;
        const char               *bname;
        char                    **av;
-       int                       i;
+       int                       exitcode, i;
 
        TAILQ_INIT(&bsdar->v_obj);
+       exitcode = EXIT_SUCCESS;
        nobj = NULL;
        pos = NULL;
        memset(&sb, 0, sizeof(sb));
@@ -400,14 +401,14 @@ write_archive(struct bsdar *bsdar, char mode)
                if (errno != ENOENT) {
                        bsdar_warnc(bsdar, 0, "stat %s failed",
                            bsdar->filename);
-                       return;
+                       return (EXIT_FAILURE);
                }
 
                /* We do not create archive in mode 'd', 'm' and 's'.  */
                if (mode != 'r' && mode != 'q') {
                        bsdar_warnc(bsdar, 0, "%s: no such file",
                            bsdar->filename);
-                       return;
+                       return (EXIT_FAILURE);
                }
 
                /* Issue a warning if -c is not specified when creating. */
@@ -491,8 +492,10 @@ write_archive(struct bsdar *bsdar, char mode)
                                 */
                                nobj = create_obj_from_file(bsdar, *av,
                                    obj->mtime);
-                               if (nobj == NULL)
+                               if (nobj == NULL) {
+                                       exitcode = EXIT_FAILURE;
                                        goto skip_obj;
+                               }
                        }
 
                        if (bsdar->options & AR_V)
@@ -526,8 +529,12 @@ new_archive:
                av = &bsdar->argv[i];
                if (*av != NULL && (mode == 'r' || mode == 'q')) {
                        nobj = create_obj_from_file(bsdar, *av, 0);
-                       if (nobj != NULL)
-                               insert_obj(bsdar, nobj, pos);
+                       if (nobj == NULL) {
+                               exitcode = EXIT_FAILURE;
+                               *av = NULL;
+                               continue;
+                       }
+                       insert_obj(bsdar, nobj, pos);
                        if (bsdar->options & AR_V && nobj != NULL)
                                (void)fprintf(stdout, "a - %s\n", *av);
                        *av = NULL;
@@ -537,6 +544,8 @@ new_archive:
 write_objs:
        write_objs(bsdar);
        write_cleanup(bsdar);
+
+       return (exitcode);
 }
 
 /*

Reply via email to