Jérémie Courrèges-Anglas wrote:
> Tobias Stoeckmann <tob...@stoeckmann.org> writes:
> 
> > $ sed s/a/b/ /nofile
> > sed: 0: /nofile: /nofile
> >
> > That message doesn't tell me a lot, let's better write
> > strerror(errno) if fopen returns NULL:
> >
> > $ ./sed s/a/b/ /nofile
> > sed: 0: /nofile: No such file or directory
> 
> That's much nicer, ok jca@
> 
> (misc.c:err() already prints the file name)

Yikes. I was initially confused because err(3) automatically appends the
errno. Then I realized that sed redefines err.

As guenther@ (and/or millert@?) has been working on lately, redefining
stdlib functions is risky. sed contains examples such as the pledge()
calls in which the programmer definitely seems to think they're using
err(3).

It looks like it can be pretty easily replaced with calls to err(3),
errx(3), warn(3), warnx(3), etc. However, it'd be easiest to rename the
function to error() first.

Thoughts?


Index: compile.c
===================================================================
RCS file: /cvs/src/usr.bin/sed/compile.c,v
retrieving revision 1.38
diff -u -p -r1.38 compile.c
--- compile.c   23 Jun 2015 22:52:55 -0000      1.38
+++ compile.c   25 Oct 2015 22:43:40 -0000
@@ -153,7 +153,7 @@ compile_stream(struct s_command **link)
        for (;;) {
                if ((p = cu_fgets(&lbuf, &bufsize)) == NULL) {
                        if (stack != 0)
-                               err(COMPILE, "unexpected EOF (pending }'s)");
+                               sed_err(COMPILE, "unexpected EOF (pending 
}'s)");
                        return (link);
                }
 
@@ -193,15 +193,15 @@ semicolon:        EATSPACE();
 
 nonsel:                /* Now parse the command */
                if (!*p)
-                       err(COMPILE, "command expected");
+                       sed_err(COMPILE, "command expected");
                cmd->code = *p;
                for (fp = cmd_fmts; fp->code; fp++)
                        if (fp->code == *p)
                                break;
                if (!fp->code)
-                       err(COMPILE, "invalid command code %c", *p);
+                       sed_err(COMPILE, "invalid command code %c", *p);
                if (naddr > fp->naddr)
-                       err(COMPILE,
+                       sed_err(COMPILE,
                            "command %c expects up to %d address(es), found %d",
                            *p, fp->naddr, naddr);
                switch (fp->args) {
@@ -226,7 +226,7 @@ nonsel:             /* Now parse the command */
                         */
                        cmd->nonsel = 1;
                        if (stack == 0)
-                               err(COMPILE, "unexpected }");
+                               sed_err(COMPILE, "unexpected }");
                        cmd2 = stack;
                        stack = cmd2->next;
                        cmd2->next = cmd;
@@ -240,19 +240,19 @@ nonsel:           /* Now parse the command */
                                goto semicolon;
                        }
                        if (*p)
-                               err(COMPILE,
+                               sed_err(COMPILE,
 "extra characters at the end of %c command", cmd->code);
                        break;
                case TEXT:                      /* a c i */
                        p++;
                        EATSPACE();
                        if (*p != '\\')
-                               err(COMPILE, "command %c expects \\ followed by"
+                               sed_err(COMPILE, "command %c expects \\ 
followed by"
                                    " text", cmd->code);
                        p++;
                        EATSPACE();
                        if (*p)
-                               err(COMPILE, "extra characters after \\ at the"
+                               sed_err(COMPILE, "extra characters after \\ at 
the"
                                    " end of %c command", cmd->code);
                        cmd->t = compile_text();
                        break;
@@ -262,14 +262,14 @@ nonsel:           /* Now parse the command */
                        p++;
                        EATSPACE();
                        if (*p == '\0')
-                               err(COMPILE, "filename expected");
+                               sed_err(COMPILE, "filename expected");
                        cmd->t = duptoeol(p, "w command", NULL);
                        if (aflag)
                                cmd->u.fd = -1;
                        else if ((cmd->u.fd = open(p,
                            O_WRONLY|O_APPEND|O_CREAT|O_TRUNC,
                            DEFFILEMODE)) == -1)
-                               err(FATAL, "%s: %s", p, strerror(errno));
+                               sed_err(FATAL, "%s: %s", p, strerror(errno));
                        break;
                case RFILE:                     /* r */
                        p++;
@@ -293,7 +293,7 @@ nonsel:             /* Now parse the command */
                        EATSPACE();
                        cmd->t = duptoeol(p, "label", &p);
                        if (strlen(cmd->t) == 0)
-                               err(COMPILE, "empty label");
+                               sed_err(COMPILE, "empty label");
                        enterlabel(cmd);
                        if (*p == ';') {
                                p++;
@@ -303,12 +303,12 @@ nonsel:           /* Now parse the command */
                case SUBST:                     /* s */
                        p++;
                        if (*p == '\0' || *p == '\\')
-                               err(COMPILE, "substitute pattern can not be"
+                               sed_err(COMPILE, "substitute pattern can not be"
                                    " delimited by newline or backslash");
                        cmd->u.s = xmalloc(sizeof(struct s_subst));
                        p = compile_re(p, &cmd->u.s->re);
                        if (p == NULL)
-                               err(COMPILE, "unterminated substitute pattern");
+                               sed_err(COMPILE, "unterminated substitute 
pattern");
                        --p;
                        p = compile_subst(p, cmd->u.s);
                        p = compile_flags(p, cmd->u.s);
@@ -329,7 +329,7 @@ nonsel:             /* Now parse the command */
                                goto semicolon;
                        }
                        if (*p)
-                               err(COMPILE, "extra text at the end of a"
+                               sed_err(COMPILE, "extra text at the end of a"
                                    " transform command");
                        break;
                }
@@ -354,13 +354,13 @@ compile_delimited(char *p, char *d, int 
        if (c == '\0')
                return (NULL);
        else if (c == '\\')
-               err(COMPILE, "\\ can not be used as a string delimiter");
+               sed_err(COMPILE, "\\ can not be used as a string delimiter");
        else if (c == '\n')
-               err(COMPILE, "newline can not be used as a string delimiter");
+               sed_err(COMPILE, "newline can not be used as a string 
delimiter");
        while (*p) {
                if (*p == '[' && *p != c) {
                        if ((d = compile_ccl(&p, d)) == NULL)
-                               err(COMPILE, "unbalanced brackets ([])");
+                               sed_err(COMPILE, "unbalanced brackets ([])");
                        continue;
                } else if (*p == '\\' && p[1] == '[') {
                        *d++ = *p++;
@@ -439,7 +439,7 @@ compile_re(char *p, regex_t **repp)
        }
        *repp = xmalloc(sizeof(regex_t));
        if (p && (eval = regcomp(*repp, re, Eflag ? REG_EXTENDED : 0)) != 0)
-               err(COMPILE, "RE error: %s", strregerror(eval, *repp));
+               sed_err(COMPILE, "RE error: %s", strregerror(eval, *repp));
        if (maxnsub < (*repp)->re_nsub)
                maxnsub = (*repp)->re_nsub;
        free(re);
@@ -505,7 +505,7 @@ compile_subst(char *p, struct s_subst *s
                                        ref = *p - '0';
                                        if (s->re != NULL &&
                                            ref > s->re->re_nsub)
-                                               err(COMPILE,
+                                               sed_err(COMPILE,
 "\\%c not defined in the RE", *p);
                                        if (s->maxbref < ref)
                                                s->maxbref = ref;
@@ -518,7 +518,7 @@ compile_subst(char *p, struct s_subst *s
                                s->new = xrealloc(text, size);
                                return (p);
                        } else if (*p == '\n') {
-                               err(COMPILE,
+                               sed_err(COMPILE,
 "unescaped newline inside substitute pattern");
                                /* NOTREACHED */
                        }
@@ -526,7 +526,7 @@ compile_subst(char *p, struct s_subst *s
                }
                size += sp - op;
        } while ((p = cu_fgets(&lbuf, &bufsize)));
-       err(COMPILE, "unterminated substitute in regular expression");
+       sed_err(COMPILE, "unterminated substitute in regular expression");
        /* NOTREACHED */
 }
 
@@ -549,7 +549,7 @@ compile_flags(char *p, struct s_subst *s
                switch (*p) {
                case 'g':
                        if (gn)
-                               err(COMPILE, "more than one number or 'g' in"
+                               sed_err(COMPILE, "more than one number or 'g' 
in"
                                    " substitute flags");
                        gn = 1;
                        s->n = 0;
@@ -565,12 +565,12 @@ compile_flags(char *p, struct s_subst *s
                case '4': case '5': case '6':
                case '7': case '8': case '9':
                        if (gn)
-                               err(COMPILE, "more than one number or 'g' in"
+                               sed_err(COMPILE, "more than one number or 'g' 
in"
                                    " substitute flags");
                        gn = 1;
                        l = strtol(p, &p, 10);
                        if (l <= 0 || l >= INT_MAX)
-                               err(COMPILE,
+                               sed_err(COMPILE,
                                    "number in substitute flags out of range");
                        s->n = (int)l;
                        continue;
@@ -578,7 +578,7 @@ compile_flags(char *p, struct s_subst *s
                        p++;
 #ifdef HISTORIC_PRACTICE
                        if (*p != ' ') {
-                               err(WARNING, "space missing before w wfile");
+                               sed_err(WARNING, "space missing before w 
wfile");
                                return (p);
                        }
 #endif
@@ -589,20 +589,20 @@ compile_flags(char *p, struct s_subst *s
                                if (*p == '\n')
                                        break;
                                if (q >= eq)
-                                       err(COMPILE, "wfile too long");
+                                       sed_err(COMPILE, "wfile too long");
                                *q++ = *p++;
                        }
                        *q = '\0';
                        if (q == wfile)
-                               err(COMPILE, "no wfile specified");
+                               sed_err(COMPILE, "no wfile specified");
                        s->wfile = strdup(wfile);
                        if (!aflag && (s->wfd = open(wfile,
                            O_WRONLY|O_APPEND|O_CREAT|O_TRUNC,
                            DEFFILEMODE)) == -1)
-                               err(FATAL, "%s: %s", wfile, strerror(errno));
+                               sed_err(FATAL, "%s: %s", wfile, 
strerror(errno));
                        return (p);
                default:
-                       err(COMPILE,
+                       sed_err(COMPILE,
                            "bad flag in substitute command: '%c'", *p);
                        break;
                }
@@ -621,23 +621,23 @@ compile_tr(char *p, char **transtab)
        char *old = NULL, *new = NULL;
 
        if (*p == '\0' || *p == '\\')
-               err(COMPILE,
+               sed_err(COMPILE,
 "transform pattern can not be delimited by newline or backslash");
        old = xmalloc(strlen(p) + 1);
        p = compile_delimited(p, old, 1);
        if (p == NULL) {
-               err(COMPILE, "unterminated transform source string");
+               sed_err(COMPILE, "unterminated transform source string");
                goto bad;
        }
        new = xmalloc(strlen(p) + 1);
        p = compile_delimited(--p, new, 1);
        if (p == NULL) {
-               err(COMPILE, "unterminated transform target string");
+               sed_err(COMPILE, "unterminated transform target string");
                goto bad;
        }
        EATSPACE();
        if (strlen(new) != strlen(old)) {
-               err(COMPILE, "transform strings are not the same length");
+               sed_err(COMPILE, "transform strings are not the same length");
                goto bad;
        }
        /* We assume characters are 8 bits */
@@ -710,7 +710,7 @@ compile_addr(char *p, struct s_addr *a)
        case '/':                               /* Context address */
                p = compile_re(p, &a->u.r);
                if (p == NULL)
-                       err(COMPILE, "unterminated regular expression");
+                       sed_err(COMPILE, "unterminated regular expression");
                a->type = AT_RE;
                return (p);
 
@@ -724,7 +724,7 @@ compile_addr(char *p, struct s_addr *a)
                a->u.l = strtoul(p, &end, 10);
                return (end);
        default:
-               err(COMPILE, "expected context address");
+               sed_err(COMPILE, "expected context address");
                return (NULL);
        }
 }
@@ -750,7 +750,7 @@ duptoeol(char *s, char *ctype, char **se
                *s = '\0';
        }
        if (ws)
-               err(WARNING, "whitespace after %s", ctype);
+               sed_err(WARNING, "whitespace after %s", ctype);
        len = s - start + 1;
        if (semi)
                *semi = s;
@@ -784,7 +784,7 @@ fixuplabel(struct s_command *cp, struct 
                                break;
                        }
                        if ((cp->u.c = findlabel(cp->t)) == NULL)
-                               err(COMPILE2, "undefined label '%s'", cp->t);
+                               sed_err(COMPILE2, "undefined label '%s'", 
cp->t);
                        free(cp->t);
                        break;
                case '{':
@@ -809,7 +809,7 @@ enterlabel(struct s_command *cp)
        lhp = &labels[h & LHMASK];
        for (lh = *lhp; lh != NULL; lh = lh->lh_next)
                if (lh->lh_hash == h && strcmp(cp->t, lh->lh_cmd->t) == 0)
-                       err(COMPILE2, "duplicate label '%s'", cp->t);
+                       sed_err(COMPILE2, "duplicate label '%s'", cp->t);
        lh = xmalloc(sizeof *lh);
        lh->lh_next = *lhp;
        lh->lh_hash = h;
@@ -854,7 +854,7 @@ uselabel(void)
                for (lh = labels[i]; lh != NULL; lh = next) {
                        next = lh->lh_next;
                        if (!lh->lh_ref)
-                               err(WARNING, "unused label '%s'",
+                               sed_err(WARNING, "unused label '%s'",
                                    lh->lh_cmd->t);
                        free(lh);
                }
Index: extern.h
===================================================================
RCS file: /cvs/src/usr.bin/sed/extern.h,v
retrieving revision 1.10
diff -u -p -r1.10 extern.h
--- extern.h    17 Jul 2015 20:38:57 -0000      1.10
+++ extern.h    25 Oct 2015 22:43:40 -0000
@@ -48,7 +48,7 @@ void   cfclose(struct s_command *, struct
 void    compile(void);
 void    cspace(SPACE *, const char *, size_t, enum e_spflag);
 char   *cu_fgets(char **, size_t *);
-void    err(int, const char *, ...);
+void    sed_err(int, const char *, ...);
 int     mf_fgets(SPACE *, enum e_spflag);
 int     lastline(void);
 void    process(void);
Index: main.c
===================================================================
RCS file: /cvs/src/usr.bin/sed/main.c,v
retrieving revision 1.27
diff -u -p -r1.27 main.c
--- main.c      10 Oct 2015 20:18:30 -0000      1.27
+++ main.c      25 Oct 2015 22:43:40 -0000
@@ -161,10 +161,10 @@ main(int argc, char *argv[])
 
        if (inplace != NULL) {
                if (pledge("stdio rpath wpath cpath fattr", NULL) == -1)
-                       err(1, "pledge");
+                       sed_err(1, "pledge");
        } else {
                if (pledge("stdio rpath wpath cpath", NULL) == -1)
-                       err(1, "pledge");
+                       sed_err(1, "pledge");
        }
 
        /* First usage case; script is the first arg */
@@ -184,7 +184,7 @@ main(int argc, char *argv[])
        process();
        cfclose(prog, NULL);
        if (fclose(stdout))
-               err(FATAL, "stdout: %s", strerror(errno));
+               sed_err(FATAL, "stdout: %s", strerror(errno));
        exit (rval);
 }
 
@@ -214,7 +214,7 @@ again:
                switch (script->type) {
                case CU_FILE:
                        if ((f = fopen(script->s, "r")) == NULL)
-                               err(FATAL,
+                               sed_err(FATAL,
                                    "%s: %s", script->s, strerror(errno));
                        fname = script->s;
                        state = ST_FILE;
@@ -305,7 +305,7 @@ mf_fgets(SPACE *sp, enum e_spflag spflag
                /* stdin? */
                if (files->fname == NULL) {
                        if (inplace != NULL)
-                               err(FATAL, "-i may not be used with stdin");
+                               sed_err(FATAL, "-i may not be used with stdin");
                        infile = stdin;
                        fname = "stdin";
                        outfile = stdout;
@@ -329,7 +329,7 @@ mf_fgets(SPACE *sp, enum e_spflag spflag
                        fclose(infile);
                        if (*oldfname != '\0') {
                                if (rename(fname, oldfname) != 0) {
-                                       err(WARNING, "rename()");
+                                       sed_err(WARNING, "rename()");
                                        unlink(tmpfname);
                                        exit(1);
                                }
@@ -355,10 +355,10 @@ mf_fgets(SPACE *sp, enum e_spflag spflag
                fname = files->fname;
                if (inplace != NULL) {
                        if (lstat(fname, &sb) != 0)
-                               err(1, "%s: %s", fname,
+                               sed_err(1, "%s: %s", fname,
                                    strerror(errno ? errno : EIO));
                        if (!S_ISREG(sb.st_mode))
-                               err(FATAL, "%s: %s %s", fname,
+                               sed_err(FATAL, "%s: %s %s", fname,
                                    "in-place editing only",
                                    "works for regular files");
                        if (*inplace != '\0') {
@@ -367,17 +367,17 @@ mf_fgets(SPACE *sp, enum e_spflag spflag
                                len = strlcat(oldfname, inplace,
                                    sizeof(oldfname));
                                if (len > sizeof(oldfname))
-                                       err(FATAL, "%s: name too long", fname);
+                                       sed_err(FATAL, "%s: name too long", 
fname);
                        }
                        len = snprintf(tmpfname, sizeof(tmpfname), 
"%s/sedXXXXXXXXXX",
                            dirname(fname));
                        if (len >= sizeof(tmpfname))
-                               err(FATAL, "%s: name too long", fname);
+                               sed_err(FATAL, "%s: name too long", fname);
                        if ((fd = mkstemp(tmpfname)) == -1)
-                               err(FATAL, "%s", fname);
+                               sed_err(FATAL, "%s", fname);
                        if ((outfile = fdopen(fd, "w")) == NULL) {
                                unlink(tmpfname);
-                               err(FATAL, "%s", fname);
+                               sed_err(FATAL, "%s", fname);
                        }
                        fchown(fileno(outfile), sb.st_uid, sb.st_gid);
                        fchmod(fileno(outfile), sb.st_mode & ALLPERMS);
@@ -389,7 +389,7 @@ mf_fgets(SPACE *sp, enum e_spflag spflag
                        outfname = "stdout";
                }
                if ((infile = fopen(fname, "r")) == NULL) {
-                       err(WARNING, "%s", fname);
+                       sed_err(WARNING, "%s", fname);
                        rval = 1;
                        continue;
                }
@@ -405,7 +405,7 @@ mf_fgets(SPACE *sp, enum e_spflag spflag
         */
        p = fgetln(infile, &len);
        if (ferror(infile))
-               err(FATAL, "%s: %s", fname, strerror(errno ? errno : EIO));
+               sed_err(FATAL, "%s: %s", fname, strerror(errno ? errno : EIO));
        if (len != 0 && p[len - 1] == '\n') {
                sp->append_newline = 1;
                len--;
Index: misc.c
===================================================================
RCS file: /cvs/src/usr.bin/sed/misc.c,v
retrieving revision 1.10
diff -u -p -r1.10 misc.c
--- misc.c      8 Oct 2014 04:19:08 -0000       1.10
+++ misc.c      25 Oct 2015 22:43:40 -0000
@@ -54,7 +54,7 @@ xmalloc(size_t size)
        void *p;
 
        if ((p = malloc(size)) == NULL)
-               err(FATAL, "%s", strerror(errno));
+               sed_err(FATAL, "%s", strerror(errno));
        return (p);
 }
 
@@ -64,7 +64,7 @@ xreallocarray(void *o, size_t nmemb, siz
        void *p;
 
        if ((p = reallocarray(o, nmemb, size)) == NULL)
-               err(FATAL, "%s", strerror(errno));
+               sed_err(FATAL, "%s", strerror(errno));
        return (p);
 }
 
@@ -76,7 +76,7 @@ xrealloc(void *p, size_t size)
 {
 
        if ((p = realloc(p, size)) == NULL)
-               err(FATAL, "%s", strerror(errno));
+               sed_err(FATAL, "%s", strerror(errno));
        return (p);
 }
 
@@ -102,7 +102,7 @@ strregerror(int errcode, regex_t *preg)
  * Error reporting function
  */
 void
-err(int severity, const char *fmt, ...)
+sed_err(int severity, const char *fmt, ...)
 {
        va_list ap;
 
Index: process.c
===================================================================
RCS file: /cvs/src/usr.bin/sed/process.c,v
retrieving revision 1.26
diff -u -p -r1.26 process.c
--- process.c   20 Jul 2015 18:24:15 -0000      1.26
+++ process.c   25 Oct 2015 22:43:40 -0000
@@ -226,11 +226,11 @@ redirect:
                                if (cp->u.fd == -1 && (cp->u.fd = open(cp->t,
                                    O_WRONLY|O_APPEND|O_CREAT|O_TRUNC,
                                    DEFFILEMODE)) == -1)
-                                       err(FATAL, "%s: %s",
+                                       sed_err(FATAL, "%s: %s",
                                            cp->t, strerror(errno));
                                if (write(cp->u.fd, ps, psl) != psl ||
                                    write(cp->u.fd, "\n", 1) != 1)
-                                       err(FATAL, "%s: %s",
+                                       sed_err(FATAL, "%s: %s",
                                            cp->t, strerror(errno));
                                break;
                        case 'x':
@@ -342,7 +342,7 @@ substitute(struct s_command *cp)
        if (re == NULL) {
                if (defpreg != NULL && cp->u.s->maxbref > defpreg->re_nsub) {
                        linenum = cp->u.s->linenum;
-                       err(COMPILE, "\\%d not defined in the RE",
+                       sed_err(COMPILE, "\\%d not defined in the RE",
                            cp->u.s->maxbref);
                }
        }
@@ -422,10 +422,10 @@ substitute(struct s_command *cp)
        if (cp->u.s->wfile && !pd) {
                if (cp->u.s->wfd == -1 && (cp->u.s->wfd = open(cp->u.s->wfile,
                    O_WRONLY|O_APPEND|O_CREAT|O_TRUNC, DEFFILEMODE)) == -1)
-                       err(FATAL, "%s: %s", cp->u.s->wfile, strerror(errno));
+                       sed_err(FATAL, "%s: %s", cp->u.s->wfile, 
strerror(errno));
                if (write(cp->u.s->wfd, ps, psl) != psl ||
                    write(cp->u.s->wfd, "\n", 1) != 1)
-                       err(FATAL, "%s: %s", cp->u.s->wfile, strerror(errno));
+                       sed_err(FATAL, "%s: %s", cp->u.s->wfile, 
strerror(errno));
        }
        return (1);
 }
@@ -464,7 +464,7 @@ flush_appends(void)
                        break;
                }
        if (ferror(outfile))
-               err(FATAL, "%s: %s", outfname, strerror(errno ? errno : EIO));
+               sed_err(FATAL, "%s: %s", outfname, strerror(errno ? errno : 
EIO));
        appendx = sdone = 0;
 }
 
@@ -504,7 +504,7 @@ lputs(char *s)
        (void)fputc('$', outfile);
        (void)fputc('\n', outfile);
        if (ferror(outfile))
-               err(FATAL, "%s: %s", outfname, strerror(errno ? errno : EIO));
+               sed_err(FATAL, "%s: %s", outfname, strerror(errno ? errno : 
EIO));
 }
 
 static inline int
@@ -515,7 +515,7 @@ regexec_e(regex_t *preg, const char *str
 
        if (preg == NULL) {
                if (defpreg == NULL)
-                       err(FATAL, "first RE may not be empty");
+                       sed_err(FATAL, "first RE may not be empty");
        } else
                defpreg = preg;
 
@@ -531,7 +531,7 @@ regexec_e(regex_t *preg, const char *str
        case REG_NOMATCH:
                return (0);
        }
-       err(FATAL, "RE error: %s", strregerror(eval, defpreg));
+       sed_err(FATAL, "RE error: %s", strregerror(eval, defpreg));
        /* NOTREACHED */
 }
 
@@ -616,13 +616,13 @@ cfclose(struct s_command *cp, struct s_c
                switch (cp->code) {
                case 's':
                        if (cp->u.s->wfd != -1 && close(cp->u.s->wfd))
-                               err(FATAL,
+                               sed_err(FATAL,
                                    "%s: %s", cp->u.s->wfile, strerror(errno));
                        cp->u.s->wfd = -1;
                        break;
                case 'w':
                        if (cp->u.fd != -1 && close(cp->u.fd))
-                               err(FATAL, "%s: %s", cp->t, strerror(errno));
+                               sed_err(FATAL, "%s: %s", cp->t, 
strerror(errno));
                        cp->u.fd = -1;
                        break;
                case '{':

Reply via email to