Skip to content

Commit 183df8f

Browse files
author
alexandr nedvedicky - Sun Microsystems - Prague Czech Republic
committed
fprintf(3) should not be used by signal handlers
On most OS platforms fprintf() et.al. are considered to be signal unsafe. I've noticed the signal handlers in tcpdump call fprintf(). The patch below defers call to fprintf() triggered by signal to pcap_loop callback. Submitted to upstream: #638
1 parent de250d5 commit 183df8f

File tree

1 file changed

+29
-20
lines changed

1 file changed

+29
-20
lines changed

tcpdump.c

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -217,8 +217,8 @@ static char *zflag = NULL; /* compress each savefile using a specified command
217217
static int immediate_mode;
218218
#endif
219219

220-
static int infodelay;
221220
static int infoprint;
221+
static int gotalarm;
222222

223223
char *program_name;
224224

@@ -2387,6 +2387,9 @@ DIAG_ON_CLANG(assign-enum)
23872387
*/
23882388
struct itimerval timer;
23892389
(void)setsignal(SIGALRM, verbose_stats_dump);
2390+
alarm(1);
2391+
/* signal alarm to get the first iteration ASAP */
2392+
gotalarm = 1;
23902393
timer.it_interval.tv_sec = 1;
23912394
timer.it_interval.tv_usec = 0;
23922395
timer.it_value.tv_sec = 1;
@@ -2738,8 +2741,6 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s
27382741

27392742
++packets_captured;
27402743

2741-
++infodelay;
2742-
27432744
dump_info = (struct dump_info *)user;
27442745

27452746
/*
@@ -2941,9 +2942,16 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s
29412942
if (dump_info->ndo != NULL)
29422943
pretty_print_packet(dump_info->ndo, h, sp, packets_captured);
29432944

2944-
--infodelay;
2945-
if (infoprint)
2945+
if (infoprint) {
29462946
info(0);
2947+
infoprint = 0;
2948+
}
2949+
2950+
if (gotalarm) {
2951+
fprintf(stderr, "Got %u\r", packets_captured);
2952+
gotalarm = 0;
2953+
alarm(1);
2954+
}
29472955
}
29482956

29492957
static void
@@ -2953,8 +2961,6 @@ dump_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
29532961

29542962
++packets_captured;
29552963

2956-
++infodelay;
2957-
29582964
dump_info = (struct dump_info *)user;
29592965

29602966
pcap_dump((u_char *)dump_info->pdd, h, sp);
@@ -2966,33 +2972,36 @@ dump_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
29662972
if (dump_info->ndo != NULL)
29672973
pretty_print_packet(dump_info->ndo, h, sp, packets_captured);
29682974

2969-
--infodelay;
2970-
if (infoprint)
2975+
if (infoprint) {
29712976
info(0);
2977+
infoprint = 0;
2978+
}
29722979
}
29732980

29742981
static void
29752982
print_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
29762983
{
29772984
++packets_captured;
29782985

2979-
++infodelay;
2980-
29812986
pretty_print_packet((netdissect_options *)user, h, sp, packets_captured);
29822987

2983-
--infodelay;
2984-
if (infoprint)
2988+
if (infoprint) {
29852989
info(0);
2990+
infoprint = 0;
2991+
}
2992+
2993+
if (gotalarm) {
2994+
fprintf(stderr, "Got %u\r", packets_captured);
2995+
gotalarm = 0;
2996+
alarm(1);
2997+
}
29862998
}
29872999

29883000
#ifdef SIGNAL_REQ_INFO
29893001
static void
29903002
requestinfo(int signo _U_)
29913003
{
2992-
if (infodelay)
2993-
++infoprint;
2994-
else
2995-
info(0);
3004+
infoprint = 1;
29963005
}
29973006
#endif
29983007

@@ -3010,7 +3019,7 @@ print_packets_captured (void)
30103019
{
30113020
static u_int prev_packets_captured, first = 1;
30123021

3013-
if (infodelay == 0 && (first || packets_captured != prev_packets_captured)) {
3022+
if (first || packets_captured != prev_packets_captured) {
30143023
fprintf(stderr, "Got %u\r", packets_captured);
30153024
first = 0;
30163025
prev_packets_captured = packets_captured;
@@ -3024,12 +3033,12 @@ print_packets_captured (void)
30243033
static void CALLBACK verbose_stats_dump(PVOID param _U_,
30253034
BOOLEAN timer_fired _U_)
30263035
{
3027-
print_packets_captured();
3036+
gotalarm = 1;
30283037
}
30293038
#else /* _WIN32 */
30303039
static void verbose_stats_dump(int sig _U_)
30313040
{
3032-
print_packets_captured();
3041+
gotalarm = 1;
30333042
}
30343043
#endif /* _WIN32 */
30353044

0 commit comments

Comments
 (0)