From: Stephen Hemminger Date: Mon, 27 Apr 2026 16:26:58 +0000 (-0700) Subject: libnetlink: flush stdout only in monitor mode X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=HEAD;p=thirdparty%2Fiproute2.git 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 --- diff --git a/bridge/fdb.c b/bridge/fdb.c index d57b5750..05f093b5 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 1c8faa85..7638797d 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 72490971..112deeb9 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 37362c45..8e46c762 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 3c240207..27d31ba8 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 57b04c8c..b28647fd 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 9412c2f0..88ff4cb8 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 4d93a04a..6017bc83 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 760cfee2..8c1e061a 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 80f34f29..2590de9a 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 18860989..118fcd1c 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 87a4b898..97f7ff08 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 fce6631d..eae51438 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 3df89db5..02cf72ce 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 c540eab1..164632e6 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 e678545a..be537187 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 020eff78..57bb99d1 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 3a33a3ad..587534ae 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 d5c42936..14b525aa 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 54db9b62..51fa067c 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 4ec30524..5704f2f9 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 c2538894..5b9e7ac1 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 3af02da2..b56b1b18 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 305b8961..efd37227 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 f0f8dcdc..8a2ac85e 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 f25a7c8b..8bd9b4dc 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 6718ec6c..0f46fe6a 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 9c8fb072..6b9e6831 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 1f67fe9d..a96358b0 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 8687ced3..e60acd5b 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 252a7a53..dcd08d59 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 6b275a1f..8905e297 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 6d707d8c..ea6d986a 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 7db850bd..b1dcf1ba 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 7eb9a31b..634d5f70 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; }