Add support to the debug subsystem for zero-length strings. This
can happen for things like warning(NULL) or fatal(NULL) where we just want to log the errno string.
This commit is contained in:
@@ -155,8 +155,14 @@ int sudo_debug_init(const char *debugfile, const char *settings)
|
||||
sudo_debug_mode = SUDO_DEBUG_MODE_CONV;
|
||||
}
|
||||
|
||||
/* Stash the pid string so we only have to format it once. */
|
||||
(void)snprintf(sudo_debug_pidstr, sizeof(sudo_debug_pidstr), "[%d] ",
|
||||
(int)getpid());
|
||||
sudo_debug_pidlen = strlen(sudo_debug_pidstr);
|
||||
|
||||
/* Parse settings string. */
|
||||
buf = estrdup(settings);
|
||||
if ((buf = strdup(settings)) == NULL)
|
||||
return 0;
|
||||
for ((cp = strtok(buf, ",")); cp != NULL; (cp = strtok(NULL, ","))) {
|
||||
/* Should be in the form subsys@pri. */
|
||||
subsys = cp;
|
||||
@@ -181,11 +187,7 @@ int sudo_debug_init(const char *debugfile, const char *settings)
|
||||
}
|
||||
}
|
||||
}
|
||||
efree(buf);
|
||||
|
||||
(void)snprintf(sudo_debug_pidstr, sizeof(sudo_debug_pidstr), "[%d] ",
|
||||
(int)getpid());
|
||||
sudo_debug_pidlen = strlen(sudo_debug_pidstr);
|
||||
free(buf);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -212,28 +214,32 @@ sudo_debug_enter(const char *func, const char *file, int line,
|
||||
"-> %s @ %s:%d", func, file, line);
|
||||
}
|
||||
|
||||
void sudo_debug_exit(const char *func, const char *file, int line,
|
||||
void
|
||||
sudo_debug_exit(const char *func, const char *file, int line,
|
||||
int subsys)
|
||||
{
|
||||
sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE,
|
||||
"<- %s @ %s:%d", func, file, line);
|
||||
}
|
||||
|
||||
void sudo_debug_exit_int(const char *func, const char *file, int line,
|
||||
void
|
||||
sudo_debug_exit_int(const char *func, const char *file, int line,
|
||||
int subsys, int rval)
|
||||
{
|
||||
sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE,
|
||||
"<- %s @ %s:%d := %d", func, file, line, rval);
|
||||
}
|
||||
|
||||
void sudo_debug_exit_long(const char *func, const char *file, int line,
|
||||
void
|
||||
sudo_debug_exit_long(const char *func, const char *file, int line,
|
||||
int subsys, long rval)
|
||||
{
|
||||
sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE,
|
||||
"<- %s @ %s:%d := %ld", func, file, line, rval);
|
||||
}
|
||||
|
||||
void sudo_debug_exit_size_t(const char *func, const char *file, int line,
|
||||
void
|
||||
sudo_debug_exit_size_t(const char *func, const char *file, int line,
|
||||
int subsys, size_t rval)
|
||||
{
|
||||
/* XXX - should use %zu but our snprintf.c doesn't support it */
|
||||
@@ -242,7 +248,8 @@ void sudo_debug_exit_size_t(const char *func, const char *file, int line,
|
||||
}
|
||||
|
||||
/* We use int, not bool, here for functions that return -1 on error. */
|
||||
void sudo_debug_exit_bool(const char *func, const char *file, int line,
|
||||
void
|
||||
sudo_debug_exit_bool(const char *func, const char *file, int line,
|
||||
int subsys, int rval)
|
||||
{
|
||||
if (rval == true || rval == false) {
|
||||
@@ -254,14 +261,16 @@ void sudo_debug_exit_bool(const char *func, const char *file, int line,
|
||||
}
|
||||
}
|
||||
|
||||
void sudo_debug_exit_str(const char *func, const char *file, int line,
|
||||
void
|
||||
sudo_debug_exit_str(const char *func, const char *file, int line,
|
||||
int subsys, const char *rval)
|
||||
{
|
||||
sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE,
|
||||
"<- %s @ %s:%d := %s", func, file, line, rval ? rval : "(null)");
|
||||
}
|
||||
|
||||
void sudo_debug_exit_str_masked(const char *func, const char *file, int line,
|
||||
void
|
||||
sudo_debug_exit_str_masked(const char *func, const char *file, int line,
|
||||
int subsys, const char *rval)
|
||||
{
|
||||
static const char stars[] = "********************************************************************************";
|
||||
@@ -271,7 +280,8 @@ void sudo_debug_exit_str_masked(const char *func, const char *file, int line,
|
||||
"<- %s @ %s:%d := %.*s", func, file, line, len, rval ? stars : "(null)");
|
||||
}
|
||||
|
||||
void sudo_debug_exit_ptr(const char *func, const char *file, int line,
|
||||
void
|
||||
sudo_debug_exit_ptr(const char *func, const char *file, int line,
|
||||
int subsys, const void *rval)
|
||||
{
|
||||
sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE,
|
||||
@@ -282,10 +292,11 @@ static void
|
||||
sudo_debug_write_conv(const char *func, const char *file, int lineno,
|
||||
const char *str, int len, int errno_val)
|
||||
{
|
||||
/* Remove the newline at the end if appending extra info. */
|
||||
if (str[len - 1] == '\n')
|
||||
/* Remove trailing newlines. */
|
||||
while (len > 0 && str[len - 1] == '\n')
|
||||
len--;
|
||||
|
||||
if (len > 0) {
|
||||
if (func != NULL && file != NULL) {
|
||||
if (errno_val) {
|
||||
sudo_printf(SUDO_CONV_DEBUG_MSG, "%.*s: %s @ %s() %s:%d",
|
||||
@@ -302,6 +313,15 @@ sudo_debug_write_conv(const char *func, const char *file, int lineno,
|
||||
sudo_printf(SUDO_CONV_DEBUG_MSG, "%.*s", len, str);
|
||||
}
|
||||
}
|
||||
} else if (errno_val) {
|
||||
/* Only print error string. */
|
||||
if (func != NULL && file != NULL) {
|
||||
sudo_printf(SUDO_CONV_DEBUG_MSG, "%s @ %s() %s:%d",
|
||||
strerror(errno_val), func, file, lineno);
|
||||
} else {
|
||||
sudo_printf(SUDO_CONV_DEBUG_MSG, "%s", strerror(errno_val));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -311,8 +331,7 @@ sudo_debug_write_file(const char *func, const char *file, int lineno,
|
||||
char *timestr, numbuf[(((sizeof(int) * 8) + 2) / 3) + 2];
|
||||
time_t now;
|
||||
struct iovec iov[12];
|
||||
int iovcnt = 4;
|
||||
bool need_newline = false;
|
||||
int iovcnt = 3;
|
||||
|
||||
/* Prepend program name and pid with a trailing space. */
|
||||
iov[1].iov_base = (char *)getprogname();
|
||||
@@ -321,25 +340,24 @@ sudo_debug_write_file(const char *func, const char *file, int lineno,
|
||||
iov[2].iov_len = sudo_debug_pidlen;
|
||||
|
||||
/* Add string along with newline if it doesn't have one. */
|
||||
iov[3].iov_base = (char *)str;
|
||||
iov[3].iov_len = len;
|
||||
if (str[len - 1] != '\n')
|
||||
need_newline = true;
|
||||
if (len > 0) {
|
||||
iov[iovcnt].iov_base = (char *)str;
|
||||
iov[iovcnt].iov_len = len;
|
||||
while (len > 0 && str[len - 1] == '\n')
|
||||
iov[iovcnt].iov_len--;
|
||||
iovcnt++;
|
||||
}
|
||||
|
||||
/* Append error string if errno is specified. */
|
||||
if (errno_val) {
|
||||
if (len > 0) {
|
||||
iov[iovcnt].iov_base = ": ";
|
||||
iov[iovcnt].iov_len = 2;
|
||||
iovcnt++;
|
||||
}
|
||||
iov[iovcnt].iov_base = strerror(errno_val);
|
||||
iov[iovcnt].iov_len = strlen(iov[iovcnt].iov_base);
|
||||
iovcnt++;
|
||||
|
||||
/* Move newline to the end. */
|
||||
if (!need_newline) {
|
||||
need_newline = true;
|
||||
iov[3].iov_len--;
|
||||
}
|
||||
}
|
||||
|
||||
/* If function, file and lineno are specified, append them. */
|
||||
@@ -364,21 +382,12 @@ sudo_debug_write_file(const char *func, const char *file, int lineno,
|
||||
iov[iovcnt].iov_base = numbuf;
|
||||
iov[iovcnt].iov_len = strlen(numbuf);
|
||||
iovcnt++;
|
||||
|
||||
/* Move newline to the end. */
|
||||
if (!need_newline) {
|
||||
need_newline = true;
|
||||
iov[3].iov_len--;
|
||||
}
|
||||
}
|
||||
|
||||
/* Append newline as needed. */
|
||||
if (need_newline) {
|
||||
/* force newline */
|
||||
/* Append newline. */
|
||||
iov[iovcnt].iov_base = "\n";
|
||||
iov[iovcnt].iov_len = 1;
|
||||
iovcnt++;
|
||||
}
|
||||
|
||||
/* Do timestamp last due to ctime's static buffer. */
|
||||
time(&now);
|
||||
@@ -396,9 +405,6 @@ void
|
||||
sudo_debug_write2(const char *func, const char *file, int lineno,
|
||||
const char *str, int len, int errno_val)
|
||||
{
|
||||
if (len <= 0)
|
||||
return;
|
||||
|
||||
switch (sudo_debug_mode) {
|
||||
case SUDO_DEBUG_MODE_CONV:
|
||||
sudo_debug_write_conv(func, file, lineno, str, len, errno_val);
|
||||
@@ -421,7 +427,7 @@ sudo_debug_vprintf2(const char *func, const char *file, int lineno, int level,
|
||||
const char *fmt, va_list ap)
|
||||
{
|
||||
int buflen, pri, subsys, saved_errno = errno;
|
||||
char *buf;
|
||||
char *buf = NULL;
|
||||
|
||||
if (!sudo_debug_mode)
|
||||
return;
|
||||
@@ -432,8 +438,7 @@ sudo_debug_vprintf2(const char *func, const char *file, int lineno, int level,
|
||||
|
||||
/* Make sure we want debug info at this level. */
|
||||
if (subsys < NUM_SUBSYSTEMS && sudo_debug_settings[subsys] >= pri) {
|
||||
buflen = vasprintf(&buf, fmt, ap);
|
||||
va_end(ap);
|
||||
buflen = fmt ? vasprintf(&buf, fmt, ap) : 0;
|
||||
if (buflen != -1) {
|
||||
int errcode = ISSET(level, SUDO_DEBUG_ERRNO) ? saved_errno : 0;
|
||||
if (ISSET(level, SUDO_DEBUG_LINENO))
|
||||
|
@@ -201,8 +201,8 @@ void sudo_debug_exit_str_masked(const char *func, const char *file, int line, in
|
||||
void sudo_debug_exit_ptr(const char *func, const char *file, int line, int subsys, const void *rval);
|
||||
int sudo_debug_fd_set(int fd);
|
||||
int sudo_debug_init(const char *debugfile, const char *settings);
|
||||
void sudo_debug_printf2(const char *func, const char *file, int line, int level, const char *fmt, ...) __printflike(5, 6);
|
||||
void sudo_debug_vprintf2(const char *func, const char *file, int line, int level, const char *fmt, va_list ap);
|
||||
void sudo_debug_printf2(const char *func, const char *file, int line, int level, const char *fmt, ...) __printf0like(5, 6);
|
||||
void sudo_debug_vprintf2(const char *func, const char *file, int line, int level, const char *fmt, va_list ap) __printf0like(5, 0);
|
||||
void sudo_debug_write(const char *str, int len, int errno_val);
|
||||
void sudo_debug_write2(const char *func, const char *file, int line, const char *str, int len, int errno_val);
|
||||
pid_t sudo_debug_fork(void);
|
||||
|
Reference in New Issue
Block a user