1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright 2020 Richard Hansen <rhansen@rhansen.org> 14 */ 15 16 #include <errno.h> 17 #include <libintl.h> 18 #include <stdbool.h> 19 #include <stdio.h> 20 #include <string.h> 21 #include <sys/sysmacros.h> 22 #include <umem.h> 23 #include <unistd.h> 24 #include "test_common.h" 25 26 const char * 27 _umem_debug_init(void) 28 { 29 return ("default"); 30 } 31 32 int 33 main(int argc, char *argv[]) 34 { 35 int ret = 0; 36 int optc; 37 while ((optc = getopt(argc, argv, "df")) != -1) { 38 switch (optc) { 39 case 'd': 40 test_set_debug(); 41 break; 42 case 'f': 43 test_set_force(); 44 break; 45 default: 46 (void) fprintf(stderr, "Usage: %s [-df]\n", argv[0]); 47 exit(1); 48 } 49 } 50 51 struct { 52 const char *name; 53 const char *dir; 54 bool malloc_fail; 55 const char *want; 56 int want_errno; 57 } test_cases[] = { 58 { 59 .name = "unbound query", 60 .dir = NULL, 61 .want = "/usr/lib/locale/", 62 }, 63 { 64 .name = "bind malloc fail", 65 .dir = "/bounddir1", 66 .malloc_fail = true, 67 .want = NULL, 68 .want_errno = EAGAIN, 69 }, 70 { 71 .name = "query after bind malloc fail", 72 .dir = NULL, 73 .want = "/usr/lib/locale/", 74 }, 75 { 76 .name = "normal bind", 77 .dir = "/bounddir2", 78 .want = "/bounddir2", 79 }, 80 { 81 .name = "query after normal bind", 82 .dir = NULL, 83 .want = "/bounddir2", 84 }, 85 { 86 .name = "rebind to same", 87 .dir = "/bounddir2", 88 .want = "/bounddir2", 89 }, 90 { 91 .name = "query after rebind to same", 92 .dir = NULL, 93 .want = "/bounddir2", 94 }, 95 { 96 .name = "rebind to new", 97 .dir = "/bounddir3", 98 .want = "/bounddir3", 99 }, 100 { 101 .name = "query after rebind to new", 102 .dir = NULL, 103 .want = "/bounddir3", 104 }, 105 { 106 .name = "rebind malloc fail", 107 .dir = "/bounddir4", 108 .malloc_fail = true, 109 .want = NULL, 110 .want_errno = EAGAIN, 111 }, 112 { 113 .name = "query after rebind malloc fail", 114 .dir = NULL, 115 .want = "/bounddir3", 116 }, 117 }, *tc; 118 119 for (size_t i = 0; i < ARRAY_SIZE(test_cases); ++i) { 120 tc = &test_cases[i]; 121 test_t t = test_start(tc->name); 122 umem_setmtbf((uint_t)tc->malloc_fail); 123 errno = 0; 124 const char *got = bindtextdomain("domain", tc->dir); 125 int got_errno = errno; 126 umem_setmtbf(0); 127 if (((got == NULL) != (tc->want == NULL)) || 128 ((got != NULL) && strcmp(got, tc->want))) { 129 test_failed(t, "returned %s, want %s", 130 got != NULL ? got : "<NULL>", 131 tc->want != NULL ? tc->want : "<NULL>"); 132 ret = 1; 133 } 134 if (got_errno != tc->want_errno) { 135 test_failed(t, "got errno %d, want %d", 136 got_errno, tc->want_errno); 137 ret = 1; 138 } 139 test_passed(t); 140 } 141 test_summary(); 142 return (ret); 143 } 144