source: trunk/kStuff/kLdr/testcase/tst-0-driver.c@ 3587

Last change on this file since 3587 was 3584, checked in by bird, 18 years ago

fixed the testcases.

  • Property svn:keywords set to Id
File size: 20.8 KB
Line 
1/* $Id: tst-0-driver.c 3584 2007-09-02 22:46:37Z bird $ */
2/** @file
3 *
4 * kLdr - Dynamic Loader testcase no. 0, Driver.
5 *
6 * Copyright (c) 2006 knut st. osmundsen <bird-kbuild-src@anduin.net>
7 *
8 *
9 * This file is part of kLdr.
10 *
11 * kLdr is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * kLdr is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with kLdr; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 */
26
27
28/*******************************************************************************
29* Header Files *
30*******************************************************************************/
31#include "tst.h"
32#include <stdarg.h>
33#include <stdio.h>
34#include <stdlib.h>
35#include <string.h>
36
37
38/*******************************************************************************
39* Defined Constants And Macros *
40*******************************************************************************/
41/** Select the appropriate KLDRSYMKIND bit define. */
42#define MY_KLDRSYMKIND_BITS ( sizeof(void *) == 4 ? KLDRSYMKIND_32BIT : KLDRSYMKIND_64BIT )
43
44
45/*******************************************************************************
46* Global Variables *
47*******************************************************************************/
48/** The numbers of errors. */
49static int g_cErrors = 0;
50
51
52
53/**
54 * Report failure.
55 */
56static int Failure(const char *pszFormat, ...)
57{
58 va_list va;
59
60 g_cErrors++;
61
62 printf("tst-0-driver: ");
63 va_start(va, pszFormat);
64 vprintf(pszFormat, va);
65 va_end(va);
66 printf("\n");
67 return 1;
68}
69
70
71int main(int argc, char **argv)
72{
73 const char *pszErrInit = "Error, szErr wasn't zapped";
74 char szErr[512];
75 char szBuf[512];
76 char *psz;
77 KSIZE cch;
78 HKLDRMOD hMod;
79 int rc;
80
81 /*
82 * The first thing to do is a simple load / unload test
83 * using the tst-0-a library (it'll drag in tst-0-d).
84 */
85 printf("tst-0-driver: Basic API test using 'tst-0-a'...\n");
86 hMod = (HKLDRMOD)0xffffeeee;
87 strcpy(szErr, pszErrInit);
88 rc = kLdrDyldLoad("tst-0-a", NULL, NULL, KLDRDYLD_SEARCH_HOST,
89 KLDRDYLD_LOAD_FLAGS_RECURSIVE_INIT, &hMod, szErr, sizeof(szErr));
90 if (rc)
91 Failure("kLdrDyldLoad(\"tst-0\",...) failed, rc=%d (%#x). szErr='%s'.\n", rc, rc, szErr);
92 if (!strcmp(szErr, pszErrInit))
93 Failure("szErr wasn't set.\n");
94 if (hMod == (HKLDRMOD)0xffffeeee)
95 Failure("hMod wasn't set.\n");
96 if (hMod == NIL_HKLDRMOD && !rc)
97 Failure("rc=0 but hMod=NIL_HKLDRMOD\n");
98 if (!rc)
99 {
100 HKLDRMOD hMod2;
101 HKLDRMOD hMod3;
102 printf("tst-0-driver: hMod=%p ('tst-0-a')\n", (void *)hMod);
103
104 /*
105 * Simple test of kLdrDyldFindByName.
106 */
107 hMod2 = (HKLDRMOD)0xffffeeee;
108 rc = kLdrDyldFindByName("tst-0", NULL, NULL, KLDRDYLD_SEARCH_HOST, 0, &hMod2);
109 if (!rc)
110 Failure("kLdrDyldFindByName(\"tst-0\",,,) didn't fail!\n");
111 if (rc && hMod2 != NIL_HKLDRMOD)
112 Failure("hMod2 wasn't set correctly on kLdrDyldFindByName failure!\n");
113
114 hMod2 = (HKLDRMOD)0xffffeeee;
115 rc = kLdrDyldFindByName("tst-0-a", NULL, NULL, KLDRDYLD_SEARCH_HOST, 0, &hMod2);
116 if (rc)
117 Failure("kLdrDyldFindByName(\"tst-0-a\",,,) failed, rc=%d (%#x)\n", rc, rc);
118 if (!rc && hMod2 != hMod)
119 Failure("kLdrDyldFindByName(\"tst-0-a\",,,) returned the wrong module handle: %p instead of %p\n",
120 (void *)hMod2, (void *)hMod);
121
122 hMod2 = (HKLDRMOD)0xffffeeee;
123 rc = kLdrDyldFindByName("tst-0-d", NULL, NULL, KLDRDYLD_SEARCH_HOST, 0, &hMod2);
124 if (!rc)
125 printf("tst-0-driver: hMod2=%p ('tst-0-d')\n", (void *)hMod2);
126 else
127 Failure("kLdrDyldFindByName(\"tst-0-d\",,,) failed, rc=%d (%#x)\n", rc, rc);
128
129 /*
130 * Get the name and filename for each of the two modules.
131 */
132 rc = kLdrDyldGetName(hMod2, szBuf, sizeof(szBuf));
133 if (!rc)
134 {
135 printf("tst-0-driver: name: '%s' ('tst-0-d')\n", szBuf);
136 psz = strstr(szBuf, "-0-");
137 if ( !psz
138 || strnicmp(psz, "-0-d", sizeof("-0-d") - 1))
139 Failure("kLdrDyldGetName(\"tst-0-d\",,,) -> '%s': pattern '-0-d' not found\n", szBuf);
140
141 /* overflow test. */
142 cch = strlen(szBuf);
143 szBuf[cch + 1] = szBuf[cch] = szBuf[cch - 1] = 'x';
144 szBuf[cch + 2] = '\0';
145 rc = kLdrDyldGetName(hMod2, szBuf, cch);
146 if (rc == KERR_BUFFER_OVERFLOW)
147 {
148 if (!szBuf[0])
149 Failure("kLdrDyldGetName didn't return partial result on overflow\n");
150 else if (szBuf[cch - 1])
151 Failure("kLdrDyldGetName didn't terminate partial result correctly overflow: '%s'\n", szBuf);
152 else if (szBuf[cch] != 'x')
153 Failure("kLdrDyldGetName exceeded the buffer limit on partial overflow: '%s'\n", szBuf);
154 }
155 else
156 Failure("kLdrDyldGetName(\"tst-0-d\",,,) -> rc=%d (%#x) instead of KERR_BUFFER_OVERFLOW\n", rc, rc);
157
158 /* check that we can query the module by the returned name. */
159 rc = kLdrDyldGetName(hMod2, szBuf, sizeof(szBuf));
160 if (!rc)
161 {
162 hMod3 = (HKLDRMOD)0xffffeeee;
163 rc = kLdrDyldFindByName(szBuf, NULL, NULL, KLDRDYLD_SEARCH_HOST, 0, &hMod3);
164 if (rc || hMod3 != hMod2)
165 Failure("kLdrDyldFindByName(\"%s\",,,) failed, rc=%d (%#x) hMod3=%p hMod2=%p\n",
166 szBuf, rc, rc, (void *)hMod3, (void *)hMod2);
167 }
168 else
169 Failure("kLdrDyldGetName(\"tst-0-d\",,,) failed (b), rc=%d (%#x)\n", rc, rc);
170 }
171 else
172 Failure("kLdrDyldGetName(\"tst-0-d\",,,) failed, rc=%d (%#x)\n", rc, rc);
173
174 rc = kLdrDyldGetFilename(hMod2, szBuf, sizeof(szBuf));
175 if (!rc)
176 {
177 printf("tst-0-driver: filename: '%s' ('tst-0-d')\n", szBuf);
178
179 /* overflow test. */
180 cch = strlen(szBuf);
181 szBuf[cch + 1] = szBuf[cch] = szBuf[cch - 1] = 'x';
182 szBuf[cch + 2] = '\0';
183 rc = kLdrDyldGetFilename(hMod2, szBuf, cch);
184 if (rc == KERR_BUFFER_OVERFLOW)
185 {
186 if (!szBuf[0])
187 Failure("kLdrDyldGetFilename didn't return partial result on overflow\n");
188 else if (szBuf[cch - 1])
189 Failure("kLdrDyldGetFilename didn't terminate partial result correctly overflow: '%s'\n", szBuf);
190 else if (szBuf[cch] != 'x')
191 Failure("kLdrDyldGetFilename exceeded the buffer limit on partial overflow: '%s'\n", szBuf);
192 }
193 else
194 Failure("kLdrDyldGetFilename(\"tst-0-d\",,,) -> rc=%d (%#x) instead of KERR_BUFFER_OVERFLOW\n", rc, rc);
195
196 /* check that we can query the module by the returned filename. */
197 rc = kLdrDyldGetFilename(hMod2, szBuf, sizeof(szBuf));
198 if (!rc)
199 {
200 hMod3 = (HKLDRMOD)0xffffeeee;
201 rc = kLdrDyldFindByName(szBuf, NULL, NULL, KLDRDYLD_SEARCH_HOST, 0, &hMod3);
202 if (rc || hMod3 != hMod2)
203 Failure("kLdrDyldFindByName(\"%s\",,,) failed, rc=%d (%#x) hMod3=%p hMod2=%p\n",
204 szBuf, rc, rc, (void *)hMod3, (void *)hMod2);
205 }
206 else
207 Failure("kLdrDyldGetName(\"tst-0-d\",,,) failed (b), rc=%d (%#x)\n", rc, rc);
208 }
209 else
210 Failure("kLdrDyldGetFilename(\"tst-0-d\",,,) failed, rc=%d (%#x)\n", rc, rc);
211
212 /* the other module */
213 rc = kLdrDyldGetName(hMod, szBuf, sizeof(szBuf));
214 if (!rc)
215 {
216 printf("tst-0-driver: name: '%s' ('tst-0-a')\n", szBuf);
217 psz = strstr(szBuf, "-0-");
218 if ( !psz
219 || strnicmp(psz, "-0-a", sizeof("-0-a") - 1))
220 Failure("kLdrDyldGetName(\"tst-0-a\",,,) -> '%s': pattern '-0-a' not found\n", szBuf);
221
222 /* check that we can query the module by the returned name. */
223 hMod3 = (HKLDRMOD)0xffffeeee;
224 rc = kLdrDyldFindByName(szBuf, NULL, NULL, KLDRDYLD_SEARCH_HOST, 0, &hMod3);
225 if (rc || hMod3 != hMod)
226 Failure("kLdrDyldFindByName(\"%s\",,,) failed, rc=%d (%#x) hMod3=%p hMod=%p\n",
227 szBuf, rc, rc, (void *)hMod3, (void *)hMod);
228 }
229 else
230 Failure("kLdrDyldGetName(\"tst-0-a\",,,) failed, rc=%d (%#x)\n", rc, rc);
231
232 rc = kLdrDyldGetFilename(hMod, szBuf, sizeof(szBuf));
233 if (!rc)
234 {
235 printf("tst-0-driver: filename: '%s' ('tst-0-a')\n", szBuf);
236
237 /* check that we can query the module by the returned filename. */
238 hMod3 = (HKLDRMOD)0xffffeeee;
239 rc = kLdrDyldFindByName(szBuf, NULL, NULL, KLDRDYLD_SEARCH_HOST, 0, &hMod3);
240 if (rc || hMod3 != hMod)
241 Failure("kLdrDyldFindByName(\"%s\",,,) failed, rc=%d (%#x) hMod3=%p hMod=%p\n",
242 szBuf, rc, rc, (void *)hMod3, (void *)hMod);
243 }
244 else
245 Failure("kLdrDyldGetFilename(\"tst-0-a\",,,) failed, rc=%d (%#x)\n", rc, rc);
246
247
248 /*
249 * Resolve the symbol exported by each of the two modules and call them.
250 */
251 if (!g_cErrors)
252 {
253 KUPTR uValue;
254 KU32 fKind;
255
256 fKind = 0xffeeffee;
257 uValue = ~(KUPTR)42;
258 rc = kLdrDyldQuerySymbol(hMod, NIL_KLDRMOD_SYM_ORDINAL, MY_NAME("FuncA"), NULL, &uValue, &fKind);
259 if (!rc)
260 {
261 if (uValue == ~(KUPTR)42)
262 Failure("kLdrDyldQuerySymbol(\"tst-0-a\",,\"FuncA\",): uValue wasn't set.\n");
263 if (fKind == 0xffeeffee)
264 Failure("kLdrDyldQuerySymbol(\"tst-0-a\",,\"FuncA\",): fKind wasn't set.\n");
265 if ( (fKind & KLDRSYMKIND_BIT_MASK) != KLDRSYMKIND_NO_BIT
266 && (fKind & KLDRSYMKIND_BIT_MASK) != MY_KLDRSYMKIND_BITS)
267 Failure("fKind=%#x indicates a different code 'bit' mode than we running at.\n", fKind);
268 if ( (fKind & KLDRSYMKIND_TYPE_MASK) != KLDRSYMKIND_NO_TYPE
269 && (fKind & KLDRSYMKIND_TYPE_MASK) != KLDRSYMKIND_CODE)
270 Failure("fKind=%#x indicates that \"FuncA\" isn't code.\n", fKind);
271 if (fKind & KLDRSYMKIND_FORWARDER)
272 Failure("fKind=%#x indicates that \"FuncA\" is a forwarder. it isn't.\n", fKind);
273
274 /* call it. */
275 if (!g_cErrors)
276 {
277 int (*pfnFuncA)(void) = (int (*)(void))uValue;
278 rc = pfnFuncA();
279 if (rc != 0x42000042)
280 Failure("FuncA returned %#x expected 0x42000042\n", rc);
281 }
282
283 /*
284 * Test kLdrDyldFindByAddress now that we've got an address.
285 */
286 hMod3 = (HKLDRMOD)0xeeeeffff;
287 rc = kLdrDyldFindByAddress(uValue, &hMod3, NULL, NULL);
288 if (!rc)
289 {
290 KUPTR offSegment;
291 KU32 iSegment;
292
293 if (hMod3 != hMod)
294 Failure("kLdrDyldFindByAddress(%#p/*FuncA*/, \"tst-0-a\",,,) return incorrect hMod3=%p instead of %p.\n",
295 uValue, hMod3, hMod);
296
297 hMod3 = (HKLDRMOD)0xeeeeffff;
298 iSegment = 0x42424242;
299 rc = kLdrDyldFindByAddress(uValue, &hMod3, &iSegment, &offSegment);
300 if (!rc)
301 {
302 if (hMod3 != hMod)
303 Failure("Bad hMod3 on 2nd kLdrDyldFindByAddress call.\n");
304 if (iSegment > 0x1000) /* safe guess */
305 Failure("Bad iSegment=%#x\n", iSegment);
306 if (offSegment > 0x100000) /* guesswork */
307 Failure("Bad offSegment=%p\n", (void *)offSegment);
308 }
309 else
310 Failure("kLdrDyldFindByAddress(%#p/*FuncA*/, \"tst-0-a\",,,) failed (b), rc=%d (%#x)\n",
311 uValue, rc, rc);
312
313 /* negative test */
314 hMod3 = (HKLDRMOD)0xeeeeffff;
315 iSegment = 0x42424242;
316 offSegment = 0x87654321;
317 rc = kLdrDyldFindByAddress(~(KUPTR)16, &hMod3, &iSegment, &offSegment);
318 if (!rc)
319 Failure("negative kLdrDyldFindByAddress test returned successfully!\n");
320 if (iSegment != ~(KU32)0)
321 Failure("negative kLdrDyldFindByAddress: bad iSegment=%#x\n", iSegment);
322 if (offSegment != ~(KUPTR)0)
323 Failure("negative kLdrDyldFindByAddress: bad offSegment=%p\n", (void *)offSegment);
324 if (hMod3 != NIL_HKLDRMOD)
325 Failure("negative kLdrDyldFindByAddress: bad hMod3=%p\n", (void *)hMod3);
326 }
327 else
328 Failure("kLdrDyldFindByAddress(%#p/*FuncA*/, \"tst-0-a\",,,) failed, rc=%d (%#x)\n",
329 uValue, rc, rc);
330 }
331 else
332 Failure("kLdrDyldQuerySymbol(\"tst-0-a\",,\"FuncA\",) failed, rc=%d (%#x)\n", rc, rc);
333
334 fKind = 0xffeeffee;
335 uValue = ~(KUPTR)42;
336 rc = kLdrDyldQuerySymbol(hMod2, NIL_KLDRMOD_SYM_ORDINAL, MY_NAME("FuncD"), NULL, &uValue, &fKind);
337 if (!rc)
338 {
339 if (uValue == ~(KUPTR)42)
340 Failure("kLdrDyldQuerySymbol(\"tst-0-d\",,\"FuncD\",): uValue wasn't set.\n");
341 if (fKind == 0xffeeffee)
342 Failure("kLdrDyldQuerySymbol(\"tst-0-d\",,\"FuncD\",): fKind wasn't set.\n");
343 if ( (fKind & KLDRSYMKIND_BIT_MASK) != KLDRSYMKIND_NO_BIT
344 && (fKind & KLDRSYMKIND_BIT_MASK) != MY_KLDRSYMKIND_BITS)
345 Failure("fKind=%#x indicates a different code 'bit' mode than we running at.\n", fKind);
346 if ( (fKind & KLDRSYMKIND_TYPE_MASK) != KLDRSYMKIND_NO_TYPE
347 && (fKind & KLDRSYMKIND_TYPE_MASK) != KLDRSYMKIND_CODE)
348 Failure("fKind=%#x indicates that \"FuncD\" isn't code.\n", fKind);
349 if (fKind & KLDRSYMKIND_FORWARDER)
350 Failure("fKind=%#x indicates that \"FuncD\" is a forwarder. it isn't.\n", fKind);
351
352 /* call it. */
353 if (!g_cErrors)
354 {
355 int (*pfnFuncD)(void) = (int (*)(void))uValue;
356 rc = pfnFuncD();
357 if (rc != 0x42000000)
358 Failure("FuncD returned %#x expected 0x42000000\n", rc);
359 }
360
361 /* use the address to get the module handle. */
362 hMod3 = (HKLDRMOD)0xeeeeffff;
363 rc = kLdrDyldFindByAddress(uValue, &hMod3, NULL, NULL);
364 if (!rc)
365 {
366 if (hMod3 != hMod2)
367 Failure("kLdrDyldFindByAddress(%#p/*FuncD*/,,,) return incorrect hMod3=%p instead of %p.\n",
368 uValue, hMod3, hMod2);
369 }
370 else
371 Failure("kLdrDyldFindByAddress(%#p/*FuncD*/,,,) failed, rc=%d (%#x)\n",
372 uValue, rc, rc);
373 }
374 else
375 Failure("kLdrDyldQuerySymbol(\"tst-0-a\",,\"FuncA\",) failed, rc=%d (%#x)\n", rc, rc);
376
377 }
378
379 /*
380 * Finally unload it.
381 */
382 rc = kLdrDyldUnload(hMod);
383 if (rc)
384 Failure("kLdrDyldUnload() failed. rc=%d (%#x)\n", rc, rc);
385 if (!rc)
386 {
387 rc = kLdrDyldFindByName("tst-0-d", NULL, NULL, KLDRDYLD_SEARCH_HOST, 0, &hMod2);
388 if (rc != KLDR_ERR_MODULE_NOT_FOUND)
389 Failure("kLdrDyldFindByName(\"tst-0-d\",,,) return rc=%d (%#x), expected KLDR_ERR_MODULE_NOT_FOUND\n", rc, rc);
390
391 rc = kLdrDyldFindByName("tst-0-a", NULL, NULL, KLDRDYLD_SEARCH_HOST, 0, &hMod2);
392 if (rc != KLDR_ERR_MODULE_NOT_FOUND)
393 Failure("kLdrDyldFindByName(\"tst-0-a\",,,) return rc=%d (%#x), expected KLDR_ERR_MODULE_NOT_FOUND\n", rc, rc);
394 }
395 }
396
397 /*
398 * Now do what tst-0 would do; load the three dlls, resolve and call their functions.
399 */
400 if (!g_cErrors)
401 {
402 HKLDRMOD hModA;
403 int (*pfnFuncA)(void);
404 HKLDRMOD hModB;
405 int (*pfnFuncB)(void);
406 HKLDRMOD hModC;
407 int (*pfnFuncC)(void);
408 KUPTR uValue;
409
410 rc = kLdrDyldLoad("tst-0-a", NULL, NULL, KLDRDYLD_SEARCH_HOST, 0, &hModA, NULL, 0);
411 if (rc)
412 Failure("kLdrDyldLoad(\"tst-0-a\",,,,) -> %d (%#x)\n", rc, rc);
413 if (!rc)
414 {
415 rc = kLdrDyldLoad("tst-0-b", NULL, NULL, KLDRDYLD_SEARCH_HOST, 0, &hModB, szErr, sizeof(szErr));
416 if (rc)
417 Failure("kLdrDyldLoad(\"tst-0-b\",,,,) -> %d (%#x) szErr='%s'\n", rc, rc, szErr);
418 }
419 if (!rc)
420 {
421 rc = kLdrDyldLoad("tst-0-c", NULL, NULL, KLDRDYLD_SEARCH_HOST, 0, &hModC, szErr, sizeof(szErr));
422 if (rc)
423 Failure("kLdrDyldLoad(\"tst-0-c\",,,,) -> %d (%#x) szErr='%s'\n", rc, rc, szErr);
424 }
425 if (!rc)
426 {
427 rc = kLdrDyldQuerySymbol(hModA, NIL_KLDRMOD_SYM_ORDINAL, MY_NAME("FuncA"), NULL, &uValue, NULL);
428 if (!rc)
429 pfnFuncA = (int (*)(void))uValue;
430 else
431 Failure("kLdrDyldQuerySymbol(,,\"FuncA\",,) -> %d (%#x)\n", rc, rc);
432 }
433 if (!rc)
434 {
435 rc = kLdrDyldQuerySymbol(hModB, NIL_KLDRMOD_SYM_ORDINAL, MY_NAME("FuncB"), NULL, &uValue, NULL);
436 if (!rc)
437 pfnFuncB = (int (*)(void))uValue;
438 else
439 Failure("kLdrDyldQuerySymbol(,,\"FuncB\",,) -> %d (%#x)\n", rc, rc);
440 }
441 if (!rc)
442 {
443 rc = kLdrDyldQuerySymbol(hModC, NIL_KLDRMOD_SYM_ORDINAL, MY_NAME("FuncC"), NULL, &uValue, NULL);
444 if (!rc)
445 pfnFuncC = (int (*)(void))uValue;
446 else
447 Failure("kLdrDyldQuerySymbol(,,\"FuncA\",,) -> %d (%#x)\n", rc, rc);
448 }
449 if (!rc)
450 {
451 int u = pfnFuncA() | pfnFuncB() | pfnFuncC();
452 if (u == 0x42424242)
453 printf("tst-0-driver: FuncA/B/C => %#x (correct)\n", u);
454 else
455 Failure("FuncA/B/C => %#x\n", u);
456
457 rc = kLdrDyldUnload(hModA);
458 if (rc)
459 Failure("Unload A failed, rc=%d (%#x)\n", rc, rc);
460 u = pfnFuncB() | pfnFuncC();
461 if (u != 0x42424200)
462 Failure("FuncB/C returns %#x instead of 0x42424200 after unloading A\n", u);
463
464 rc = kLdrDyldUnload(hModB);
465 if (rc)
466 Failure("Unload B failed, rc=%d (%#x)\n", rc, rc);
467 u = pfnFuncC();
468 if (u != 0x42420000)
469 Failure("FuncC returns %#x instead of 0x42420000 after unloading A\n", u);
470
471 rc = kLdrDyldUnload(hModC);
472 if (rc)
473 Failure("Unload C failed, rc=%d (%#x)\n", rc, rc);
474
475 rc = kLdrDyldFindByName("tst-0-d", NULL, NULL, KLDRDYLD_SEARCH_HOST, 0, &hMod);
476 if (rc != KLDR_ERR_MODULE_NOT_FOUND)
477 Failure("Query for \"tst-0-d\" after unloading A,B and C returns rc=%d (%#x) instead of KLDR_ERR_MODULE_NOT_FOUND\n",
478 rc, rc);
479 }
480 }
481
482 /*
483 * Now invoke the executable stub which launches the tst-0 program.
484 */
485 if (!g_cErrors)
486 {
487 /// @todo
488 }
489
490 /*
491 * Summary
492 */
493 if (!g_cErrors)
494 printf("tst-0-driver: SUCCESS\n");
495 else
496 printf("tst-0-driver: FAILURE - %d errors\n", g_cErrors);
497 return !!g_cErrors;
498}
499
Note: See TracBrowser for help on using the repository browser.