}
}
+void lg_vperror(struct log_if *lg, const char *desc, struct cloc *loc,
+ int class, int errnoval, const char *fmt, va_list al)
+{
+ int status=current_phase;
+ int esave=errno;
+
+ if (!lg)
+ lg=system_log;
+
+ if (class & M_FATAL)
+ enter_phase(PHASE_SHUTDOWN);
+
+ slilog_part(lg,class,"%s",desc);
+ if (loc)
+ slilog_part(lg,class," (%s:%d)",loc->file,loc->line);
+ slilog_part(lg,class,": ");
+ vslilog_part(lg,class,fmt,al);
+ if (errnoval)
+ slilog_part(lg,class,": %s",strerror(errnoval));
+ slilog_part(lg,class,"\n");
+
+ if (class & M_FATAL)
+ exit(status);
+
+ errno=esave;
+}
+
+void lg_perror(struct log_if *lg, const char *desc, struct cloc *loc,
+ int class, int errnoval, const char *fmt, ...)
+{
+ va_list al;
+ va_start(al,fmt);
+ lg_vperror(lg,desc,loc,class,errnoval,fmt,al);
+ va_end(al);
+}
+
struct log_if *init_log(list_t *ll)
{
int i=0;
extern NORETURN(fatal_perror_status(int status, const char *message, ...))
FORMAT(printf,2,3);
+/* Convenient nonfatal logging. Requires message that does not end in '\n'.
+ * If class contains M_FATAL, exits (after entering PHASE_SHUTDOWN).
+ * lg, errnoval and loc may sensibly be 0. desc must NOT be 0.
+ * lg_[v]perror save and restore errno. */
+void lg_vperror(struct log_if *lg, const char *desc, struct cloc *loc,
+ int class, int errnoval, const char *fmt, va_list al)
+ FORMAT(printf,6,0);
+void lg_perror(struct log_if *lg, const char *desc, struct cloc *loc,
+ int class, int errnoval, const char *fmt, ...)
+ FORMAT(printf,6,7);
+
/* The cfgfatal() family of functions require messages that end in '\n' */
extern NORETURN(cfgfatal(struct cloc loc, cstring_t facility,
const char *message, ...)) FORMAT(printf,3,4);