Merge branch 'master' of ssh://sourceware.org/git/glibc
[platform/upstream/glibc.git] / debug / tst-longjmp_chk.c
1 #include <errno.h>
2 #include <fcntl.h>
3 #include <paths.h>
4 #include <setjmp.h>
5 #include <signal.h>
6 #include <stdbool.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <unistd.h>
10
11 static jmp_buf b;
12
13
14 static void
15 __attribute__ ((noinline))
16 f (void)
17 {
18   char buf[1000];
19   asm volatile ("" : "=m" (buf));
20
21   if (setjmp (b) != 0)
22     {
23       puts ("second longjmp succeeded");
24       exit (1);
25     }
26 }
27
28
29 static bool expected_to_fail;
30
31
32 static void
33 handler (int sig)
34 {
35   if (expected_to_fail)
36     _exit (0);
37   else
38     {
39       static const char msg[] = "unexpected longjmp failure\n";
40       TEMP_FAILURE_RETRY (write (STDOUT_FILENO, msg, sizeof (msg) - 1));
41       _exit (1);
42     }
43 }
44
45
46 int
47 main (void)
48 {
49   struct sigaction sa;
50   sa.sa_handler = handler;
51   sa.sa_flags = 0;
52   sigemptyset (&sa.sa_mask);
53
54   sigaction (SIGABRT, &sa, NULL);
55
56   /* Avoid all the buffer overflow messages on stderr.  */
57   int fd = open (_PATH_DEVNULL, O_WRONLY);
58   if (fd == -1)
59     close (STDERR_FILENO);
60   else
61     {
62       dup2 (fd, STDERR_FILENO);
63       close (fd);
64     }
65   setenv ("LIBC_FATAL_STDERR_", "1", 1);
66
67
68   expected_to_fail = false;
69
70   if (setjmp (b) == 0)
71     {
72       longjmp (b, 1);
73       /* NOTREACHED */
74       printf ("first longjmp returned\n");
75       return 1;
76     }
77
78
79   expected_to_fail = true;
80
81   f ();
82   longjmp (b, 1);
83
84   puts ("second longjmp returned");
85   return 1;
86 }