110d63b7dSRichard Lowe /*
210d63b7dSRichard Lowe * CDDL HEADER START
310d63b7dSRichard Lowe *
410d63b7dSRichard Lowe * The contents of this file are subject to the terms of the
510d63b7dSRichard Lowe * Common Development and Distribution License (the "License").
610d63b7dSRichard Lowe * You may not use this file except in compliance with the License.
710d63b7dSRichard Lowe *
810d63b7dSRichard Lowe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
910d63b7dSRichard Lowe * or http://www.opensolaris.org/os/licensing.
1010d63b7dSRichard Lowe * See the License for the specific language governing permissions
1110d63b7dSRichard Lowe * and limitations under the License.
1210d63b7dSRichard Lowe *
1310d63b7dSRichard Lowe * When distributing Covered Code, include this CDDL HEADER in each
1410d63b7dSRichard Lowe * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1510d63b7dSRichard Lowe * If applicable, add the following below this CDDL HEADER, with the
1610d63b7dSRichard Lowe * fields enclosed by brackets "[]" replaced with your own identifying
1710d63b7dSRichard Lowe * information: Portions Copyright [yyyy] [name of copyright owner]
1810d63b7dSRichard Lowe *
1910d63b7dSRichard Lowe * CDDL HEADER END
2010d63b7dSRichard Lowe */
2110d63b7dSRichard Lowe /*
2210d63b7dSRichard Lowe * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
2310d63b7dSRichard Lowe * Use is subject to license terms.
2410d63b7dSRichard Lowe */
2510d63b7dSRichard Lowe
2610d63b7dSRichard Lowe
2710d63b7dSRichard Lowe /*
2810d63b7dSRichard Lowe * read.c
2910d63b7dSRichard Lowe *
3010d63b7dSRichard Lowe * This file contains the makefile reader.
3110d63b7dSRichard Lowe */
3210d63b7dSRichard Lowe
3310d63b7dSRichard Lowe /*
3410d63b7dSRichard Lowe * Included files
3510d63b7dSRichard Lowe */
3610d63b7dSRichard Lowe #include <mksh/misc.h> /* retmem() */
3710d63b7dSRichard Lowe #include <mksh/read.h>
3810d63b7dSRichard Lowe #include <sys/uio.h> /* read() */
3910d63b7dSRichard Lowe #include <unistd.h> /* close(), unlink(), read() */
4010d63b7dSRichard Lowe #include <libintl.h>
4110d63b7dSRichard Lowe
4210d63b7dSRichard Lowe #define STRING_LEN_TO_CONVERT (8*1024)
4310d63b7dSRichard Lowe
4410d63b7dSRichard Lowe /*
4510d63b7dSRichard Lowe * get_next_block_fn(source)
4610d63b7dSRichard Lowe *
4710d63b7dSRichard Lowe * Will get the next block of text to read either
4810d63b7dSRichard Lowe * by popping one source bVSIZEOFlock of the stack of Sources
4910d63b7dSRichard Lowe * or by reading some more from the makefile.
5010d63b7dSRichard Lowe *
5110d63b7dSRichard Lowe * Return value:
5210d63b7dSRichard Lowe * The new source block to read from
5310d63b7dSRichard Lowe *
5410d63b7dSRichard Lowe * Parameters:
5510d63b7dSRichard Lowe * source The old source block
5610d63b7dSRichard Lowe *
5710d63b7dSRichard Lowe * Global variables used:
5810d63b7dSRichard Lowe * file_being_read The name of the current file, error msg
5910d63b7dSRichard Lowe */
6010d63b7dSRichard Lowe Boolean make_state_locked;
6110d63b7dSRichard Lowe Source
get_next_block_fn(Source source)62*e7afc443SToomas Soome get_next_block_fn(Source source)
6310d63b7dSRichard Lowe {
64*e7afc443SToomas Soome off_t to_read;
65*e7afc443SToomas Soome int length;
66*e7afc443SToomas Soome size_t num_wc_chars;
6710d63b7dSRichard Lowe char ch_save;
6810d63b7dSRichard Lowe char *ptr;
6910d63b7dSRichard Lowe
7010d63b7dSRichard Lowe if (source == NULL) {
7110d63b7dSRichard Lowe return NULL;
7210d63b7dSRichard Lowe }
73*e7afc443SToomas Soome if ((source->fd < 0) ||
7410d63b7dSRichard Lowe ((source->bytes_left_in_file <= 0) &&
7510d63b7dSRichard Lowe (source->inp_buf_ptr >= source->inp_buf_end))) {
7610d63b7dSRichard Lowe /* We can't read from the makefile, so pop the source block */
7710d63b7dSRichard Lowe if (source->fd > 2) {
7810d63b7dSRichard Lowe (void) close(source->fd);
7910d63b7dSRichard Lowe if (make_state_lockfile != NULL) {
8010d63b7dSRichard Lowe (void) unlink(make_state_lockfile);
8110d63b7dSRichard Lowe retmem_mb(make_state_lockfile);
8210d63b7dSRichard Lowe make_state_lockfile = NULL;
8310d63b7dSRichard Lowe make_state_locked = false;
8410d63b7dSRichard Lowe }
8510d63b7dSRichard Lowe }
8610d63b7dSRichard Lowe if (source->string.free_after_use &&
8710d63b7dSRichard Lowe (source->string.buffer.start != NULL)) {
8810d63b7dSRichard Lowe retmem(source->string.buffer.start);
8910d63b7dSRichard Lowe source->string.buffer.start = NULL;
9010d63b7dSRichard Lowe }
9110d63b7dSRichard Lowe if (source->inp_buf != NULL) {
9210d63b7dSRichard Lowe retmem_mb(source->inp_buf);
9310d63b7dSRichard Lowe source->inp_buf = NULL;
9410d63b7dSRichard Lowe }
9510d63b7dSRichard Lowe source = source->previous;
9610d63b7dSRichard Lowe if (source != NULL) {
9710d63b7dSRichard Lowe source->error_converting = false;
9810d63b7dSRichard Lowe }
9910d63b7dSRichard Lowe return source;
10010d63b7dSRichard Lowe }
10110d63b7dSRichard Lowe if (source->bytes_left_in_file > 0) {
10210d63b7dSRichard Lowe /*
10310d63b7dSRichard Lowe * Read the whole makefile.
10410d63b7dSRichard Lowe * Hopefully the kernel managed to prefetch the stuff.
10510d63b7dSRichard Lowe */
10610d63b7dSRichard Lowe to_read = source->bytes_left_in_file;
107*e7afc443SToomas Soome source->inp_buf_ptr = source->inp_buf = getmem(to_read + 1);
10810d63b7dSRichard Lowe source->inp_buf_end = source->inp_buf + to_read;
10910d63b7dSRichard Lowe length = read(source->fd, source->inp_buf, (unsigned int) to_read);
11010d63b7dSRichard Lowe if (length != to_read) {
11110d63b7dSRichard Lowe WCSTOMBS(mbs_buffer, file_being_read);
11210d63b7dSRichard Lowe if (length == 0) {
11310d63b7dSRichard Lowe fatal_mksh(gettext("Error reading `%s': Premature EOF"),
11410d63b7dSRichard Lowe mbs_buffer);
11510d63b7dSRichard Lowe } else {
11610d63b7dSRichard Lowe fatal_mksh(gettext("Error reading `%s': %s"),
11710d63b7dSRichard Lowe mbs_buffer,
11810d63b7dSRichard Lowe errmsg(errno));
11910d63b7dSRichard Lowe }
12010d63b7dSRichard Lowe }
12110d63b7dSRichard Lowe *source->inp_buf_end = nul_char;
12210d63b7dSRichard Lowe source->bytes_left_in_file = 0;
12310d63b7dSRichard Lowe }
12410d63b7dSRichard Lowe /*
12510d63b7dSRichard Lowe * Try to convert the next piece.
12610d63b7dSRichard Lowe */
12710d63b7dSRichard Lowe ptr = source->inp_buf_ptr + STRING_LEN_TO_CONVERT;
12810d63b7dSRichard Lowe if (ptr > source->inp_buf_end) {
12910d63b7dSRichard Lowe ptr = source->inp_buf_end;
13010d63b7dSRichard Lowe }
13110d63b7dSRichard Lowe for (num_wc_chars = 0; ptr > source->inp_buf_ptr; ptr--) {
13210d63b7dSRichard Lowe ch_save = *ptr;
13310d63b7dSRichard Lowe *ptr = nul_char;
13410d63b7dSRichard Lowe num_wc_chars = mbstowcs(source->string.text.end,
13510d63b7dSRichard Lowe source->inp_buf_ptr,
13610d63b7dSRichard Lowe STRING_LEN_TO_CONVERT);
13710d63b7dSRichard Lowe *ptr = ch_save;
13810d63b7dSRichard Lowe if (num_wc_chars != (size_t)-1) {
13910d63b7dSRichard Lowe break;
14010d63b7dSRichard Lowe }
14110d63b7dSRichard Lowe }
142*e7afc443SToomas Soome
14310d63b7dSRichard Lowe if ((int) num_wc_chars == (size_t)-1) {
14410d63b7dSRichard Lowe source->error_converting = true;
14510d63b7dSRichard Lowe return source;
14610d63b7dSRichard Lowe }
14710d63b7dSRichard Lowe
14810d63b7dSRichard Lowe source->error_converting = false;
14910d63b7dSRichard Lowe source->inp_buf_ptr = ptr;
15010d63b7dSRichard Lowe source->string.text.end += num_wc_chars;
15110d63b7dSRichard Lowe *source->string.text.end = 0;
15210d63b7dSRichard Lowe
15310d63b7dSRichard Lowe if (source->inp_buf_ptr >= source->inp_buf_end) {
15410d63b7dSRichard Lowe if (*(source->string.text.end - 1) != (int) newline_char) {
15510d63b7dSRichard Lowe WCSTOMBS(mbs_buffer, file_being_read);
15610d63b7dSRichard Lowe warning_mksh(gettext("newline is not last character in file %s"),
15710d63b7dSRichard Lowe mbs_buffer);
15810d63b7dSRichard Lowe *source->string.text.end++ = (int) newline_char;
15910d63b7dSRichard Lowe *source->string.text.end = (int) nul_char;
16010d63b7dSRichard Lowe *source->string.buffer.end++;
16110d63b7dSRichard Lowe }
16210d63b7dSRichard Lowe if (source->inp_buf != NULL) {
16310d63b7dSRichard Lowe retmem_mb(source->inp_buf);
16410d63b7dSRichard Lowe source->inp_buf = NULL;
16510d63b7dSRichard Lowe }
16610d63b7dSRichard Lowe }
16710d63b7dSRichard Lowe return source;
16810d63b7dSRichard Lowe }
16910d63b7dSRichard Lowe
17010d63b7dSRichard Lowe
171