Use older shell constructs to fix PR47382
[dejagnu.git] / testglue.c
blob06f4a90fb023ee395338573d29f73981e3013791
1 #include <stdio.h>
2 #include <string.h>
3 #ifndef NO_UNISTD_H
4 #include <sys/unistd.h>
5 #endif
7 /* A simple glue file for embedded targets so we can get the real exit
8 status from the program. This assumes we're using GNU ld and can use
9 the -wrap option, and that write(1, ...) does something useful. */
11 /* There is a bunch of weird cruft with #ifdef UNDERSCORES. This is needed
12 because currently GNU ld doesn't deal well with a.out targets and
13 the -wrap option. When GNU ld is fixed, this should definitely be
14 removed. Note that we actually wrap __exit, not _exit on a target
15 that has UNDERSCORES defined. On non-UNDERSCORE targets, we
16 wrap _exit separately; it's actually a different function. */
18 #ifdef WRAP_M68K_AOUT
19 #define REAL_EXIT(code) asm ( "trap %0" : : "i" (0) );
20 #define REAL_ABORT() REAL_EXIT(6)
21 #define ORIG_EXIT _exit
22 #define ORIG_ABORT abort
23 #else
24 #ifdef UNDERSCORES
25 #define REAL_EXIT _real___exit
26 #define REAL_MAIN _real__main
27 #define REAL_ABORT _real__abort
28 #define ORIG_EXIT _wrap___exit
29 #define ORIG_ABORT _wrap__abort
30 #define ORIG_MAIN _wrap__main
31 #else
32 #define REAL_EXIT __real_exit
33 #ifndef VXWORKS
34 #define REAL__EXIT __real__exit
35 #endif
36 #define REAL_MAIN __real_main
37 #define REAL_ABORT __real_abort
38 #define ORIG_EXIT __wrap_exit
39 #define ORIG__EXIT __wrap__exit
40 #define ORIG_ABORT __wrap_abort
41 #define ORIG_MAIN __wrap_main
43 #endif
45 extern void abort (void);
46 extern void exit (int);
48 #endif
50 #ifdef REAL_MAIN
51 extern void REAL_EXIT ();
52 extern void REAL_ABORT ();
53 extern int REAL_MAIN (int argc, char **argv, char **envp);
54 #endif
55 #ifdef REAL__EXIT
56 extern void REAL__EXIT ();
57 #endif
59 static int done_exit_message = 0;
60 int ___constval = 1;
62 #ifdef VXWORKS
63 static void __runexit();
64 #endif
66 static char *
67 write_int(val, ptr)
68 int val;
69 char *ptr;
71 char c;
72 if (val<0) {
73 *(ptr++) = '-';
74 val = -val;
76 if (val>9) {
77 ptr = write_int (val/10, ptr);
79 c = (val%10)+'0';
80 *(ptr++) = c;
81 return ptr;
84 void
85 ORIG_EXIT (code)
86 int code;
88 char buf[30];
89 char *ptr;
91 #ifdef VXWORKS
92 __runexit ();
93 #endif
94 strcpy (buf, "\n*** EXIT code ");
95 ptr = write_int (code, buf + strlen(buf));
96 *(ptr++) = '\n';
97 write (1, buf, ptr-buf);
98 done_exit_message = 1;
99 REAL_EXIT (code);
100 while (___constval);
103 #ifdef ORIG__EXIT
104 void
105 ORIG__EXIT (code)
106 int code;
108 char buf[30];
109 char *ptr;
111 /* Since exit may call _exit, we need to avoid a second message. */
112 if (! done_exit_message)
114 strcpy (buf, "\n*** EXIT code ");
115 ptr = write_int (code, buf + strlen(buf));
116 *(ptr++) = '\n';
117 write (1, buf, ptr-buf);
120 REAL__EXIT (code);
121 while (___constval);
123 #endif
125 void
126 ORIG_ABORT ()
128 write (1, "\n*** EXIT code 4242\n", 20);
129 REAL_ABORT ();
130 while (___constval);
131 abort ();
134 #ifdef REAL_MAIN
136 ORIG_MAIN (argc, argv, envp)
137 int argc;
138 char **argv;
139 char **envp;
141 #ifdef WRAP_FILE_ARGS
142 extern int __argc;
143 extern char *__args[];
145 exit (REAL_MAIN (__argc,__args,envp));
146 #else
147 exit (REAL_MAIN (argc, argv, envp));
148 #endif
149 while (___constval);
151 #endif
153 #ifdef VXWORKS
154 void
155 _exit (status)
156 int status;
158 REAL_EXIT (status);
161 typedef (*PFV)(void);
163 static PFV __list[32];
164 static int __listcnt = 0;
165 static int __running = 0;
168 atexit (PFV func)
170 __list[__listcnt++] = func;
173 static void
174 __runexit ()
176 int i;
177 if (__running++)
178 return;
180 for (i = 0; i < __listcnt; i++)
181 __list[i]();
182 __running = 0;
184 #endif