waitpid + timeout

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>

static pid_t fork_child(void)
{
  int pid = fork();
  if (pid == -1) {
   perror("fork");
   exit(1);
  }
  if (pid == 0) {
   puts("child: sleeping...");
   sleep(10);
   puts("child: exiting");
   exit(0);
  }
  return pid;
}

int waitpid_timeout(pid_t pid, int mseconds)
{
  sigset_t mask, orig_mask;
  sigemptyset(&mask);
  sigaddset(&mask, SIGCHLD);
  if (sigprocmask(SIG_BLOCK, &mask, &orig_mask) < 0) {
   perror("sigprocmask");
   return 1;
 }
 else {
   struct timespec timeout;
   timeout.tv_sec = mseconds / 1000;
   timeout.tv_nsec = ( mseconds % 1000 ) * 1000000;
   do {
      if (sigtimedwait(&mask, NULL, &timeout) < 0) {
          if (errno == EINTR) {
             /* Interrupted by a signal other than SIGCHLD. */
            continue;
          }
          else if (errno == EAGAIN) {
             printf("Timeout, killing child\n");
             kill(pid, SIGKILL);
          }
         else {
            perror("sigtimedwait");
            return 1;
         }
     }
     else puts("got child quit signal");
     break;
   } while (1);
  if (waitpid(pid, NULL, 0) < 0) {
     perror("waitpid");
     return 1;
   }
   return 0;
  }
}

int main(int argc, char *argv[])
{
  pid_t pid = fork_child();

  waitpid_timeout(pid, 15000);

  return 0;
}

posted @ 2019-08-18 07:50  Reboost  阅读(773)  评论(0编辑  收藏  举报