Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/lib/libc/tests/stdio/eintr_test.c
39530 views
1
/*
2
* Initially written by Yar Tikhiy <[email protected]> in PR 76398.
3
* Bug fixes and instrumentation by [email protected].
4
*/
5
6
#include <sys/types.h>
7
#include <sys/socket.h>
8
#include <sys/stat.h>
9
#include <sys/wait.h>
10
#include <err.h>
11
#include <errno.h>
12
#include <fcntl.h>
13
#include <md5.h>
14
#include <signal.h>
15
#include <stdio.h>
16
#include <stdlib.h>
17
#include <string.h>
18
#include <unistd.h>
19
20
#include <atf-c.h>
21
22
#define NDATA 1000
23
#define DELAY 2
24
25
static void
26
hup(int signo __unused)
27
{
28
}
29
30
static int ndata, seq;
31
32
static void
33
setdata(int n)
34
{
35
ndata = n;
36
seq = 0;
37
}
38
39
static char *
40
getdata(void)
41
{
42
static char databuf[256];
43
static char xeof[] = "#";
44
45
if (seq > ndata)
46
return (NULL);
47
if (seq == ndata) {
48
seq++;
49
return (xeof);
50
}
51
sprintf(databuf, "%08d xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", seq++);
52
return (databuf);
53
}
54
55
ATF_TC_WITHOUT_HEAD(eintr_test);
56
ATF_TC_BODY(eintr_test, tc)
57
{
58
char c, digest0[33], digest[33], *p;
59
FILE *fp;
60
int i, s[2], total0, total;
61
MD5_CTX md5;
62
pid_t child;
63
struct sigaction sa;
64
65
MD5Init(&md5);
66
setdata(NDATA);
67
for (total0 = 0; (p = getdata()) != NULL; total0 += strlen(p))
68
MD5Update(&md5, p, strlen(p));
69
p = MD5End(&md5, digest0);
70
71
sa.sa_handler = hup;
72
sigemptyset(&sa.sa_mask);
73
sa.sa_flags = 0;
74
ATF_REQUIRE(sigaction(SIGHUP, &sa, NULL) == 0);
75
76
ATF_REQUIRE(socketpair(PF_UNIX, SOCK_STREAM, 0, s) == 0);
77
78
switch (child = fork()) {
79
case -1:
80
atf_tc_fail("fork failed %s", strerror(errno));
81
break;
82
83
case 0:
84
ATF_REQUIRE((fp = fdopen(s[0], "w")) != NULL);
85
close(s[1]);
86
setdata(NDATA);
87
while ((p = getdata())) {
88
for (; *p;) {
89
if (fputc(*p, fp) == EOF) {
90
if (errno == EINTR) {
91
clearerr(fp);
92
} else {
93
atf_tc_fail("fputc errno %s",
94
strerror(errno));
95
}
96
} else {
97
p++;
98
}
99
}
100
}
101
fclose(fp);
102
break;
103
104
default:
105
close(s[0]);
106
ATF_REQUIRE((fp = fdopen(s[1], "r")) != NULL);
107
sleep(DELAY);
108
ATF_REQUIRE(kill(child, SIGHUP) != -1);
109
sleep(DELAY);
110
MD5Init(&md5);
111
for (total = 0;;) {
112
i = fgetc(fp);
113
if (i == EOF) {
114
if (errno == EINTR) {
115
clearerr(fp);
116
} else {
117
atf_tc_fail("fgetc errno %s",
118
strerror(errno));
119
}
120
continue;
121
}
122
total++;
123
c = i;
124
MD5Update(&md5, &c, 1);
125
if (i == '#')
126
break;
127
}
128
MD5End(&md5, digest);
129
fclose(fp);
130
ATF_REQUIRE_MSG(total == total0,
131
"Total number of bytes read does not match: %d %d",
132
total, total0);
133
ATF_REQUIRE_MSG(strcmp(digest, digest0) == 0,
134
"Digests do not match %s %s", digest, digest0);
135
break;
136
}
137
}
138
139
ATF_TP_ADD_TCS(tp)
140
{
141
ATF_TP_ADD_TC(tp, eintr_test);
142
return (atf_no_error());
143
}
144
145