Path: blob/main/lib/libc/tests/stdio/eintr_test.c
104133 views
/*1* Initially written by Yar Tikhiy <[email protected]> in PR 76398.2* Bug fixes and instrumentation by [email protected].3*/45#include <sys/types.h>6#include <sys/socket.h>7#include <sys/stat.h>8#include <sys/wait.h>9#include <err.h>10#include <errno.h>11#include <fcntl.h>12#include <md5.h>13#include <signal.h>14#include <stdio.h>15#include <stdlib.h>16#include <string.h>17#include <unistd.h>1819#include <atf-c.h>2021#define NDATA 100022#define DELAY 22324static void25hup(int signo __unused)26{27}2829static int ndata, seq;3031static void32setdata(int n)33{34ndata = n;35seq = 0;36}3738static char *39getdata(void)40{41static char databuf[256];42static char xeof[] = "#";4344if (seq > ndata)45return (NULL);46if (seq == ndata) {47seq++;48return (xeof);49}50sprintf(databuf, "%08d xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", seq++);51return (databuf);52}5354ATF_TC_WITHOUT_HEAD(eintr_test);55ATF_TC_BODY(eintr_test, tc)56{57char c, digest0[33], digest[33], *p;58FILE *fp;59int i, s[2], total0, total;60MD5_CTX md5;61pid_t child;62struct sigaction sa;6364MD5Init(&md5);65setdata(NDATA);66for (total0 = 0; (p = getdata()) != NULL; total0 += strlen(p))67MD5Update(&md5, p, strlen(p));68p = MD5End(&md5, digest0);6970sa.sa_handler = hup;71sigemptyset(&sa.sa_mask);72sa.sa_flags = 0;73ATF_REQUIRE(sigaction(SIGHUP, &sa, NULL) == 0);7475ATF_REQUIRE(socketpair(PF_UNIX, SOCK_STREAM, 0, s) == 0);7677switch (child = fork()) {78case -1:79atf_tc_fail("fork failed %s", strerror(errno));80break;8182case 0:83ATF_REQUIRE((fp = fdopen(s[0], "w")) != NULL);84close(s[1]);85setdata(NDATA);86while ((p = getdata())) {87for (; *p;) {88if (fputc(*p, fp) == EOF) {89if (errno == EINTR) {90clearerr(fp);91} else {92atf_tc_fail("fputc errno %s",93strerror(errno));94}95} else {96p++;97}98}99}100fclose(fp);101break;102103default:104close(s[0]);105ATF_REQUIRE((fp = fdopen(s[1], "r")) != NULL);106sleep(DELAY);107ATF_REQUIRE(kill(child, SIGHUP) != -1);108sleep(DELAY);109MD5Init(&md5);110for (total = 0;;) {111i = fgetc(fp);112if (i == EOF) {113if (errno == EINTR) {114clearerr(fp);115} else {116atf_tc_fail("fgetc errno %s",117strerror(errno));118}119continue;120}121total++;122c = i;123MD5Update(&md5, &c, 1);124if (i == '#')125break;126}127MD5End(&md5, digest);128fclose(fp);129ATF_REQUIRE_MSG(total == total0,130"Total number of bytes read does not match: %d %d",131total, total0);132ATF_REQUIRE_MSG(strcmp(digest, digest0) == 0,133"Digests do not match %s %s", digest, digest0);134break;135}136}137138ATF_TP_ADD_TCS(tp)139{140ATF_TP_ADD_TC(tp, eintr_test);141return (atf_no_error());142}143144145