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