RUN
The RUN
instruction executes the command passed as argument.
Syntax
RUN command
[ IN {FORM|LINE} MODE ]
[ RETURNING variable | WITHOUT WAITING ]
- command is a string expression with the command to be executed.
- variable is an integer variable receiving the execution status of the command.
Understanding the RUN command
The RUN
instruction hands the argument command to the command interpreter.
When not specifying the WITHOUT WAITING
clause, the calling process waits
for the called process to finish execution. Otherwise, the calling process waits the command
termination.
RUN
instruction has limited
support on mobile platforms.- The
RUN
instruction is not supported on mobile devices, because of operating system limitations. RUN command WITHOUT WAITING
is not supported when programs run on an application server and display on a mobile device, because the Genero GUI protocol is not able to handle multiple connections at the same time.
Defining the command execution shell
In order to execute the command line, the RUN
instruction uses the OS-specific
shell defined in the environment of the current user. On UNIX™, this is defined by the SHELL environment variable. On Windows®, this is defined by COMSPEC. On Windows, the program defined by the COMSPEC variable must
support the /c option as CMD.EXE.
Waiting for the subprocess
By default, the runtime system waits for the end of the execution of the command, suspending the execution of the current program. After executing the command, the display of the parent program is restored.
If
you specify WITHOUT WAITING
, the specified command
line is executed as a background process, and generally does
not affect the visual display. This clause can be used when
the command takes some time to execute, and the parent program does
not need the result to continue. It is also typically used
in GUI mode to start another program. Do not use this clause
in TUI mode when the sub-program displays forms, otherwise both programs
would run simultaneously on the same terminal.
Catching the execution status
The RETURNING
clause saves the
termination status code of the command that RUN
executes
in a program variable of type SMALLINT. Examine the variable
after execution to determine the next action to take. A status
code of zero usually indicates that the command has terminated
normally. A non-zero exit status indicates an error.
RETURNING
clause is
platform-dependent.- On UNIX systems, the value is composed of two bytes having
different meanings: The lower byte (x mod 256) of the return status defines the termination status
of the
RUN
command. The higher byte (x / 256) of the return status defines the execution status of the program. - On Windows platforms, the execution status is zero for success, or a non-zero value if an error occurred: The value of the return status only defines the execution status of the program.
IN LINE MODE and IN FORM MODE
When using the TUI mode, programs operate by default in line mode, but as many statements
take it into form mode (including OPTIONS
statements that set keys,
DISPLAY
, OPEN WINDOW
, DISPLAY FORM
, and other
screen interaction statements), typical interactive TUI programs are actually in form mode
most of the time.
According to the type of command to be executed, you may need to use the IN
{LINE|FORM} MODE
clause with the RUN
instruction. It
defines how the terminal or the graphical front-end behaves when running the child process.
Besides RUN
, the OPTIONS
, START
REPORT
and START REPORT... TO
PIPE
instructions can explicitly specify a screen mode.
If no screen mode is specified in the RUN
command, the current value from the
OPTIONS
statement is used. This is, by default, IN LINE MODE
.
START REPORT
using PIPE
specifications, the default
screen mode is IN FORM MODE
.When the RUN
statement
specifies IN FORM MODE
, the program remains in form
mode if it is currently in form mode, but it does not enter form
mode if it is currently in line mode. When the prevailing RUN
option
specifies IN LINE MODE
, the program remains in line
mode if it is currently in line mode, and it switches to line
mode if it is currently in form mode. This also applies
to the PIPE
option.
Typically, if you need
to run another interactive program, you must use the IN LINE
MODE
clause:
- In TUI mode, the terminal is in the same state (in terms if tty options) as when the program began. Usually the terminal input is in cooked mode, with interrupts enabled and input not becoming available until after a newline character is typed.
- In GUI mode, if the
WITHOUT WAITING
clause in used, the front-end is warned before the child process is started (this causes a first network round-trip) After the child is started, the front-end is warned that the command was executed (second network round-trip). If theRUN
command must wait for child termination (i.e. noWITHOUT WAITING
clause is used), no particular action is taken.
However, if you want to execute a subprocess running silently
(batch program without output), you must use the IN FORM MODE
clause:
- In TUI mode, the screen stays in form mode if it was in form
mode, which saves a clear / redraw of the screen. The
FORM
mode specifies the terminal raw mode, in which each character of input becomes available to the program as it is typed or read. - In GUI mode, no particular action is taken to warn the front-end (there is no need to warn the front-end for batch program execution).
To summarize, no matter if you are in TUI or GUI mode, run silent (batch) programs in
FORM MODE
, and if the program to run is interactive, or displays messages to the
terminal, or if you don't known what it does, use the LINE MODE
(which is the
default).
RUN … IN FORM MODE
WITHOUT WAITING
(or with RUN … WITHOUT WAITING
and the FORM
MODE
is set by OPTIONS
), can lead to unexpected behavior.A good practice is to encapsulate child program and system command execution in functions.
Example
MAIN
DEFINE result SMALLINT
CALL runApplication("app2 -p xxx")
CALL runBatch("ls -l", FALSE) RETURNING result
CALL runBatch("ls -l > /tmp/files", TRUE) RETURNING result
END MAIN
FUNCTION runApplication(pname)
DEFINE pname, cmd STRING
LET cmd = "fglrun " || pname
IF fgl_getenv("FGLGUI") == 0 THEN
RUN cmd
ELSE
RUN cmd WITHOUT WAITING
END IF
END FUNCTION
FUNCTION runBatch(cmd, silent)
DEFINE cmd STRING
DEFINE silent STRING
DEFINE result SMALLINT
IF silent THEN
RUN cmd IN FORM MODE RETURNING result
ELSE
RUN cmd IN LINE MODE RETURNING result
END IF
IF fgl_getenv("OS") MATCHES "Win*" THEN
RETURN result
ELSE
RETURN ( result / 256 )
END IF
END FUNCTION