1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*	$NetBSD: input.c,v 1.39 2003/08/07 09:05:32 agc Exp $	*/
2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*-
4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (c) 1991, 1993
5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *	The Regents of the University of California.  All rights reserved.
6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * This code is derived from software contributed to Berkeley by
8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Kenneth Almquist.
9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Redistribution and use in source and binary forms, with or without
11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * modification, are permitted provided that the following conditions
12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * are met:
13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *    documentation and/or other materials provided with the distribution.
18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 3. Neither the name of the University nor the names of its contributors
19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *    may be used to endorse or promote products derived from this software
20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *    without specific prior written permission.
21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * SUCH DAMAGE.
33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/cdefs.h>
36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef lint
37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if 0
38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic char sccsid[] = "@(#)input.c	8.3 (Berkeley) 6/9/95";
39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else
40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project__RCSID("$NetBSD: input.c,v 1.39 2003/08/07 09:05:32 agc Exp $");
41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* not lint */
43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h>	/* defines BUFSIZ */
45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <fcntl.h>
46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h>
47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h>
48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h>
49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h>
50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * This file implements the input routines used by the parser.
53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "shell.h"
56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "redir.h"
57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "syntax.h"
58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "input.h"
59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "output.h"
60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "options.h"
61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "memalloc.h"
62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "error.h"
63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "alias.h"
64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "parser.h"
65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "myhistedit.h"
66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
677fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich#ifdef WITH_LINENOISE
687fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich#include "linenoise.h"
697fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich#endif
707fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich
71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define EOF_NLEFT -99		/* value of parsenleft when EOF pushed back */
72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectMKINIT
74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct strpush {
75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct strpush *prev;	/* preceding string on stack */
76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	char *prevstring;
77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int prevnleft;
78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int prevlleft;
79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct alias *ap;	/* if push was associated with an alias */
80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project};
81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * The parsefile structure pointed to by the global variable parsefile
84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * contains information about the current file being read.
85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectMKINIT
88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct parsefile {
89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct parsefile *prev;	/* preceding file on stack */
90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int linno;		/* current line */
91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int fd;			/* file descriptor (or -1 if string) */
92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int nleft;		/* number of chars left in this line */
93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int lleft;		/* number of chars left in this buffer */
94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	char *nextc;		/* next char in buffer */
95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	char *buf;		/* input buffer */
96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct strpush *strpush; /* for pushing strings at this level */
97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct strpush basestrpush; /* so pushing one is fast */
98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project};
99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint plinno = 1;			/* input line number */
102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint parsenleft;			/* copy of parsefile->nleft */
103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectMKINIT int parselleft;		/* copy of parsefile->lleft */
104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectchar *parsenextc;		/* copy of parsefile->nextc */
105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectMKINIT struct parsefile basepf;	/* top level input file */
106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectMKINIT char basebuf[BUFSIZ];	/* buffer for top level input file */
107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct parsefile *parsefile = &basepf;	/* current input file */
108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint init_editline = 0;		/* editline library initialized? */
109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint whichprompt;		/* 1 == PS1, 2 == PS2 */
110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if WITH_HISTORY
112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectEditLine *el;			/* cookie for editline package */
113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC void pushfile(void);
116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int preadfd(void);
117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef mkinit
119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectINCLUDE <stdio.h>
120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectINCLUDE "input.h"
121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectINCLUDE "error.h"
122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectINIT {
124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	basepf.nextc = basepf.buf = basebuf;
125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectRESET {
128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (exception != EXSHELLPROC)
129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		parselleft = parsenleft = 0;	/* clear input buffer */
130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	popallfiles();
131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSHELLPROC {
134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	popallfiles();
135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Read a line from the script.
141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectchar *
144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectpfgets(char *line, int len)
145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	char *p = line;
147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int nleft = len;
148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int c;
149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	while (--nleft > 0) {
151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		c = pgetc_macro();
152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (c == PEOF) {
153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (p == line)
154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				return NULL;
155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			break;
156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		*p++ = c;
158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (c == '\n')
159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			break;
160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	*p = '\0';
162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return line;
163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Read a character from the script, returning PEOF on end of file.
169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Nul characters in the input are silently discarded.
170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint
173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectpgetc(void)
174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return pgetc_macro();
176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
178ad5431d2ca9c4dd454dfb3bc8e9de3ee0ad28a27Jack Palevichint in_interactive_mode() {
179ad5431d2ca9c4dd454dfb3bc8e9de3ee0ad28a27Jack Palevich    return parsefile != NULL && parsefile->fd == 0;
180ad5431d2ca9c4dd454dfb3bc8e9de3ee0ad28a27Jack Palevich}
181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectpreadfd(void)
184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int nr;
186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	char *buf =  parsefile->buf;
187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	parsenextc = buf;
188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectretry:
190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef WITH_HISTORY
191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (parsefile->fd == 0 && el) {
192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		static const char *rl_cp;
193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		static int el_len;
194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (rl_cp == NULL)
196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			rl_cp = el_gets(el, &el_len);
197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (rl_cp == NULL)
198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			nr = 0;
199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		else {
200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			nr = el_len;
201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (nr > BUFSIZ - 8)
202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				nr = BUFSIZ - 8;
203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			memcpy(buf, rl_cp, nr);
204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (nr != el_len) {
205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				el_len -= nr;
206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				rl_cp += nr;
207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			} else
208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				rl_cp = 0;
209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	} else
212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
2137fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich#ifdef WITH_LINENOISE
2147fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich    if (parsefile->fd == 0) {
2157fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich        static char *rl_start;
2167fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich        static const char *rl_cp;
2177fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich        static int el_len;
2187fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich
2197fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich        if (rl_cp == NULL) {
2207fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich            rl_cp = rl_start = linenoise(getprompt(""));
2217fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich            if (rl_cp != NULL) {
2227fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich                el_len = strlen(rl_start);
2237fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich                if (el_len != 0) {
2247fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich                    /* Add non-blank lines to history. */
2257fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich                    linenoiseHistoryAdd(rl_start);
2267fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich                }
2271bc4eae3492b5e5fd8afdb3bb92c63287e8e994cMike Lockwood                out2str("\n");
2287fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich                /* Client expects a newline at end of input, doesn't expect null */
2297fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich                rl_start[el_len++] = '\n';
2307fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich            }
2317fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich        }
2327fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich        if (rl_cp == NULL)
2337fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich            nr = 0;
2347fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich        else {
2357fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich            nr = el_len;
2367fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich            if (nr > BUFSIZ - 8)
2377fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich                nr = BUFSIZ - 8;
2387fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich            memcpy(buf, rl_cp, nr);
2397fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich            if (nr != el_len) {
2407fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich                el_len -= nr;
2417fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich                rl_cp += nr;
2427fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich            } else {
2437fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich                rl_cp = 0;
2447fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich                if (rl_start != NULL) {
2457fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich                    free(rl_start);
2467fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich                    rl_start = NULL;
2477fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich                }
2487fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich            }
2497fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich        }
2507fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich    } else
2517fe202f160ca1926bc0277e3c276ad7b3f9b9aebJack Palevich#endif
252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		nr = read(parsefile->fd, buf, BUFSIZ - 8);
253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (nr <= 0) {
256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                if (nr < 0) {
257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        if (errno == EINTR)
258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                goto retry;
259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        if (parsefile->fd == 0 && errno == EWOULDBLOCK) {
260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                int flags = fcntl(0, F_GETFL, 0);
261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                if (flags >= 0 && flags & O_NONBLOCK) {
262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                        flags &=~ O_NONBLOCK;
263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                        if (fcntl(0, F_SETFL, flags) >= 0) {
264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project						out2str("sh: turning off NDELAY mode\n");
265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                                goto retry;
266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                        }
267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                }
268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        }
269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                }
270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                nr = -1;
271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return nr;
273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Refill the input buffer and return the next input character:
277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 1) If a string was pushed back on the input, pop it;
279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 2) If an EOF was pushed back (parsenleft == EOF_NLEFT) or we are reading
280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *    from a string so we can't refill the buffer, return EOF.
281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 3) If the is more stuff in this buffer, use it else call read to fill it.
282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 4) Process input up to the next newline, deleting nul characters.
283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint
286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectpreadbuffer(void)
287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	char *p, *q;
289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int more;
290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int something;
291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	char savec;
292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (parsefile->strpush) {
294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		popstring();
295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (--parsenleft >= 0)
296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			return (*parsenextc++);
297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (parsenleft == EOF_NLEFT || parsefile->buf == NULL)
299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return PEOF;
300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	flushout(&output);
301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	flushout(&errout);
302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectagain:
304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (parselleft <= 0) {
305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if ((parselleft = preadfd()) == -1) {
306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			parselleft = parsenleft = EOF_NLEFT;
307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			return PEOF;
308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	q = p = parsenextc;
312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/* delete nul characters */
314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	something = 0;
315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	for (more = 1; more;) {
316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		switch (*p) {
317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		case '\0':
318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			p++;	/* Skip nul */
319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			goto check;
320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		case '\t':
322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		case ' ':
323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			break;
324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		case '\n':
326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			parsenleft = q - parsenextc;
327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			more = 0; /* Stop processing here */
328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			break;
329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		default:
331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			something = 1;
332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			break;
333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		*q++ = *p++;
336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectcheck:
337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (--parselleft <= 0) {
338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			parsenleft = q - parsenextc - 1;
339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (parsenleft < 0)
340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				goto again;
341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			*q = '\0';
342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			more = 0;
343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	savec = *q;
347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	*q = '\0';
348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef WITH_HISTORY
350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (parsefile->fd == 0 && hist && something) {
351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		HistEvent he;
352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		INTOFF;
353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		history(hist, &he, whichprompt == 1? H_ENTER : H_APPEND,
354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		    parsenextc);
355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		INTON;
356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (vflag) {
360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		out2str(parsenextc);
361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		flushout(out2);
362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	*q = savec;
365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return *parsenextc++;
367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Undo the last call to pgetc.  Only one character may be pushed back.
371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * PEOF may be pushed back.
372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid
375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectpungetc(void)
376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	parsenleft++;
378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	parsenextc--;
379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Push a string back onto the input at this current parsefile level.
383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * We handle aliases this way.
384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid
386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectpushstring(char *s, int len, void *ap)
387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct strpush *sp;
389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	INTOFF;
391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*dprintf("*** calling pushstring: %s, %d\n", s, len);*/
392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (parsefile->strpush) {
393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		sp = ckmalloc(sizeof (struct strpush));
394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		sp->prev = parsefile->strpush;
395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		parsefile->strpush = sp;
396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	} else
397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		sp = parsefile->strpush = &(parsefile->basestrpush);
398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	sp->prevstring = parsenextc;
399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	sp->prevnleft = parsenleft;
400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	sp->prevlleft = parselleft;
401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	sp->ap = (struct alias *)ap;
402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (ap)
403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		((struct alias *)ap)->flag |= ALIASINUSE;
404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	parsenextc = s;
405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	parsenleft = len;
406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	INTON;
407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid
410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectpopstring(void)
411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct strpush *sp = parsefile->strpush;
413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	INTOFF;
415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	parsenextc = sp->prevstring;
416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	parsenleft = sp->prevnleft;
417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	parselleft = sp->prevlleft;
418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*dprintf("*** calling popstring: restoring to '%s'\n", parsenextc);*/
419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (sp->ap)
420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		sp->ap->flag &= ~ALIASINUSE;
421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	parsefile->strpush = sp->prev;
422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (sp != &(parsefile->basestrpush))
423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		ckfree(sp);
424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	INTON;
425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Set the input to take input from a file.  If push is set, push the
429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * old input onto the stack first.
430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid
433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectsetinputfile(const char *fname, int push)
434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int fd;
436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int fd2;
437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	INTOFF;
439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if ((fd = open(fname, O_RDONLY)) < 0)
440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		error("Can't open %s", fname);
441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (fd < 10) {
442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		fd2 = copyfd(fd, 10);
443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		close(fd);
444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (fd2 < 0)
445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			error("Out of file descriptors");
446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		fd = fd2;
447dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	setinputfd(fd, push);
449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	INTON;
450dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Like setinputfile, but takes an open file descriptor.  Call this with
455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * interrupts off.
456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid
459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectsetinputfd(int fd, int push)
460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	(void) fcntl(fd, F_SETFD, FD_CLOEXEC);
462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (push) {
463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		pushfile();
464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		parsefile->buf = ckmalloc(BUFSIZ);
465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (parsefile->fd > 0)
467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		close(parsefile->fd);
468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	parsefile->fd = fd;
469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (parsefile->buf == NULL)
470dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		parsefile->buf = ckmalloc(BUFSIZ);
471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	parselleft = parsenleft = 0;
472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	plinno = 1;
473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
476dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Like setinputfile, but takes input from a string.
478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid
481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectsetinputstring(char *string, int push)
482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	INTOFF;
484dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (push)
485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		pushfile();
486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	parsenextc = string;
487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	parselleft = parsenleft = strlen(string);
488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	parsefile->buf = NULL;
489dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	plinno = 1;
490dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	INTON;
491dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
493dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
494dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
495dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
496dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * To handle the "." command, a stack of input files is used.  Pushfile
497dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * adds a new entry to the stack and popfile restores the previous level.
498dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
499dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
500dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTATIC void
501dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectpushfile(void)
502dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
503dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct parsefile *pf;
504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
505dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	parsefile->nleft = parsenleft;
506dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	parsefile->lleft = parselleft;
507dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	parsefile->nextc = parsenextc;
508dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	parsefile->linno = plinno;
509dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	pf = (struct parsefile *)ckmalloc(sizeof (struct parsefile));
510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	pf->prev = parsefile;
511dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	pf->fd = -1;
512dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	pf->strpush = NULL;
513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	pf->basestrpush.prev = NULL;
514dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	parsefile = pf;
515dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
516dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
517dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
518dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid
519dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectpopfile(void)
520dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
521dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct parsefile *pf = parsefile;
522dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
523dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	INTOFF;
524dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (pf->fd >= 0)
525dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		close(pf->fd);
526dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (pf->buf)
527dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		ckfree(pf->buf);
528dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	while (pf->strpush)
529dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		popstring();
530dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	parsefile = pf->prev;
531dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	ckfree(pf);
532dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	parsenleft = parsefile->nleft;
533dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	parselleft = parsefile->lleft;
534dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	parsenextc = parsefile->nextc;
535dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	plinno = parsefile->linno;
536dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	INTON;
537dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
538dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
539dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
540dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
541dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Return to top level.
542dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
543dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
544dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid
545dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectpopallfiles(void)
546dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
547dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	while (parsefile != &basepf)
548dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		popfile();
549dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
550dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
551dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
552dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
553dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
554dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Close the file(s) that the shell is reading commands from.  Called
555dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * after a fork is done.
556dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
557dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Takes one arg, vfork, which tells it to not modify its global vars
558dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * as it is still running in the parent.
559dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
560dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * This code is (probably) unnecessary as the 'close on exec' flag is
561dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * set and should be enough.  In the vfork case it is definitely wrong
562dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * to close the fds as another fork() may be done later to feed data
563dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * from a 'here' document into a pipe and we don't want to close the
564dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * pipe!
565dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
566dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
567dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid
568dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectclosescript(int vforked)
569dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
570dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (vforked)
571dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return;
572dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	popallfiles();
573dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (parsefile->fd > 0) {
574dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		close(parsefile->fd);
575dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		parsefile->fd = 0;
576dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
577dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
578