#include #include #include #include #include #include #include #include #include static jmp_buf b; static void __attribute__ ((noinline)) f (void) { char buf[1000]; asm volatile ("" : "=m" (buf)); if (setjmp (b) != 0) { puts ("second longjmp succeeded"); exit (1); } } static bool expected_to_fail; static void handler (int sig) { if (expected_to_fail) _exit (0); else { static const char msg[] = "unexpected longjmp failure\n"; TEMP_FAILURE_RETRY (write (STDOUT_FILENO, msg, sizeof (msg) - 1)); _exit (1); } } int main (void) { struct sigaction sa; sa.sa_handler = handler; sa.sa_flags = 0; sigemptyset (&sa.sa_mask); sigaction (SIGABRT, &sa, NULL); /* Avoid all the buffer overflow messages on stderr. */ int fd = open (_PATH_DEVNULL, O_WRONLY); if (fd == -1) close (STDERR_FILENO); else { dup2 (fd, STDERR_FILENO); close (fd); } setenv ("LIBC_FATAL_STDERR_", "1", 1); expected_to_fail = false; if (setjmp (b) == 0) { longjmp (b, 1); /* NOTREACHED */ printf ("first longjmp returned\n"); return 1; } expected_to_fail = true; f (); longjmp (b, 1); puts ("second longjmp returned"); return 1; }