+ fflush(stdout);
+ _exit(EXIT_SUCCESS);
+ }
+ case -1:
+ // Error.
+ perror("fork");
+ exit(EXIT_FAILURE);
+ default:
+ // Parent.
+ close(pipefd[1]);
+ break;
+ }
+
+ // Wait for the child to finish.
+ int wstatus;
+ pid_t err;
+ do {
+ err = waitpid(child_pid, &wstatus, 0);
+ } while (err == -1 && errno == EINTR);
+ if (err == -1) {
+ perror("waitpid");
+ exit(EXIT_FAILURE);
+ }
+ if (WIFEXITED(wstatus)) {
+ if (WEXITSTATUS(wstatus) != 0) {
+ // The child has probably already printed out its error, so just propagate the exit status.
+ exit(WEXITSTATUS(wstatus));
+ }
+ // Success!
+ } else if (!WIFEXITED(wstatus)) {
+ fprintf(stderr, "FATAL: Child died unexpectedly while processing %s\n", filename.c_str());
+ exit(1);
+ }
+
+ // Now get the number of matches from the child.
+ uint64_t matched;
+ int ret;
+ do {
+ ret = read(pipefd[0], &matched, sizeof(matched));
+ } while (ret == -1 && errno == EINTR);
+ if (ret == -1) {
+ perror("read");
+ exit(EXIT_FAILURE);
+ } else if (ret != sizeof(matched)) {
+ fprintf(stderr, "FATAL: Short read through pipe (got %d bytes)\n", ret);
+ exit(EXIT_FAILURE);