Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.17 114 lines 2.0 kB view raw
1/* 2 * Copyright 2013, Michael Ellerman, IBM Corp. 3 * Licensed under GPLv2. 4 */ 5 6#include <errno.h> 7#include <signal.h> 8#include <stdbool.h> 9#include <stdio.h> 10#include <stdlib.h> 11#include <sys/types.h> 12#include <sys/wait.h> 13#include <unistd.h> 14 15#include "subunit.h" 16#include "utils.h" 17 18#define TIMEOUT 120 19#define KILL_TIMEOUT 5 20 21 22int run_test(int (test_function)(void), char *name) 23{ 24 bool terminated; 25 int rc, status; 26 pid_t pid; 27 28 /* Make sure output is flushed before forking */ 29 fflush(stdout); 30 31 pid = fork(); 32 if (pid == 0) { 33 setpgid(0, 0); 34 exit(test_function()); 35 } else if (pid == -1) { 36 perror("fork"); 37 return 1; 38 } 39 40 setpgid(pid, pid); 41 42 /* Wake us up in timeout seconds */ 43 alarm(TIMEOUT); 44 terminated = false; 45 46wait: 47 rc = waitpid(pid, &status, 0); 48 if (rc == -1) { 49 if (errno != EINTR) { 50 printf("unknown error from waitpid\n"); 51 return 1; 52 } 53 54 if (terminated) { 55 printf("!! force killing %s\n", name); 56 kill(-pid, SIGKILL); 57 return 1; 58 } else { 59 printf("!! killing %s\n", name); 60 kill(-pid, SIGTERM); 61 terminated = true; 62 alarm(KILL_TIMEOUT); 63 goto wait; 64 } 65 } 66 67 /* Kill anything else in the process group that is still running */ 68 kill(-pid, SIGTERM); 69 70 if (WIFEXITED(status)) 71 status = WEXITSTATUS(status); 72 else { 73 if (WIFSIGNALED(status)) 74 printf("!! child died by signal %d\n", WTERMSIG(status)); 75 else 76 printf("!! child died by unknown cause\n"); 77 78 status = 1; /* Signal or other */ 79 } 80 81 return status; 82} 83 84static void alarm_handler(int signum) 85{ 86 /* Jut wake us up from waitpid */ 87} 88 89static struct sigaction alarm_action = { 90 .sa_handler = alarm_handler, 91}; 92 93int test_harness(int (test_function)(void), char *name) 94{ 95 int rc; 96 97 test_start(name); 98 test_set_git_version(GIT_VERSION); 99 100 if (sigaction(SIGALRM, &alarm_action, NULL)) { 101 perror("sigaction"); 102 test_error(name); 103 return 1; 104 } 105 106 rc = run_test(test_function, name); 107 108 if (rc == MAGIC_SKIP_RETURN_VALUE) 109 test_skip(name); 110 else 111 test_finish(name, rc); 112 113 return rc; 114}