* Add missing copyright header.
[dejagnu.git] / testglue.c
blob55a7f92fd0027c16cf7e3d5b8213bae00d66bb88
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
42 #endif
43 #endif
45 #ifdef REAL_MAIN
46 extern void REAL_EXIT ();
47 extern void REAL_ABORT ();
48 extern int REAL_MAIN (int argc, char **argv, char **envp);
49 #endif
50 #ifdef REAL__EXIT
51 extern void REAL__EXIT ();
52 #endif
54 static int done_exit_message = 0;
55 int ___constval = 1;
57 #ifdef VXWORKS
58 static void __runexit();
59 #endif
61 static char *
62 write_int(val, ptr)
63 int val;
64 char *ptr;
66 char c;
67 if (val<0) {
68 *(ptr++) = '-';
69 val = -val;
71 if (val>9) {
72 ptr = write_int (val/10, ptr);
74 c = (val%10)+'0';
75 *(ptr++) = c;
76 return ptr;
79 void
80 ORIG_EXIT (code)
81 int code;
83 char buf[30];
84 char *ptr;
86 #ifdef VXWORKS
87 __runexit ();
88 #endif
89 strcpy (buf, "\n*** EXIT code ");
90 ptr = write_int (code, buf + strlen(buf));
91 *(ptr++) = '\n';
92 write (1, buf, ptr-buf);
93 done_exit_message = 1;
94 REAL_EXIT (code);
95 while (___constval);
98 #ifdef ORIG__EXIT
99 void
100 ORIG__EXIT (code)
101 int code;
103 char buf[30];
104 char *ptr;
106 /* Since exit may call _exit, we need to avoid a second message. */
107 if (! done_exit_message)
109 strcpy (buf, "\n*** EXIT code ");
110 ptr = write_int (code, buf + strlen(buf));
111 *(ptr++) = '\n';
112 write (1, buf, ptr-buf);
115 REAL__EXIT (code);
116 while (___constval);
118 #endif
120 void
121 ORIG_ABORT ()
123 write (1, "\n*** EXIT code 4242\n", 20);
124 REAL_ABORT ();
125 while (___constval);
126 abort ();
129 #ifdef REAL_MAIN
131 ORIG_MAIN (argc, argv, envp)
132 int argc;
133 char **argv;
134 char **envp;
136 #ifdef WRAP_FILE_ARGS
137 extern int __argc;
138 extern char *__args[];
140 exit (REAL_MAIN (__argc,__args,envp));
141 #else
142 exit (REAL_MAIN (argc, argv, envp));
143 #endif
144 while (___constval);
146 #endif
148 #ifdef VXWORKS
149 void
150 _exit (status)
151 int status;
153 REAL_EXIT (status);
156 typedef (*PFV)(void);
158 static PFV __list[32];
159 static int __listcnt = 0;
160 static int __running = 0;
163 atexit (PFV func)
165 __list[__listcnt++] = func;
168 static void
169 __runexit ()
171 int i;
172 if (__running++)
173 return;
175 for (i = 0; i < __listcnt; i++)
176 __list[i]();
177 __running = 0;
179 #endif