10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe/*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * CDDL HEADER START
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * The contents of this file are subject to the terms of the
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Common Development and Distribution License (the "License").
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * You may not use this file except in compliance with the License.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * or http://www.opensolaris.org/os/licensing.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * See the License for the specific language governing permissions
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * and limitations under the License.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * When distributing Covered Code, include this CDDL HEADER in each
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * If applicable, add the following below this CDDL HEADER, with the
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * fields enclosed by brackets "[]" replaced with your own identifying
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * information: Portions Copyright [yyyy] [name of copyright owner]
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * CDDL HEADER END
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe/*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Use is subject to license terms.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe/*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * read.c
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * This file contains the makefile reader.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe/*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Included files
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe#include <mksh/misc.h> /* retmem() */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe#include <mksh/read.h>
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe#include <sys/uio.h> /* read() */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe#include <unistd.h> /* close(), unlink(), read() */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe#include <libintl.h>
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe#define STRING_LEN_TO_CONVERT (8*1024)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe/*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * get_next_block_fn(source)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Will get the next block of text to read either
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * by popping one source bVSIZEOFlock of the stack of Sources
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * or by reading some more from the makefile.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Return value:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * The new source block to read from
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Parameters:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * source The old source block
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Global variables used:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * file_being_read The name of the current file, error msg
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard LoweBoolean make_state_locked;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard LoweSource
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweget_next_block_fn(register Source source)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe{
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe register off_t to_read;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe register int length;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe register size_t num_wc_chars;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe char ch_save;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe char *ptr;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (source == NULL) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return NULL;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if ((source->fd < 0) ||
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe ((source->bytes_left_in_file <= 0) &&
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (source->inp_buf_ptr >= source->inp_buf_end))) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* We can't read from the makefile, so pop the source block */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (source->fd > 2) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (void) close(source->fd);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (make_state_lockfile != NULL) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (void) unlink(make_state_lockfile);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe retmem_mb(make_state_lockfile);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe make_state_lockfile = NULL;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe make_state_locked = false;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (source->string.free_after_use &&
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (source->string.buffer.start != NULL)) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe retmem(source->string.buffer.start);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe source->string.buffer.start = NULL;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (source->inp_buf != NULL) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe retmem_mb(source->inp_buf);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe source->inp_buf = NULL;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe source = source->previous;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (source != NULL) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe source->error_converting = false;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return source;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (source->bytes_left_in_file > 0) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Read the whole makefile.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Hopefully the kernel managed to prefetch the stuff.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe to_read = source->bytes_left_in_file;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe source->inp_buf_ptr = source->inp_buf = getmem(to_read + 1);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe source->inp_buf_end = source->inp_buf + to_read;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe length = read(source->fd, source->inp_buf, (unsigned int) to_read);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (length != to_read) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe WCSTOMBS(mbs_buffer, file_being_read);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (length == 0) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fatal_mksh(gettext("Error reading `%s': Premature EOF"),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe mbs_buffer);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe } else {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fatal_mksh(gettext("Error reading `%s': %s"),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe mbs_buffer,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe errmsg(errno));
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *source->inp_buf_end = nul_char;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe source->bytes_left_in_file = 0;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Try to convert the next piece.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe ptr = source->inp_buf_ptr + STRING_LEN_TO_CONVERT;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (ptr > source->inp_buf_end) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe ptr = source->inp_buf_end;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe for (num_wc_chars = 0; ptr > source->inp_buf_ptr; ptr--) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe ch_save = *ptr;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *ptr = nul_char;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe num_wc_chars = mbstowcs(source->string.text.end,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe source->inp_buf_ptr,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe STRING_LEN_TO_CONVERT);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *ptr = ch_save;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (num_wc_chars != (size_t)-1) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe break;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if ((int) num_wc_chars == (size_t)-1) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe source->error_converting = true;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return source;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe source->error_converting = false;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe source->inp_buf_ptr = ptr;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe source->string.text.end += num_wc_chars;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *source->string.text.end = 0;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (source->inp_buf_ptr >= source->inp_buf_end) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (*(source->string.text.end - 1) != (int) newline_char) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe WCSTOMBS(mbs_buffer, file_being_read);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe warning_mksh(gettext("newline is not last character in file %s"),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe mbs_buffer);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *source->string.text.end++ = (int) newline_char;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *source->string.text.end = (int) nul_char;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *source->string.buffer.end++;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (source->inp_buf != NULL) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe retmem_mb(source->inp_buf);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe source->inp_buf = NULL;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return source;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe}
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe