Linux Audio

Check our new training course

Loading...
v6.13.7
  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), const 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), const 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}
v4.6
 
  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#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 TIMEOUT		120
 23#define KILL_TIMEOUT	5
 24
 
 
 25
 26int run_test(int (test_function)(void), char *name)
 27{
 28	bool terminated;
 29	int rc, status;
 30	pid_t pid;
 31
 32	/* Make sure output is flushed before forking */
 33	fflush(stdout);
 34
 35	pid = fork();
 36	if (pid == 0) {
 37		setpgid(0, 0);
 38		exit(test_function());
 39	} else if (pid == -1) {
 40		perror("fork");
 41		return 1;
 42	}
 43
 44	setpgid(pid, pid);
 45
 46	/* Wake us up in timeout seconds */
 47	alarm(TIMEOUT);
 
 48	terminated = false;
 49
 50wait:
 51	rc = waitpid(pid, &status, 0);
 52	if (rc == -1) {
 53		if (errno != EINTR) {
 54			printf("unknown error from waitpid\n");
 55			return 1;
 56		}
 57
 58		if (terminated) {
 59			printf("!! force killing %s\n", name);
 60			kill(-pid, SIGKILL);
 61			return 1;
 62		} else {
 63			printf("!! killing %s\n", name);
 64			kill(-pid, SIGTERM);
 65			terminated = true;
 66			alarm(KILL_TIMEOUT);
 67			goto wait;
 68		}
 69	}
 70
 71	/* Kill anything else in the process group that is still running */
 72	kill(-pid, SIGTERM);
 73
 74	if (WIFEXITED(status))
 75		status = WEXITSTATUS(status);
 76	else {
 77		if (WIFSIGNALED(status))
 78			printf("!! child died by signal %d\n", WTERMSIG(status));
 79		else
 80			printf("!! child died by unknown cause\n");
 81
 82		status = 1; /* Signal or other */
 83	}
 84
 85	return status;
 86}
 87
 88static void alarm_handler(int signum)
 89{
 90	/* Jut wake us up from waitpid */
 91}
 92
 93static struct sigaction alarm_action = {
 94	.sa_handler = alarm_handler,
 95};
 96
 97int test_harness(int (test_function)(void), char *name)
 
 
 
 
 
 98{
 99	int rc;
100
101	test_start(name);
102	test_set_git_version(GIT_VERSION);
103
104	if (sigaction(SIGALRM, &alarm_action, NULL)) {
105		perror("sigaction");
 
 
 
 
 
 
106		test_error(name);
107		return 1;
108	}
109
110	rc = run_test(test_function, name);
111
112	if (rc == MAGIC_SKIP_RETURN_VALUE)
113		test_skip(name);
114	else
 
 
115		test_finish(name, rc);
116
117	return rc;
118}