xref: /titanic_41/usr/src/cmd/sort/common/initialize.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
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