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 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