+ /* Wait for first child to exit. */
+ int status;
+ pid_t exited_pid = wait(&status);
+ ret = (WIFEXITED(status) && WEXITSTATUS(status)) ||
+ (WIFSIGNALED(status) && WTERMSIG(status));
+ if (ret) {
+ fprintf(stderr, cRED "%s child %s with %d %s" cNORM,
+ exited_pid == server_pid? "server" : "client",
+ WIFSIGNALED(status)? "killed" : "exited",
+ WIFSIGNALED(status)? WTERMSIG(status) : WEXITSTATUS(status),
+ WIFSIGNALED(status)? strsignal(WTERMSIG(status)) : "");
+
+ /* If first child exited with error, kill other. */
+ fprintf(stderr, "terminating %s by force",
+ exited_pid == server_pid? "client" : "server");
+ kill(exited_pid == server_pid? client_pid : server_pid, SIGTERM);
+ }
+
+ exited_pid = wait(&status);
+ /* Report error unless we killed it. */
+ if (!ret && (!WIFEXITED(status) || WEXITSTATUS(status)))
+ fprintf(stderr, cRED "%s child %s with %d %s" cNORM,
+ exited_pid == server_pid? "server" : "client",
+ WIFSIGNALED(status)? "killed" : "exited",
+ WIFSIGNALED(status)? WTERMSIG(status) : WEXITSTATUS(status),
+ WIFSIGNALED(status)? strsignal(WTERMSIG(status)) : "");
+ ret |= (WIFEXITED(status) && WEXITSTATUS(status)) ||
+ (WIFSIGNALED(status) && WTERMSIG(status));
+
+ /* Every responsible process should free this. */
+ X509_free(ck.cert);
+ EVP_PKEY_free(ck.pkey);
+#ifdef __SANITIZE_ADDRESS__
+ /* Abort on the first (hopefully) ASan error. */
+ if (ret)
+ _exit(ret);
+#endif