Commit 901be562 authored by Per Cederqvist's avatar Per Cederqvist
Browse files

Test if select() can be interrupted by a signal even when SA_RESTART

is specified.
parent 6bb52e2b
/*
* 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>
#include <time.h>
#include <unistd.h>
#include "unused.h"
sig_atomic_t ctr = 0;
static void
my_sighandler(int UNUSED(x))
{
ctr++;
}
int
main(void)
{
fd_set r;
FD_ZERO(&r);
FD_SET(0, &r);
struct timeval timeout;
#ifdef HAVE_STRUCT_SIGACTION
struct sigaction act;
#endif
int rv;
int er;
time_t before;
time_t after;
pid_t pid;
if ((pid = fork()) < 0)
{
perror("fork");
return 1;
}
if (pid == 0)
{
sleep(1);
kill(getppid(), SIGHUP);
sleep(5); /* avoid triggering a SIGCHLD */
return 0;
}
#ifdef HAVE_STRUCT_SIGACTION
sigemptyset(&act.sa_mask);
act.sa_flags = SA_RESTART;
act.sa_handler = my_sighandler;
if (sigaction(SIGHUP, &act, NULL) < 0)
{
perror("sigaction");
return 1;
}
#else
if (signal(SIGHUP, my_sighandler) == SIG_ERR)
{
perror("signal");
return 1;
}
#endif
timeout.tv_sec = 5;
timeout.tv_usec = 0;
time(&before);
rv = select(1, &r, NULL, NULL, &timeout);
er = errno;
time(&after);
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));
if (after - before < 3 && rv < 0 && er == EINTR && ctr == 1)
printf("PASS: select returns EINTR\n");
else
printf("FAIL: select returns EINTR (got %d signals) (%d seconds)"
" (retval=%d)\n",
(int)ctr, (int)(after - before), (int)rv);
return 0;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment