mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-06 03:23:58 +00:00
Various minor changes to make these compile on AIX5. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@6257
121 lines
2.6 KiB
C
121 lines
2.6 KiB
C
#include <signal.h>
|
|
#include <unistd.h>
|
|
#include <sys/wait.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <time.h>
|
|
|
|
static const struct timespec bip = { 0, 1000000000 / 5 };
|
|
|
|
static void handler(int sig)
|
|
{
|
|
}
|
|
|
|
/* Kill our child, but use a separate kill command. This is so that
|
|
it's running independently of Valgrind, and so is async with
|
|
respect to thread scheduling. */
|
|
static void do_kill(int pid, int sig)
|
|
{
|
|
int status;
|
|
int killer;
|
|
int ret;
|
|
|
|
killer = vfork();
|
|
|
|
if (killer == -1) {
|
|
perror("killer/vfork");
|
|
exit(1);
|
|
}
|
|
|
|
if (killer == 0) {
|
|
char sigbuf[20];
|
|
char pidbuf[20];
|
|
sprintf(sigbuf, "-%d", sig);
|
|
sprintf(pidbuf, "%d", pid);
|
|
execl("/bin/kill", "kill", sigbuf, pidbuf, NULL);
|
|
perror("exec failed");
|
|
exit(1);
|
|
}
|
|
|
|
do
|
|
ret = waitpid(killer, &status, 0);
|
|
while(ret == -1 && errno == EINTR);
|
|
|
|
if (ret != killer) {
|
|
perror("kill/waitpid");
|
|
exit(1);
|
|
}
|
|
|
|
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
|
|
printf("kill %d failed status=%s %d\n", killer,
|
|
WIFEXITED(status) ? "exit" : "signal",
|
|
WIFEXITED(status) ? WEXITSTATUS(status) : WTERMSIG(status));
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
static void test(int block, int caughtsig, int fatalsig)
|
|
{
|
|
int pid;
|
|
int status;
|
|
int i;
|
|
|
|
printf("testing: blocking=%d caught=%d fatal=%d... ", block, caughtsig, fatalsig);
|
|
fflush(stdout);
|
|
|
|
pid = fork();
|
|
if (pid == -1) {
|
|
perror("fork");
|
|
exit(1);
|
|
}
|
|
|
|
if (pid == 0) {
|
|
alarm(10); /* if something breaks, don't spin forever */
|
|
signal(caughtsig, handler);
|
|
|
|
for(;;)
|
|
if (block)
|
|
pause();
|
|
|
|
}
|
|
|
|
nanosleep(&bip, 0); /* wait for child to get going */
|
|
|
|
for(i = 0; i < 5; i++) {
|
|
do_kill(pid, caughtsig); /* should be caught */
|
|
nanosleep(&bip, 0);
|
|
do_kill(pid, caughtsig);
|
|
do_kill(pid, caughtsig);
|
|
}
|
|
|
|
nanosleep(&bip, 0);
|
|
|
|
do_kill(pid, fatalsig); /* should kill it */
|
|
|
|
if (waitpid(pid, &status, 0) != pid)
|
|
printf("FAILED: waitpid failed: %s\n", strerror(errno));
|
|
else if (!WIFSIGNALED(status) || WTERMSIG(status) != fatalsig)
|
|
printf("FAILED: child exited with unexpected status %s %d\n",
|
|
WIFEXITED(status) ? "exit" : "signal",
|
|
WIFEXITED(status) ? WEXITSTATUS(status) : WTERMSIG(status));
|
|
else
|
|
printf("PASSED\n");
|
|
}
|
|
|
|
int main()
|
|
{
|
|
static const int catch[] = { SIGSEGV, SIGUSR1 };
|
|
static const int fatal[] = { SIGBUS, SIGUSR2 };
|
|
int block, catchidx, fatalidx;
|
|
|
|
setvbuf(stdout, NULL, _IOLBF, 0);
|
|
|
|
for(block = 0; block < 2; block++)
|
|
for(catchidx = 0; catchidx < sizeof(catch)/sizeof(*catch); catchidx++)
|
|
for(fatalidx = 0; fatalidx < sizeof(fatal)/sizeof(*fatal); fatalidx++)
|
|
test(block, catch[catchidx], fatal[fatalidx]);
|
|
return 0;
|
|
}
|