version 1.9, 2014/03/31 21:42:05 |
version 1.10, 2014/03/31 21:42:45 |
|
|
#include <stdio.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <stdlib.h> |
#include <string.h> |
#include <string.h> |
#include <syslog.h> |
|
#include <time.h> |
|
|
|
#include "tmux.h" |
#include "tmux.h" |
|
|
/* Log file, if needed. */ |
FILE *log_file; |
FILE *log_file; |
|
|
|
/* Debug level. */ |
void log_event_cb(int, const char *); |
int log_level = 0; |
void log_vwrite(const char *, va_list); |
|
|
void log_event_cb(int, const char *); |
|
void log_vwrite(const char *, va_list); |
|
__dead void log_vfatal(const char *, va_list); |
|
|
|
/* Log callback for libevent. */ |
/* Log callback for libevent. */ |
void |
void |
log_event_cb(unused int severity, const char *msg) |
log_event_cb(unused int severity, const char *msg) |
|
|
|
|
/* Open logging to file. */ |
/* Open logging to file. */ |
void |
void |
log_open(int level, const char *path) |
log_open(const char *path) |
{ |
{ |
log_file = fopen(path, "w"); |
log_file = fopen(path, "w"); |
if (log_file == NULL) |
if (log_file == NULL) |
return; |
return; |
log_level = level; |
|
|
|
setlinebuf(log_file); |
setlinebuf(log_file); |
event_set_log_callback(log_event_cb); |
event_set_log_callback(log_event_cb); |
|
|
{ |
{ |
if (log_file != NULL) |
if (log_file != NULL) |
fclose(log_file); |
fclose(log_file); |
|
log_file = NULL; |
|
|
event_set_log_callback(NULL); |
event_set_log_callback(NULL); |
} |
} |
|
|
{ |
{ |
va_list ap; |
va_list ap; |
|
|
if (log_level > 0) { |
va_start(ap, msg); |
va_start(ap, msg); |
log_vwrite(msg, ap); |
log_vwrite(msg, ap); |
va_end(ap); |
va_end(ap); |
|
} |
|
} |
} |
|
|
/* Log a debug message at level 2. */ |
/* Log a critical error with error string and die. */ |
void printflike1 |
|
log_debug2(const char *msg, ...) |
|
{ |
|
va_list ap; |
|
|
|
if (log_level > 1) { |
|
va_start(ap, msg); |
|
log_vwrite(msg, ap); |
|
va_end(ap); |
|
} |
|
} |
|
|
|
/* Log a critical error, with error string if necessary, and die. */ |
|
__dead void |
|
log_vfatal(const char *msg, va_list ap) |
|
{ |
|
char *fmt; |
|
|
|
if (errno != 0) { |
|
if (asprintf(&fmt, "fatal: %s: %s", msg, strerror(errno)) == -1) |
|
exit(1); |
|
log_vwrite(fmt, ap); |
|
} else { |
|
if (asprintf(&fmt, "fatal: %s", msg) == -1) |
|
exit(1); |
|
log_vwrite(fmt, ap); |
|
} |
|
free(fmt); |
|
|
|
exit(1); |
|
} |
|
|
|
/* Log a critical error, with error string, and die. */ |
|
__dead void printflike1 |
__dead void printflike1 |
log_fatal(const char *msg, ...) |
log_fatal(const char *msg, ...) |
{ |
{ |
va_list ap; |
char *fmt; |
|
va_list ap; |
|
|
va_start(ap, msg); |
va_start(ap, msg); |
log_vfatal(msg, ap); |
if (asprintf(&fmt, "fatal: %s: %s", msg, strerror(errno)) == -1) |
|
exit(1); |
|
log_vwrite(fmt, ap); |
|
exit(1); |
} |
} |
|
|
/* Log a critical error and die. */ |
/* Log a critical error and die. */ |
__dead void printflike1 |
__dead void printflike1 |
log_fatalx(const char *msg, ...) |
log_fatalx(const char *msg, ...) |
{ |
{ |
va_list ap; |
char *fmt; |
|
va_list ap; |
|
|
errno = 0; |
|
va_start(ap, msg); |
va_start(ap, msg); |
log_vfatal(msg, ap); |
if (asprintf(&fmt, "fatal: %s", msg) == -1) |
|
exit(1); |
|
log_vwrite(fmt, ap); |
|
exit(1); |
} |
} |