bionic (3) blt::bgexec.3tcl.gz

Provided by: blt-dev_2.5.3+dfsg-4_amd64 bug

NAME

       bgexec  -  Run  programs  in  the  background while handling Tk events.  kill - Terminate program or send
       signal.

SYNOPSIS

       blt::bgexec varName ?switches? program ?arg?...
       blt::kill processid ?signal?
_________________________________________________________________

DESCRIPTION

       The kill command terminates a processid or under unix sends a signal.

       The bgexec command executes a program pipleline  using  the  Tcl  event-loop  allowing  other  events  to
       continue  to  be  serviced.   Upon completion it sets the global variable varName with a list of 4 status
       values: a text token, the process-id, the exit code, and a text message.   Bgexec  provides  capabilities
       similar to the exec command, but with added support for callbacks, output to variables and termination.

       When  used  with no options, the returned value from bgexec is the output from the program.  But when the
       last arg is an ampersand (&) the program runs detached, and bgexec immediately returns with a list of the
       process ids created in the command pipeline.  Detached processes can be interrupted and terminated simply
       by setting varName.

       The valid switches are as follows:

       -check num
              Interval in ms to poll for the exiting processes.  The default is 1000.

       -closeonkill millisecs
              Force close of stdin/stdout on kill after the given interval.  This lets kill finalize  processes,
              even  uninterruptably  sleeping ones unable to receive signals.  The default is 0 for do not force
              close.

       -command script
              Specifies a command to call upon command completion/termination.  Two extra arguments are appended
              before the call.  The data output from the command, and the status info as set into varName.

       -decodeerror encodingName
              Specifies  the  encoding  of  the  stderr  channel.   This  affects  only data returned to the Tcl
              interpreter.  No translation is done on file redirection.  For example if data is to be  converted
              from  Unicode  for  use  in  Tcl,  you  would  use  the "unicode" encoding. The default is that no
              tranlation is performed.

       -decodeoutput encodingName
              Specifies the encoding of the stdout channels.   This  affects  only  data  returned  to  the  Tcl
              interpreter.   No translation is done on file redirection.  For example if data is to be converted
              from Unicode for use in Tcl, you would  use  the  "unicode"  encoding.  The  default  is  that  no
              tranlation is performed.

       -echo boolean
              Indicates if the pipeline's stderr stream should be echoed.  Note: this option is deprecated.

       -error varName
              Specifies  that  a  global  variable  varName  is  to be set with the contents of stderr after the
              program has completed.

       -keepnewline boolean
              Specifies that a trailing newline should be retained in  the  output.  If  boolean  is  true,  the
              trailing newline is truncated from the output of the -onoutput and -output variables.  The default
              value is true.

       -killsignal signal
              Specifies the signal to be sent to the program when terminating. This option is available only  on
              Unix.  Signal can either be a number (typically 1-32) or a mnemonic (such as SIGINT). If signal is
              the empty string, then no signal is sent.  The default signal is 9 (SIGKILL).

       -lasterror varName
              Specifies a variable varName that is updated whenever data becomes available from  standard  error
              of the program.  VarName is a global variable. Unlike the -error option, data is available as soon
              as it arrives.

       -lastoutput varName
              Specifies a variable varName that is updated whenever data becomes available from standard  output
              of  the  program.   VarName  is a global variable. Unlike the -output option, data is available as
              soon as it arrives.

       -limit numBytes
              Limit the size of the returned data to numBytes, terminating the program if exceeded.   The  limit
              applies to both stdout and stderr.

       -linebuffered boolean
              Specifies  that  updates  should  be  made  on  a  line-by-line  basis.  Normally when new data is
              available bgexec will set the variable (-lastoutput and -lasterror options) or invoke the  command
              (-onoutput  and  -onerror options) delivering all the new data currently available.  If boolean is
              true, only one line at a time will be delivered.  This can be useful when you want to process  the
              output on a line-by-line basis.  The default value is false.

       -local boolean
              When  boolean  is  true,  any unqualified variables or command options are treated as local to the
              current namespace.  This is mostly useful for non-detaching (no ampersand)  commands.   Note  that
              using  this  flag  with a detached command will use variables from the current namespace, not from
              the current proc stack-frame.

       -onerror command
              Specifies the start of a Tcl command that will be executed whenever new  data  is  available  from
              standard error. The data is appended to the command as an extra argument before it is executed.

       -onoutput command
              Specifies  the  start  of  a Tcl command that will be executed whenever new data is available from
              standard output. The data is appended to the command as an extra argument before it is executed.

       -output varName
              Specifies a global variable varName to be set with the output of the program, upon completion.

       -raise boolean
              When boolean is true, a non-zero return code from a non-detached command will raise an error  (.ie
              emulates  exec).   The default is false an error is generated only if one of the following occurs:
              invalid options are given, a redirection  error,  or  process  creation  failure  (eg.  executable
              program not found).  Detached commands, of course, never raise an error on a non-zero return code.

       --     This  marks  the  end  of  the  options.   The following argument will be considered the name of a
              program even if it starts with a dash (-).

USAGE

       Invoking bgexec without a trailing ampersand will block and wait for result.  However, other  Tcl  events
       continue to be serviced.  This prevents Tcl from hanging, eg:

              pack [text .t]
              set val [blt::bgexec myStatus du -s]

       Note that text widget .t continues to respond to events.

CALLBACKS

       Here is an example that invokes the Unix du program with a -command callback.

              proc Done {data status} {  puts "Done($status)\n$data" }

              blt::bgexec myStatus  -command Done   du -s $dir &

       When  du  has  completed,  the  handler  Done  is called with data and status.  Also, the global variable
       myStatus is set to contain the program's exit status, eg:

              EXITED 26811 0 {child completed normally}

       If myStatus is set before du has completed, the process will be killed. Under Unix, this sends  a  signal
       (SIGKILL by default).  Under Win32, TerminateProcess is called.

VARIABLE

       Here is another example, this time using the -output option to direct output to a variable.

              global myStatus myOutput
              blt::bgexec myStatus -output myOutput du -s $dir
              puts "Disk usage for $dir is $myOutput"

       Upon completion, MyOutput will contain the output of the program.

STDERR

       Various bgexec options can be used to capture stderr separately from stdout.

              global myStatus myOutput myErrs
              blt::bgexec myStatus -output myOutput -error myErrs du -s $dir

       The  -error  option is similar to -output in that it sets a variable when the program completes with data
       written to stderr.

LOCAL

       By default, bgexec treats variable or command options as being  in  the  global  namespace.   The  -local
       option  can  change  this  to  use  the current namespace.  Thus data can be collected to namespace-local
       variables even those inside of procs,  eg.

              proc Work {} {
                blt::bgexec myStatus -local 1 -output val -error err du -s
                puts "VAL=$val"
                puts "ERR=$err"
              }

       which collects data to local variables.

       For detached processes, -local will cause data to aggregate to namespace variables, ie. outside the proc,
       eg.

              namespace eval ::Ns {
                set pval {}
                set perr {}
                proc Work {} {
                  blt::bgexec myStatus -local 1 -output pval -error perr du -s &
                }
              }

       This collects data to ::Ns::pval and stderr to  ::Ns::perr.  Similarly, proc names (eg -onoutput) will be
       relative to the current namespace.

PROGRESS

       The -output and -error variables are set only after the program completes.  But if a program runs  for  a
       long  time,  you can gather data as it becomes available using the -onoutput option.  As new data becomes
       available, this command is executed, with data appended as an argument.

              proc GetInfo { data } { puts $data }

              blt::bgexec myStatus -onoutput GetInfo du -s $dir

       The -onerror option performs a similar function for the stderr data stream.

ERROR HANDLING

       Like exec, bgexec returns an error if the exit code of the program is non-zero.  To  handle  this  invoke
       bgexec from within a catch.

              catch { blt::bgexec myStatus -output myOutput du -s $dir }

       Detached  jobs  will generate an error only if the program startup failed.  Otherwise the only indication
       is the status code set in myStatus.

TKWAIT

       By default, bgexec waits for a program to finish and returns the resulting output.  To detach  a  program
       simply append an ampersand (&) as the last argument on the command line, eg.

              global myStatus myOutput
              blt::bgexec myStatus -output myOutput du -s $dir &

       Bgexec  will then return immediately with the spawned process ids as the result.  If needed tkwait can be
       used to wait for the program to finish:

              global myStatus myOutput
              blt::bgexec myStatus -output myOutput du -s $dir &
                    ...
              tkwait variable myStatus

       Note however that using tkwait can be dangerous.   Multiple  tkwait/vwait  calls  must  complete  in  the
       reverse order called.  The BLT busy command can be used to try and enforce this, but a better alternative
       is to just use -command instead.

DIFFERENCES WITH EXEC

       Using bgexec without an ampersand will not hang Tcl: events continue to be serviced by the event  handler
       while  the call blocks.  Also unlike exec, an error will not be generated if output is appears on stderr.
       And output from stderr can be separately managed and collected (without having  to  redirect  to  files).
       Finally, bgexec ensures that invoked processes get properly cleaned up at termination.

DIFFERENCES WITH FILEEVENT

       Since  Tk  4.0,  a subset of bgexec can be achieved using the fileevent command.  The steps for running a
       program in the background are:

       Execute the program with the open command (using the "|" syntax) and save the file handle.

                global fileId
                set fileId [open "|du -s $dir" r]

       Next register a Tcl code snippet with fileevent to be run  whenever  output  is  available  on  the  file
       handle.  The code snippet will read from the file handle and save the output in a variable.

              fileevent fileId readable {
                if { [gets $fileId line] < 0 } {
                    close $fileId
                    set output $temp
                    unset fileId temp
                } else {
                    append temp $line
                }
              }

       However,  Bgexec  is  simpler  and less error prone than using open + fileevent.  You don't have to worry
       about non-blocking I/O.  Everything is handled for you automatically.

       Moreover, bgexec can run programs that fileevent can not.  Fileevent assumes  that  the  when  stdout  is
       closed  the  program  has  completed.   But some programs, like the Unix compress program, reopen stdout,
       fooling fileevent into thinking the program has terminated.  In the example above,  we  assume  that  the
       program  will  write  and  flush  its  output  line-by-line.   However when running another program, your
       application can block in the gets command reading a partial line.

       Bgexec gives you get back the exit status of the program.   It  also  lets  you  reliably  kill  detached
       processes  and  allows you to collect data from both stdout and stderr individually.  Finally, since data
       collection is handled in C code, bgexec is faster and more efficient.

SEE ALSO

       busy, exec, tkwait, vwait

KEYWORDS

       exec, background, busy