Commit 62704f0f authored by Per Cederqvist's avatar Per Cederqvist
Browse files

Verify that select can be broken by a siglongjmp call from a signal

handler.
parent f5584802
/*
* Copyright (C) 2002, 2003 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>
#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
#include <unistd.h>
#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
#include <setjmp.h>
#include "linkansi.h"
#include "unused.h"
sig_atomic_t ctr = 0;
sigjmp_buf env;
static void
my_sighandler(int UNUSED(x))
{
ctr++;
siglongjmp(env, 1);
}
time_t before;
time_t after;
int
main(int argc,
char **argv)
{
fd_set r;
struct timeval timeout;
#ifdef HAVE_STRUCT_SIGACTION
struct sigaction act;
#endif
volatile int rv = -2;
volatile int er = -2;
volatile int jumped = 0;
pid_t pid;
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;
}
link_ansi();
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);
#ifdef SA_RESTART
act.sa_flags = use_sa_restart ? SA_RESTART : 0;
#else
act.sa_flags = 0;
#endif
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
FD_ZERO(&r);
FD_SET(0, &r);
timeout.tv_sec = 5;
timeout.tv_usec = 0;
time(&before);
if (sigsetjmp(env, 1))
jumped = 1;
else
{
rv = select(1, &r, NULL, NULL, &timeout);
er = errno;
}
time(&after);
if (jumped == 1)
;
else if (rv == 0)
printf("select: timeout\n");
else if (rv > 0)
printf("select: input available\n");
else
printf("select: fail: %s\n", strerror(er));
if (after - before < 3 && jumped == 1 && ctr == 1)
{
printf("PASS: siglongjmp breaks select\n");
return 0;
}
else
{
printf("FAIL: siglongjmp breaks select (got %d signals) (%d seconds)"
" (retval=%d) (jumped=%d)\n",
(int)ctr, (int)(after - before), (int)rv, jumped);
return 1;
}
}
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