[GRASS-dev] Exit code for Tk GUI

Glynn Clements glynn at gclements.plus.com
Sun Sep 23 20:23:54 EDT 2007


Maris Nartiss wrote:

> Hi folks,
> 
> I was looking at open issue list and noted some interesting issue #483
> [1]. It seemed to be easy to fix, but after some hours of digging into
> code, it started to look like unfixable.
> 
> As I'm not a good programmer, please, correct me at any place where I'm wrong.
> 
> First - I understood that current GRASS autogenerated tcl/tk GUI works
> in following way (with respect to exit codes and with shortenings):
> 1) module (i.e. r.info) is launched and control is passed to G_parser;
> 2) as there are no args, G_parser builds tcl/tk description for module
> and passes it to wish (via popen and fprintf);
> 3) when user hits RUN button in module GUI, another instance of module
> gets launched with users provided args via gronsole;
> 4) when user closes GUI, control is returned to G_parser;
> 5) G_parser returns error (-1) to caller;
> 6) module checks G_parser return code and exits as there was an error.
> 
> Final result == module with tcl interface allways exits with error.
> It's a design failure. Returning other value from G_parser if user
> just ended GUI session will break all modules that use G_parser (no-no
> till GRASS7);
> 
> Still there may be some way around:
> 1) In G_gui_tcltk (parser.c) collect whole tcl/tk wish script (file,array) and
> 2) launch wish via execlp(getenv("GRASS_WISH"),script);
> We get rid of first module instance that created GUI and exit code is
> up to gis.tcl/gronsole.

An alternative is to make the initial command return wish's exit code
(which is returned from pclose()), i.e.:

--- lib/gis/parser.c	8 Sep 2007 16:22:21 -0000	1.130
+++ lib/gis/parser.c	24 Sep 2007 00:05:54 -0000
@@ -1887,6 +1887,7 @@
 static void G_gui_tcltk (void)
 {
 	FILE *fp;
+	int status;
 
 	if (!pgm_name)
 		pgm_name = G_program_name ();
@@ -1912,7 +1913,10 @@
 
 	generate_tcl(fp);
 
-	pclose(fp);
+	status = pclose(fp);
+	if (status < 0)
+		G_fatal_error("error executing 'wish'");
+	exit(status);
 }
 
 /* Build wxPython gui */

However, that's only part of the solution, as you note in point #2
below.

> Currently such approach has some problems:
> 1) if user hits RUN button in GUI w/o any param's, it starts another
> module window (hint - need to look how parser determines that GUI is
> already running);

It doesn't.

To generate the dialogs, gis.m invokes the command with the --tcltk
switch. This causes the command to write the generated code to stdout,
rather than spawning a wish process. gis.m reads the Tcl/Tk and
executes it locally, having previously overriden some of the
procedures in gui.tcl (specifically, run_cmd and
make_{buttons,output,progress}).

> 2) still way how to get module exit code from gronsole is required.

Getting the actual exit code isn't possible, AFAICT. The problem is
that Tcl's "open |..." syntax can create a pipeline consisiting of
multiple commands. In fact, the gronsole code always spawns two
commands (the second is the grocat program, used to merge stdout and
stderr).

It is possible to determine success or failure, according to whether
the "close" command throws an exception. It isn't possible to get the
actual exit code, though.

It should be feasible to have gronsole return success or failure, and
having gui.tcl indicate that through its overall exit code.

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




More information about the grass-dev mailing list