static void _log_nomem(int loglevel, const char *syscall, int errnum, const char *msg, size_t bytes, int fd) { char fmtbytes[FMT_UINT], fmtfd[FMT_UINT]; fmtbytes[fmtuint(&fmtbytes[0], bytes)] = '\0'; if (-1 == fd) { _log(loglevel, syscall, errnum, msg, &fmtbytes[0], 1 == bytes ? " byte" : " bytes", 0, 0); } else { fmtfd[fmtuint(&fmtfd[0], fd)] = '\0'; _log(loglevel, syscall, errnum, msg, &fmtbytes[0], 1 == bytes ? " byte" : "bytes", " to pipe file descriptor ", &fmtfd[0]); } }
static size_t fmtsint(char *s, ssize_t n) { if (n < 0) { if (s) *s++ = '-'; return fmtuint(s, -n) + 1; } else { return fmtuint(s, n); } }
static void _log_waitpid(int loglevel, int errnum, pid_t pid) { char fmt[FMT_UINT]; fmt[fmtuint(&fmt[0], pid)] = '\0'; _log1(loglevel, "waitpid", errnum, "cannot wait child process ", &fmt[0]); }
static void _log_dup2(int loglevel, int errnum, int fd) { char fmt[FMT_UINT]; fmt[fmtuint(&fmt[0], fd)] = '\0'; _log1(LOG_FATAL, "dup2", errnum, "cannot duplicated fd ", &fmt[0]); }
static void _log_close(int loglevel, int errnum, int fd) { char fmt[FMT_UINT]; fmt[fmtuint(&fmt[0], fd)] = '\0'; _log1(loglevel, "close", errnum, "cannot close fd ", &fmt[0]); }
static struct iovec* _log_postamble(struct iovec *v, char *fmt, int errnum) { if (errnum) { v->iov_base = ": "; v->iov_len = strlen(v->iov_base); ++v; v->iov_base = strerror(errnum); v->iov_len = strlen(v->iov_base); ++v; v->iov_base = " ("; v->iov_len = strlen(v->iov_base); ++v; v->iov_base = &fmt[0]; v->iov_len = fmtuint(&fmt[0], errnum); ++v; v->iov_base = ")"; v->iov_len = strlen(v->iov_base); ++v; } v->iov_base = "\n"; v->iov_len = strlen(v->iov_base); ++v; return v; }
__attribute__((noreturn)) static void die_waithang(pid_t pid) { char fmt[FMT_UINT]; fmt[fmtuint(&fmt[0], pid)] = '\0'; _log1(LOG_FATAL, "waitpid", ECHILD, "unwaited child process ", &fmt[0]); die(); }
__attribute__((noreturn)) static void die_pollfd(int fd) { char fmt[FMT_UINT]; fmt[fmtuint(&fmt[0], fd)] = '\0'; _log1(LOG_FATAL, "poll", 0, "cannot poll fd ", &fmt[0]); die(); }
static void _log_noblock(int loglevel, int errnum, int fd) { char fmt[FMT_UINT]; fmt[fmtuint(&fmt[0], fd)] = '\0'; _log1(loglevel, "fcntl", errnum, "cannot set non-blocking mode for fd ", &fmt[0]); }
static void _log_coe(int loglevel, int errnum, int fd) { char fmt[FMT_UINT]; fmt[fmtuint(&fmt[0], fd)] = '\0'; _log1(loglevel, "fcntl", errnum, "cannot set close-on-exec flag for fd ", &fmt[0]); }
__attribute__((noreturn)) static void die_waitstatus(pid_t pid) { char fmt[FMT_UINT]; fmt[fmtuint(&fmt[0], pid)] = '\0'; _log1(LOG_FATAL, "waitpid", EINVAL, "unexpected status from child process ", &fmt[0]); die(); }
static void fmtint(struct fmtbuf *out, int value, int z, int base) { unsigned int a; if (value < 0) { fmtputc(out, '-'); a = -value; } else a = value; fmtuint(out, a, z, base); }
/** ** ** logging interface ** **/ static struct iovec* _log_preamble(struct iovec *v, char *fmt, int loglevel, const char *syscall) { static const char *_loglevel[] = { 0, "fatal", "error", "warning", "info", "debug" }; pid_t pid; if (loglevel > sizeof(_loglevel) / sizeof(_loglevel[0])) loglevel = sizeof(_loglevel) / sizeof(_loglevel[0]) - 1; pid = getpid(); v->iov_base = __progname; v->iov_len = strlen(v->iov_base); ++v; v->iov_base = "["; v->iov_len = strlen(v->iov_base); ++v; v->iov_base = &fmt[0]; v->iov_len = fmtuint(&fmt[0], pid); ++v; v->iov_base = "]: "; v->iov_len = strlen(v->iov_base); ++v; v->iov_base = (char*)_loglevel[loglevel]; v->iov_len = strlen(v->iov_base); ++v; v->iov_base = ": "; v->iov_len = strlen(v->iov_base); ++v; v->iov_base = (char*)syscall; v->iov_len = strlen(v->iov_base); ++v; v->iov_base = ": "; v->iov_len = strlen(v->iov_base); ++v; return v; }