Linux Audio

Check our new training course

Loading...
v3.15
 
  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		exit(test_function());
 34	} else if (pid == -1) {
 35		perror("fork");
 36		return 1;
 37	}
 38
 39	/* Wake us up in timeout seconds */
 40	alarm(TIMEOUT);
 
 
 
 41	terminated = false;
 42
 43wait:
 44	rc = waitpid(pid, &status, 0);
 45	if (rc == -1) {
 46		if (errno != EINTR) {
 47			printf("unknown error from waitpid\n");
 48			return 1;
 49		}
 50
 51		if (terminated) {
 52			printf("!! force killing %s\n", name);
 53			kill(pid, SIGKILL);
 54			return 1;
 55		} else {
 56			printf("!! killing %s\n", name);
 57			kill(pid, SIGTERM);
 58			terminated = true;
 59			alarm(KILL_TIMEOUT);
 60			goto wait;
 61		}
 62	}
 63
 
 
 
 64	if (WIFEXITED(status))
 65		status = WEXITSTATUS(status);
 66	else {
 67		if (WIFSIGNALED(status))
 68			printf("!! child died by signal %d\n", WTERMSIG(status));
 69		else
 70			printf("!! child died by unknown cause\n");
 71
 72		status = 1; /* Signal or other */
 73	}
 74
 75	return status;
 76}
 77
 78static void alarm_handler(int signum)
 79{
 80	/* Jut wake us up from waitpid */
 81}
 82
 83static struct sigaction alarm_action = {
 84	.sa_handler = alarm_handler,
 85};
 86
 
 
 
 
 
 87int test_harness(int (test_function)(void), char *name)
 88{
 89	int rc;
 90
 91	test_start(name);
 92	test_set_git_version(GIT_VERSION);
 93
 94	if (sigaction(SIGALRM, &alarm_action, NULL)) {
 95		perror("sigaction");
 
 
 
 
 
 
 96		test_error(name);
 97		return 1;
 98	}
 99
100	rc = run_test(test_function, name);
101
102	test_finish(name, rc);
 
 
 
 
 
103
104	return rc;
105}
v5.4
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Copyright 2013, Michael Ellerman, IBM Corp.
 
  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#include <elf.h>
 15#include <fcntl.h>
 16#include <link.h>
 17#include <sys/stat.h>
 18
 19#include "subunit.h"
 20#include "utils.h"
 21
 
 22#define KILL_TIMEOUT	5
 23
 24/* Setting timeout to -1 disables the alarm */
 25static uint64_t timeout = 120;
 26
 27int run_test(int (test_function)(void), char *name)
 28{
 29	bool terminated;
 30	int rc, status;
 31	pid_t pid;
 32
 33	/* Make sure output is flushed before forking */
 34	fflush(stdout);
 35
 36	pid = fork();
 37	if (pid == 0) {
 38		setpgid(0, 0);
 39		exit(test_function());
 40	} else if (pid == -1) {
 41		perror("fork");
 42		return 1;
 43	}
 44
 45	setpgid(pid, pid);
 46
 47	if (timeout != -1)
 48		/* Wake us up in timeout seconds */
 49		alarm(timeout);
 50	terminated = false;
 51
 52wait:
 53	rc = waitpid(pid, &status, 0);
 54	if (rc == -1) {
 55		if (errno != EINTR) {
 56			printf("unknown error from waitpid\n");
 57			return 1;
 58		}
 59
 60		if (terminated) {
 61			printf("!! force killing %s\n", name);
 62			kill(-pid, SIGKILL);
 63			return 1;
 64		} else {
 65			printf("!! killing %s\n", name);
 66			kill(-pid, SIGTERM);
 67			terminated = true;
 68			alarm(KILL_TIMEOUT);
 69			goto wait;
 70		}
 71	}
 72
 73	/* Kill anything else in the process group that is still running */
 74	kill(-pid, SIGTERM);
 75
 76	if (WIFEXITED(status))
 77		status = WEXITSTATUS(status);
 78	else {
 79		if (WIFSIGNALED(status))
 80			printf("!! child died by signal %d\n", WTERMSIG(status));
 81		else
 82			printf("!! child died by unknown cause\n");
 83
 84		status = 1; /* Signal or other */
 85	}
 86
 87	return status;
 88}
 89
 90static void sig_handler(int signum)
 91{
 92	/* Just wake us up from waitpid */
 93}
 94
 95static struct sigaction sig_action = {
 96	.sa_handler = sig_handler,
 97};
 98
 99void test_harness_set_timeout(uint64_t time)
100{
101	timeout = time;
102}
103
104int test_harness(int (test_function)(void), char *name)
105{
106	int rc;
107
108	test_start(name);
109	test_set_git_version(GIT_VERSION);
110
111	if (sigaction(SIGINT, &sig_action, NULL)) {
112		perror("sigaction (sigint)");
113		test_error(name);
114		return 1;
115	}
116
117	if (sigaction(SIGALRM, &sig_action, NULL)) {
118		perror("sigaction (sigalrm)");
119		test_error(name);
120		return 1;
121	}
122
123	rc = run_test(test_function, name);
124
125	if (rc == MAGIC_SKIP_RETURN_VALUE) {
126		test_skip(name);
127		/* so that skipped test is not marked as failed */
128		rc = 0;
129	} else
130		test_finish(name, rc);
131
132	return rc;
133}