1 /* Test of POSIX compatible printf() function.
2    Copyright (C) 2007, 2009-2021 Free Software Foundation, Inc.
3 
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 3 of the License, or
7    (at your option) any later version.
8 
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
16 
17 /* Written by Bruno Haible <bruno@clisp.org>, 2007.  */
18 
19 #include <config.h>
20 
21 #include <stdio.h>
22 
23 /* This test assumes getrlimit() and setrlimit().
24    With "gcc -fcheck-pointer-bounds -mmpx -static", it produces an
25    endless loop of "Saw a #BR!" messages.  */
26 #if HAVE_GETRLIMIT && HAVE_SETRLIMIT && !defined __CHKP__
27 
28 #include <stdlib.h>
29 #include <sys/types.h>
30 #include <sys/time.h>
31 #include <sys/resource.h>
32 #include <string.h>
33 #include <errno.h>
34 
35 #include "qemu.h"
36 
37 int
main(int argc,char * argv[])38 main (int argc, char *argv[])
39 {
40   struct rlimit limit;
41   int arg;
42   int ret;
43 
44   if (is_running_under_qemu_user ())
45     return 77;
46 
47   /* Some printf implementations allocate temporary space with malloc.  */
48   /* On BSD systems, malloc() is limited by RLIMIT_DATA.  */
49 #ifdef RLIMIT_DATA
50   if (getrlimit (RLIMIT_DATA, &limit) < 0)
51     return 77;
52   if (limit.rlim_max == RLIM_INFINITY || limit.rlim_max > 10000000)
53     limit.rlim_max = 10000000;
54   limit.rlim_cur = limit.rlim_max;
55   if (setrlimit (RLIMIT_DATA, &limit) < 0)
56     return 77;
57 #endif
58   /* On Linux systems, malloc() is limited by RLIMIT_AS.  */
59 #ifdef RLIMIT_AS
60   if (getrlimit (RLIMIT_AS, &limit) < 0)
61     return 77;
62   if (limit.rlim_max == RLIM_INFINITY || limit.rlim_max > 10000000)
63     limit.rlim_max = 10000000;
64   limit.rlim_cur = limit.rlim_max;
65   if (setrlimit (RLIMIT_AS, &limit) < 0)
66     return 77;
67 #endif
68   /* Some printf implementations allocate temporary space on the stack.  */
69 #ifdef RLIMIT_STACK
70   if (getrlimit (RLIMIT_STACK, &limit) < 0)
71     return 77;
72   if (limit.rlim_max == RLIM_INFINITY || limit.rlim_max > 10000000)
73     limit.rlim_max = 10000000;
74   limit.rlim_cur = limit.rlim_max;
75   if (setrlimit (RLIMIT_STACK, &limit) < 0)
76     return 77;
77 #endif
78 
79   arg = atoi (argv[1]);
80   switch (arg)
81     {
82     case 0:
83       {
84         void *memory = malloc (10000000);
85         if (memory == NULL)
86           return 1;
87         memset (memory, 17, 10000000);
88         return 78;
89       }
90     case 1:
91       ret = printf ("%.10000000f", 1.0);
92       return !(ret == 10000002 || (ret < 0 && errno == ENOMEM));
93     case 2:
94       ret = printf ("%.10000000f", -1.0);
95       return !(ret == 10000003 || (ret < 0 && errno == ENOMEM));
96     case 3:
97       ret = printf ("%.10000000e", 1.0);
98       return !(ret >= 10000006 || (ret < 0 && errno == ENOMEM));
99     case 4:
100       ret = printf ("%.10000000d", 1);
101       return !(ret == 10000000 || (ret < 0 && errno == ENOMEM));
102     case 5:
103       ret = printf ("%.10000000d", -1);
104       return !(ret == 10000001 || (ret < 0 && errno == ENOMEM));
105     case 6:
106       ret = printf ("%.10000000u", 1);
107       return !(ret == 10000000 || (ret < 0 && errno == ENOMEM));
108     }
109   return 0;
110 }
111 
112 #else
113 
114 int
main(int argc,char * argv[])115 main (int argc, char *argv[])
116 {
117   return 77;
118 }
119 
120 #endif
121