Re: system calls was Progress Bar



On Mon, 8 Jan 2001, Steve & Patti Getzinger wrote:

My first is: locate filename > file
and the second is: rm -f file

Steve

OK, there are several ways of doing this.  'system' will run the command,
and return only when it is finished, hence the problems with updating your
progress bar.  Instead, you need to do something like this:

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>

void sig_chld_func (int signum) {
  waitpid(-1, NULL, WNOHANG);
}

pid_t run_command (char *cmd) {
  pid_t child_pid;
  char *child_argv[] = { "/bin/sh", "-c", cmd, (char *) NULL };
  struct sigaction chld_act;

  chld_act.sa_handler = sig_chld_func;
  sigaction(SIGINT, &chld_act, NULL);

  switch(child_pid = fork()) {
  case -1:
    return(-1);
    /* NOTREACHED */
  case 0:
    execve("/bin/sh", child_argv, NULL);
    _exit(127);
    /* NOTREACHED */
  }

  return(child_pid);
}

int check_for_completion (pid_t child_pid) {
  int child_status;

  switch(waitpid(child_pid, &child_status, WNOHANG | WUNTRACED)) {
  case -1:
    return(-1);
  case 0:
    return(-2);
  }

  /* Something interesting happened, see what */

  if(WIFEXITED(child_status))
    return(WEXITSTATUS(child_status));
  if(WIFSIGNALED(child_status))
    return(0);

  return(-2);
}

The function run_command executes the command specified, returning -1
if something failed.  The function check_for_completion checks to see
if the command finished.  If it did, it returns the exit code from the
command, if not it returns -2, and -1 if the waitpid(2) function failed.
It will return 127 if the command could not be executed but fork(2)
succeeded.  This function should be put into a timeout, and run at
regular intervals to check if the command has finished (it can be in the
same function which updates the progress bar).

This implementation probably needs some more signals (Unix ones, not GTK
ones) to be handled so that the child process gets killed (and wait()ed
for) when the GUI process is killed, and also the same needs to happen
when your program exits normally, but hopefully you get the idea.

Also, you can avoid having to run 'rm -f' by using the unlink() system
call instead.

If you are using the redirected 'locate' output in your program only, it
might be better to adapt my example to create some pipes with pipe(2)
and read the output of 'locate' directly.

Hope this helps,

Jonathan






[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]