File: sigtest.c

package info (click to toggle)
rt-tests 1.0-3
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 708 kB
  • ctags: 1,268
  • sloc: ansic: 8,836; python: 480; makefile: 183
file content (142 lines) | stat: -rw-r--r-- 3,250 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*
  sigtest - simple little program to verify signal behavior
  
   Copyright (C) 2006, 2007 Clark Williams <williams@redhat.com>
  
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
   USA */

#include <stdio.h>
#include <signal.h>
#include <time.h>
#include <memory.h>
#include <errno.h>
#include <pthread.h>

#define TIMER_SIGNAL (SIGRTMIN+1)
#define SUCCESS 0
#define FAILURE -1

int
setup_timer(timer_t *timer)
{
	int status;
	struct sigevent sigev;

	memset(&sigev, 0, sizeof(sigev));
	sigev.sigev_notify = SIGEV_SIGNAL;
	sigev.sigev_signo = TIMER_SIGNAL;
	status = timer_create(CLOCK_MONOTONIC, &sigev, timer);
	if (status) {
		fprintf(stderr,"error from timer_create: %s\n", strerror(errno));
		return FAILURE;
	}
	return SUCCESS;
}
	
int
start_timer(timer_t t, int sec, int nsec)
{
	int status;
	struct itimerspec it;

	// set up as a one-shot
	memset(&it, 0, sizeof(it));
	it.it_value.tv_sec = sec;
	it.it_value.tv_nsec = nsec;
	status = timer_settime(t, 0, &it, NULL);
	if (status)
		fprintf(stderr,"starting timer: %s\n", strerror(errno));
	return status;
}

int
wait_for_signal(void)
{
	int signo;
	sigset_t sigset;

	if (sigemptyset(&sigset)) {
		fprintf(stderr,"creating empty signal wait set: %s\n", strerror(errno));
		return -1;
	}
	if (sigaddset(&sigset, SIGINT)) {
		fprintf(stderr,"adding SIGINT to signal set: %s\n", strerror(errno));
		return -1;
	}
	if (sigaddset(&sigset, TIMER_SIGNAL)) {
		fprintf(stderr,"adding TIMER_SIGNAL to signal set: %s\n", strerror(errno));
		return -1;
	}
	
	if (sigwait(&sigset, &signo)) {
		fprintf(stderr,"waiting for signal: %s\n", strerror(errno));
		return -1;
	}
	return signo;
}

int
block_signals(void)
{
	int status;
	sigset_t sigset;

	// mask off all signals
	status = sigfillset(&sigset);
	if (status) {
		fprintf(stderr,"setting up full signal set %d\n", status);
		return FAILURE;
	}
	status = pthread_sigmask(SIG_BLOCK, &sigset, NULL);
	if (status) {
		fprintf(stderr,"setting signal mask: %d\n", status);
		return FAILURE;
	}
	return SUCCESS;
}

int
main(int argc, char **argv)
{
	int status;
	timer_t timer;
	unsigned long count = 0;
	int stop_test = 0;

	block_signals();
	setup_timer(&timer);
	printf("Press Ctrl-C to stop\n");
	while (stop_test == 0) {
		if (start_timer(timer, 0, 500000000)) {
			stop_test = 1;
			continue;
		}
		status = wait_for_signal();
		if (status == SIGINT) {
			fputs("\033[1B", stdout);
			stop_test = 1;
		}
		else if (status == TIMER_SIGNAL) {
			printf("count: %lu\n", ++count);
			fputs("\033[1A", stdout);
		}
		else {
			fprintf(stderr, "WTF?\n");
			return -1;
		}
	}
	return 0;
}