From 95e4163ab7a5537668afd6f66d8bab7069ca2c48 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sun, 2 Mar 2014 22:14:51 +0000 Subject: [PATCH] Handle too-short write(3)s in mod_json_cdr write(3) can write fewer bytes than was requested for any number of reasons. The correct behavior is to retry unless there is an error. If there is an error, try to unlink the file; no sense in leaving corrupted data laying around. --- .../mod_json_cdr/mod_json_cdr.c | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/mod/event_handlers/mod_json_cdr/mod_json_cdr.c b/src/mod/event_handlers/mod_json_cdr/mod_json_cdr.c index e2dc3b6122..2d08f5175a 100644 --- a/src/mod/event_handlers/mod_json_cdr/mod_json_cdr.c +++ b/src/mod/event_handlers/mod_json_cdr/mod_json_cdr.c @@ -213,11 +213,15 @@ static void backup_cdr(cdr_data_t *data) mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; #endif if ((fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, mode)) > -1) { - int wrote = write(fd, json_text, (unsigned) strlen(json_text)); - close(fd); - fd = -1; - if (wrote < 0) { + switch_size_t json_len = strlen(json_text); + switch_ssize_t wrote = 0, x; + do { x = write(fd, json_text, json_len); + } while (!(x<0) && json_len > (wrote += x)); + close(fd); fd = -1; + if (x < 0) { switch_log_printf(SWITCH_CHANNEL_UUID_LOG(data->uuid), SWITCH_LOG_ERROR, "Error writing [%s]\n",path); + if (0 > unlink(path)) + switch_log_printf(SWITCH_CHANNEL_UUID_LOG(data->uuid), SWITCH_LOG_ERROR, "Error unlinking [%s]\n",path); } switch_safe_free(path); break; @@ -273,11 +277,15 @@ static void process_cdr(cdr_data_t *data) #else if ((fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) > -1) { #endif - int wrote = write(fd, data->json_text, (unsigned) strlen(data->json_text)); - close(fd); - fd = -1; - if (wrote < 0) { + switch_size_t json_len = strlen(data->json_text); + switch_ssize_t wrote = 0, x; + do { x = write(fd, data->json_text, json_len); + } while (!(x<0) && json_len > (wrote += x)); + close(fd); fd = -1; + if (x < 0) { switch_log_printf(SWITCH_CHANNEL_UUID_LOG(data->uuid), SWITCH_LOG_ERROR, "Error writing [%s]\n",path); + if (0 > unlink(path)) + switch_log_printf(SWITCH_CHANNEL_UUID_LOG(data->uuid), SWITCH_LOG_ERROR, "Error unlinking [%s]\n",path); } } else { char ebuf[512] = { 0 };