bpftool: Fix spurious batch file read error

do_batch() checks errno after the read loop to detect read failures,
but fgets() does not clear errno on success, so a stale errno left by
a previously executed command (e.g. map dump's EBADF from a double
close) makes bpftool report a batch file read failure and exit with an
error even though every command succeeded.

Clear errno before each fgets() call, so the post-loop check only
sees the outcome of the last read: zero on success or EOF, E2BIG for
an overlong line, and a genuine errno when fgets() fails.

Since errno is now reset before every read in batch mode, drop the
USE_LIBCAP errno reset in main() that existed only to keep errno clean
for the batch mode.

Fixes: 71bb428fe2 ("tools: bpf: add bpftool")
Signed-off-by: Yuan Chen <chenyuan@kylinos.cn>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20260824092657.1789956-2-chenyuan_fl@163.com
This commit is contained in:
Yuan Chen 2026-08-24 17:26:56 +08:00 committed by Andrii Nakryiko
parent 48b69cc882
commit 713c02b59e

View File

@ -365,7 +365,11 @@ static int do_batch(int argc, char **argv)
if (json_output)
jsonw_start_array(json_wtr);
while (fgets(buf, sizeof(buf), fp)) {
for (;;) {
errno = 0;
if (!fgets(buf, sizeof(buf), fp))
break;
cp = strchr(buf, '#');
if (cp)
*cp = '\0';
@ -467,16 +471,6 @@ int main(int argc, char **argv)
setlinebuf(stdout);
#ifdef USE_LIBCAP
/* Libcap < 2.63 hooks before main() to compute the number of
* capabilities of the running kernel, and doing so it calls prctl()
* which may fail and set errno to non-zero.
* Let's reset errno to make sure this does not interfere with the
* batch mode.
*/
errno = 0;
#endif
last_do_help = do_help;
pretty_output = false;
json_output = false;