diff --git a/src/plugins/xfer/xfer-buffer.c b/src/plugins/xfer/xfer-buffer.c index c356ac38e..d442eca94 100644 --- a/src/plugins/xfer/xfer-buffer.c +++ b/src/plugins/xfer/xfer-buffer.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "../weechat-plugin.h" #include "xfer.h" @@ -217,12 +218,22 @@ xfer_buffer_refresh (const char *hotlist) eta[0] = '\0'; if (ptr_xfer->status == XFER_STATUS_ACTIVE) { - snprintf (eta, sizeof (eta), - "%s: %.2llu:%.2llu:%.2llu - ", - _("ETA"), - ptr_xfer->eta / 3600, - (ptr_xfer->eta / 60) % 60, - ptr_xfer->eta % 60); + if (ptr_xfer->eta != ULLONG_MAX) + { + snprintf (eta, sizeof (eta), + "%s: %.2llu:%.2llu:%.2llu - ", + _("ETA"), + ptr_xfer->eta / 3600, + (ptr_xfer->eta / 60) % 60, + ptr_xfer->eta % 60); + } + else + { + snprintf (eta, sizeof (eta), + "%s: %s - ", + _("ETA"), + _("unknown")); + } } /* display second line for file with status, progress bar and estimated time */ diff --git a/src/plugins/xfer/xfer-command.c b/src/plugins/xfer/xfer-command.c index 9b74c9e0e..ac232759f 100644 --- a/src/plugins/xfer/xfer-command.c +++ b/src/plugins/xfer/xfer-command.c @@ -170,7 +170,7 @@ xfer_command_xfer_list (int full) ptr_xfer->remote_address_str, ptr_xfer->port); date[0] = '\0'; - date_tmp = localtime (&(ptr_xfer->start_transfer)); + date_tmp = localtime (&(ptr_xfer->start_transfer.tv_sec)); if (date_tmp) { if (strftime (date, sizeof (date), diff --git a/src/plugins/xfer/xfer-file.c b/src/plugins/xfer/xfer-file.c index 9433aa30f..cf4663c7e 100644 --- a/src/plugins/xfer/xfer-file.c +++ b/src/plugins/xfer/xfer-file.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "../weechat-plugin.h" #include "xfer.h" @@ -304,37 +305,44 @@ xfer_file_find_filename (struct t_xfer *xfer) void xfer_file_calculate_speed (struct t_xfer *xfer, int ended) { - time_t local_time, elapsed; - unsigned long long bytes_per_sec_total; + struct timeval local_time; + long long elapsed_usec; + double bytes_per_usec_total; - local_time = time (NULL); - if (ended || local_time > xfer->last_check_time) + gettimeofday (&local_time, NULL); + if (ended || (weechat_util_timeval_cmp (&local_time, &xfer->last_check_time) > 0)) { if (ended) { /* calculate bytes per second (global) */ - elapsed = local_time - xfer->start_transfer; - if (elapsed == 0) - elapsed = 1; - xfer->bytes_per_sec = (xfer->pos - xfer->start_resume) / elapsed; + elapsed_usec = weechat_util_timeval_diff (&xfer->start_transfer, &local_time); + if (elapsed_usec == 0) + elapsed_usec = 1; + xfer->bytes_per_sec = ((xfer->pos - xfer->start_resume) * 1000000.0) / elapsed_usec; xfer->eta = 0; } else { /* calculate ETA */ - elapsed = local_time - xfer->start_transfer; - if (elapsed == 0) - elapsed = 1; - bytes_per_sec_total = (xfer->pos - xfer->start_resume) / elapsed; - if (bytes_per_sec_total == 0) - bytes_per_sec_total = 1; - xfer->eta = (xfer->size - xfer->pos) / bytes_per_sec_total; + elapsed_usec = weechat_util_timeval_diff (&xfer->start_transfer, &local_time); + if (elapsed_usec == 0) + { + xfer->eta = ULLONG_MAX; + } + else + { + bytes_per_usec_total = (double)(xfer->pos - xfer->start_resume) / (double)elapsed_usec; + if (bytes_per_usec_total == 0) + xfer->eta = ULLONG_MAX; + else + xfer->eta = (xfer->size - xfer->pos) / bytes_per_usec_total / 1000000.0; + } /* calculate bytes per second (since last check time) */ - elapsed = local_time - xfer->last_check_time; - if (elapsed == 0) - elapsed = 1; - xfer->bytes_per_sec = (xfer->pos - xfer->last_check_pos) / elapsed; + elapsed_usec = weechat_util_timeval_diff (&xfer->last_check_time, &local_time); + if (elapsed_usec == 0) + elapsed_usec = 1; + xfer->bytes_per_sec = ((xfer->pos - xfer->last_check_pos) * 1000000.0) / elapsed_usec; } xfer->last_check_time = local_time; xfer->last_check_pos = xfer->pos; diff --git a/src/plugins/xfer/xfer-network.c b/src/plugins/xfer/xfer-network.c index 892ba5292..84b6feb84 100644 --- a/src/plugins/xfer/xfer-network.c +++ b/src/plugins/xfer/xfer-network.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -287,8 +288,8 @@ xfer_network_child_read_cb (const void *pointer, void *data, int fd) { /* connection was successful by child, init transfer times */ xfer->status = XFER_STATUS_ACTIVE; - xfer->start_transfer = time (NULL); - xfer->last_check_time = time (NULL); + gettimeofday (&xfer->start_transfer, NULL); + xfer->last_check_time = xfer->start_transfer; xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE); } else @@ -571,7 +572,7 @@ xfer_network_fd_cb (const void *pointer, void *data, int fd) xfer_set_remote_address (xfer, (struct sockaddr *)&addr, length, str_address); xfer->status = XFER_STATUS_ACTIVE; - xfer->start_transfer = time (NULL); + gettimeofday (&xfer->start_transfer, NULL); xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE); switch (xfer->type) { diff --git a/src/plugins/xfer/xfer.c b/src/plugins/xfer/xfer.c index 09e440029..717c4a7d8 100644 --- a/src/plugins/xfer/xfer.c +++ b/src/plugins/xfer/xfer.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -544,7 +545,7 @@ xfer_alloc (void) new_xfer->send_ack = weechat_config_boolean (xfer_config_network_send_ack); new_xfer->blocksize = weechat_config_integer (xfer_config_network_blocksize); new_xfer->start_time = time_now; - new_xfer->start_transfer = time_now; + gettimeofday (&new_xfer->start_transfer, NULL); new_xfer->sock = -1; new_xfer->child_pid = 0; new_xfer->child_read = -1; @@ -560,7 +561,7 @@ xfer_alloc (void) new_xfer->pos = 0; new_xfer->ack = 0; new_xfer->start_resume = 0; - new_xfer->last_check_time = time_now; + new_xfer->last_check_time = new_xfer->start_transfer; new_xfer->last_check_pos = time_now; new_xfer->last_activity = 0; new_xfer->bytes_per_sec = 0; @@ -1644,7 +1645,9 @@ xfer_add_to_infolist (struct t_infolist *infolist, struct t_xfer *xfer) return 0; if (!weechat_infolist_new_var_time (ptr_item, "start_time", xfer->start_time)) return 0; - if (!weechat_infolist_new_var_time (ptr_item, "start_transfer", xfer->start_transfer)) + if (!weechat_infolist_new_var_time (ptr_item, "start_transfer", xfer->start_transfer.tv_sec)) + return 0; + if (!weechat_infolist_new_var_integer (ptr_item, "start_transfer_usec", xfer->start_transfer.tv_usec)) return 0; if (!weechat_infolist_new_var_integer (ptr_item, "sock", xfer->sock)) return 0; @@ -1679,7 +1682,9 @@ xfer_add_to_infolist (struct t_infolist *infolist, struct t_xfer *xfer) snprintf (value, sizeof (value), "%llu", xfer->start_resume); if (!weechat_infolist_new_var_string (ptr_item, "start_resume", value)) return 0; - if (!weechat_infolist_new_var_time (ptr_item, "last_check_time", xfer->last_check_time)) + if (!weechat_infolist_new_var_time (ptr_item, "last_check_time", xfer->last_check_time.tv_sec)) + return 0; + if (!weechat_infolist_new_var_integer (ptr_item, "last_check_time_usec", xfer->last_check_time.tv_usec)) return 0; snprintf (value, sizeof (value), "%llu", xfer->last_check_pos); if (!weechat_infolist_new_var_string (ptr_item, "last_check_pos", value)) @@ -1746,7 +1751,9 @@ xfer_print_log (void) weechat_log_printf (" fast_send . . . . . . . : %d", ptr_xfer->fast_send); weechat_log_printf (" blocksize . . . . . . . : %d", ptr_xfer->blocksize); weechat_log_printf (" start_time. . . . . . . : %lld", (long long)ptr_xfer->start_time); - weechat_log_printf (" start_transfer. . . . . : %lld", (long long)ptr_xfer->start_transfer); + weechat_log_printf (" start_transfer. . . . . : tv_sec:%lld, tv_usec:%ld", + (long long)(ptr_xfer->start_transfer.tv_sec), + (long)(ptr_xfer->start_transfer.tv_usec)); weechat_log_printf (" sock. . . . . . . . . . : %d", ptr_xfer->sock); weechat_log_printf (" child_pid . . . . . . . : %d", ptr_xfer->child_pid); weechat_log_printf (" child_read. . . . . . . : %d", ptr_xfer->child_read); @@ -1762,7 +1769,9 @@ xfer_print_log (void) weechat_log_printf (" pos . . . . . . . . . . : %llu", ptr_xfer->pos); weechat_log_printf (" ack . . . . . . . . . . : %llu", ptr_xfer->ack); weechat_log_printf (" start_resume. . . . . . : %llu", ptr_xfer->start_resume); - weechat_log_printf (" last_check_time . . . . : %lld", (long long)ptr_xfer->last_check_time); + weechat_log_printf (" last_check_time . . . . : tv_sec:%lld, tv_usec:%ld", + (long long)(ptr_xfer->last_check_time.tv_sec), + (long)(ptr_xfer->last_check_time.tv_usec)); weechat_log_printf (" last_check_pos. . . . . : %llu", ptr_xfer->last_check_pos); weechat_log_printf (" last_activity . . . . . : %lld", (long long)ptr_xfer->last_activity); weechat_log_printf (" bytes_per_sec . . . . . : %llu", ptr_xfer->bytes_per_sec); diff --git a/src/plugins/xfer/xfer.h b/src/plugins/xfer/xfer.h index fd69128c4..171ce0d3b 100644 --- a/src/plugins/xfer/xfer.h +++ b/src/plugins/xfer/xfer.h @@ -171,7 +171,7 @@ struct t_xfer int send_ack; /* send acks on file receive */ int blocksize; /* block size for sending file */ time_t start_time; /* time when xfer started */ - time_t start_transfer; /* time when xfer transfer started */ + struct timeval start_transfer; /* time when xfer transfer started */ int sock; /* socket for connection */ pid_t child_pid; /* pid of child process (send/recv) */ int child_read; /* to read into child pipe */ @@ -189,7 +189,7 @@ struct t_xfer unsigned long long pos; /* number of bytes received/sent */ unsigned long long ack; /* number of bytes received OK */ unsigned long long start_resume; /* start of resume (in bytes) */ - time_t last_check_time; /* last time we checked bytes snt/rcv*/ + struct timeval last_check_time; /* last time we checked bytes snt/rcv*/ unsigned long long last_check_pos; /* bytes sent/recv at last check */ time_t last_activity; /* time of last byte received/sent */ unsigned long long bytes_per_sec; /* bytes per second */