Next: Colormap, Previous: Messages and Questions, Up: Part I Goodies [Contents][Index]
In a number of situations, a GUI is created specifically to make an
existing command-line oriented program easier to use. For stylistic
considerations, you probably don’t want to have the output
(stderr
and stdout
) as a result of running the command
printed on the terminal. Rather you want to log all the messages to a
browser so the user can decide if and when to view the log. For this, a
goodie is available
long fl_exe_command(const char *cmd, int block);
This function, similar to a system(3)
call, forks a new process
that runs the command cmd
, which must be a (null-terminated)
string containing a command line passed to the (sh) shell. The output
(both stderr
and stdout
) of cmd
is logged into a
browser, which can be presented to the user when appropriate (see
below). The block
argument is a flag indicating if the function
should wait for the child process to finish. If the argument
block
is true (non-zero), the function waits until the command
cmd
completes and then returns the exit status of the command
cmd
(i.e., the status one gets form wait()
or
waitpid()
, so use WEXITSTATUS()
on it if you want the
return or exit()
value from the program started)). If the
argument block
is false (0), the function returns immediately
without waiting for the command to finish. In this case, the function
returns the process ID of the child process or -1 if an error occured.
Unlike other goodies, fl_exe_command()
does not
deactivate other forms even in blockng mode. This means that the user
can interact with the GUI while fl_exe_command()
waits
for the child process to finish. If this is not desired, you can use
fl_deactivate_all_forms()
and
fl_activate_all_forms()
to wrap the function.
If fl_exe_command()
is called in non-blocking mode, the
following function should be called to clean up related processes and
resources before the caller exits (otherwise a zombie process may
result)
int fl_end_command(long pid);
where pid
is the process ID returned by
fl_exe_command()
. The function suspends the current
process and waits until the child process is completed, then it
returns the exit status of the child process or -1 if an error has
occurred.
There is another routine that will wait for all the child processes
initiated by fl_exe_command()
to complete
int fl_end_all_command(void)
The function returns the status of the last child process.
You can also poll the status of a child process using the following routine
int fl_check_command(long pid);
where pid
is the process ID returned by
fl_exe_command()
. The function returns the following
values: 0 if the child process is finished; 1 if the child process
still exists (running or stopped) and -1 if an error has occurred
inside the function.
If some interaction with the command being executed is desired, the
following functions may be more appropriate. These functions operates
almost exactly as the popen(3)
and pclose(3)
functions:
FILE *fl_popen(const char *command, const char *type); int fl_pclose(FILE *stream);
The fl_popen()
function executes the command in a child
process, and logs the stderr
messages into the command log.
Further, if type is "w"
, stdout
will also be logged into
the command browser. fl_pclose()
should be used to clean
up the child process.
To show or hide the logs of the command output, use the following functions
int fl_show_command_log(int border); void fl_hide_command_log(void);
where border
is the same as that used in
fl_show_form()
. These two routines can be called anytime
anywhere after fl_initialize()
has been invoked.
The command log is by default placed at the top-right corner of the screen. To change the default placement, use the following routine
void fl_set_command_log_position(int x, int y);
where x
and y
are the coordinates of the upper-left
corner of the form relative to the root window. The logging of the
output is accumulative, i.e., fl_exe_command()
does not
clear the browser. To clear the browser, use the following routine
void fl_clear_command_log(void);
It is possible to add arbitrary text to the command browser via the following routine
void fl_addto_command_log(const char *txt); void fl_addto_command_log_f(const char *fmt, ...);
where txt
for fl_addto_command_log()
is a string and
fmt
for fl_addto_command_log_f()
is a format string like
for printf()
that gets expanded using the following arguments.
This string, with possible embedded newlines, gets added to the last
line of the browser using fl_addto_browser_chars()
.
Finally, there is a routine that can be used to obtain the GUI structure of the command browser
typedef struct { FL_FORM * form; /* the form */ FL_OBJECT * browser; /* the browser */ FL_OBJECT * close_browser; /* the close button */ FL_OBJECT * clear_browser; /* the clear button */ } FD_CMDLOG; FD_CMDLOG *fl_get_command_log_fdstruct(void);
From the information returned the application program can change various attributes of the command browser and its associated objects. Note however, that you should not hide/show the form or free any members of the structure.
Next: Colormap, Previous: Messages and Questions, Up: Part I Goodies [Contents][Index]