Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/tests/c_lib.c
4045 views
1
/*
2
* C functions for use in sage/tests
3
*/
4
5
#include <stdlib.h>
6
#include <stdio.h>
7
#include <string.h>
8
#include <sys/types.h>
9
#include <time.h>
10
#include <unistd.h>
11
#include <signal.h>
12
#include <sys/select.h>
13
#include <sys/wait.h>
14
15
void ms_sleep(long ms)
16
{
17
struct timespec t;
18
t.tv_sec = (ms / 1000);
19
t.tv_nsec = (ms % 1000) * 1000000;
20
pselect(0, NULL, NULL, NULL, &t, NULL);
21
}
22
23
24
/* Signal process ``killpid`` with signal ``signum`` after ``ms``
25
* milliseconds. Wait ``interval`` milliseconds, then signal again.
26
* Repeat this until ``n`` signals have been sent.
27
*
28
* This works as follows:
29
* - create a first child process in a new process group
30
* - the main process waits until the first child process terminates
31
* - this child process creates a second child process
32
* - the second child process kills the first child process
33
* - the main process sees that the first child process is killed
34
* and continues with Sage
35
* - the second child process does the actual waiting and signalling
36
*/
37
void signal_pid_after_delay(int signum, pid_t killpid, long ms, long interval, int n)
38
{
39
/* Flush all buffers before forking (otherwise we end up with two
40
* copies of each buffer). */
41
fflush(stdout);
42
fflush(stderr);
43
44
pid_t child1 = fork();
45
if (child1 == -1) {perror("fork"); exit(1);}
46
47
if (!child1)
48
{
49
/* This is child process 1 */
50
child1 = getpid();
51
52
/* New process group to prevent us getting the signals. */
53
setpgid(0,0);
54
55
/* Make sure SIGTERM simply terminates the process */
56
signal(SIGTERM, SIG_DFL);
57
58
pid_t child2 = fork();
59
if (child2 == -1) exit(1);
60
61
if (!child2)
62
{
63
/* This is child process 2 */
64
kill(child1, SIGTERM);
65
66
/* Signal Sage after delay */
67
ms_sleep(ms);
68
for (;;)
69
{
70
kill(killpid, signum);
71
if (--n == 0) exit(0);
72
ms_sleep(interval);
73
}
74
}
75
76
/* Wait to be killed by child process 2... */
77
/* We use a 2-second timeout in case there is trouble. */
78
ms_sleep(2000);
79
exit(2); /* This should NOT be reached */
80
}
81
82
/* Main Sage process, continue when child 1 finishes */
83
int wait_status;
84
waitpid(child1, &wait_status, 0);
85
}
86
87