[GRASS-dev] How to check return code of subprocess in C

Hi,

how should the C module check if the subprocess succeeded, i.e. what is subprocess return code.

I just committed fix for r.mode (1) and before the fix, r.mode was pretending that everything is all right although it was not (r.reclass failed and printed help). Now the r.reclass does not fail and r.mode works, however there is still the check of return code missing.

So, the question is, how to deal with the failed subprocess when using G_popen_write and G_popen_close function as in case of r.mode. Unfortunately, ./lib/gis/popen.c does not contain any documentation, so that’s why I’m asking.

Thanks,
Vaclav

[r58838] https://trac.osgeo.org/grass/changeset/58838

(1) Is anybody using r.mode? The bug was there for a long time.

Vaclav Petras wrote:

how should the C module check if the subprocess succeeded, i.e. what is
subprocess return code.

I just committed fix for r.mode (1) and before the fix, r.mode was
pretending that everything is all right although it was not (r.reclass
failed and printed help). Now the r.reclass does not fail and r.mode works,
however there is still the check of return code missing.

So, the question is, how to deal with the failed subprocess when using
G_popen_write and G_popen_close function as in case of r.mode.
Unfortunately, ./lib/gis/popen.c does not contain any documentation, so
that's why I'm asking.

Currently, that isn't possible.

Consider replacing G_popen_close() with:

  int G_popen_close(struct Popen *state)
  {
      if (state->fp)
    fclose(state->fp);
  
      if (state->pid == -1)
    return -1;
  
      return G_wait(state->pid);
  }

But bear in mind that the same issue applies to r.rescale, r.mode,
r.statistics, r.coin and the functions in lib/gis/pager.c.

An alternative would be for G_popen_close() to raise a fatal error if
the child process terminates with a non-zero exit status or on a
signal.

FWIW, the Unix pclose() function returns -1 and sets errno in the
event of an error.

Also G_wait (in spawn.c) probably needs:

  else if (WIFSIGNALED(status))
- return WTERMSIG(status);
+ return -WTERMSIG(status);

Currently, there's no way to distinguish between an exit status and a
signal.

--
Glynn Clements <glynn@gclements.plus.com>