From patchwork Mon Aug 28 17:16:55 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Pluzhnikov X-Patchwork-Id: 22384 Received: (qmail 6667 invoked by alias); 28 Aug 2017 17:17:40 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 5981 invoked by uid 89); 28 Aug 2017 17:17:38 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.4 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, RP_MATCHES_RCVD, SPF_PASS autolearn=ham version=3.3.2 spammy=registrations, 9640, 2120 X-HELO: mail-ua0-f176.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=l3ocmsvJfQxZ15lKwu1r278Z2K0QgcR6o8jnOnQ7ix8=; b=eBU3RZJcOQ4hrDL4IPd1vuDxqRzGJzOGnrIqXEtzad2I05RqEbrp0+FyUOmwsGPQ2p M+iZboFwfSsVO07q639ItYE5agcJZmydUhc1U/OKfIhAv3DgPHNGSghOHvOmWgcCpG6I wGlOAoicOLRtJ+/JdV3g+822P8fOWz2SD94ZWpo4S3ttF4NWUYv79dniu6QGDp+lWnqV pVzmj1n5Jb9dQpBynWKmHdvldEW1OO/rmGx2WR2HuVDX+j7EiMfvjoQvDlfoNtpgdqbX a2q1R08rgfMwBXrJtzEf8Fa+vpmwBYkc5DlNvtHhjhQVzKDvlv+00H5WlUDzuGeafoD5 qtBA== X-Gm-Message-State: AHYfb5jzoPJQb0qM+DkrYN+FIbeB+mUJBUQpMrzVr194oj9SY6MNT4wZ xrC3sBP22maMZxCakei3g6nCtJnV4ssBoKMwEg== X-Google-Smtp-Source: ADKCNb7oFUkbsoAGdtJQu2NRWO9v6WZp3c+kPmxYWqv/fQgPy/EShUXquEUq5qD2V/ulG7REE/4xg9l8BvAgTYLbf9k= X-Received: by 10.176.23.84 with SMTP id k20mr854618uaf.130.1503940646393; Mon, 28 Aug 2017 10:17:26 -0700 (PDT) MIME-Version: 1.0 From: Paul Pluzhnikov Date: Mon, 28 Aug 2017 10:16:55 -0700 Message-ID: Subject: [PATCH] Extend tst-{atexit, at_quick_exit, cxa_atexit, onexit} to verify inheritance across fork To: GLIBC Devel Greetings, Attached patch implements one of the TODOs in stdlib/tst-atexit-common.c 2017-08-28 Paul Pluzhnikov * stdlib/tst-atexit-common.c (do_test): Test handler inheritance by child. diff --git a/stdlib/tst-atexit-common.c b/stdlib/tst-atexit-common.c index 262235a478..99b00bf3aa 100644 --- a/stdlib/tst-atexit-common.c +++ b/stdlib/tst-atexit-common.c @@ -21,11 +21,20 @@ #include #include #include +#include #define MAX_ATEXIT 20 /* Large enough for current set of invocations. */ static char crumbs[MAX_ATEXIT]; static int next_slot = 0; +/* Helper: flush stdout and _exit. */ +static void +_exit_with_flush (int code) +{ + fflush (stdout); + _exit (code); +} + static void fn0 (void) { @@ -60,11 +69,11 @@ fn_final (void) const char expected[] = "3021121130211"; if (strcmp (crumbs, expected) == 0) - _exit (0); + _exit_with_flush (0); printf ("crumbs: %s\n", crumbs); printf ("expected: %s\n", expected); - _exit (1); + _exit_with_flush (1); } /* This is currently just a basic test to verify that exit handlers execute @@ -72,8 +81,7 @@ fn_final (void) TODO: Additional tests that we should do: 1. POSIX says we need to support at least ATEXIT_MAX - 2. Verify that fork'd child inherit the registrations of the parent. - 3. ... */ + 2. ... */ static int do_test (void) @@ -88,6 +96,40 @@ do_test (void) ATEXIT (fn1); ATEXIT (fn3); + /* Verify that handlers registered above are inherited across fork. */ + const pid_t child = fork (); + switch (child) + { + case -1: + printf ("fork: %m\n"); + _exit_with_flush (3); + case 0: /* Child. */ + break; + default: + { + int status; + const pid_t exited = waitpid (child, &status, 0); + if (child != exited) + { + printf ("unexpected child: %d, expected %d\n", exited, child); + _exit_with_flush (4); + } + if (status != 0) + { + if (WIFEXITED (status)) + printf ("unexpected exit status %d from child %d\n", + WEXITSTATUS (status), child); + else if (WIFSIGNALED (status)) + printf ("unexpected signal %d from child %d\n", + WTERMSIG (status), child); + else + printf ("unexpected status %d from child %d\n", status, child); + _exit_with_flush (5); + } + } + break; + } + EXIT (2); /* If we see this exit code, fn_final must have not worked. */ }