static int count;
-static struct store_log_forward *log_head;
-static int log_forward_count;
-
-struct store_log_forward {
- struct store_log_forward *next;
- const char *file;
- int line;
- const char *function;
- const char *string;
-};
-
-/* either forward the log to the listeners or store it for possible forwarding later */
+/* forward the log to the listeners */
static void log_forward(const char *file, unsigned line, const char *function, const char *string)
{
- if (log_forward_count == 0) {
- struct log_callback *cb, *next;
- cb = log_callbacks;
- /* DANGER!!!! the log callback can remove itself!!!! */
- while (cb) {
- next = cb->next;
- cb->fn(cb->priv, file, line, function, string);
- cb = next;
- }
- } else {
- struct store_log_forward *log = malloc(sizeof(struct store_log_forward));
- log->file = strdup(file);
- log->line = line;
- log->function = strdup(function);
- log->string = strdup(string);
- log->next = NULL;
- if (log_head == NULL)
- log_head = log;
- else {
- /* append to tail */
- struct store_log_forward *t;
- t = log_head;
- while (t->next != NULL)
- t = t->next;
- t->next = log;
- }
+ struct log_callback *cb, *next;
+ cb = log_callbacks;
+ /* DANGER!!!! the log callback can remove itself!!!! */
+ while (cb) {
+ next = cb->next;
+ cb->fn(cb->priv, file, line, function, string);
+ cb = next;
}
}
} else if (CMD_ARGC > 1)
return ERROR_COMMAND_SYNTAX_ERROR;
- command_print(CMD_CTX, "debug_level: %i", debug_level);
+ command_print(CMD, "debug_level: %i", debug_level);
return ERROR_OK;
}
COMMAND_HANDLER(handle_log_output_command)
{
+ if (CMD_ARGC == 0 || (CMD_ARGC == 1 && strcmp(CMD_ARGV[0], "default") == 0)) {
+ if (log_output != stderr && log_output != NULL) {
+ /* Close previous log file, if it was open and wasn't stderr. */
+ fclose(log_output);
+ }
+ log_output = stderr;
+ LOG_DEBUG("set log_output to default");
+ return ERROR_OK;
+ }
if (CMD_ARGC == 1) {
FILE *file = fopen(CMD_ARGV[0], "w");
if (file == NULL) {
fclose(log_output);
}
log_output = file;
+ LOG_DEBUG("set log_output to \"%s\"", CMD_ARGV[0]);
+ return ERROR_OK;
}
- return ERROR_OK;
+ return ERROR_COMMAND_SYNTAX_ERROR;
}
-static struct command_registration log_command_handlers[] = {
+static const struct command_registration log_command_handlers[] = {
{
.name = "log_output",
.handler = handle_log_output_command,
.mode = COMMAND_ANY,
.help = "redirect logging to a file (default: stderr)",
- .usage = "file_name",
+ .usage = "[file_name | \"default\"]",
},
{
.name = "debug_level",
* fast when invoked more often than every 500ms.
*
*/
-void keep_alive()
+void keep_alive(void)
{
current_time = timeval_ms();
if (current_time-last_time > 1000) {
}
/* reset keep alive timer without sending message */
-void kept_alive()
+void kept_alive(void)
{
current_time = timeval_ms();
last_time = current_time;
*/
}
}
+
+/* Maximum size of socket error message retreived from operation system */
+#define MAX_SOCKET_ERR_MSG_LENGTH 256
+
+/* Provide log message for the last socket error.
+ Uses errno on *nix and WSAGetLastError() on Windows */
+void log_socket_error(const char *socket_desc)
+{
+ int error_code;
+#ifdef _WIN32
+ error_code = WSAGetLastError();
+ char error_message[MAX_SOCKET_ERR_MSG_LENGTH];
+ error_message[0] = '\0';
+ DWORD retval = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error_code, 0,
+ error_message, MAX_SOCKET_ERR_MSG_LENGTH, NULL);
+ error_message[MAX_SOCKET_ERR_MSG_LENGTH - 1] = '\0';
+ const bool have_message = (retval != 0) && (error_message[0] != '\0');
+ LOG_ERROR("Error on socket '%s': WSAGetLastError==%d%s%s.", socket_desc, error_code,
+ (have_message ? ", message: " : ""),
+ (have_message ? error_message : ""));
+#else
+ error_code = errno;
+ LOG_ERROR("Error on socket '%s': errno==%d, message: %s.", socket_desc, error_code, strerror(error_code));
+#endif
+}