1*10d63b7dSRichard Lowe /*
2*10d63b7dSRichard Lowe * CDDL HEADER START
3*10d63b7dSRichard Lowe *
4*10d63b7dSRichard Lowe * The contents of this file are subject to the terms of the
5*10d63b7dSRichard Lowe * Common Development and Distribution License (the "License").
6*10d63b7dSRichard Lowe * You may not use this file except in compliance with the License.
7*10d63b7dSRichard Lowe *
8*10d63b7dSRichard Lowe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*10d63b7dSRichard Lowe * or http://www.opensolaris.org/os/licensing.
10*10d63b7dSRichard Lowe * See the License for the specific language governing permissions
11*10d63b7dSRichard Lowe * and limitations under the License.
12*10d63b7dSRichard Lowe *
13*10d63b7dSRichard Lowe * When distributing Covered Code, include this CDDL HEADER in each
14*10d63b7dSRichard Lowe * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*10d63b7dSRichard Lowe * If applicable, add the following below this CDDL HEADER, with the
16*10d63b7dSRichard Lowe * fields enclosed by brackets "[]" replaced with your own identifying
17*10d63b7dSRichard Lowe * information: Portions Copyright [yyyy] [name of copyright owner]
18*10d63b7dSRichard Lowe *
19*10d63b7dSRichard Lowe * CDDL HEADER END
20*10d63b7dSRichard Lowe */
21*10d63b7dSRichard Lowe /*
22*10d63b7dSRichard Lowe * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
23*10d63b7dSRichard Lowe * Use is subject to license terms.
24*10d63b7dSRichard Lowe */
25*10d63b7dSRichard Lowe
26*10d63b7dSRichard Lowe
27*10d63b7dSRichard Lowe /*
28*10d63b7dSRichard Lowe * read.c
29*10d63b7dSRichard Lowe *
30*10d63b7dSRichard Lowe * This file contains the makefile reader.
31*10d63b7dSRichard Lowe */
32*10d63b7dSRichard Lowe
33*10d63b7dSRichard Lowe /*
34*10d63b7dSRichard Lowe * Included files
35*10d63b7dSRichard Lowe */
36*10d63b7dSRichard Lowe #include <mksh/misc.h> /* retmem() */
37*10d63b7dSRichard Lowe #include <mksh/read.h>
38*10d63b7dSRichard Lowe #include <sys/uio.h> /* read() */
39*10d63b7dSRichard Lowe #include <unistd.h> /* close(), unlink(), read() */
40*10d63b7dSRichard Lowe #include <libintl.h>
41*10d63b7dSRichard Lowe
42*10d63b7dSRichard Lowe #define STRING_LEN_TO_CONVERT (8*1024)
43*10d63b7dSRichard Lowe
44*10d63b7dSRichard Lowe /*
45*10d63b7dSRichard Lowe * get_next_block_fn(source)
46*10d63b7dSRichard Lowe *
47*10d63b7dSRichard Lowe * Will get the next block of text to read either
48*10d63b7dSRichard Lowe * by popping one source bVSIZEOFlock of the stack of Sources
49*10d63b7dSRichard Lowe * or by reading some more from the makefile.
50*10d63b7dSRichard Lowe *
51*10d63b7dSRichard Lowe * Return value:
52*10d63b7dSRichard Lowe * The new source block to read from
53*10d63b7dSRichard Lowe *
54*10d63b7dSRichard Lowe * Parameters:
55*10d63b7dSRichard Lowe * source The old source block
56*10d63b7dSRichard Lowe *
57*10d63b7dSRichard Lowe * Global variables used:
58*10d63b7dSRichard Lowe * file_being_read The name of the current file, error msg
59*10d63b7dSRichard Lowe */
60*10d63b7dSRichard Lowe Boolean make_state_locked;
61*10d63b7dSRichard Lowe Source
get_next_block_fn(register Source source)62*10d63b7dSRichard Lowe get_next_block_fn(register Source source)
63*10d63b7dSRichard Lowe {
64*10d63b7dSRichard Lowe register off_t to_read;
65*10d63b7dSRichard Lowe register int length;
66*10d63b7dSRichard Lowe register size_t num_wc_chars;
67*10d63b7dSRichard Lowe char ch_save;
68*10d63b7dSRichard Lowe char *ptr;
69*10d63b7dSRichard Lowe
70*10d63b7dSRichard Lowe if (source == NULL) {
71*10d63b7dSRichard Lowe return NULL;
72*10d63b7dSRichard Lowe }
73*10d63b7dSRichard Lowe if ((source->fd < 0) ||
74*10d63b7dSRichard Lowe ((source->bytes_left_in_file <= 0) &&
75*10d63b7dSRichard Lowe (source->inp_buf_ptr >= source->inp_buf_end))) {
76*10d63b7dSRichard Lowe /* We can't read from the makefile, so pop the source block */
77*10d63b7dSRichard Lowe if (source->fd > 2) {
78*10d63b7dSRichard Lowe (void) close(source->fd);
79*10d63b7dSRichard Lowe if (make_state_lockfile != NULL) {
80*10d63b7dSRichard Lowe (void) unlink(make_state_lockfile);
81*10d63b7dSRichard Lowe retmem_mb(make_state_lockfile);
82*10d63b7dSRichard Lowe make_state_lockfile = NULL;
83*10d63b7dSRichard Lowe make_state_locked = false;
84*10d63b7dSRichard Lowe }
85*10d63b7dSRichard Lowe }
86*10d63b7dSRichard Lowe if (source->string.free_after_use &&
87*10d63b7dSRichard Lowe (source->string.buffer.start != NULL)) {
88*10d63b7dSRichard Lowe retmem(source->string.buffer.start);
89*10d63b7dSRichard Lowe source->string.buffer.start = NULL;
90*10d63b7dSRichard Lowe }
91*10d63b7dSRichard Lowe if (source->inp_buf != NULL) {
92*10d63b7dSRichard Lowe retmem_mb(source->inp_buf);
93*10d63b7dSRichard Lowe source->inp_buf = NULL;
94*10d63b7dSRichard Lowe }
95*10d63b7dSRichard Lowe source = source->previous;
96*10d63b7dSRichard Lowe if (source != NULL) {
97*10d63b7dSRichard Lowe source->error_converting = false;
98*10d63b7dSRichard Lowe }
99*10d63b7dSRichard Lowe return source;
100*10d63b7dSRichard Lowe }
101*10d63b7dSRichard Lowe if (source->bytes_left_in_file > 0) {
102*10d63b7dSRichard Lowe /*
103*10d63b7dSRichard Lowe * Read the whole makefile.
104*10d63b7dSRichard Lowe * Hopefully the kernel managed to prefetch the stuff.
105*10d63b7dSRichard Lowe */
106*10d63b7dSRichard Lowe to_read = source->bytes_left_in_file;
107*10d63b7dSRichard Lowe source->inp_buf_ptr = source->inp_buf = getmem(to_read + 1);
108*10d63b7dSRichard Lowe source->inp_buf_end = source->inp_buf + to_read;
109*10d63b7dSRichard Lowe length = read(source->fd, source->inp_buf, (unsigned int) to_read);
110*10d63b7dSRichard Lowe if (length != to_read) {
111*10d63b7dSRichard Lowe WCSTOMBS(mbs_buffer, file_being_read);
112*10d63b7dSRichard Lowe if (length == 0) {
113*10d63b7dSRichard Lowe fatal_mksh(gettext("Error reading `%s': Premature EOF"),
114*10d63b7dSRichard Lowe mbs_buffer);
115*10d63b7dSRichard Lowe } else {
116*10d63b7dSRichard Lowe fatal_mksh(gettext("Error reading `%s': %s"),
117*10d63b7dSRichard Lowe mbs_buffer,
118*10d63b7dSRichard Lowe errmsg(errno));
119*10d63b7dSRichard Lowe }
120*10d63b7dSRichard Lowe }
121*10d63b7dSRichard Lowe *source->inp_buf_end = nul_char;
122*10d63b7dSRichard Lowe source->bytes_left_in_file = 0;
123*10d63b7dSRichard Lowe }
124*10d63b7dSRichard Lowe /*
125*10d63b7dSRichard Lowe * Try to convert the next piece.
126*10d63b7dSRichard Lowe */
127*10d63b7dSRichard Lowe ptr = source->inp_buf_ptr + STRING_LEN_TO_CONVERT;
128*10d63b7dSRichard Lowe if (ptr > source->inp_buf_end) {
129*10d63b7dSRichard Lowe ptr = source->inp_buf_end;
130*10d63b7dSRichard Lowe }
131*10d63b7dSRichard Lowe for (num_wc_chars = 0; ptr > source->inp_buf_ptr; ptr--) {
132*10d63b7dSRichard Lowe ch_save = *ptr;
133*10d63b7dSRichard Lowe *ptr = nul_char;
134*10d63b7dSRichard Lowe num_wc_chars = mbstowcs(source->string.text.end,
135*10d63b7dSRichard Lowe source->inp_buf_ptr,
136*10d63b7dSRichard Lowe STRING_LEN_TO_CONVERT);
137*10d63b7dSRichard Lowe *ptr = ch_save;
138*10d63b7dSRichard Lowe if (num_wc_chars != (size_t)-1) {
139*10d63b7dSRichard Lowe break;
140*10d63b7dSRichard Lowe }
141*10d63b7dSRichard Lowe }
142*10d63b7dSRichard Lowe
143*10d63b7dSRichard Lowe if ((int) num_wc_chars == (size_t)-1) {
144*10d63b7dSRichard Lowe source->error_converting = true;
145*10d63b7dSRichard Lowe return source;
146*10d63b7dSRichard Lowe }
147*10d63b7dSRichard Lowe
148*10d63b7dSRichard Lowe source->error_converting = false;
149*10d63b7dSRichard Lowe source->inp_buf_ptr = ptr;
150*10d63b7dSRichard Lowe source->string.text.end += num_wc_chars;
151*10d63b7dSRichard Lowe *source->string.text.end = 0;
152*10d63b7dSRichard Lowe
153*10d63b7dSRichard Lowe if (source->inp_buf_ptr >= source->inp_buf_end) {
154*10d63b7dSRichard Lowe if (*(source->string.text.end - 1) != (int) newline_char) {
155*10d63b7dSRichard Lowe WCSTOMBS(mbs_buffer, file_being_read);
156*10d63b7dSRichard Lowe warning_mksh(gettext("newline is not last character in file %s"),
157*10d63b7dSRichard Lowe mbs_buffer);
158*10d63b7dSRichard Lowe *source->string.text.end++ = (int) newline_char;
159*10d63b7dSRichard Lowe *source->string.text.end = (int) nul_char;
160*10d63b7dSRichard Lowe *source->string.buffer.end++;
161*10d63b7dSRichard Lowe }
162*10d63b7dSRichard Lowe if (source->inp_buf != NULL) {
163*10d63b7dSRichard Lowe retmem_mb(source->inp_buf);
164*10d63b7dSRichard Lowe source->inp_buf = NULL;
165*10d63b7dSRichard Lowe }
166*10d63b7dSRichard Lowe }
167*10d63b7dSRichard Lowe return source;
168*10d63b7dSRichard Lowe }
169*10d63b7dSRichard Lowe
170*10d63b7dSRichard Lowe
171