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
set_signal_jmp(void)50 set_signal_jmp(void)
51 {
52 if (sigsetjmp(signal_jmp_buf, 1))
53 exit(127 + signal_delivered);
54 }
55
56 static void
sig_handler(int signo)57 sig_handler(int signo)
58 {
59 signal_delivered = signo;
60 siglongjmp(signal_jmp_buf, 1);
61 }
62
63 void
initialize_pre(sort_t * S)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
initialize_post(sort_t * S)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