1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 1998-2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include "initialize.h" 28 29 #ifndef TEXT_DOMAIN 30 /* 31 * TEXT_DOMAIN should have been set by build environment. 32 */ 33 #define TEXT_DOMAIN "SUNW_OST_OSCMD" 34 #endif /* TEXT_DOMAIN */ 35 36 /* 37 * /dev/zero, output file, stdin, stdout, and stderr 38 */ 39 #define N_FILES_ALREADY_OPEN 5 40 41 static const char *filename_stdin = "STDIN"; 42 const char *filename_stdout = "STDOUT"; 43 44 static sigjmp_buf signal_jmp_buf; 45 static volatile sig_atomic_t signal_delivered; 46 47 static void 48 set_signal_jmp(void) 49 { 50 if (sigsetjmp(signal_jmp_buf, 1)) 51 exit(127 + signal_delivered); 52 } 53 54 static void 55 sig_handler(int signo) 56 { 57 signal_delivered = signo; 58 siglongjmp(signal_jmp_buf, 1); 59 } 60 61 void 62 initialize_pre(sort_t *S) 63 { 64 /* 65 * Initialize sort structure. 66 */ 67 (void) memset(S, 0, sizeof (sort_t)); 68 69 S->m_stats = safe_realloc(NULL, sizeof (sort_statistics_t)); 70 __S(stats_init(S->m_stats)); 71 72 S->m_default_species = ALPHA; 73 74 /* 75 * Simple localization issues. 76 */ 77 (void) setlocale(LC_ALL, ""); 78 (void) textdomain(TEXT_DOMAIN); 79 80 #ifndef DEBUG_FORCE_WIDE 81 S->m_c_locale = xstreql("C", setlocale(LC_COLLATE, NULL)); 82 S->m_single_byte_locale = SGN(MB_CUR_MAX == 1); 83 #else /* DEBUG_FORCE_WIDE */ 84 S->m_c_locale = 0; 85 S->m_single_byte_locale = 0; 86 #endif /* DEBUG_FORCE_WIDE */ 87 88 /* 89 * We use a constant seed so that our sorts on a given file are 90 * reproducible. 91 */ 92 srand(3459871433U); 93 94 if (atexit(atexit_handler) < 0) 95 warn(gettext("atexit() handler installation failed")); 96 97 /* 98 * Establish signal handlers and sufficient state for clean up. 99 */ 100 if (signal(SIGTERM, sig_handler) == SIG_ERR) 101 die(EMSG_SIGNAL, "SIGTERM"); 102 if (signal(SIGHUP, sig_handler) == SIG_ERR) 103 die(EMSG_SIGNAL, "SIGHUP"); 104 if (signal(SIGPIPE, sig_handler) == SIG_ERR) 105 die(EMSG_SIGNAL, "SIGPIPE"); 106 107 set_signal_jmp(); 108 } 109 110 static int 111 strcoll_cmp(void *s1, void *s2, flag_t f __unused) 112 { 113 return (strcoll(s1, s2)); 114 } 115 116 static int 117 wcscoll_cmp(void *s1, void *s2, flag_t f __unused) 118 { 119 return (wcscoll(s1, s2)); 120 } 121 122 void 123 initialize_post(sort_t *S) 124 { 125 field_t *F; 126 127 S->m_memory_available = available_memory(S->m_memory_limit); 128 129 set_file_template(&S->m_tmpdir_template); 130 131 /* 132 * Initialize locale-specific ops vectors. 133 */ 134 field_initialize(S); 135 136 if (S->m_single_byte_locale) { 137 S->m_compare_fn = strcoll_cmp; 138 S->m_coll_convert = field_convert; 139 F = S->m_fields_head; 140 141 while (F != NULL) { 142 switch (F->f_species) { 143 case ALPHA: 144 if (F->f_options & 145 (FIELD_IGNORE_NONPRINTABLES | 146 FIELD_DICTIONARY_ORDER | 147 FIELD_FOLD_UPPERCASE)) 148 F->f_convert = field_convert_alpha; 149 else 150 F->f_convert = 151 field_convert_alpha_simple; 152 break; 153 case NUMERIC: 154 F->f_convert = field_convert_numeric; 155 break; 156 case MONTH: 157 F->f_convert = field_convert_month; 158 break; 159 default: 160 die(EMSG_UNKN_FIELD, F->f_species); 161 break; 162 } 163 F = F->f_next; 164 } 165 } else { 166 S->m_compare_fn = wcscoll_cmp; 167 S->m_coll_convert = field_convert_wide; 168 169 F = S->m_fields_head; 170 while (F != NULL) { 171 switch (F->f_species) { 172 case ALPHA: 173 F->f_convert = field_convert_alpha_wide; 174 break; 175 case NUMERIC: 176 F->f_convert = 177 field_convert_numeric_wide; 178 break; 179 case MONTH: 180 F->f_convert = field_convert_month_wide; 181 break; 182 default: 183 die(EMSG_UNKN_FIELD, F->f_species); 184 break; 185 } 186 F = F->f_next; 187 } 188 } 189 190 /* 191 * Validate and obtain sizes, inodes for input streams. 192 */ 193 stream_stat_chain(S->m_input_streams); 194 __S(stats_set_input_files(stream_count_chain(S->m_input_streams))); 195 196 /* 197 * Output guard. 198 */ 199 establish_output_guard(S); 200 201 /* 202 * Ready stdin for usage as stream. 203 */ 204 if (S->m_input_from_stdin) { 205 stream_t *str; 206 207 if (S->m_single_byte_locale) { 208 str = stream_new(STREAM_SINGLE | STREAM_NOTFILE); 209 str->s_element_size = sizeof (char); 210 } else { 211 str = stream_new(STREAM_WIDE | STREAM_NOTFILE); 212 str->s_element_size = sizeof (wchar_t); 213 } 214 str->s_filename = (char *)filename_stdin; 215 stream_push_to_chain(&S->m_input_streams, str); 216 __S(stats_incr_input_files()); 217 } 218 } 219