From 7509f0b27196cab9da7661a7ba819dab76d786f4 Mon Sep 17 00:00:00 2001 From: German Service Network Date: Sun, 25 Jan 2026 18:46:09 +0100 Subject: [PATCH] Buffer output so that output is per line --- README.md | 2 +- src/ftraceroute.c | 47 ++++++++++++++++++++--------------------------- 2 files changed, 21 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 92abbcd..5c12cf7 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ The program can only be run as root. Help: `ftraceroute -h` ``` -Usage: ftraceroute [options] +Usage: ftraceroute [options] [host2 ...] Options: -h Show this help message -v Show version info diff --git a/src/ftraceroute.c b/src/ftraceroute.c index 9555c19..19cea7b 100644 --- a/src/ftraceroute.c +++ b/src/ftraceroute.c @@ -190,16 +190,10 @@ void *run_trace(void *arg) { } } - // Buffer output for this hop to print it atomically - char out_buf[1024]; - int off = 0; - off += snprintf(out_buf + off, sizeof(out_buf) - off, "[%s] %2d ", args->host, ttl); - // Print the prefix, but since we probe loop, we might want to just print directly - // To keep the 'live' feel, we print the prefix line start: - pthread_mutex_lock(&log_mutex); - printf("%s", out_buf); - fflush(stdout); - pthread_mutex_unlock(&log_mutex); + // Create buffer for entire line to prevent “mixed output” + char line_buf[2048]; + size_t off = 0; + off += snprintf(line_buf + off, sizeof(line_buf) - off, "[%s] %2d ", args->host, ttl); bool printed_addr = false; @@ -244,10 +238,9 @@ void *run_trace(void *arg) { gettimeofday(&t_send, NULL); if (sendto(sock, packet, pkt_len, 0, dst, dst_len) < 0) { perror("sendto"); - pthread_mutex_lock(&log_mutex); - printf("* "); - fflush(stdout); - pthread_mutex_unlock(&log_mutex); + if (off < sizeof(line_buf)) { + off += snprintf(line_buf + off, sizeof(line_buf) - off, "* "); + } continue; } @@ -262,10 +255,9 @@ void *run_trace(void *arg) { if (n < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK) { - pthread_mutex_lock(&log_mutex); - printf("* "); - fflush(stdout); - pthread_mutex_unlock(&log_mutex); + if (off < sizeof(line_buf)) { + off += snprintf(line_buf + off, sizeof(line_buf) - off, "* "); + } break; } else { perror("recvfrom"); @@ -337,29 +329,30 @@ void *run_trace(void *arg) { addr_to_host((struct sockaddr *)&reply_addr, rlen, host_name, sizeof(host_name), ip_txt, sizeof(ip_txt)); - pthread_mutex_lock(&log_mutex); + // Write address to buffer (only for the first hit per hop) + int written = 0; if (host_name[0] == '\0') { - printf("%s ", ip_txt); + written = snprintf(line_buf + off, sizeof(line_buf) - off, "%s ", ip_txt); } else { - printf("%s (%s) ", host_name, ip_txt); + written = snprintf(line_buf + off, sizeof(line_buf) - off, "%s (%s) ", host_name, ip_txt); } - pthread_mutex_unlock(&log_mutex); + if (written > 0) off += written; printed_addr = true; } double rtt_ms = ms_between(t_send, t_rcv); - pthread_mutex_lock(&log_mutex); - printf("%.3f ms ", rtt_ms); - fflush(stdout); - pthread_mutex_unlock(&log_mutex); + if (off < sizeof(line_buf)) { + off += snprintf(line_buf + off, sizeof(line_buf) - off, "%.3f ms ", rtt_ms); + } if (final_reply) reached = true; break; // Next probe } } + // Now output the entire line atomically pthread_mutex_lock(&log_mutex); - printf("\n"); + printf("%s\n", line_buf); pthread_mutex_unlock(&log_mutex); if (reached) break; } -- 2.43.0