From b468824a278648ce384f39a4bb1c9dd45a9b3772 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 27 Apr 2026 09:26:58 -0700 Subject: [PATCH] libnetlink: flush stdout only in monitor mode As Eric pointed out, fflush() only makes sense in monitor mode. In other modes buffering the output helps with large outputs like route dumps. Move the fflush() into rtnl_listen() which is the common code used by all monitoring subcommands. This also ensures any future monitor subcommand gets correct flushing behavior automatically. Signed-off-by: Stephen Hemminger --- bridge/fdb.c | 2 -- bridge/link.c | 2 -- bridge/mdb.c | 1 - bridge/mst.c | 1 - bridge/vlan.c | 4 ---- bridge/vni.c | 2 -- genl/ctrl.c | 2 -- ip/ipaddress.c | 5 ----- ip/ipfou.c | 1 - ip/ipila.c | 1 - ip/ipioam6.c | 1 - ip/ipl2tp.c | 2 -- ip/iplink.c | 2 -- ip/ipmptcp.c | 6 ------ ip/ipmroute.c | 1 - ip/ipneigh.c | 2 -- ip/ipnetconf.c | 1 - ip/ipnetns.c | 1 - ip/ipnexthop.c | 6 ------ ip/ipntable.c | 2 -- ip/ipprefix.c | 1 - ip/iproute.c | 3 +-- ip/iprule.c | 1 - ip/ipseg6.c | 1 - ip/ipstats.c | 2 -- ip/iptoken.c | 2 -- ip/iptuntap.c | 1 - ip/tcp_metrics.c | 2 -- ip/xfrm_monitor.c | 5 ----- ip/xfrm_policy.c | 2 -- ip/xfrm_state.c | 1 - lib/libnetlink.c | 1 + tc/tc_class.c | 1 - tc/tc_filter.c | 1 - tc/tc_qdisc.c | 1 - 35 files changed, 2 insertions(+), 68 deletions(-) diff --git a/bridge/fdb.c b/bridge/fdb.c index d57b57503..05f093b58 100644 --- a/bridge/fdb.c +++ b/bridge/fdb.c @@ -309,7 +309,6 @@ int print_fdb(struct nlmsghdr *n, void *arg) print_string(PRINT_ANY, "state", "%s\n", state_n2a(r->ndm_state)); close_json_object(); - fflush(fp); return 0; } @@ -417,7 +416,6 @@ static int fdb_show(int argc, char **argv) exit(1); } delete_json_obj(); - fflush(stdout); return 0; } diff --git a/bridge/link.c b/bridge/link.c index 1c8faa85e..7638797d2 100644 --- a/bridge/link.c +++ b/bridge/link.c @@ -292,7 +292,6 @@ int print_linkinfo(struct nlmsghdr *n, void *arg) print_string(PRINT_FP, NULL, "%s", "\n"); close_json_object(); - fflush(fp); return 0; } @@ -669,7 +668,6 @@ static int brlink_show(int argc, char **argv) } delete_json_obj(); - fflush(stdout); return 0; } diff --git a/bridge/mdb.c b/bridge/mdb.c index 72490971c..112deeb9c 100644 --- a/bridge/mdb.c +++ b/bridge/mdb.c @@ -501,7 +501,6 @@ static int mdb_show(int argc, char **argv) close_json_object(); delete_json_obj(); - fflush(stdout); return 0; } diff --git a/bridge/mst.c b/bridge/mst.c index 37362c45e..8e46c7620 100644 --- a/bridge/mst.c +++ b/bridge/mst.c @@ -158,7 +158,6 @@ static int mst_show(int argc, char **argv) } delete_json_obj(); - fflush(stdout); return 0; } diff --git a/bridge/vlan.c b/bridge/vlan.c index 3c2402070..27d31ba8c 100644 --- a/bridge/vlan.c +++ b/bridge/vlan.c @@ -756,7 +756,6 @@ static int print_vlan_stats(struct nlmsghdr *n, void *arg) struct if_stats_msg *ifsm = NLMSG_DATA(n); struct rtattr *tb[IFLA_STATS_MAX+1]; int len = n->nlmsg_len; - FILE *fp = arg; len -= NLMSG_LENGTH(sizeof(*ifsm)); if (len < 0) { @@ -778,7 +777,6 @@ static int print_vlan_stats(struct nlmsghdr *n, void *arg) print_vlan_stats_attr(tb[IFLA_STATS_LINK_XSTATS_SLAVE], ifsm->ifindex); - fflush(fp); return 0; } @@ -1205,7 +1203,6 @@ static int vlan_show(int argc, char **argv, int subject) out: delete_json_obj(); - fflush(stdout); return 0; } @@ -1260,7 +1257,6 @@ static int vlan_global_show(int argc, char **argv) close_vlan_port(); delete_json_obj(); - fflush(stdout); return 0; } diff --git a/bridge/vni.c b/bridge/vni.c index 57b04c8c2..b28647fd2 100644 --- a/bridge/vni.c +++ b/bridge/vni.c @@ -333,7 +333,6 @@ int print_vnifilter_rtm(struct nlmsghdr *n, void *arg) if (opened) close_vni_port(); - fflush(stdout); return 0; } @@ -381,7 +380,6 @@ static int vni_show(int argc, char **argv) } delete_json_obj(); - fflush(stdout); return 0; } diff --git a/genl/ctrl.c b/genl/ctrl.c index 9412c2f0a..88ff4cb85 100644 --- a/genl/ctrl.c +++ b/genl/ctrl.c @@ -275,7 +275,6 @@ static int print_ctrl(struct rtnl_ctrl_data *ctrl, struct genlmsghdr *ghdr = NLMSG_DATA(n); int len = n->nlmsg_len; struct rtattr *attrs; - FILE *fp = (FILE *) arg; if (n->nlmsg_type != GENL_ID_CTRL) { fprintf(stderr, "Not a controller message, nlmsg_len=%d " @@ -339,7 +338,6 @@ static int print_ctrl(struct rtnl_ctrl_data *ctrl, if (tb[CTRL_ATTR_MCAST_GROUPS]) print_ctrl_mcast(tb[CTRL_ATTR_MCAST_GROUPS]); - fflush(fp); return 0; } diff --git a/ip/ipaddress.c b/ip/ipaddress.c index 4d93a04a8..6017bc837 100644 --- a/ip/ipaddress.c +++ b/ip/ipaddress.c @@ -894,7 +894,6 @@ static int print_linkinfo_brief(FILE *fp, const char *name, print_string(PRINT_FP, NULL, "%s", "\n"); } - fflush(fp); return 0; } @@ -1346,7 +1345,6 @@ int print_linkinfo(struct nlmsghdr *n, void *arg) } print_string(PRINT_FP, NULL, "%s", "\n"); - fflush(fp); /* prettier here if stderr and stdout go to the same place */ if (truncated_vfs) fprintf(stderr, "Truncated VF list: %s\n", name); @@ -1732,7 +1730,6 @@ int print_addrinfo(struct nlmsghdr *n, void *arg) } print_string(PRINT_FP, NULL, "%s", "\n"); brief_exit: - fflush(fp); return 0; } @@ -1768,7 +1765,6 @@ static int print_selected_addrinfo(struct ifinfomsg *ifi, if (brief) { print_string(PRINT_FP, NULL, "%s", "\n"); - fflush(fp); } return 0; } @@ -2351,7 +2347,6 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action) print_link_stats(stdout, n); close_json_object(); } - fflush(stdout); out: free_nlmsg_chain(ainfo); diff --git a/ip/ipfou.c b/ip/ipfou.c index 760cfee27..8c1e061a7 100644 --- a/ip/ipfou.c +++ b/ip/ipfou.c @@ -322,7 +322,6 @@ static int do_show(int argc, char **argv) return 1; } delete_json_obj(); - fflush(stdout); return 0; } diff --git a/ip/ipila.c b/ip/ipila.c index 80f34f293..2590de9ae 100644 --- a/ip/ipila.c +++ b/ip/ipila.c @@ -159,7 +159,6 @@ static int do_list(int argc, char **argv) return 1; } delete_json_obj(); - fflush(stdout); return 0; } diff --git a/ip/ipioam6.c b/ip/ipioam6.c index 188609892..118fcd1c3 100644 --- a/ip/ipioam6.c +++ b/ip/ipioam6.c @@ -261,7 +261,6 @@ static int ioam6_do_cmd(void) exit(1); } delete_json_obj(); - fflush(stdout); } return 0; diff --git a/ip/ipl2tp.c b/ip/ipl2tp.c index 87a4b8980..97f7ff080 100644 --- a/ip/ipl2tp.c +++ b/ip/ipl2tp.c @@ -467,7 +467,6 @@ static int get_session(struct l2tp_data *p) exit(1); } delete_json_obj(); - fflush(stdout); return 0; } @@ -502,7 +501,6 @@ static int get_tunnel(struct l2tp_data *p) exit(1); } delete_json_obj(); - fflush(stdout); return 0; } diff --git a/ip/iplink.c b/ip/iplink.c index fce6631d2..eae51438d 100644 --- a/ip/iplink.c +++ b/ip/iplink.c @@ -1296,7 +1296,6 @@ static void print_mpls_stats(FILE *fp, struct rtattr *attr) print_nl(); print_mpls_link_stats(fp, stats, " "); print_string(PRINT_FP, NULL, "%s", "\n"); - fflush(fp); } static void print_af_stats_attr(FILE *fp, int ifindex, struct rtattr *attr) @@ -1359,7 +1358,6 @@ static int print_af_stats(struct nlmsghdr *n, void *arg) if (tb[IFLA_STATS_AF_SPEC]) print_af_stats_attr(fp, ifsm->ifindex, tb[IFLA_STATS_AF_SPEC]); - fflush(fp); return 0; } diff --git a/ip/ipmptcp.c b/ip/ipmptcp.c index 3df89db54..02cf72ce5 100644 --- a/ip/ipmptcp.c +++ b/ip/ipmptcp.c @@ -276,7 +276,6 @@ static int print_mptcp_addrinfo(struct rtattr *addrinfo) print_nl(); close_json_object(); - fflush(stdout); return 0; } @@ -320,12 +319,10 @@ static int mptcp_addr_dump(void) if (rtnl_dump_filter(&genl_rth, print_mptcp_addr, stdout) < 0) { fprintf(stderr, "Dump terminated\n"); delete_json_obj(); - fflush(stdout); return -2; } delete_json_obj(); - fflush(stdout); return 0; } @@ -349,7 +346,6 @@ static int mptcp_addr_show(int argc, char **argv) ret = print_mptcp_addr(answer, stdout); delete_json_obj(); free(answer); - fflush(stdout); return ret; } @@ -430,7 +426,6 @@ static int print_mptcp_limit(struct nlmsghdr *n, void *arg) print_nl(); close_json_object(); - fflush(stdout); return 0; } @@ -592,7 +587,6 @@ static int mptcp_monitor_msg(struct rtnl_ctrl_data *ctrl, out: print_nl(); close_json_object(); - fflush(stdout); return 0; } diff --git a/ip/ipmroute.c b/ip/ipmroute.c index c540eab13..164632e6f 100644 --- a/ip/ipmroute.c +++ b/ip/ipmroute.c @@ -206,7 +206,6 @@ int print_mroute(struct nlmsghdr *n, void *arg) print_string(PRINT_FP, NULL, "\n", NULL); close_json_object(); - fflush(fp); return 0; } diff --git a/ip/ipneigh.c b/ip/ipneigh.c index e678545ad..be5371870 100644 --- a/ip/ipneigh.c +++ b/ip/ipneigh.c @@ -298,7 +298,6 @@ static int print_neigh_brief(FILE *fp, struct ndmsg *r, struct rtattr *tb[]) print_string(PRINT_FP, NULL, "%s", "\n"); close_json_object(); - fflush(fp); return 0; } @@ -472,7 +471,6 @@ int print_neigh(struct nlmsghdr *n, void *arg) print_string(PRINT_FP, NULL, "\n", ""); close_json_object(); - fflush(fp); return 0; } diff --git a/ip/ipnetconf.c b/ip/ipnetconf.c index 020eff786..57bb99d1f 100644 --- a/ip/ipnetconf.c +++ b/ip/ipnetconf.c @@ -140,7 +140,6 @@ int print_netconf(struct rtnl_ctrl_data *ctrl, struct nlmsghdr *n, void *arg) close_json_object(); print_string(PRINT_FP, NULL, "\n", NULL); - fflush(fp); return 0; } diff --git a/ip/ipnetns.c b/ip/ipnetns.c index 3a33a3ada..587534ae0 100644 --- a/ip/ipnetns.c +++ b/ip/ipnetns.c @@ -327,7 +327,6 @@ int print_nsid(struct nlmsghdr *n, void *arg) print_string(PRINT_FP, NULL, "\n", NULL); close_json_object(); - fflush(fp); return 0; } diff --git a/ip/ipnexthop.c b/ip/ipnexthop.c index d5c429369..14b525aa0 100644 --- a/ip/ipnexthop.c +++ b/ip/ipnexthop.c @@ -826,7 +826,6 @@ int print_cache_nexthop(struct nlmsghdr *n, void *arg, bool process_cache) __print_nexthop_entry(fp, NULL, &nhe, n->nlmsg_type == RTM_DELNEXTHOP); print_string(PRINT_FP, NULL, "%s", "\n"); - fflush(fp); if (process_cache) ipnh_cache_process_nlmsg(n, &nhe); @@ -882,7 +881,6 @@ int print_nexthop_bucket(struct nlmsghdr *n, void *arg) print_string(PRINT_FP, NULL, "%s", "\n"); close_json_object(); - fflush(fp); return 0; } @@ -1178,7 +1176,6 @@ static int ipnh_get_id(__u32 id) } delete_json_obj(); - fflush(stdout); free(answer); @@ -1266,7 +1263,6 @@ static int ipnh_list_flush(int argc, char **argv, int action) } delete_json_obj(); - fflush(stdout); return 0; } @@ -1342,7 +1338,6 @@ static int ipnh_bucket_list(int argc, char **argv) } delete_json_obj(); - fflush(stdout); return 0; } @@ -1383,7 +1378,6 @@ static int ipnh_bucket_get_id(__u32 id, __u16 bucket_index) } delete_json_obj(); - fflush(stdout); free(answer); diff --git a/ip/ipntable.c b/ip/ipntable.c index 54db9b62c..51fa067cc 100644 --- a/ip/ipntable.c +++ b/ip/ipntable.c @@ -532,7 +532,6 @@ static void print_ndtstats(const struct ndt_stats *ndts) static int print_ntable(struct nlmsghdr *n, void *arg) { - FILE *fp = (FILE *)arg; struct ndtmsg *ndtm = NLMSG_DATA(n); int len = n->nlmsg_len; struct rtattr *tb[NDTA_MAX+1]; @@ -633,7 +632,6 @@ static int print_ntable(struct nlmsghdr *n, void *arg) print_string(PRINT_FP, NULL, "\n", ""); close_json_object(); - fflush(fp); return 0; } diff --git a/ip/ipprefix.c b/ip/ipprefix.c index 4ec305241..5704f2f95 100644 --- a/ip/ipprefix.c +++ b/ip/ipprefix.c @@ -81,7 +81,6 @@ int print_prefix(struct nlmsghdr *n, void *arg) } fprintf(fp, "\n"); - fflush(fp); return 0; } diff --git a/ip/iproute.c b/ip/iproute.c index c2538894d..5b9e7ac11 100644 --- a/ip/iproute.c +++ b/ip/iproute.c @@ -1012,7 +1012,6 @@ int print_route(struct nlmsghdr *n, void *arg) print_string(PRINT_FP, NULL, "\n", NULL); close_json_object(); - fflush(fp); return 0; } @@ -1792,6 +1791,7 @@ static int iproute_flush(int family, rtnl_filter_t filter_fn) if (time(0) - start > 30) { printf("\n*** Flush not completed after %ld seconds, %d entries remain ***\n", (long)(time(0) - start), filter.flushed); + fflush(stdout); return -1; } @@ -2035,7 +2035,6 @@ static int iproute_list_flush_or_save(int argc, char **argv, int action) } delete_json_obj(); - fflush(stdout); return 0; } diff --git a/ip/iprule.c b/ip/iprule.c index 3af02da24..b56b1b183 100644 --- a/ip/iprule.c +++ b/ip/iprule.c @@ -599,7 +599,6 @@ int print_rule(struct nlmsghdr *n, void *arg) print_string(PRINT_FP, NULL, "\n", ""); close_json_object(); - fflush(fp); return 0; } diff --git a/ip/ipseg6.c b/ip/ipseg6.c index 305b89614..efd372275 100644 --- a/ip/ipseg6.c +++ b/ip/ipseg6.c @@ -197,7 +197,6 @@ static int seg6_do_cmd(void) exit(1); } delete_json_obj(); - fflush(stdout); } return 0; diff --git a/ip/ipstats.c b/ip/ipstats.c index f0f8dcdcb..8a2ac85e2 100644 --- a/ip/ipstats.c +++ b/ip/ipstats.c @@ -879,7 +879,6 @@ static int ipstats_dump(struct ipstats_stat_enabled *enabled) rc = -2; } - fflush(stdout); return rc; } @@ -1355,6 +1354,5 @@ int ipstats_print(struct nlmsghdr *n, void *arg) if (rc) return rc; - fflush(fp); return 0; } diff --git a/ip/iptoken.c b/ip/iptoken.c index f25a7c8b2..8bd9b4dc9 100644 --- a/ip/iptoken.c +++ b/ip/iptoken.c @@ -41,7 +41,6 @@ static void usage(void) static int print_token(struct nlmsghdr *n, void *arg) { struct rtnl_dump_args *args = arg; - FILE *fp = args->fp; int ifindex = args->ifindex; struct ifinfomsg *ifi = NLMSG_DATA(n); int len = n->nlmsg_len; @@ -85,7 +84,6 @@ static int print_token(struct nlmsghdr *n, void *arg) "ifname", "%s\n", ll_index_to_name(ifi->ifi_index)); close_json_object(); - fflush(fp); return 0; } diff --git a/ip/iptuntap.c b/ip/iptuntap.c index 6718ec6cb..0f46fe6a0 100644 --- a/ip/iptuntap.c +++ b/ip/iptuntap.c @@ -444,7 +444,6 @@ static int do_show(int argc, char **argv) } delete_json_obj(); - fflush(stdout); return 0; } diff --git a/ip/tcp_metrics.c b/ip/tcp_metrics.c index 9c8fb0724..6b9e68316 100644 --- a/ip/tcp_metrics.c +++ b/ip/tcp_metrics.c @@ -156,7 +156,6 @@ static void print_tcp_metrics(struct rtattr *a) static int process_msg(struct nlmsghdr *n, void *arg) { - FILE *fp = (FILE *) arg; struct genlmsghdr *ghdr; struct rtattr *attrs[TCP_METRICS_ATTR_MAX + 1], *a; const char *h; @@ -334,7 +333,6 @@ static int process_msg(struct nlmsghdr *n, void *arg) print_string(PRINT_FP, NULL, "\n", ""); close_json_object(); - fflush(fp); return 0; } diff --git a/ip/xfrm_monitor.c b/ip/xfrm_monitor.c index 1f67fe9d1..a96358b04 100644 --- a/ip/xfrm_monitor.c +++ b/ip/xfrm_monitor.c @@ -85,7 +85,6 @@ static int xfrm_acquire_print(struct nlmsghdr *n, void *arg) if (oneline) fprintf(fp, "\n"); - fflush(fp); return 0; } @@ -114,7 +113,6 @@ static int xfrm_state_flush_print(struct nlmsghdr *n, void *arg) if (oneline) fprintf(fp, "\n"); - fflush(fp); return 0; } @@ -151,7 +149,6 @@ static int xfrm_policy_flush_print(struct nlmsghdr *n, void *arg) if (oneline) fprintf(fp, "\n"); - fflush(fp); return 0; } @@ -232,7 +229,6 @@ static int xfrm_ae_print(struct nlmsghdr *n, void *arg) xfrm_usersa_print(&id->sa_id, id->reqid, fp); fprintf(fp, "\n"); - fflush(fp); return 0; } @@ -257,7 +253,6 @@ static int xfrm_mapping_print(struct nlmsghdr *n, void *arg) xfrm_usersa_print(&map->id, map->reqid, fp); fprintf(fp, "\n"); - fflush(fp); return 0; } diff --git a/ip/xfrm_policy.c b/ip/xfrm_policy.c index 8687ced35..e60acd5bb 100644 --- a/ip/xfrm_policy.c +++ b/ip/xfrm_policy.c @@ -565,7 +565,6 @@ int xfrm_policy_print(struct nlmsghdr *n, void *arg) if (oneline) fprintf(fp, "\n"); - fflush(fp); return 0; } @@ -1232,7 +1231,6 @@ int xfrm_policy_default_print(struct nlmsghdr *n, FILE *fp) fprintf(fp, " in: %s\n", xfrm_policy_to_str(up->in)); fprintf(fp, " fwd: %s\n", xfrm_policy_to_str(up->fwd)); fprintf(fp, " out: %s\n", xfrm_policy_to_str(up->out)); - fflush(fp); return 0; } diff --git a/ip/xfrm_state.c b/ip/xfrm_state.c index 252a7a534..dcd08d595 100644 --- a/ip/xfrm_state.c +++ b/ip/xfrm_state.c @@ -1051,7 +1051,6 @@ static int __do_xfrm_state_print(struct nlmsghdr *n, void *arg, bool nokeys) if (oneline) fprintf(fp, "\n"); - fflush(fp); return 0; } diff --git a/lib/libnetlink.c b/lib/libnetlink.c index 6b275a1f1..8905e297f 100644 --- a/lib/libnetlink.c +++ b/lib/libnetlink.c @@ -1275,6 +1275,7 @@ int rtnl_listen(struct rtnl_handle *rtnl, } err = handler(&ctrl, h, jarg); + fflush(stdout); if (err < 0) return err; diff --git a/tc/tc_class.c b/tc/tc_class.c index 6d707d8c9..ea6d986ae 100644 --- a/tc/tc_class.c +++ b/tc/tc_class.c @@ -380,7 +380,6 @@ int print_class(struct nlmsghdr *n, void *arg) close_json_object(); } close_json_object(); - fflush(fp); return 0; } diff --git a/tc/tc_filter.c b/tc/tc_filter.c index 7db850bda..b1dcf1bae 100644 --- a/tc/tc_filter.c +++ b/tc/tc_filter.c @@ -374,7 +374,6 @@ int print_filter(struct nlmsghdr *n, void *arg) print_ext_msg(tb); close_json_object(); - fflush(fp); return 0; } diff --git a/tc/tc_qdisc.c b/tc/tc_qdisc.c index 7eb9a31ba..634d5f70b 100644 --- a/tc/tc_qdisc.c +++ b/tc/tc_qdisc.c @@ -344,7 +344,6 @@ int print_qdisc(struct nlmsghdr *n, void *arg) print_ext_msg(tb); close_json_object(); - fflush(fp); return 0; } -- 2.47.3