input.c revision 242895
150027Speter/*- 272376Sjake * Copyright (c) 1991, 1993 372376Sjake * The Regents of the University of California. All rights reserved. 450027Speter * 550027Speter * This code is derived from software contributed to Berkeley by 650027Speter * Kenneth Almquist. 750027Speter * 850027Speter * Redistribution and use in source and binary forms, with or without 950027Speter * modification, are permitted provided that the following conditions 1050027Speter * are met: 1150027Speter * 1. Redistributions of source code must retain the above copyright 1250027Speter * notice, this list of conditions and the following disclaimer. 1350027Speter * 2. Redistributions in binary form must reproduce the above copyright 1450027Speter * notice, this list of conditions and the following disclaimer in the 1550027Speter * documentation and/or other materials provided with the distribution. 1650027Speter * 4. Neither the name of the University nor the names of its contributors 1750027Speter * may be used to endorse or promote products derived from this software 1850027Speter * without specific prior written permission. 1950027Speter * 2050027Speter * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2150027Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2250027Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2350027Speter * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2450027Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2550027Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2650027Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2799072Sjulian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2899072Sjulian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2999072Sjulian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3099072Sjulian * SUCH DAMAGE. 3199072Sjulian */ 32123499Srwatson 3399072Sjulian#ifndef lint 3499072Sjulian#if 0 3599072Sjulianstatic char sccsid[] = "@(#)input.c 8.3 (Berkeley) 6/9/95"; 3699072Sjulian#endif 3799072Sjulian#endif /* not lint */ 3899072Sjulian#include <sys/cdefs.h> 3999072Sjulian__FBSDID("$FreeBSD: head/bin/sh/input.c 242895 2012-11-11 15:13:24Z jilles $"); 4099072Sjulian 4199072Sjulian#include <stdio.h> /* defines BUFSIZ */ 4299072Sjulian#include <fcntl.h> 4399072Sjulian#include <errno.h> 4499072Sjulian#include <unistd.h> 4599072Sjulian#include <stdlib.h> 4699072Sjulian#include <string.h> 4799072Sjulian 4899072Sjulian/* 4999072Sjulian * This file implements the input routines used by the parser. 5099072Sjulian */ 5199072Sjulian 5299072Sjulian#include "shell.h" 5399072Sjulian#include "redir.h" 5499072Sjulian#include "syntax.h" 5599072Sjulian#include "input.h" 5699072Sjulian#include "output.h" 5799072Sjulian#include "options.h" 5899072Sjulian#include "memalloc.h" 5999072Sjulian#include "error.h" 6099072Sjulian#include "alias.h" 6199072Sjulian#include "parser.h" 6299072Sjulian#include "myhistedit.h" 6399072Sjulian#include "trap.h" 6499072Sjulian 6599072Sjulian#define EOF_NLEFT -99 /* value of parsenleft when EOF pushed back */ 6699072Sjulian 6799072SjulianMKINIT 6899072Sjulianstruct strpush { 6999072Sjulian struct strpush *prev; /* preceding string on stack */ 7099072Sjulian char *prevstring; 7199072Sjulian int prevnleft; 7299072Sjulian int prevlleft; 7399072Sjulian struct alias *ap; /* if push was associated with an alias */ 7499072Sjulian}; 7599072Sjulian 7699072Sjulian/* 7799072Sjulian * The parsefile structure pointed to by the global variable parsefile 7899072Sjulian * contains information about the current file being read. 7999072Sjulian */ 8099072Sjulian 8199072SjulianMKINIT 8299072Sjulianstruct parsefile { 8399072Sjulian struct parsefile *prev; /* preceding file on stack */ 8499072Sjulian int linno; /* current line */ 8599072Sjulian int fd; /* file descriptor (or -1 if string) */ 86116182Sobrien int nleft; /* number of chars left in this line */ 8799072Sjulian int lleft; /* number of lines left in this buffer */ 88116182Sobrien char *nextc; /* next char in buffer */ 89116182Sobrien char *buf; /* input buffer */ 90116182Sobrien struct strpush *strpush; /* for pushing strings at this level */ 91131481Sjhb struct strpush basestrpush; /* so pushing one is fast */ 92134591Sjulian}; 93131481Sjhb 9450027Speter 9550027Speterint plinno = 1; /* input line number */ 96131927Smarcelint parsenleft; /* copy of parsefile->nleft */ 9750027SpeterMKINIT int parselleft; /* copy of parsefile->lleft */ 9865557Sjasonechar *parsenextc; /* copy of parsefile->nextc */ 9974914SjhbMKINIT struct parsefile basepf; /* top level input file */ 10067365Sjhbchar basebuf[BUFSIZ + 1]; /* buffer for top level input file */ 10150027Speterstatic struct parsefile *parsefile = &basepf; /* current input file */ 10250027Speterint init_editline = 0; /* editline library initialized? */ 103104964Sjeffint whichprompt; /* 1 == PS1, 2 == PS2 */ 104122849Speter 105112993SpeterEditLine *el; /* cookie for editline package */ 106112993Speter 10793607Sdillonstatic void pushfile(void); 108134591Sjulianstatic int preadfd(void); 109134591Sjulianstatic void popstring(void); 110134591Sjulian 11150027Speter#ifdef mkinit 112134591SjulianINCLUDE "input.h" 11397261SjakeINCLUDE "error.h" 11497261Sjake 115104695SjulianMKINIT char basebuf[]; 116104695Sjulian 117104695SjulianINIT { 11899072Sjulian basepf.nextc = basepf.buf = basebuf; 119104695Sjulian} 12099072Sjulian 12199072SjulianRESET { 12299072Sjulian popallfiles(); 12350027Speter parselleft = parsenleft = 0; /* clear input buffer */ 124111028Sjeff} 12599072Sjulian#endif 12699072Sjulian 12750027Speter 12883366Sjulian/* 12983366Sjulian * Read a line from the script. 13050027Speter */ 13199072Sjulian 13299072Sjulianchar * 13399072Sjulianpfgets(char *line, int len) 13499072Sjulian{ 135122849Speter char *p = line; 136112993Speter int nleft = len; 137112993Speter int c; 138112993Speter 139112993Speter while (--nleft > 0) { 140112993Speter c = pgetc_macro(); 141112993Speter if (c == PEOF) { 142112993Speter if (p == line) 143112993Speter return NULL; 144112993Speter break; 145112993Speter } 146112993Speter *p++ = c; 147100209Sgallatin if (c == '\n') 148112993Speter break; 149112993Speter } 15099072Sjulian *p = '\0'; 15199072Sjulian return line; 15299072Sjulian} 153116361Sdavidxu 154103832Sjulian 15599072Sjulian 15699072Sjulian/* 157103832Sjulian * Read a character from the script, returning PEOF on end of file. 158112021Sdavidxu * Nul characters in the input are silently discarded. 159133404Sjulian */ 16099072Sjulian 16199072Sjulianint 16299072Sjulianpgetc(void) 16399072Sjulian{ 16499889Sjulian return pgetc_macro(); 16599072Sjulian} 166102592Sjulian 16799072Sjulian 16899072Sjulianstatic int 169102592Sjulianpreadfd(void) 170108338Sjulian{ 171108338Sjulian int nr; 172115215Sjulian parsenextc = parsefile->buf; 173115215Sjulian 174108338Sjulian#ifndef NO_HISTORY 175100209Sgallatin if (el != NULL && gotwinch) { 176115215Sjulian gotwinch = 0; 177115215Sjulian el_resize(el); 178115215Sjulian } 179100209Sgallatin#endif 180115215Sjulianretry: 181108338Sjulian#ifndef NO_HISTORY 182103216Sjulian if (parsefile->fd == 0 && el) { 18399072Sjulian static const char *rl_cp; 18472376Sjake static int el_len; 18550027Speter 18699072Sjulian if (rl_cp == NULL) 187111028Sjeff rl_cp = el_gets(el, &el_len); 188111028Sjeff if (rl_cp == NULL) 189111128Sdavidxu nr = el_len == 0 ? 0 : -1; 19099072Sjulian else { 19199072Sjulian nr = el_len; 19299072Sjulian if (nr > BUFSIZ) 19399072Sjulian nr = BUFSIZ; 19499072Sjulian memcpy(parsenextc, rl_cp, nr); 19599072Sjulian if (nr != el_len) { 196104695Sjulian el_len -= nr; 19799072Sjulian rl_cp += nr; 198103832Sjulian } else 199111028Sjeff rl_cp = NULL; 200111028Sjeff } 201111028Sjeff } else 202110190Sjulian#endif 203112397Sdavidxu nr = read(parsefile->fd, parsenextc, BUFSIZ); 204111028Sjeff 205108338Sjulian if (nr <= 0) { 20699072Sjulian if (nr < 0) { 20799072Sjulian if (errno == EINTR) 20899072Sjulian goto retry; 209111028Sjeff if (parsefile->fd == 0 && errno == EWOULDBLOCK) { 21099072Sjulian int flags = fcntl(0, F_GETFL, 0); 211111028Sjeff if (flags >= 0 && flags & O_NONBLOCK) { 21299072Sjulian flags &=~ O_NONBLOCK; 21399072Sjulian if (fcntl(0, F_SETFL, flags) >= 0) { 21499072Sjulian out2fmt_flush("sh: turning off NDELAY mode\n"); 215111028Sjeff goto retry; 21699072Sjulian } 21799072Sjulian } 21899072Sjulian } 21999072Sjulian } 22099072Sjulian nr = -1; 221133396Sjulian } 222134586Sjulian return nr; 223104695Sjulian} 224104695Sjulian 225104695Sjulian/* 226111028Sjeff * Refill the input buffer and return the next input character: 227111028Sjeff * 228111028Sjeff * 1) If a string was pushed back on the input, pop it; 229111028Sjeff * 2) If an EOF was pushed back (parsenleft == EOF_NLEFT) or we are reading 230111028Sjeff * from a string so we can't refill the buffer, return EOF. 231108338Sjulian * 3) If there is more in this buffer, use it else call read to fill it. 23299072Sjulian * 4) Process input up to the next newline, deleting nul characters. 23399072Sjulian */ 234105127Sjulian 23599072Sjulianint 23699072Sjulianpreadbuffer(void) 23799072Sjulian{ 23899072Sjulian char *p, *q; 239111028Sjeff int more; 24099072Sjulian int something; 241105127Sjulian char savec; 24283366Sjulian 24372376Sjake if (parsefile->strpush) { 244104695Sjulian popstring(); 24599072Sjulian if (--parsenleft >= 0) 24699072Sjulian return (*parsenextc++); 24799072Sjulian } 24899072Sjulian if (parsenleft == EOF_NLEFT || parsefile->buf == NULL) 249111028Sjeff return PEOF; 25099072Sjulian flushout(&output); 25199072Sjulian flushout(&errout); 25299072Sjulian 253103216Sjulianagain: 254111028Sjeff if (parselleft <= 0) { 255111028Sjeff if ((parselleft = preadfd()) == -1) { 256111028Sjeff parselleft = parsenleft = EOF_NLEFT; 257116361Sdavidxu return PEOF; 25899072Sjulian } 259121127Sjeff } 26099942Sjulian 26199072Sjulian q = p = parsenextc; 26299072Sjulian 263104695Sjulian /* delete nul characters */ 264104695Sjulian something = 0; 265133404Sjulian for (more = 1; more;) { 26699072Sjulian switch (*p) { 26799072Sjulian case '\0': 26899072Sjulian p++; /* Skip nul */ 26999072Sjulian goto check; 27099072Sjulian 27199072Sjulian case '\t': 27299072Sjulian case ' ': 273121127Sjeff break; 274108338Sjulian 27599072Sjulian case '\n': 276111028Sjeff parsenleft = q - parsenextc; 277104695Sjulian more = 0; /* Stop processing here */ 278104695Sjulian break; 279104695Sjulian 28099072Sjulian default: 28172376Sjake something = 1; 282105127Sjulian break; 28372376Sjake } 284105127Sjulian 285105127Sjulian *q++ = *p++; 286105127Sjuliancheck: 28772376Sjake if (--parselleft <= 0) { 288105127Sjulian parsenleft = q - parsenextc - 1; 289105127Sjulian if (parsenleft < 0) 290105127Sjulian goto again; 291105127Sjulian *q = '\0'; 292105127Sjulian more = 0; 293105127Sjulian } 294111028Sjeff } 295111028Sjeff 296111028Sjeff savec = *q; 297111028Sjeff *q = '\0'; 298110190Sjulian 299111028Sjeff#ifndef NO_HISTORY 300110190Sjulian if (parsefile->fd == 0 && hist && something) { 301116361Sdavidxu HistEvent he; 302105127Sjulian INTOFF; 303105129Sjulian history(hist, &he, whichprompt == 1 ? H_ENTER : H_ADD, 304105127Sjulian parsenextc); 305121127Sjeff INTON; 306134586Sjulian } 307105127Sjulian#endif 308105127Sjulian 309105127Sjulian if (vflag) { 310111028Sjeff out2str(parsenextc); 311111028Sjeff flushout(out2); 312105127Sjulian } 313105127Sjulian 314105127Sjulian *q = savec; 315105127Sjulian 316105127Sjulian return *parsenextc++; 317105127Sjulian} 318105127Sjulian 319121127Sjeff/* 320105127Sjulian * Returns if we are certain we are at EOF. Does not cause any more input 321105127Sjulian * to be read from the outside world. 322133404Sjulian */ 323105127Sjulian 324134586Sjulianint 325105127Sjulianpreadateof(void) 326105127Sjulian{ 327105127Sjulian if (parsenleft > 0) 328134586Sjulian return 0; 32950027Speter if (parsefile->strpush) 33099072Sjulian return 0; 33199072Sjulian if (parsenleft == EOF_NLEFT || parsefile->buf == NULL) 33299072Sjulian return 1; 33399072Sjulian return 0; 334133414Sscottl} 33599072Sjulian 336133396Sjulian/* 337133396Sjulian * Undo the last call to pgetc. Only one character may be pushed back. 33899072Sjulian * PEOF may be pushed back. 339103216Sjulian */ 340103216Sjulian 341103216Sjulianvoid 34299072Sjulianpungetc(void) 343116361Sdavidxu{ 344104695Sjulian parsenleft++; 345104695Sjulian parsenextc--; 346104695Sjulian} 347104695Sjulian 348104695Sjulian/* 349134586Sjulian * Push a string back onto the input at this current parsefile level. 350104695Sjulian * We handle aliases this way. 351104695Sjulian */ 352104695Sjulianvoid 35399072Sjulianpushstring(char *s, int len, struct alias *ap) 35499072Sjulian{ 355111028Sjeff struct strpush *sp; 35699072Sjulian 357111028Sjeff INTOFF; 358104695Sjulian/*out2fmt_flush("*** calling pushstring: %s, %d\n", s, len);*/ 359111028Sjeff if (parsefile->strpush) { 360133396Sjulian sp = ckmalloc(sizeof (struct strpush)); 361133396Sjulian sp->prev = parsefile->strpush; 362111028Sjeff parsefile->strpush = sp; 363104157Sjulian } else 364111028Sjeff sp = parsefile->strpush = &(parsefile->basestrpush); 36599072Sjulian sp->prevstring = parsenextc; 36699072Sjulian sp->prevnleft = parsenleft; 36799072Sjulian sp->prevlleft = parselleft; 36899072Sjulian sp->ap = ap; 36999072Sjulian if (ap) 370133396Sjulian ap->flag |= ALIASINUSE; 371133396Sjulian parsenextc = s; 372133396Sjulian parsenleft = len; 373121171Sjeff INTON; 37499072Sjulian} 37599072Sjulian 37699072Sjulianstatic void 37799072Sjulianpopstring(void) 37899072Sjulian{ 37999072Sjulian struct strpush *sp = parsefile->strpush; 38099942Sjulian 38199942Sjulian INTOFF; 38299942Sjulian parsenextc = sp->prevstring; 38399072Sjulian parsenleft = sp->prevnleft; 38499072Sjulian parselleft = sp->prevlleft; 38599072Sjulian/*out2fmt_flush("*** calling popstring: restoring to '%s'\n", parsenextc);*/ 38699072Sjulian if (sp->ap) 38799072Sjulian sp->ap->flag &= ~ALIASINUSE; 38899072Sjulian parsefile->strpush = sp->prev; 38999072Sjulian if (sp != &(parsefile->basestrpush)) 39099072Sjulian ckfree(sp); 391133414Sscottl INTON; 39299072Sjulian} 39399072Sjulian 394133404Sjulian/* 39599072Sjulian * Set the input to take input from a file. If push is set, push the 39699072Sjulian * old input onto the stack first. 39799072Sjulian */ 398133414Sscottl 399133414Sscottlvoid 400133414Sscottlsetinputfile(const char *fname, int push) 401133414Sscottl{ 402133414Sscottl int fd; 40399072Sjulian int fd2; 40499072Sjulian 40599072Sjulian INTOFF; 406133404Sjulian if ((fd = open(fname, O_RDONLY)) < 0) 40799072Sjulian error("cannot open %s: %s", fname, strerror(errno)); 40899072Sjulian if (fd < 10) { 40999072Sjulian fd2 = fcntl(fd, F_DUPFD, 10); 41099072Sjulian close(fd); 41199072Sjulian if (fd2 < 0) 41299072Sjulian error("Out of file descriptors"); 41399072Sjulian fd = fd2; 41499072Sjulian } 41599072Sjulian setinputfd(fd, push); 41699072Sjulian INTON; 41799072Sjulian} 41899942Sjulian 41999072Sjulian 42099072Sjulian/* 42199072Sjulian * Like setinputfile, but takes an open file descriptor. Call this with 42299072Sjulian * interrupts off. 42399072Sjulian */ 42499072Sjulian 42599072Sjulianvoid 42699072Sjuliansetinputfd(int fd, int push) 42799072Sjulian{ 42899072Sjulian (void)fcntl(fd, F_SETFD, FD_CLOEXEC); 42999072Sjulian if (push) { 43099072Sjulian pushfile(); 43199072Sjulian parsefile->buf = ckmalloc(BUFSIZ + 1); 43299072Sjulian } 43399072Sjulian if (parsefile->fd > 0) 43499072Sjulian close(parsefile->fd); 43599072Sjulian parsefile->fd = fd; 43699072Sjulian if (parsefile->buf == NULL) 43799072Sjulian parsefile->buf = ckmalloc(BUFSIZ + 1); 43899072Sjulian parselleft = parsenleft = 0; 43999072Sjulian plinno = 1; 44099072Sjulian} 44199072Sjulian 44299072Sjulian 44399072Sjulian/* 444134586Sjulian * Like setinputfile, but takes input from a string. 445133396Sjulian */ 446133396Sjulian 447133396Sjulianvoid 44899072Sjuliansetinputstring(char *string, int push) 44972376Sjake{ 45050027Speter INTOFF; 451131481Sjhb if (push) 452131481Sjhb pushfile(); 453131481Sjhb parsenextc = string; 454131481Sjhb parselleft = parsenleft = strlen(string); 45588088Sjhb parsefile->buf = NULL; 45688088Sjhb plinno = 1; 45788088Sjhb INTON; 45888088Sjhb} 45988088Sjhb 46088088Sjhb 46188088Sjhb 462132700Srwatson/* 46388088Sjhb * To handle the "." command, a stack of input files is used. Pushfile 46488088Sjhb * adds a new entry to the stack and popfile restores the previous level. 46588088Sjhb */ 46688088Sjhb 46788088Sjhbstatic void 46888088Sjhbpushfile(void) 46988088Sjhb{ 47088088Sjhb struct parsefile *pf; 47188088Sjhb 472125315Sjeff parsefile->nleft = parsenleft; 473125315Sjeff parsefile->lleft = parselleft; 47488088Sjhb parsefile->nextc = parsenextc; 475131481Sjhb parsefile->linno = plinno; 476132266Sjhb pf = (struct parsefile *)ckmalloc(sizeof (struct parsefile)); 477132266Sjhb pf->prev = parsefile; 478131481Sjhb pf->fd = -1; 479131481Sjhb pf->strpush = NULL; 480131481Sjhb pf->basestrpush.prev = NULL; 481131481Sjhb parsefile = pf; 482131481Sjhb} 48388088Sjhb 484132700Srwatson 48593264Sdillonvoid 48688088Sjhbpopfile(void) 48793264Sdillon{ 48888088Sjhb struct parsefile *pf = parsefile; 48988088Sjhb 490131481Sjhb INTOFF; 491131481Sjhb if (pf->fd >= 0) 492131481Sjhb close(pf->fd); 493131481Sjhb if (pf->buf) 494131481Sjhb ckfree(pf->buf); 495131481Sjhb while (pf->strpush) 496131481Sjhb popstring(); 497131481Sjhb parsefile = pf->prev; 498131481Sjhb ckfree(pf); 499131481Sjhb parsenleft = parsefile->nleft; 500131508Smarcel parselleft = parsefile->lleft; 501131481Sjhb parsenextc = parsefile->nextc; 502131481Sjhb plinno = parsefile->linno; 503131508Smarcel INTON; 50499072Sjulian} 505131481Sjhb 506131481Sjhb 507131481Sjhb/* 508131481Sjhb * Return current file (to go back to it later using popfilesupto()). 509131481Sjhb */ 510131481Sjhb 511132266Sjhbstruct parsefile * 512132266Sjhbgetcurrentfile(void) 513132266Sjhb{ 514131481Sjhb return parsefile; 515131481Sjhb} 516131481Sjhb 517131481Sjhb 518131481Sjhb/* 519131481Sjhb * Pop files until the given file is on top again. Useful for regular 520131481Sjhb * builtins that read shell commands from files or strings. 521131481Sjhb * If the given file is not an active file, an error is raised. 522131481Sjhb */ 523131481Sjhb 524131481Sjhbvoid 525131481Sjhbpopfilesupto(struct parsefile *file) 526131481Sjhb{ 527131481Sjhb while (parsefile != file && parsefile != &basepf) 528131481Sjhb popfile(); 529131481Sjhb if (parsefile != file) 530134417Speter error("popfilesupto() misused"); 531134417Speter} 532131481Sjhb 533131481Sjhb/* 534131481Sjhb * Return to top level. 535131481Sjhb */ 536131481Sjhb 537131481Sjhbvoid 538131481Sjhbpopallfiles(void) 539131481Sjhb{ 540131481Sjhb while (parsefile != &basepf) 541131481Sjhb popfile(); 542131481Sjhb} 543131481Sjhb 544131481Sjhb 545132266Sjhb 546131481Sjhb/* 547131481Sjhb * Close the file(s) that the shell is reading commands from. Called 548131481Sjhb * after a fork is done. 549131481Sjhb */ 550131481Sjhb 551131481Sjhbvoid 552131481Sjhbclosescript(void) 553131481Sjhb{ 554131481Sjhb popallfiles(); 555131481Sjhb if (parsefile->fd > 0) { 556131481Sjhb close(parsefile->fd); 557131481Sjhb parsefile->fd = 0; 558131481Sjhb } 559131481Sjhb} 560131481Sjhb