On Wed, Oct 18, 2023 at 11:34:09AM +0200, Claudio Jeker wrote:
> On Tue, Oct 17, 2023 at 10:06:54AM +0200, Sebastian Benoit wrote:
> > Theo Buehler(t...@theobuehler.org) on 2023.10.17 09:13:15 +0200:
> > > On Mon, Oct 16, 2023 at 12:19:17PM +0200, Claudio Jeker wrote:
> > > > I dislike how log.c does all these asprintf() calls with dubious
> > > > workaround calls in case asprintf() fails.
> > > 
> > > You're not alone.
> > > 
> > > > IMO it is easier to use the stdio provided buffers and fflush() to get
> > > > "atomic" writes on stderr. At least from my understanding this is the
> > > > reason to go all this lenght to do a single fprintf call.
> > > 
> > > This makes sense, but I don't know the history here.
> > 
> > as far as i can remember, it was done so it would still be able to work
> > somewhat when out of memeory.
> >  
> 
> After some input off-list here another idea.
> Require that logit() is called with a \n and by that simplify a lot of
> code around it. vsyslog() handles both so having the \n should not cause
> any breakage.

Really hard to say which is the lesser evil: requiring \n or the ugly
asprintf dances. I don't think it is flat out objectionable, but I can
see people disliking this. The churn you outline below seems indeed
rather limited, so I guess we can go this way.

Definitely ok with using a stack buffer rather than a static one.

> 
> Now logit() is mostly used internally but in bgpd it is also used in
> logmsg.c and parse.y. Fixing those is simple.
> 
> Also this uses a stack buffer for all the log_* cases now. This should
> make the code more thread safe.
> 
> Also this removes vlog() from the API.  I had a quick look at all the
> other log.c users and apart from ldapd this can be added to all of them
> without much issues. Nothing else uses vlog() and the logit() is also very
> minimal (mostly the same parse.y change as below).
> 
> -- 
> :wq Claudio
> 
> Index: log.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/log.c,v
> retrieving revision 1.64
> diff -u -p -r1.64 log.c
> --- log.c     21 Mar 2017 12:06:55 -0000      1.64
> +++ log.c     18 Oct 2023 07:10:32 -0000
> @@ -26,6 +26,8 @@
>  
>  #include "log.h"
>  
> +#define MAX_LOGLEN   4096
> +
>  static int            debug;
>  static int            verbose;
>  static const char    *log_procname;
> @@ -68,30 +70,15 @@ void
>  logit(int pri, const char *fmt, ...)
>  {
>       va_list ap;
> +     int     saved_errno = errno;
>  
>       va_start(ap, fmt);
> -     vlog(pri, fmt, ap);
> -     va_end(ap);
> -}
> -
> -void
> -vlog(int pri, const char *fmt, va_list ap)
> -{
> -     char    *nfmt;
> -     int      saved_errno = errno;
> -
>       if (debug) {
> -             /* best effort in out of mem situations */
> -             if (asprintf(&nfmt, "%s\n", fmt) == -1) {
> -                     vfprintf(stderr, fmt, ap);
> -                     fprintf(stderr, "\n");
> -             } else {
> -                     vfprintf(stderr, nfmt, ap);
> -                     free(nfmt);
> -             }
> +             vfprintf(stderr, fmt, ap);
>               fflush(stderr);
>       } else
>               vsyslog(pri, fmt, ap);
> +     va_end(ap);
>  
>       errno = saved_errno;
>  }
> @@ -99,26 +86,18 @@ vlog(int pri, const char *fmt, va_list a
>  void
>  log_warn(const char *emsg, ...)
>  {
> -     char            *nfmt;
> -     va_list          ap;
> -     int              saved_errno = errno;
> +     char    fmtbuf[MAX_LOGLEN];
> +     va_list ap;
> +     int     saved_errno = errno;
>  
>       /* best effort to even work in out of memory situations */
>       if (emsg == NULL)
> -             logit(LOG_ERR, "%s", strerror(saved_errno));
> +             logit(LOG_ERR, "%s\n", strerror(saved_errno));
>       else {
>               va_start(ap, emsg);
> -
> -             if (asprintf(&nfmt, "%s: %s", emsg,
> -                 strerror(saved_errno)) == -1) {
> -                     /* we tried it... */
> -                     vlog(LOG_ERR, emsg, ap);
> -                     logit(LOG_ERR, "%s", strerror(saved_errno));
> -             } else {
> -                     vlog(LOG_ERR, nfmt, ap);
> -                     free(nfmt);
> -             }
> +             (void)vsnprintf(fmtbuf, sizeof(fmtbuf), emsg, ap);
>               va_end(ap);
> +             logit(LOG_ERR, "%s: %s\n", fmtbuf, strerror(saved_errno));
>       }
>  
>       errno = saved_errno;
> @@ -127,53 +106,65 @@ log_warn(const char *emsg, ...)
>  void
>  log_warnx(const char *emsg, ...)
>  {
> -     va_list  ap;
> +     char    fmtbuf[MAX_LOGLEN];
> +     va_list ap;
> +     int     saved_errno = errno;
>  
>       va_start(ap, emsg);
> -     vlog(LOG_ERR, emsg, ap);
> +     (void)vsnprintf(fmtbuf, sizeof(fmtbuf), emsg, ap);
>       va_end(ap);
> +     logit(LOG_ERR, "%s\n", fmtbuf);
> +
> +     errno = saved_errno;
>  }
>  
>  void
>  log_info(const char *emsg, ...)
>  {
> -     va_list  ap;
> +     char    fmtbuf[MAX_LOGLEN];
> +     va_list ap;
> +     int     saved_errno = errno;
>  
>       va_start(ap, emsg);
> -     vlog(LOG_INFO, emsg, ap);
> +     (void)vsnprintf(fmtbuf, sizeof(fmtbuf), emsg, ap);
>       va_end(ap);
> +     logit(LOG_INFO, "%s\n", fmtbuf);
> +
> +     errno = saved_errno;
>  }
>  
>  void
>  log_debug(const char *emsg, ...)
>  {
> -     va_list  ap;
> +     char    fmtbuf[MAX_LOGLEN];
> +     va_list ap;
>  
>       if (verbose) {
>               va_start(ap, emsg);
> -             vlog(LOG_DEBUG, emsg, ap);
> +             (void)vsnprintf(fmtbuf, sizeof(fmtbuf), emsg, ap);
>               va_end(ap);
> +             logit(LOG_DEBUG, "%s\n", fmtbuf);
>       }
>  }
>  
>  static void
>  vfatalc(int code, const char *emsg, va_list ap)
>  {
> -     static char     s[BUFSIZ];
> +     char             fmtbuf[MAX_LOGLEN];
>       const char      *sep;
>  
>       if (emsg != NULL) {
> -             (void)vsnprintf(s, sizeof(s), emsg, ap);
> +             (void)vsnprintf(fmtbuf, sizeof(fmtbuf), emsg, ap);
>               sep = ": ";
>       } else {
> -             s[0] = '\0';
> +             fmtbuf[0] = '\0';
>               sep = "";
>       }
>       if (code)
> -             logit(LOG_CRIT, "fatal in %s: %s%s%s",
> -                 log_procname, s, sep, strerror(code));
> +             logit(LOG_CRIT, "fatal in %s: %s%s%s\n",
> +                 log_procname, fmtbuf, sep, strerror(code));
>       else
> -             logit(LOG_CRIT, "fatal in %s%s%s", log_procname, sep, s);
> +             logit(LOG_CRIT, "fatal in %s%s%s\n", log_procname, sep, fmtbuf);
>  }
>  
>  void
> Index: log.h
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/log.h,v
> retrieving revision 1.20
> diff -u -p -r1.20 log.h
> --- log.h     21 Oct 2020 06:48:33 -0000      1.20
> +++ log.h     18 Oct 2023 07:05:17 -0000
> @@ -36,8 +36,6 @@ void        log_debug(const char *, ...)
>           __attribute__((__format__ (printf, 1, 2)));
>  void logit(int, const char *, ...)
>           __attribute__((__format__ (printf, 2, 3)));
> -void vlog(int, const char *, va_list)
> -         __attribute__((__format__ (printf, 2, 0)));
>  __dead void fatal(const char *, ...)
>           __attribute__((__format__ (printf, 1, 2)));
>  __dead void fatalx(const char *, ...)
> Index: logmsg.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/logmsg.c,v
> retrieving revision 1.10
> diff -u -p -r1.10 logmsg.c
> --- logmsg.c  14 Oct 2023 09:46:14 -0000      1.10
> +++ logmsg.c  18 Oct 2023 07:04:57 -0000
> @@ -68,7 +68,7 @@ log_peer_info(const struct peer_config *
>       if (vasprintf(&msg, emsg, ap) == -1)
>               fatal(NULL);
>       va_end(ap);
> -     logit(LOG_INFO, "%s: %s", p, msg);
> +     logit(LOG_INFO, "%s: %s\n", p, msg);
>       free(msg);
>       free(p);
>  }
> @@ -82,13 +82,13 @@ log_peer_warn(const struct peer_config *
>  
>       p = log_fmt_peer(peer);
>       if (emsg == NULL) {
> -             logit(LOG_ERR, "%s: %s", p, strerror(saved_errno));
> +             logit(LOG_ERR, "%s: %s\n", p, strerror(saved_errno));
>       } else {
>               va_start(ap, emsg);
>               if (vasprintf(&msg, emsg, ap) == -1)
>                       fatal(NULL);
>               va_end(ap);
> -             logit(LOG_ERR, "%s: %s: %s", p, msg, strerror(saved_errno));
> +             logit(LOG_ERR, "%s: %s: %s\n", p, msg, strerror(saved_errno));
>               free(msg);
>       }
>       free(p);
> @@ -105,7 +105,7 @@ log_peer_warnx(const struct peer_config 
>       if (vasprintf(&msg, emsg, ap) == -1)
>               fatal(NULL);
>       va_end(ap);
> -     logit(LOG_ERR, "%s: %s", p, msg);
> +     logit(LOG_ERR, "%s: %s\n", p, msg);
>       free(msg);
>       free(p);
>  }
> @@ -126,7 +126,7 @@ log_statechange(struct peer *peer, enum 
>  
>       peer->lasterr = 0;
>       p = log_fmt_peer(&peer->conf);
> -     logit(LOG_INFO, "%s: state change %s -> %s, reason: %s",
> +     logit(LOG_INFO, "%s: state change %s -> %s, reason: %s\n",
>           p, statenames[peer->state], statenames[nstate], eventnames[event]);
>       free(p);
>  }
> @@ -189,20 +189,20 @@ log_notification(const struct peer *peer
>               break;
>       default:
>               logit(LOG_ERR, "%s: %s notification, unknown errcode "
> -                 "%u, subcode %u", p, dir, errcode, subcode);
> +                 "%u, subcode %u\n", p, dir, errcode, subcode);
>               free(p);
>               return;
>       }
>  
>       if (uk)
> -             logit(LOG_ERR, "%s: %s notification: %s, unknown subcode %u",
> +             logit(LOG_ERR, "%s: %s notification: %s, unknown subcode %u\n",
>                   p, dir, errnames[errcode], subcode);
>       else {
>               if (suberrname == NULL)
> -                     logit(LOG_ERR, "%s: %s notification: %s", p,
> +                     logit(LOG_ERR, "%s: %s notification: %s\n", p,
>                           dir, errnames[errcode]);
>               else
> -                     logit(LOG_ERR, "%s: %s notification: %s, %s",
> +                     logit(LOG_ERR, "%s: %s notification: %s, %s\n",
>                           p, dir, errnames[errcode], suberrname);
>       }
>       free(p);
> @@ -215,7 +215,7 @@ log_conn_attempt(const struct peer *peer
>  
>       if (peer == NULL) {     /* connection from non-peer, drop */
>               if (log_getverbose())
> -                     logit(LOG_INFO, "connection from non-peer %s refused",
> +                     logit(LOG_INFO, "connection from non-peer %s refused\n",
>                           log_sockaddr(sa, len));
>       } else {
>               /* only log if there is a chance that the session may come up */
> @@ -223,7 +223,7 @@ log_conn_attempt(const struct peer *peer
>                       return;
>               p = log_fmt_peer(&peer->conf);
>               logit(LOG_INFO, "Connection attempt from %s while session is "
> -                 "in state %s", p, statenames[peer->state]);
> +                 "in state %s\n", p, statenames[peer->state]);
>               free(p);
>       }
>  }
> Index: parse.y
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/parse.y,v
> retrieving revision 1.455
> diff -u -p -r1.455 parse.y
> --- parse.y   16 Aug 2023 08:26:35 -0000      1.455
> +++ parse.y   18 Oct 2023 07:20:46 -0000
> @@ -3477,7 +3477,7 @@ yyerror(const char *fmt, ...)
>       if (vasprintf(&msg, fmt, ap) == -1)
>               fatalx("yyerror vasprintf");
>       va_end(ap);
> -     logit(LOG_CRIT, "%s:%d: %s", file->name, yylval.lineno, msg);
> +     logit(LOG_CRIT, "%s:%d: %s\n", file->name, yylval.lineno, msg);
>       free(msg);
>       return (0);
>  }

Reply via email to