Date: Tue, 10 Aug 2021 21:11:45 GMT From: Ed Maste <emaste@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 38911b3c2c7d - main - ar: provide error exit status upon failure Message-ID: <202108102111.17ALBj38005221@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by emaste: URL: https://cgit.FreeBSD.org/src/commit/?id=38911b3c2c7dbb9a097b44856472ebbbedde71fc commit 38911b3c2c7dbb9a097b44856472ebbbedde71fc Author: Ed Maste <emaste@FreeBSD.org> AuthorDate: 2021-08-03 18:30:06 +0000 Commit: Ed Maste <emaste@FreeBSD.org> CommitDate: 2021-08-10 21:08:10 +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 --- 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 6ca20a372fdb..4cbdc12dcc2d 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); } /*
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202108102111.17ALBj38005221>