/*1* C functions for use in sage/tests2*/34#include <stdlib.h>5#include <stdio.h>6#include <string.h>7#include <sys/types.h>8#include <time.h>9#include <unistd.h>10#include <signal.h>11#include <sys/select.h>12#include <sys/wait.h>1314void ms_sleep(long ms)15{16struct timespec t;17t.tv_sec = (ms / 1000);18t.tv_nsec = (ms % 1000) * 1000000;19pselect(0, NULL, NULL, NULL, &t, NULL);20}212223/* Signal process ``killpid`` with signal ``signum`` after ``ms``24* milliseconds. Wait ``interval`` milliseconds, then signal again.25* Repeat this until ``n`` signals have been sent.26*27* This works as follows:28* - create a first child process in a new process group29* - the main process waits until the first child process terminates30* - this child process creates a second child process31* - the second child process kills the first child process32* - the main process sees that the first child process is killed33* and continues with Sage34* - the second child process does the actual waiting and signalling35*/36void signal_pid_after_delay(int signum, pid_t killpid, long ms, long interval, int n)37{38/* Flush all buffers before forking (otherwise we end up with two39* copies of each buffer). */40fflush(stdout);41fflush(stderr);4243pid_t child1 = fork();44if (child1 == -1) {perror("fork"); exit(1);}4546if (!child1)47{48/* This is child process 1 */49child1 = getpid();5051/* New process group to prevent us getting the signals. */52setpgid(0,0);5354/* Make sure SIGTERM simply terminates the process */55signal(SIGTERM, SIG_DFL);5657pid_t child2 = fork();58if (child2 == -1) exit(1);5960if (!child2)61{62/* This is child process 2 */63kill(child1, SIGTERM);6465/* Signal Sage after delay */66ms_sleep(ms);67for (;;)68{69kill(killpid, signum);70if (--n == 0) exit(0);71ms_sleep(interval);72}73}7475/* Wait to be killed by child process 2... */76/* We use a 2-second timeout in case there is trouble. */77ms_sleep(2000);78exit(2); /* This should NOT be reached */79}8081/* Main Sage process, continue when child 1 finishes */82int wait_status;83waitpid(child1, &wait_status, 0);84}858687