t_openpam_readword.c revision 236099
1/*- 2 * Copyright (c) 2012 Dag-Erling Sm��rgrav 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer 10 * in this position and unchanged. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote 15 * products derived from this software without specific prior written 16 * permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 * $Id: t_openpam_readword.c 584 2012-04-07 22:47:16Z des $ 31 */ 32 33#ifdef HAVE_CONFIG_H 34# include "config.h" 35#endif 36 37#include <err.h> 38#include <errno.h> 39#include <fcntl.h> 40#include <stdio.h> 41#include <stdlib.h> 42#include <string.h> 43#include <unistd.h> 44 45#include <security/pam_appl.h> 46#include <security/openpam.h> 47 48#include "t.h" 49 50static char filename[1024]; 51static FILE *f; 52 53/* 54 * Open the temp file and immediately unlink it so it doesn't leak in case 55 * of premature exit. 56 */ 57static void 58orw_open(void) 59{ 60 int fd; 61 62 if ((fd = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0600)) < 0) 63 err(1, "%s(): %s", __func__, filename); 64 if ((f = fdopen(fd, "r+")) == NULL) 65 err(1, "%s(): %s", __func__, filename); 66 if (unlink(filename) < 0) 67 err(1, "%s(): %s", __func__, filename); 68} 69 70/* 71 * Write text to the temp file. 72 */ 73static void 74orw_output(const char *fmt, ...) 75{ 76 va_list ap; 77 78 va_start(ap, fmt); 79 vfprintf(f, fmt, ap); 80 va_end(ap); 81 if (ferror(f)) 82 err(1, "%s", filename); 83} 84 85/* 86 * Rewind the temp file. 87 */ 88static void 89orw_rewind(void) 90{ 91 92 errno = 0; 93 rewind(f); 94 if (errno != 0) 95 err(1, "%s(): %s", __func__, filename); 96} 97 98/* 99 * Read a word from the temp file and verify that the result matches our 100 * expectations: whether a word was read at all, how many lines were read 101 * (in case of quoted or escaped newlines), whether we reached the end of 102 * the file and whether we reached the end of the line. 103 */ 104static int 105orw_expect(const char *expected, int lines, int eof, int eol) 106{ 107 int ch, lineno = 0; 108 char *got; 109 size_t len; 110 111 got = openpam_readword(f, &lineno, &len); 112 if (ferror(f)) 113 err(1, "%s(): %s", __func__, filename); 114 if (expected != NULL && got == NULL) { 115 t_verbose("expected <<%s>>, got nothing\n", expected); 116 return (0); 117 } 118 if (expected == NULL && got != NULL) { 119 t_verbose("expected nothing, got <<%s>>\n", got); 120 return (0); 121 } 122 if (expected != NULL && got != NULL && strcmp(expected, got) != 0) { 123 t_verbose("expected <<%s>>, got <<%s>>\n", expected, got); 124 return (0); 125 } 126 if (lineno != lines) { 127 t_verbose("expected to advance %d lines, advanced %d lines\n", 128 lines, lineno); 129 return (0); 130 } 131 if (eof && !feof(f)) { 132 t_verbose("expected EOF, but didn't get it\n"); 133 return (0); 134 } 135 if (!eof && feof(f)) { 136 t_verbose("didn't expect EOF, but got it anyway\n"); 137 return (0); 138 } 139 ch = fgetc(f); 140 if (ferror(f)) 141 err(1, "%s(): %s", __func__, filename); 142 if (eol && ch != '\n') { 143 t_verbose("expected EOL, but didn't get it\n"); 144 return (0); 145 } 146 if (!eol && ch == '\n') { 147 t_verbose("didn't expect EOL, but got it anyway\n"); 148 return (0); 149 } 150 if (ch != EOF) 151 ungetc(ch, f); 152 return (1); 153} 154 155/* 156 * Close the temp file. 157 */ 158void 159orw_close(void) 160{ 161 162 if (fclose(f) != 0) 163 err(1, "%s(): %s", __func__, filename); 164 f = NULL; 165} 166 167 168/*************************************************************************** 169 * Lines without words 170 */ 171 172T_FUNC(empty_input, "empty input") 173{ 174 int ret; 175 176 orw_open(); 177 ret = orw_expect(NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/); 178 orw_close(); 179 return (ret); 180} 181 182T_FUNC(empty_line, "empty line") 183{ 184 int ret; 185 186 orw_open(); 187 orw_output("\n"); 188 orw_rewind(); 189 ret = orw_expect(NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 190 orw_close(); 191 return (ret); 192} 193 194T_FUNC(unterminated_line, "unterminated line") 195{ 196 int ret; 197 198 orw_open(); 199 orw_output(" "); 200 orw_rewind(); 201 ret = orw_expect(NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/); 202 orw_close(); 203 return (ret); 204} 205 206T_FUNC(single_whitespace, "single whitespace") 207{ 208 int ret; 209 210 orw_open(); 211 orw_output(" \n"); 212 orw_rewind(); 213 ret = orw_expect(NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 214 orw_close(); 215 return (ret); 216} 217 218T_FUNC(multiple_whitespace, "multiple whitespace") 219{ 220 int ret; 221 222 orw_open(); 223 orw_output(" \t\r\n"); 224 orw_rewind(); 225 ret = orw_expect(NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 226 orw_close(); 227 return (ret); 228} 229 230T_FUNC(comment, "comment") 231{ 232 int ret; 233 234 orw_open(); 235 orw_output("# comment\n"); 236 orw_rewind(); 237 ret = orw_expect(NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 238 orw_close(); 239 return (ret); 240} 241 242T_FUNC(whitespace_before_comment, "whitespace before comment") 243{ 244 int ret; 245 246 orw_open(); 247 orw_output(" # comment\n"); 248 orw_rewind(); 249 ret = orw_expect(NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 250 orw_close(); 251 return (ret); 252} 253 254 255/*************************************************************************** 256 * Simple cases - no quotes or escapes 257 */ 258 259T_FUNC(single_word, "single word") 260{ 261 const char *word = "hello"; 262 int ret; 263 264 orw_open(); 265 orw_output("%s\n", word); 266 orw_rewind(); 267 ret = orw_expect(word, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 268 orw_close(); 269 return (ret); 270} 271 272T_FUNC(single_whitespace_before_word, "single whitespace before word") 273{ 274 const char *word = "hello"; 275 int ret; 276 277 orw_open(); 278 orw_output(" %s\n", word); 279 orw_rewind(); 280 ret = orw_expect(word, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 281 orw_close(); 282 return (ret); 283} 284 285T_FUNC(double_whitespace_before_word, "double whitespace before word") 286{ 287 const char *word = "hello"; 288 int ret; 289 290 orw_open(); 291 orw_output(" %s\n", word); 292 orw_rewind(); 293 ret = orw_expect(word, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 294 orw_close(); 295 return (ret); 296} 297 298T_FUNC(single_whitespace_after_word, "single whitespace after word") 299{ 300 const char *word = "hello"; 301 int ret; 302 303 orw_open(); 304 orw_output("%s \n", word); 305 orw_rewind(); 306 ret = orw_expect(word, 0 /*lines*/, 0 /*eof*/, 0 /*eol*/); 307 orw_close(); 308 return (ret); 309} 310 311T_FUNC(double_whitespace_after_word, "double whitespace after word") 312{ 313 const char *word = "hello"; 314 int ret; 315 316 orw_open(); 317 orw_output("%s \n", word); 318 orw_rewind(); 319 ret = orw_expect(word, 0 /*lines*/, 0 /*eof*/, 0 /*eol*/); 320 orw_close(); 321 return (ret); 322} 323 324T_FUNC(comment_after_word, "comment after word") 325{ 326 const char *word = "hello"; 327 int ret; 328 329 orw_open(); 330 orw_output("%s # comment\n", word); 331 orw_rewind(); 332 ret = orw_expect(word, 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && 333 orw_expect(NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 334 orw_close(); 335 return (ret); 336} 337 338T_FUNC(word_containing_hash, "word containing hash") 339{ 340 const char *word = "hello#world"; 341 int ret; 342 343 orw_open(); 344 orw_output("%s\n", word); 345 orw_rewind(); 346 ret = orw_expect(word, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 347 orw_close(); 348 return (ret); 349} 350 351T_FUNC(two_words, "two words") 352{ 353 const char *word[] = { "hello", "world" }; 354 int ret; 355 356 orw_open(); 357 orw_output("%s %s\n", word[0], word[1]); 358 orw_rewind(); 359 ret = orw_expect(word[0], 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && 360 orw_expect(word[1], 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 361 orw_close(); 362 return (ret); 363} 364 365 366/*************************************************************************** 367 * Escapes 368 */ 369 370T_FUNC(naked_escape, "naked escape") 371{ 372 int ret; 373 374 orw_open(); 375 orw_output("\\"); 376 orw_rewind(); 377 ret = orw_expect(NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/); 378 orw_close(); 379 return (ret); 380} 381 382T_FUNC(escaped_escape, "escaped escape") 383{ 384 int ret; 385 386 orw_open(); 387 orw_output("\\\\\n"); 388 orw_rewind(); 389 ret = orw_expect("\\", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 390 orw_close(); 391 return (ret); 392} 393 394T_FUNC(escaped_whitespace, "escaped whitespace") 395{ 396 int ret; 397 398 orw_open(); 399 orw_output("\\ \\\t \\\r \\\n\n"); 400 orw_rewind(); 401 ret = orw_expect(" ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && 402 orw_expect("\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && 403 orw_expect("\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && 404 /* this last one is a line continuation */ 405 orw_expect(NULL, 1 /*lines*/, 0 /*eof*/, 1 /*eol*/); 406 orw_close(); 407 return (ret); 408} 409 410T_FUNC(escaped_newline_before_word, "escaped newline before word") 411{ 412 int ret; 413 414 orw_open(); 415 orw_output("\\\nhello world\n"); 416 orw_rewind(); 417 ret = orw_expect("hello", 1 /*lines*/, 0 /*eof*/, 0 /*eol*/); 418 orw_close(); 419 return (ret); 420} 421 422T_FUNC(escaped_newline_within_word, "escaped newline within word") 423{ 424 int ret; 425 426 orw_open(); 427 orw_output("hello\\\nworld\n"); 428 orw_rewind(); 429 ret = orw_expect("helloworld", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/); 430 orw_close(); 431 return (ret); 432} 433 434T_FUNC(escaped_newline_after_word, "escaped newline after word") 435{ 436 int ret; 437 438 orw_open(); 439 orw_output("hello\\\n world\n"); 440 orw_rewind(); 441 ret = orw_expect("hello", 1 /*lines*/, 0 /*eof*/, 0 /*eol*/); 442 orw_close(); 443 return (ret); 444} 445 446T_FUNC(escaped_letter, "escaped letter") 447{ 448 int ret; 449 450 orw_open(); 451 orw_output("\\z\n"); 452 orw_rewind(); 453 ret = orw_expect("z", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 454 orw_close(); 455 return (ret); 456} 457 458 459/*************************************************************************** 460 * Quotes 461 */ 462 463T_FUNC(naked_single_quote, "naked single quote") 464{ 465 int ret; 466 467 orw_open(); 468 orw_output("'"); 469 orw_rewind(); 470 ret = orw_expect(NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/); 471 orw_close(); 472 return (ret); 473} 474 475T_FUNC(naked_double_quote, "naked double quote") 476{ 477 int ret; 478 479 orw_open(); 480 orw_output("\""); 481 orw_rewind(); 482 ret = orw_expect(NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/); 483 orw_close(); 484 return (ret); 485} 486 487T_FUNC(empty_single_quotes, "empty single quotes") 488{ 489 int ret; 490 491 orw_open(); 492 orw_output("''\n"); 493 orw_rewind(); 494 ret = orw_expect("", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 495 orw_close(); 496 return (ret); 497} 498 499T_FUNC(empty_double_quotes, "empty double quotes") 500{ 501 int ret; 502 503 orw_open(); 504 orw_output("\"\"\n"); 505 orw_rewind(); 506 ret = orw_expect("", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 507 orw_close(); 508 return (ret); 509} 510 511T_FUNC(single_quotes_within_double_quotes, "single quotes within double quotes") 512{ 513 int ret; 514 515 orw_open(); 516 orw_output("\"' '\"\n"); 517 orw_rewind(); 518 ret = orw_expect("' '", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 519 orw_close(); 520 return (ret); 521} 522 523T_FUNC(double_quotes_within_single_quotes, "double quotes within single quotes") 524{ 525 int ret; 526 527 orw_open(); 528 orw_output("'\" \"'\n"); 529 orw_rewind(); 530 ret = orw_expect("\" \"", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 531 orw_close(); 532 return (ret); 533} 534 535T_FUNC(single_quoted_whitespace, "single-quoted whitespace") 536{ 537 int ret; 538 539 orw_open(); 540 orw_output("' ' '\t' '\r' '\n'\n"); 541 orw_rewind(); 542 ret = orw_expect(" ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && 543 orw_expect("\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && 544 orw_expect("\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && 545 orw_expect("\n", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/); 546 orw_close(); 547 return (ret); 548} 549 550T_FUNC(double_quoted_whitespace, "double-quoted whitespace") 551{ 552 int ret; 553 554 orw_open(); 555 orw_output("\" \" \"\t\" \"\r\" \"\n\"\n"); 556 orw_rewind(); 557 ret = orw_expect(" ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && 558 orw_expect("\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && 559 orw_expect("\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && 560 orw_expect("\n", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/); 561 orw_close(); 562 return (ret); 563} 564 565T_FUNC(single_quoted_words, "single-quoted words") 566{ 567 int ret; 568 569 orw_open(); 570 orw_output("'hello world'\n"); 571 orw_rewind(); 572 ret = orw_expect("hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 573 orw_close(); 574 return (ret); 575} 576 577T_FUNC(double_quoted_words, "double-quoted words") 578{ 579 int ret; 580 581 orw_open(); 582 orw_output("\"hello world\"\n"); 583 orw_rewind(); 584 ret = orw_expect("hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 585 orw_close(); 586 return (ret); 587} 588 589 590/*************************************************************************** 591 * Combinations of escape and quotes 592 */ 593 594T_FUNC(escaped_single_quote, 595 "escaped single quote") 596{ 597 int ret; 598 599 orw_open(); 600 orw_output("\\'\n"); 601 orw_rewind(); 602 ret = orw_expect("'", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 603 orw_close(); 604 return (ret); 605} 606 607T_FUNC(escaped_double_quote, 608 "escaped double quote") 609{ 610 int ret; 611 612 orw_open(); 613 orw_output("\\\"\n"); 614 orw_rewind(); 615 ret = orw_expect("\"", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 616 orw_close(); 617 return (ret); 618} 619 620T_FUNC(escaped_whitespace_within_single_quotes, 621 "escaped whitespace within single quotes") 622{ 623 int ret; 624 625 orw_open(); 626 orw_output("'\\ ' '\\\t' '\\\r' '\\\n'\n"); 627 orw_rewind(); 628 ret = orw_expect("\\ ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && 629 orw_expect("\\\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && 630 orw_expect("\\\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && 631 orw_expect("\\\n", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/); 632 orw_close(); 633 return (ret); 634} 635 636T_FUNC(escaped_whitespace_within_double_quotes, 637 "escaped whitespace within double quotes") 638{ 639 int ret; 640 641 orw_open(); 642 orw_output("\"\\ \" \"\\\t\" \"\\\r\" \"\\\n\"\n"); 643 orw_rewind(); 644 ret = orw_expect("\\ ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && 645 orw_expect("\\\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && 646 orw_expect("\\\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) && 647 /* this last one is a line continuation */ 648 orw_expect("", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/); 649 orw_close(); 650 return (ret); 651} 652 653T_FUNC(escaped_letter_within_single_quotes, 654 "escaped letter within single quotes") 655{ 656 int ret; 657 658 orw_open(); 659 orw_output("'\\z'\n"); 660 orw_rewind(); 661 ret = orw_expect("\\z", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 662 orw_close(); 663 return (ret); 664} 665 666T_FUNC(escaped_letter_within_double_quotes, 667 "escaped letter within double quotes") 668{ 669 int ret; 670 671 orw_open(); 672 orw_output("\"\\z\"\n"); 673 orw_rewind(); 674 ret = orw_expect("\\z", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 675 orw_close(); 676 return (ret); 677} 678 679T_FUNC(escaped_escape_within_single_quotes, 680 "escaped escape within single quotes") 681{ 682 int ret; 683 684 orw_open(); 685 orw_output("'\\\\'\n"); 686 orw_rewind(); 687 ret = orw_expect("\\\\", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 688 orw_close(); 689 return (ret); 690} 691 692T_FUNC(escaped_escape_within_double_quotes, 693 "escaped escape within double quotes") 694{ 695 int ret; 696 697 orw_open(); 698 orw_output("\"\\\\\"\n"); 699 orw_rewind(); 700 ret = orw_expect("\\", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 701 orw_close(); 702 return (ret); 703} 704 705T_FUNC(escaped_single_quote_within_single_quotes, 706 "escaped single quote within single quotes") 707{ 708 int ret; 709 710 orw_open(); 711 orw_output("'\\''\n"); 712 orw_rewind(); 713 ret = orw_expect(NULL, 1 /*lines*/, 1 /*eof*/, 0 /*eol*/); 714 orw_close(); 715 return (ret); 716} 717 718T_FUNC(escaped_double_quote_within_single_quotes, 719 "escaped double quote within single quotes") 720{ 721 int ret; 722 723 orw_open(); 724 orw_output("'\\\"'\n"); 725 orw_rewind(); 726 ret = orw_expect("\\\"", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 727 orw_close(); 728 return (ret); 729} 730 731T_FUNC(escaped_single_quote_within_double_quotes, 732 "escaped single quote within double quotes") 733{ 734 int ret; 735 736 orw_open(); 737 orw_output("\"\\'\"\n"); 738 orw_rewind(); 739 ret = orw_expect("\\'", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 740 orw_close(); 741 return (ret); 742} 743 744T_FUNC(escaped_double_quote_within_double_quotes, 745 "escaped double quote within double quotes") 746{ 747 int ret; 748 749 orw_open(); 750 orw_output("\"\\\"\"\n"); 751 orw_rewind(); 752 ret = orw_expect("\"", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/); 753 orw_close(); 754 return (ret); 755} 756 757 758/*************************************************************************** 759 * Boilerplate 760 */ 761 762const struct t_test *t_plan[] = { 763 T(empty_input), 764 T(empty_line), 765 T(single_whitespace), 766 T(multiple_whitespace), 767 T(comment), 768 T(whitespace_before_comment), 769 770 T(single_word), 771 T(single_whitespace_before_word), 772 T(double_whitespace_before_word), 773 T(single_whitespace_after_word), 774 T(double_whitespace_after_word), 775 T(comment_after_word), 776 T(word_containing_hash), 777 T(two_words), 778 779 T(naked_escape), 780 T(escaped_escape), 781 T(escaped_whitespace), 782 T(escaped_newline_before_word), 783 T(escaped_newline_within_word), 784 T(escaped_newline_after_word), 785 T(escaped_letter), 786 787 T(naked_single_quote), 788 T(naked_double_quote), 789 T(empty_single_quotes), 790 T(empty_double_quotes), 791 T(single_quotes_within_double_quotes), 792 T(double_quotes_within_single_quotes), 793 T(single_quoted_whitespace), 794 T(double_quoted_whitespace), 795 T(single_quoted_words), 796 T(double_quoted_words), 797 798 T(escaped_single_quote), 799 T(escaped_double_quote), 800 T(escaped_whitespace_within_single_quotes), 801 T(escaped_whitespace_within_double_quotes), 802 T(escaped_letter_within_single_quotes), 803 T(escaped_letter_within_double_quotes), 804 T(escaped_escape_within_single_quotes), 805 T(escaped_escape_within_double_quotes), 806 T(escaped_single_quote_within_single_quotes), 807 T(escaped_double_quote_within_single_quotes), 808 T(escaped_single_quote_within_double_quotes), 809 T(escaped_double_quote_within_double_quotes), 810 811 NULL 812}; 813 814const struct t_test ** 815t_prepare(int argc, char *argv[]) 816{ 817 818 (void)argc; 819 (void)argv; 820 snprintf(filename, sizeof filename, "%s.%d.tmp", t_progname, getpid()); 821 if (filename == NULL) 822 err(1, "asprintf()"); 823 return (t_plan); 824} 825 826void 827t_cleanup(void) 828{ 829} 830