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 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include "initialize.h" 30 31 #ifndef TEXT_DOMAIN 32 /* 33 * TEXT_DOMAIN should have been set by build environment. 34 */ 35 #define TEXT_DOMAIN "SUNW_OST_OSCMD" 36 #endif /* TEXT_DOMAIN */ 37 38 /* 39 * /dev/zero, output file, stdin, stdout, and stderr 40 */ 41 #define N_FILES_ALREADY_OPEN 5 42 43 static const char *filename_stdin = "STDIN"; 44 const char *filename_stdout = "STDOUT"; 45 46 static sigjmp_buf signal_jmp_buf; 47 static volatile sig_atomic_t signal_delivered; 48 49 static void 50 set_signal_jmp(void) 51 { 52 if (sigsetjmp(signal_jmp_buf, 1)) 53 exit(127 + signal_delivered); 54 } 55 56 static void 57 sig_handler(int signo) 58 { 59 signal_delivered = signo; 60 siglongjmp(signal_jmp_buf, 1); 61 } 62 63 void 64 initialize_pre(sort_t *S) 65 { 66 /* 67 * Initialize sort structure. 68 */ 69 (void) memset(S, 0, sizeof (sort_t)); 70 71 S->m_stats = safe_realloc(NULL, sizeof (sort_statistics_t)); 72 __S(stats_init(S->m_stats)); 73 74 S->m_default_species = ALPHA; 75 76 /* 77 * Simple localization issues. 78 */ 79 (void) setlocale(LC_ALL, ""); 80 (void) textdomain(TEXT_DOMAIN); 81 82 #ifndef DEBUG_FORCE_WIDE 83 S->m_c_locale = xstreql("C", setlocale(LC_COLLATE, NULL)); 84 S->m_single_byte_locale = SGN(MB_CUR_MAX == 1); 85 #else /* DEBUG_FORCE_WIDE */ 86 S->m_c_locale = 0; 87 S->m_single_byte_locale = 0; 88 #endif /* DEBUG_FORCE_WIDE */ 89 90 /* 91 * We use a constant seed so that our sorts on a given file are 92 * reproducible. 93 */ 94 srand(3459871433U); 95 96 if (atexit(atexit_handler) < 0) 97 warn(gettext("atexit() handler installation failed")); 98 99 /* 100 * Establish signal handlers and sufficient state for clean up. 101 */ 102 if (signal(SIGTERM, sig_handler) == SIG_ERR) 103 die(EMSG_SIGNAL, "SIGTERM"); 104 if (signal(SIGHUP, sig_handler) == SIG_ERR) 105 die(EMSG_SIGNAL, "SIGHUP"); 106 if (signal(SIGPIPE, sig_handler) == SIG_ERR) 107 die(EMSG_SIGNAL, "SIGPIPE"); 108 109 set_signal_jmp(); 110 } 111 112 void 113 initialize_post(sort_t *S) 114 { 115 field_t *F; 116 117 S->m_memory_available = available_memory(S->m_memory_limit); 118 119 set_file_template(&S->m_tmpdir_template); 120 121 /* 122 * Initialize locale-specific ops vectors. 123 */ 124 field_initialize(S); 125 126 if (S->m_single_byte_locale) { 127 S->m_compare_fn = (cmp_fcn_t)strcoll; 128 S->m_coll_convert = field_convert; 129 F = S->m_fields_head; 130 131 while (F != NULL) { 132 switch (F->f_species) { 133 case ALPHA: 134 if (F->f_options & 135 (FIELD_IGNORE_NONPRINTABLES | 136 FIELD_DICTIONARY_ORDER | 137 FIELD_FOLD_UPPERCASE)) 138 F->f_convert = field_convert_alpha; 139 else 140 F->f_convert = 141 field_convert_alpha_simple; 142 break; 143 case NUMERIC: 144 F->f_convert = field_convert_numeric; 145 break; 146 case MONTH: 147 F->f_convert = field_convert_month; 148 break; 149 default: 150 die(EMSG_UNKN_FIELD, F->f_species); 151 break; 152 } 153 F = F->f_next; 154 } 155 } else { 156 S->m_compare_fn = (cmp_fcn_t)wcscoll; 157 S->m_coll_convert = field_convert_wide; 158 159 F = S->m_fields_head; 160 while (F != NULL) { 161 switch (F->f_species) { 162 case ALPHA: 163 F->f_convert = field_convert_alpha_wide; 164 break; 165 case NUMERIC: 166 F->f_convert = 167 field_convert_numeric_wide; 168 break; 169 case MONTH: 170 F->f_convert = field_convert_month_wide; 171 break; 172 default: 173 die(EMSG_UNKN_FIELD, F->f_species); 174 break; 175 } 176 F = F->f_next; 177 } 178 } 179 180 /* 181 * Validate and obtain sizes, inodes for input streams. 182 */ 183 stream_stat_chain(S->m_input_streams); 184 __S(stats_set_input_files(stream_count_chain(S->m_input_streams))); 185 186 /* 187 * Output guard. 188 */ 189 establish_output_guard(S); 190 191 /* 192 * Ready stdin for usage as stream. 193 */ 194 if (S->m_input_from_stdin) { 195 stream_t *str; 196 197 if (S->m_single_byte_locale) { 198 str = stream_new(STREAM_SINGLE | STREAM_NOTFILE); 199 str->s_element_size = sizeof (char); 200 } else { 201 str = stream_new(STREAM_WIDE | STREAM_NOTFILE); 202 str->s_element_size = sizeof (wchar_t); 203 } 204 str->s_filename = (char *)filename_stdin; 205 stream_push_to_chain(&S->m_input_streams, str); 206 __S(stats_incr_input_files()); 207 } 208 } 209