test-select.c 3.78 KB
Newer Older
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
/*
 * Copyright (C) 2002  Lysator Academic Computer Association.
 *
 * This file is part of the LysKOM server.
 * 
 * LysKOM 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 1, or (at your option) 
 * any later version.
 * 
 * LysKOM 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 LysKOM; see the file COPYING.  If not, write to
 * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN,
 * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, 
 * MA 02139, USA.
 *
 * Please mail bug reports to bug-lyskom@lysator.liu.se. 
 */

/*
 * The lyskomd process assumes that select() returns with EINTR even
 * when a signal handle has been set up with SA_RESTART.  This program
 * checks if that assumption is true or not.  When started, it should
 * print a single line after 1 second:
 *
 *    PASS: select returns EINTR
 *
 * This program will fail if input is available on stdin.
 */

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
45
46
47
48
49
50
51
52
53
54
#ifdef TIME_WITH_SYS_TIME
#  include <sys/time.h>
#  include <time.h>
#else
#  ifdef HAVE_SYS_TIME_H
#    include <sys/time.h>
#  else
#    include <time.h>
#  endif
#endif
55
#include <unistd.h>
56
57
58
59
60
61
62
63
64
65
66
67
#ifdef HAVE_SYS_SELECT_H
#  include <sys/select.h>
#endif
#ifdef HAVE_UNISTD_H
#  include <unistd.h>	/* Needed on NetBSD1.1/SPARC due to select */
#endif
#ifdef HAVE_STRING_H
#  include <string.h>	/* Needed on NetBSD1.1/SPARC due to bzero */
#endif
#ifdef HAVE_STRINGS_H
#  include <strings.h>  /* Needed on AIX 4.2 due to bzero */
#endif
68

69
#include "linkansi.h"
70
71
72
73
74
75
76
#include "unused.h"

sig_atomic_t ctr = 0;

static void
my_sighandler(int UNUSED(x))
{
77
    ctr++;
78
79
80
}

int
81
82
main(int argc,
     char **argv)
83
{
84
85
    fd_set r;
    struct timeval timeout;
86
#ifdef HAVE_STRUCT_SIGACTION
87
    struct sigaction act;
88
#endif
89
90
91
92
93
    int rv;
    int er;
    time_t before;
    time_t after;
    pid_t pid;
94
95
96
97
98
99
100
101
102
103
104
    int use_sa_restart = 1;

    if (argc == 1)
	use_sa_restart = 1;
    else if (argc == 2 && !strcmp(argv[1], "--no-sa-restart"))
	use_sa_restart = 0;
    else
    {
	fprintf(stderr, "%s: usage: %s [--no-sa-restart]\n", argv[0], argv[0]);
	return 1;
    }
105

106
107
    link_ansi();

108
    if ((pid = fork()) < 0)
109
    {
110
111
	perror("fork");
	return 1;
112
113
    }

114
    if (pid == 0)
115
    {
116
117
118
119
	sleep(1);
	kill(getppid(), SIGHUP);
	sleep(5); /* avoid triggering a SIGCHLD */
	return 0;
120
121
122
    }

#ifdef HAVE_STRUCT_SIGACTION
123
    sigemptyset(&act.sa_mask);
124
#ifdef SA_RESTART
125
    act.sa_flags = use_sa_restart ? SA_RESTART : 0;
126
127
128
#else
    act.sa_flags = 0;
#endif
129
130
131
132
133
134
    act.sa_handler = my_sighandler;
    if (sigaction(SIGHUP, &act, NULL) < 0)
    {
	perror("sigaction");
	return 1;
    }
135
#else
136
137
138
139
140
    if (signal(SIGHUP, my_sighandler) == SIG_ERR)
    {
	perror("signal");
	return 1;
    }
141
142
#endif

143
144
145
146
    FD_ZERO(&r);
    FD_SET(0, &r);
    timeout.tv_sec = 5;
    timeout.tv_usec = 0;
147

148
149
150
151
    time(&before);
    rv = select(1, &r, NULL, NULL, &timeout);
    er = errno;
    time(&after);
152

153
154
155
156
157
158
    if (rv == 0)
	printf("select: timeout\n");
    else if (rv > 0)
	printf("select: input available\n");
    else if (er != EINTR)
	printf("select: fail: %s\n", strerror(er));
159

160
161
162
163
164
165
166
167
168
169
170
171
    if (after - before < 3 && rv < 0 && er == EINTR && ctr == 1)
    {
	printf("PASS: select returns EINTR\n");
	return 0;
    }
    else
    {
	printf("FAIL: select returns EINTR (got %d signals) (%d seconds)"
	       " (retval=%d)\n",
	       (int)ctr, (int)(after - before), (int)rv);
	return 1;
    }
172
}