This patch improves the error handling in the javacomp, javaversion modules: - When fdopen() fails, we can assume that it is because of out-of-memory and terminate the process, like xalloc_die() does. - In the case of other failures, proper cleanup is needed.
2024-10-06 Bruno Haible <br...@clisp.org> javacomp, javaversion: Fix resource leak. * lib/javacomp.c (execute_and_read_line): When fdopen fails, terminate the program. * lib/javaversion.c (execute_and_read_line): Likewise. When we can't read a single line, call fclose and wait_subprocess, to free resources. diff --git a/lib/javacomp.c b/lib/javacomp.c index 46944f490a..107f373740 100644 --- a/lib/javacomp.c +++ b/lib/javacomp.c @@ -352,10 +352,7 @@ execute_and_read_line (const char *progname, /* Retrieve its result. */ fp = fdopen (fd[0], "r"); if (fp == NULL) - { - error (0, errno, _("fdopen() failed")); - return NULL; - } + error (EXIT_FAILURE, errno, _("fdopen() failed")); line = NULL; linesize = 0; linelen = getline (&line, &linesize, fp); diff --git a/lib/javaversion.c b/lib/javaversion.c index 60a59def76..fefdfe560d 100644 --- a/lib/javaversion.c +++ b/lib/javaversion.c @@ -61,7 +61,6 @@ execute_and_read_line (const char *progname, char *line; size_t linesize; size_t linelen; - int exitstatus; /* Open a pipe to the JVM. */ child = create_pipe_in (progname, prog_path, prog_argv, NULL, @@ -73,33 +72,35 @@ execute_and_read_line (const char *progname, /* Retrieve its result. */ fp = fdopen (fd[0], "r"); if (fp == NULL) - { - error (0, errno, _("fdopen() failed")); - return false; - } + error (EXIT_FAILURE, errno, _("fdopen() failed")); line = NULL; linesize = 0; linelen = getline (&line, &linesize, fp); if (linelen == (size_t)(-1)) { error (0, 0, _("%s subprocess I/O error"), progname); - return false; + fclose (fp); + wait_subprocess (child, progname, true, false, true, false, NULL); } - if (linelen > 0 && line[linelen - 1] == '\n') - line[linelen - 1] = '\0'; + else + { + int exitstatus; - fclose (fp); + if (linelen > 0 && line[linelen - 1] == '\n') + line[linelen - 1] = '\0'; - /* Remove zombie process from process list, and retrieve exit status. */ - exitstatus = - wait_subprocess (child, progname, true, false, true, false, NULL); - if (exitstatus != 0) - { - free (line); - return false; - } + fclose (fp); - l->line = line; + /* Remove zombie process from process list, and retrieve exit status. */ + exitstatus = + wait_subprocess (child, progname, true, false, true, false, NULL); + if (exitstatus == 0) + { + l->line = line; + return false; + } + } + free (line); return false; }