1 /*
2 * Some utility routines for writing tests.
3 *
4 * Here are a variety of utility routines for writing tests compatible with
5 * the TAP protocol. All routines of the form ok() or is*() take a test
6 * number and some number of appropriate arguments, check to be sure the
7 * results match the expected output using the arguments, and print out
8 * something appropriate for that test number. Other utility routines help in
9 * constructing more complex tests, skipping tests, reporting errors, setting
10 * up the TAP output format, or finding things in the test environment.
11 *
12 * This file is part of C TAP Harness. The current version plus supporting
13 * documentation is at <https://www.eyrie.org/~eagle/software/c-tap-harness/>.
14 *
15 * Written by Russ Allbery <eagle@eyrie.org>
16 * Copyright 2009-2019 Russ Allbery <eagle@eyrie.org>
17 * Copyright 2001-2002, 2004-2008, 2011-2014
18 * The Board of Trustees of the Leland Stanford Junior University
19 *
20 * Permission is hereby granted, free of charge, to any person obtaining a
21 * copy of this software and associated documentation files (the "Software"),
22 * to deal in the Software without restriction, including without limitation
23 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
24 * and/or sell copies of the Software, and to permit persons to whom the
25 * Software is furnished to do so, subject to the following conditions:
26 *
27 * The above copyright notice and this permission notice shall be included in
28 * all copies or substantial portions of the Software.
29 *
30 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
31 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
32 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
33 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
34 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
35 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
36 * DEALINGS IN THE SOFTWARE.
37 *
38 * SPDX-License-Identifier: MIT
39 */
40
41 #include <errno.h>
42 #include <limits.h>
43 #include <stdarg.h>
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #ifdef _WIN32
48 # include <direct.h>
49 #else
50 # include <sys/stat.h>
51 #endif
52 #include <sys/types.h>
53 #include <unistd.h>
54
55 #include <tap/basic.h>
56
57 /* Specific to the integration of C TAP Harness in INN. */
58 #ifndef LIBTEST_NEW_FORMAT
59 # include "inn/libinn.h"
60
61 void
test_init(int count)62 test_init(int count)
63 {
64 plan(count);
65 }
66
67 void
ok(int n UNUSED,int success)68 ok(int n UNUSED, int success)
69 {
70 new_ok(success, NULL);
71 }
72
73 void
skip(int n UNUSED,const char * reason)74 skip(int n UNUSED, const char *reason)
75 {
76 # if __GNUC__ > 4 || defined(__llvm__) || defined(__clang__)
77 # pragma GCC diagnostic ignored "-Wformat-nonliteral"
78 # endif
79 new_skip(reason, NULL);
80 # if __GNUC__ > 4 || defined(__llvm__) || defined(__clang__)
81 # pragma GCC diagnostic warning "-Wformat-nonliteral"
82 # endif
83 }
84
85 void
ok_block(int n UNUSED,int count,int success)86 ok_block(int n UNUSED, int count, int success)
87 {
88 new_ok_block(count, success, NULL);
89 }
90
91 void
skip_block(int n UNUSED,int count,const char * reason)92 skip_block(int n UNUSED, int count, const char *reason)
93 {
94 # if __GNUC__ > 4 || defined(__llvm__) || defined(__clang__)
95 # pragma GCC diagnostic ignored "-Wformat-nonliteral"
96 # endif
97 new_skip_block(count, reason, NULL);
98 # if __GNUC__ > 4 || defined(__llvm__) || defined(__clang__)
99 # pragma GCC diagnostic warning "-Wformat-nonliteral"
100 # endif
101 }
102
103 void
ok_int(int n UNUSED,int wanted,int seen)104 ok_int(int n UNUSED, int wanted, int seen)
105 {
106 is_int(wanted, seen, NULL);
107 }
108
109 void
ok_string(int n UNUSED,const char * wanted,const char * seen)110 ok_string(int n UNUSED, const char *wanted, const char *seen)
111 {
112 is_string(wanted, seen, NULL);
113 }
114 #endif
115
116 /* Windows provides mkdir and rmdir under different names. */
117 #ifdef _WIN32
118 # define mkdir(p, m) _mkdir(p)
119 # define rmdir(p) _rmdir(p)
120 #endif
121
122 /*
123 * The test count. Always contains the number that will be used for the next
124 * test status. This is exported to callers of the library.
125 */
126 unsigned long testnum = 1;
127
128 /*
129 * Status information stored so that we can give a test summary at the end of
130 * the test case. We store the planned final test and the count of failures.
131 * We can get the highest test count from testnum.
132 */
133 static unsigned long _planned = 0;
134 static unsigned long _failed = 0;
135
136 /*
137 * Store the PID of the process that called plan() and only summarize
138 * results when that process exits, so as to not misreport results in forked
139 * processes.
140 */
141 static pid_t _process = 0;
142
143 /*
144 * If true, we're doing lazy planning and will print out the plan based on the
145 * last test number at the end of testing.
146 */
147 static int _lazy = 0;
148
149 /*
150 * If true, the test was aborted by calling bail(). Currently, this is only
151 * used to ensure that we pass a false value to any cleanup functions even if
152 * all tests to that point have passed.
153 */
154 static int _aborted = 0;
155
156 /*
157 * Registered cleanup functions. These are stored as a linked list and run in
158 * registered order by finish when the test program exits. Each function is
159 * passed a boolean value indicating whether all tests were successful.
160 */
161 struct cleanup_func {
162 test_cleanup_func func;
163 test_cleanup_func_with_data func_with_data;
164 void *data;
165 struct cleanup_func *next;
166 };
167 static struct cleanup_func *cleanup_funcs = NULL;
168
169 /*
170 * Registered diag files. Any output found in these files will be printed out
171 * as if it were passed to diag() before any other output we do. This allows
172 * background processes to log to a file and have that output interleaved with
173 * the test output.
174 */
175 struct diag_file {
176 char *name;
177 FILE *file;
178 char *buffer;
179 size_t bufsize;
180 struct diag_file *next;
181 };
182 static struct diag_file *diag_files = NULL;
183
184 /*
185 * Print a specified prefix and then the test description. Handles turning
186 * the argument list into a va_args structure suitable for passing to
187 * print_desc, which has to be done in a macro. Assumes that format is the
188 * argument immediately before the variadic arguments.
189 */
190 #define PRINT_DESC(prefix, format) \
191 do { \
192 if (format != NULL) { \
193 va_list args; \
194 printf("%s", prefix); \
195 va_start(args, format); \
196 vprintf(format, args); \
197 va_end(args); \
198 } \
199 } while (0)
200
201
202 /*
203 * Form a new string by concatenating multiple strings. The arguments must be
204 * terminated by (const char *) 0.
205 *
206 * This function only exists because we can't assume asprintf. We can't
207 * simulate asprintf with snprintf because we're only assuming SUSv3, which
208 * does not require that snprintf with a NULL buffer return the required
209 * length. When those constraints are relaxed, this should be ripped out and
210 * replaced with asprintf or a more trivial replacement with snprintf.
211 */
212 #ifndef INN_LIBINN_H
213 static char *
concat(const char * first,...)214 concat(const char *first, ...)
215 {
216 va_list args;
217 char *result;
218 const char *string;
219 size_t offset;
220 size_t length = 0;
221
222 /*
223 * Find the total memory required. Ensure we don't overflow length. See
224 * the comment for breallocarray for why we're using UINT_MAX here.
225 */
226 va_start(args, first);
227 for (string = first; string != NULL; string = va_arg(args, const char *)) {
228 if (length >= UINT_MAX - strlen(string))
229 bail("strings too long in concat");
230 length += strlen(string);
231 }
232 va_end(args);
233 length++;
234
235 /* Create the string. */
236 result = bcalloc_type(length, char);
237 va_start(args, first);
238 offset = 0;
239 for (string = first; string != NULL; string = va_arg(args, const char *)) {
240 memcpy(result + offset, string, strlen(string));
241 offset += strlen(string);
242 }
243 va_end(args);
244 result[offset] = '\0';
245 return result;
246 }
247 #endif
248
249
250 /*
251 * Helper function for check_diag_files to handle a single line in a diag
252 * file.
253 *
254 * The general scheme here used is as follows: read one line of output. If we
255 * get NULL, check for an error. If there was one, bail out of the test
256 * program; otherwise, return, and the enclosing loop will check for EOF.
257 *
258 * If we get some data, see if it ends in a newline. If it doesn't end in a
259 * newline, we have one of two cases: our buffer isn't large enough, in which
260 * case we resize it and try again, or we have incomplete data in the file, in
261 * which case we rewind the file and will try again next time.
262 *
263 * Returns a boolean indicating whether the last line was incomplete.
264 */
265 static int
handle_diag_file_line(struct diag_file * file,fpos_t where)266 handle_diag_file_line(struct diag_file *file, fpos_t where)
267 {
268 int size;
269 size_t length;
270
271 /* Read the next line from the file. */
272 size = file->bufsize > INT_MAX ? INT_MAX : (int) file->bufsize;
273 if (fgets(file->buffer, size, file->file) == NULL) {
274 if (ferror(file->file))
275 sysbail("cannot read from %s", file->name);
276 return 0;
277 }
278
279 /*
280 * See if the line ends in a newline. If not, see which error case we
281 * have.
282 */
283 length = strlen(file->buffer);
284 if (file->buffer[length - 1] != '\n') {
285 int incomplete = 0;
286
287 /* Check whether we ran out of buffer space and resize if so. */
288 if (length < file->bufsize - 1)
289 incomplete = 1;
290 else {
291 file->bufsize += BUFSIZ;
292 file->buffer =
293 breallocarray_type(file->buffer, file->bufsize, char);
294 }
295
296 /*
297 * On either incomplete lines or too small of a buffer, rewind
298 * and read the file again (on the next pass, if incomplete).
299 * It's simpler than trying to double-buffer the file.
300 */
301 if (fsetpos(file->file, &where) < 0)
302 sysbail("cannot set position in %s", file->name);
303 return incomplete;
304 }
305
306 /* We saw a complete line. Print it out. */
307 printf("# %s", file->buffer);
308 return 0;
309 }
310
311
312 /*
313 * Check all registered diag_files for any output. We only print out the
314 * output if we see a complete line; otherwise, we wait for the next newline.
315 */
316 static void
check_diag_files(void)317 check_diag_files(void)
318 {
319 struct diag_file *file;
320 fpos_t where;
321 int incomplete;
322
323 /*
324 * Walk through each file and read each line of output available.
325 */
326 for (file = diag_files; file != NULL; file = file->next) {
327 clearerr(file->file);
328
329 /* Store the current position in case we have to rewind. */
330 if (fgetpos(file->file, &where) < 0)
331 sysbail("cannot get position in %s", file->name);
332
333 /* Continue until we get EOF or an incomplete line of data. */
334 incomplete = 0;
335 while (!feof(file->file) && !incomplete) {
336 incomplete = handle_diag_file_line(file, where);
337 }
338 }
339 }
340
341
342 /*
343 * Our exit handler. Called on completion of the test to report a summary of
344 * results provided we're still in the original process. This also handles
345 * printing out the plan if we used plan_lazy(), although that's suppressed if
346 * we never ran a test (due to an early bail, for example), and running any
347 * registered cleanup functions.
348 */
349 static void
finish(void)350 finish(void)
351 {
352 int success, primary;
353 struct cleanup_func *current;
354 unsigned long highest = testnum - 1;
355 struct diag_file *file, *tmp;
356
357 /* Check for pending diag_file output. */
358 check_diag_files();
359
360 /* Free the diag_files. */
361 file = diag_files;
362 while (file != NULL) {
363 tmp = file;
364 file = file->next;
365 fclose(tmp->file);
366 free(tmp->name);
367 free(tmp->buffer);
368 free(tmp);
369 }
370 diag_files = NULL;
371
372 /*
373 * Determine whether all tests were successful, which is needed before
374 * calling cleanup functions since we pass that fact to the functions.
375 */
376 if (_planned == 0 && _lazy)
377 _planned = highest;
378 success = (!_aborted && _planned == highest && _failed == 0);
379
380 /*
381 * If there are any registered cleanup functions, we run those first. We
382 * always run them, even if we didn't run a test. Don't do anything
383 * except free the diag_files and call cleanup functions if we aren't the
384 * primary process (the process in which plan or plan_lazy was called),
385 * and tell the cleanup functions that fact.
386 */
387 primary = (_process == 0 || getpid() == _process);
388 while (cleanup_funcs != NULL) {
389 if (cleanup_funcs->func_with_data) {
390 void *data = cleanup_funcs->data;
391
392 cleanup_funcs->func_with_data(success, primary, data);
393 } else {
394 cleanup_funcs->func(success, primary);
395 }
396 current = cleanup_funcs;
397 cleanup_funcs = cleanup_funcs->next;
398 free(current);
399 }
400 if (!primary)
401 return;
402
403 /* Don't do anything further if we never planned a test. */
404 if (_planned == 0)
405 return;
406
407 /* If we're aborting due to bail, don't print summaries. */
408 if (_aborted)
409 return;
410
411 /* Print out the lazy plan if needed. */
412 fflush(stderr);
413 if (_lazy && _planned > 0)
414 printf("1..%lu\n", _planned);
415
416 /* Print out a summary of the results. */
417 if (_planned > highest)
418 diag("Looks like you planned %lu test%s but only ran %lu", _planned,
419 (_planned > 1 ? "s" : ""), highest);
420 else if (_planned < highest)
421 diag("Looks like you planned %lu test%s but ran %lu extra", _planned,
422 (_planned > 1 ? "s" : ""), highest - _planned);
423 else if (_failed > 0)
424 diag("Looks like you failed %lu test%s of %lu", _failed,
425 (_failed > 1 ? "s" : ""), _planned);
426 else if (_planned != 1)
427 diag("All %lu tests successful or skipped", _planned);
428 else
429 diag("%lu test successful or skipped", _planned);
430 }
431
432
433 /*
434 * Initialize things. Turns on line buffering on stdout and then prints out
435 * the number of tests in the test suite. We intentionally don't check for
436 * pending diag_file output here, since it should really come after the plan.
437 */
438 void
plan(unsigned long count)439 plan(unsigned long count)
440 {
441 if (setvbuf(stdout, NULL, _IOLBF, BUFSIZ) != 0)
442 sysdiag("cannot set stdout to line buffered");
443 fflush(stderr);
444 printf("1..%lu\n", count);
445 testnum = 1;
446 _planned = count;
447 _process = getpid();
448 if (atexit(finish) != 0) {
449 sysdiag("cannot register exit handler");
450 diag("cleanups will not be run");
451 }
452 }
453
454
455 /*
456 * Initialize things for lazy planning, where we'll automatically print out a
457 * plan at the end of the program. Turns on line buffering on stdout as well.
458 */
459 void
plan_lazy(void)460 plan_lazy(void)
461 {
462 if (setvbuf(stdout, NULL, _IOLBF, BUFSIZ) != 0)
463 sysdiag("cannot set stdout to line buffered");
464 testnum = 1;
465 _process = getpid();
466 _lazy = 1;
467 if (atexit(finish) != 0)
468 sysbail("cannot register exit handler to display plan");
469 }
470
471
472 /*
473 * Skip the entire test suite and exits. Should be called instead of plan(),
474 * not after it, since it prints out a special plan line. Ignore diag_file
475 * output here, since it's not clear if it's allowed before the plan.
476 */
477 void
skip_all(const char * format,...)478 skip_all(const char *format, ...)
479 {
480 fflush(stderr);
481 printf("1..0 # skip");
482 PRINT_DESC(" ", format);
483 putchar('\n');
484 exit(0);
485 }
486
487
488 /*
489 * Takes a boolean success value and assumes the test passes if that value
490 * is true and fails if that value is false.
491 */
492 int
new_ok(int success,const char * format,...)493 new_ok(int success, const char *format, ...)
494 {
495 fflush(stderr);
496 check_diag_files();
497 printf("%sok %lu", success ? "" : "not ", testnum++);
498 if (!success)
499 _failed++;
500 PRINT_DESC(" - ", format);
501 putchar('\n');
502 return success;
503 }
504
505
506 /*
507 * Same as ok(), but takes the format arguments as a va_list.
508 */
509 int
okv(int success,const char * format,va_list args)510 okv(int success, const char *format, va_list args)
511 {
512 fflush(stderr);
513 check_diag_files();
514 printf("%sok %lu", success ? "" : "not ", testnum++);
515 if (!success)
516 _failed++;
517 if (format != NULL) {
518 printf(" - ");
519 vprintf(format, args);
520 }
521 putchar('\n');
522 return success;
523 }
524
525
526 /*
527 * Skip a test.
528 */
529 void
new_skip(const char * reason,...)530 new_skip(const char *reason, ...)
531 {
532 fflush(stderr);
533 check_diag_files();
534 printf("ok %lu # skip", testnum++);
535 PRINT_DESC(" ", reason);
536 putchar('\n');
537 }
538
539
540 /*
541 * Report the same status on the next count tests.
542 */
543 int
new_ok_block(unsigned long count,int success,const char * format,...)544 new_ok_block(unsigned long count, int success, const char *format, ...)
545 {
546 unsigned long i;
547
548 fflush(stderr);
549 check_diag_files();
550 for (i = 0; i < count; i++) {
551 printf("%sok %lu", success ? "" : "not ", testnum++);
552 if (!success)
553 _failed++;
554 PRINT_DESC(" - ", format);
555 putchar('\n');
556 }
557 return success;
558 }
559
560
561 /*
562 * Skip the next count tests.
563 */
564 void
new_skip_block(unsigned long count,const char * reason,...)565 new_skip_block(unsigned long count, const char *reason, ...)
566 {
567 unsigned long i;
568
569 fflush(stderr);
570 check_diag_files();
571 for (i = 0; i < count; i++) {
572 printf("ok %lu # skip", testnum++);
573 PRINT_DESC(" ", reason);
574 putchar('\n');
575 }
576 }
577
578
579 /*
580 * Takes two boolean values and requires the truth value of both match.
581 */
582 int
is_bool(int left,int right,const char * format,...)583 is_bool(int left, int right, const char *format, ...)
584 {
585 int success;
586
587 fflush(stderr);
588 check_diag_files();
589 success = (!!left == !!right);
590 if (success)
591 printf("ok %lu", testnum++);
592 else {
593 diag(" left: %s", !!left ? "true" : "false");
594 diag("right: %s", !!right ? "true" : "false");
595 printf("not ok %lu", testnum++);
596 _failed++;
597 }
598 PRINT_DESC(" - ", format);
599 putchar('\n');
600 return success;
601 }
602
603
604 /*
605 * Takes two integer values and requires they match.
606 */
607 int
is_int(long left,long right,const char * format,...)608 is_int(long left, long right, const char *format, ...)
609 {
610 int success;
611
612 fflush(stderr);
613 check_diag_files();
614 success = (left == right);
615 if (success)
616 printf("ok %lu", testnum++);
617 else {
618 diag(" left: %ld", left);
619 diag("right: %ld", right);
620 printf("not ok %lu", testnum++);
621 _failed++;
622 }
623 PRINT_DESC(" - ", format);
624 putchar('\n');
625 return success;
626 }
627
628
629 /*
630 * Takes two strings and requires they match (using strcmp). NULL arguments
631 * are permitted and handled correctly.
632 */
633 int
is_string(const char * left,const char * right,const char * format,...)634 is_string(const char *left, const char *right, const char *format, ...)
635 {
636 int success;
637
638 fflush(stderr);
639 check_diag_files();
640
641 /* Compare the strings, being careful of NULL. */
642 if (left == NULL)
643 success = (right == NULL);
644 else if (right == NULL)
645 success = 0;
646 else
647 success = (strcmp(left, right) == 0);
648
649 /* Report the results. */
650 if (success)
651 printf("ok %lu", testnum++);
652 else {
653 diag(" left: %s", left == NULL ? "(null)" : left);
654 diag("right: %s", right == NULL ? "(null)" : right);
655 printf("not ok %lu", testnum++);
656 _failed++;
657 }
658 PRINT_DESC(" - ", format);
659 putchar('\n');
660 return success;
661 }
662
663
664 /*
665 * Takes two unsigned longs and requires they match. On failure, reports them
666 * in hex.
667 */
668 int
is_hex(unsigned long left,unsigned long right,const char * format,...)669 is_hex(unsigned long left, unsigned long right, const char *format, ...)
670 {
671 int success;
672
673 fflush(stderr);
674 check_diag_files();
675 success = (left == right);
676 if (success)
677 printf("ok %lu", testnum++);
678 else {
679 diag(" left: %lx", (unsigned long) left);
680 diag("right: %lx", (unsigned long) right);
681 printf("not ok %lu", testnum++);
682 _failed++;
683 }
684 PRINT_DESC(" - ", format);
685 putchar('\n');
686 return success;
687 }
688
689
690 /*
691 * Takes pointers to a regions of memory and requires that len bytes from each
692 * match. Otherwise reports any bytes which didn't match.
693 */
694 int
is_blob(const void * left,const void * right,size_t len,const char * format,...)695 is_blob(const void *left, const void *right, size_t len, const char *format,
696 ...)
697 {
698 int success;
699 size_t i;
700
701 fflush(stderr);
702 check_diag_files();
703 success = (memcmp(left, right, len) == 0);
704 if (success)
705 printf("ok %lu", testnum++);
706 else {
707 const unsigned char *left_c = (const unsigned char *) left;
708 const unsigned char *right_c = (const unsigned char *) right;
709
710 for (i = 0; i < len; i++) {
711 if (left_c[i] != right_c[i])
712 diag("offset %lu: left %02x, right %02x", (unsigned long) i,
713 left_c[i], right_c[i]);
714 }
715 printf("not ok %lu", testnum++);
716 _failed++;
717 }
718 PRINT_DESC(" - ", format);
719 putchar('\n');
720 return success;
721 }
722
723
724 /*
725 * Bail out with an error.
726 */
727 void
bail(const char * format,...)728 bail(const char *format, ...)
729 {
730 va_list args;
731
732 _aborted = 1;
733 fflush(stderr);
734 check_diag_files();
735 fflush(stdout);
736 printf("Bail out! ");
737 va_start(args, format);
738 vprintf(format, args);
739 va_end(args);
740 printf("\n");
741 exit(255);
742 }
743
744
745 /*
746 * Bail out with an error, appending strerror(errno).
747 */
748 void
sysbail(const char * format,...)749 sysbail(const char *format, ...)
750 {
751 va_list args;
752 int oerrno = errno;
753
754 _aborted = 1;
755 fflush(stderr);
756 check_diag_files();
757 fflush(stdout);
758 printf("Bail out! ");
759 va_start(args, format);
760 vprintf(format, args);
761 va_end(args);
762 printf(": %s\n", strerror(oerrno));
763 exit(255);
764 }
765
766
767 /*
768 * Report a diagnostic to stderr. Always returns 1 to allow embedding in
769 * compound statements.
770 */
771 int
diag(const char * format,...)772 diag(const char *format, ...)
773 {
774 va_list args;
775
776 fflush(stderr);
777 check_diag_files();
778 fflush(stdout);
779 printf("# ");
780 va_start(args, format);
781 vprintf(format, args);
782 va_end(args);
783 printf("\n");
784 return 1;
785 }
786
787
788 /*
789 * Report a diagnostic to stderr, appending strerror(errno). Always returns 1
790 * to allow embedding in compound statements.
791 */
792 int
sysdiag(const char * format,...)793 sysdiag(const char *format, ...)
794 {
795 va_list args;
796 int oerrno = errno;
797
798 fflush(stderr);
799 check_diag_files();
800 fflush(stdout);
801 printf("# ");
802 va_start(args, format);
803 vprintf(format, args);
804 va_end(args);
805 printf(": %s\n", strerror(oerrno));
806 return 1;
807 }
808
809
810 /*
811 * Register a new file for diag_file processing.
812 */
813 void
diag_file_add(const char * name)814 diag_file_add(const char *name)
815 {
816 struct diag_file *file, *prev;
817
818 file = bcalloc_type(1, struct diag_file);
819 file->name = bstrdup(name);
820 file->file = fopen(file->name, "r");
821 if (file->file == NULL)
822 sysbail("cannot open %s", name);
823 file->buffer = bcalloc_type(BUFSIZ, char);
824 file->bufsize = BUFSIZ;
825 if (diag_files == NULL)
826 diag_files = file;
827 else {
828 for (prev = diag_files; prev->next != NULL; prev = prev->next)
829 ;
830 prev->next = file;
831 }
832 }
833
834
835 /*
836 * Remove a file from diag_file processing. If the file is not found, do
837 * nothing, since there are some situations where it can be removed twice
838 * (such as if it's removed from a cleanup function, since cleanup functions
839 * are called after freeing all the diag_files).
840 */
841 void
diag_file_remove(const char * name)842 diag_file_remove(const char *name)
843 {
844 struct diag_file *file;
845 struct diag_file **prev = &diag_files;
846
847 for (file = diag_files; file != NULL; file = file->next) {
848 if (strcmp(file->name, name) == 0) {
849 *prev = file->next;
850 fclose(file->file);
851 free(file->name);
852 free(file->buffer);
853 free(file);
854 return;
855 }
856 prev = &file->next;
857 }
858 }
859
860
861 /*
862 * Allocate cleared memory, reporting a fatal error with bail on failure.
863 */
864 void *
bcalloc(size_t n,size_t size)865 bcalloc(size_t n, size_t size)
866 {
867 void *p;
868
869 p = calloc(n, size);
870 if (p == NULL)
871 sysbail("failed to calloc %lu", (unsigned long) (n * size));
872 return p;
873 }
874
875
876 /*
877 * Allocate memory, reporting a fatal error with bail on failure.
878 */
879 void *
bmalloc(size_t size)880 bmalloc(size_t size)
881 {
882 void *p;
883
884 p = malloc(size);
885 if (p == NULL)
886 sysbail("failed to malloc %lu", (unsigned long) size);
887 return p;
888 }
889
890
891 /*
892 * Reallocate memory, reporting a fatal error with bail on failure.
893 */
894 void *
brealloc(void * p,size_t size)895 brealloc(void *p, size_t size)
896 {
897 p = realloc(p, size);
898 if (p == NULL)
899 sysbail("failed to realloc %lu bytes", (unsigned long) size);
900 return p;
901 }
902
903
904 /*
905 * The same as brealloc, but determine the size by multiplying an element
906 * count by a size, similar to calloc. The multiplication is checked for
907 * integer overflow.
908 *
909 * We should technically use SIZE_MAX here for the overflow check, but
910 * SIZE_MAX is C99 and we're only assuming C89 + SUSv3, which does not
911 * guarantee that it exists. They do guarantee that UINT_MAX exists, and we
912 * can assume that UINT_MAX <= SIZE_MAX.
913 *
914 * (In theory, C89 and C99 permit size_t to be smaller than unsigned int, but
915 * I disbelieve in the existence of such systems and they will have to cope
916 * without overflow checks.)
917 */
918 void *
breallocarray(void * p,size_t n,size_t size)919 breallocarray(void *p, size_t n, size_t size)
920 {
921 if (n > 0 && UINT_MAX / n <= size)
922 bail("reallocarray too large");
923 if (n == 0)
924 n = 1;
925 p = realloc(p, n * size);
926 if (p == NULL)
927 sysbail("failed to realloc %lu bytes", (unsigned long) (n * size));
928 return p;
929 }
930
931
932 /*
933 * Copy a string, reporting a fatal error with bail on failure.
934 */
935 char *
bstrdup(const char * s)936 bstrdup(const char *s)
937 {
938 char *p;
939 size_t len;
940
941 len = strlen(s) + 1;
942 p = (char *) malloc(len);
943 if (p == NULL)
944 sysbail("failed to strdup %lu bytes", (unsigned long) len);
945 memcpy(p, s, len);
946 return p;
947 }
948
949
950 /*
951 * Copy up to n characters of a string, reporting a fatal error with bail on
952 * failure. Don't use the system strndup function, since it may not exist and
953 * the TAP library doesn't assume any portability support.
954 */
955 char *
bstrndup(const char * s,size_t n)956 bstrndup(const char *s, size_t n)
957 {
958 const char *p;
959 char *copy;
960 size_t length;
961
962 /* Don't assume that the source string is nul-terminated. */
963 for (p = s; (size_t)(p - s) < n && *p != '\0'; p++)
964 ;
965 length = (size_t)(p - s);
966 copy = (char *) malloc(length + 1);
967 if (copy == NULL)
968 sysbail("failed to strndup %lu bytes", (unsigned long) length);
969 memcpy(copy, s, length);
970 copy[length] = '\0';
971 return copy;
972 }
973
974
975 /*
976 * Locate a test file. Given the partial path to a file, look under
977 * C_TAP_BUILD and then C_TAP_SOURCE for the file and return the full path to
978 * the file. Returns NULL if the file doesn't exist. A non-NULL return
979 * should be freed with test_file_path_free().
980 */
981 char *
test_file_path(const char * file)982 test_file_path(const char *file)
983 {
984 char *base;
985 char *path = NULL;
986 const char *envs[] = {"C_TAP_BUILD", "C_TAP_SOURCE", NULL};
987 int i;
988
989 for (i = 0; envs[i] != NULL; i++) {
990 base = getenv(envs[i]);
991 if (base == NULL)
992 continue;
993 path = concat(base, "/", file, (const char *) 0);
994 if (access(path, R_OK) == 0)
995 break;
996 free(path);
997 path = NULL;
998 }
999 return path;
1000 }
1001
1002
1003 /*
1004 * Free a path returned from test_file_path(). This function exists primarily
1005 * for Windows, where memory must be freed from the same library domain that
1006 * it was allocated from.
1007 */
1008 void
test_file_path_free(char * path)1009 test_file_path_free(char *path)
1010 {
1011 free(path);
1012 }
1013
1014
1015 /*
1016 * Create a temporary directory, tmp, under C_TAP_BUILD if set and the current
1017 * directory if it does not. Returns the path to the temporary directory in
1018 * newly allocated memory, and calls bail on any failure. The return value
1019 * should be freed with test_tmpdir_free.
1020 *
1021 * This function uses sprintf because it attempts to be independent of all
1022 * other portability layers. The use immediately after a memory allocation
1023 * should be safe without using snprintf or strlcpy/strlcat.
1024 */
1025 char *
test_tmpdir(void)1026 test_tmpdir(void)
1027 {
1028 const char *build;
1029 char *path = NULL;
1030
1031 build = getenv("C_TAP_BUILD");
1032 if (build == NULL)
1033 build = ".";
1034 path = concat(build, "/tmp", (const char *) 0);
1035 if (access(path, X_OK) < 0)
1036 if (mkdir(path, 0777) < 0)
1037 sysbail("error creating temporary directory %s", path);
1038 return path;
1039 }
1040
1041
1042 /*
1043 * Free a path returned from test_tmpdir() and attempt to remove the
1044 * directory. If we can't delete the directory, don't worry; something else
1045 * that hasn't yet cleaned up may still be using it.
1046 */
1047 void
test_tmpdir_free(char * path)1048 test_tmpdir_free(char *path)
1049 {
1050 if (path != NULL)
1051 rmdir(path);
1052 free(path);
1053 }
1054
1055 static void
register_cleanup(test_cleanup_func func,test_cleanup_func_with_data func_with_data,void * data)1056 register_cleanup(test_cleanup_func func,
1057 test_cleanup_func_with_data func_with_data, void *data)
1058 {
1059 struct cleanup_func *cleanup, **last;
1060
1061 cleanup = bcalloc_type(1, struct cleanup_func);
1062 cleanup->func = func;
1063 cleanup->func_with_data = func_with_data;
1064 cleanup->data = data;
1065 cleanup->next = NULL;
1066 last = &cleanup_funcs;
1067 while (*last != NULL)
1068 last = &(*last)->next;
1069 *last = cleanup;
1070 }
1071
1072 /*
1073 * Register a cleanup function that is called when testing ends. All such
1074 * registered functions will be run by finish.
1075 */
1076 void
test_cleanup_register(test_cleanup_func func)1077 test_cleanup_register(test_cleanup_func func)
1078 {
1079 register_cleanup(func, NULL, NULL);
1080 }
1081
1082 /*
1083 * Same as above, but also allows an opaque pointer to be passed to the cleanup
1084 * function.
1085 */
1086 void
test_cleanup_register_with_data(test_cleanup_func_with_data func,void * data)1087 test_cleanup_register_with_data(test_cleanup_func_with_data func, void *data)
1088 {
1089 register_cleanup(NULL, func, data);
1090 }
1091