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