G_popen_close() waits for the child process but discards the exit status and returns void, so callers of G_popen_read()/G_popen_write() cannot tell whether the child succeeded. POSIX pclose() returns the status for this reason.
Details (analysis generated with Claude Code)
lib/gis/popen.c:
void G_popen_close(struct Popen *state)
{
if (state->fp)
fclose(state->fp);
if (state->pid != -1)
G_wait(state->pid);
}
The value of G_wait() is dropped. Returning it (with something distinguishable when there was no child) lets callers check the child, like pclose() does.
This is one of the links that made #7734 silent: r.coin runs r.stats through G_popen_read(), and when r.stats failed, the exit status was discarded here, so r.coin printed an empty table and exited with success. Analysis in #7732.
G_popen_close()waits for the child process but discards the exit status and returns void, so callers ofG_popen_read()/G_popen_write()cannot tell whether the child succeeded. POSIXpclose()returns the status for this reason.Details (analysis generated with Claude Code)
lib/gis/popen.c:The value of
G_wait()is dropped. Returning it (with something distinguishable when there was no child) lets callers check the child, likepclose()does.This is one of the links that made #7734 silent: r.coin runs r.stats through
G_popen_read(), and when r.stats failed, the exit status was discarded here, so r.coin printed an empty table and exited with success. Analysis in #7732.