1427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes/* $OpenBSD: main.c,v 1.54 2013/11/28 10:33:37 sobrado Exp $ */ 2b4542e99ca8562aa584e15df8ef35356ff8c10feElliott Hughes/* $OpenBSD: tty.c,v 1.10 2014/08/10 02:44:26 guenther Exp $ */ 3b4542e99ca8562aa584e15df8ef35356ff8c10feElliott Hughes/* $OpenBSD: io.c,v 1.25 2014/08/11 20:28:47 guenther Exp $ */ 4c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser/* $OpenBSD: table.c,v 1.15 2012/02/19 07:52:30 otto Exp $ */ 55155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 65155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/*- 7c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 8427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * 2011, 2012, 2013, 2014 95155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Thorsten Glaser <tg@mirbsd.org> 105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Provided that these terms and disclaimer and all copyright notices 125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * are retained or reproduced in an accompanying document, permission 135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * is granted to deal in this work without restriction, including un- 145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * limited rights to use, publicly perform, distribute, sell, modify, 155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * merge, give away, or sublicence. 165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to 185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * the utmost extent permitted by applicable law, neither express nor 195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * implied; without malicious intent or gross negligence. In no event 205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * may a licensor, author or contributor be held liable for indirect, 215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * direct, other damage, loss, or other issues arising in any way out 225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * of dealing in the work, even if advised of the possibility of such 235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * damage or existence of a defect, except proven that it results out 245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * of said person's immediate fault when using the work as intended. 255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define EXTERN 285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#include "sh.h" 295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if HAVE_LANGINFO_CODESET 315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#include <langinfo.h> 325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if HAVE_SETLOCALE_CTYPE 345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#include <locale.h> 355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 37b4542e99ca8562aa584e15df8ef35356ff8c10feElliott Hughes__RCSID("$MirOS: src/bin/mksh/main.c,v 1.284 2014/10/03 17:19:27 tg Exp $"); 385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruextern char **environ; 405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSHRC_PATH 425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define MKSHRC_PATH "~/.mkshrc" 435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_DEFAULT_TMPDIR 465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define MKSH_DEFAULT_TMPDIR "/tmp" 475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 49c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstatic uint8_t isuc(const char *); 50c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstatic int main_init(int, const char *[], Source **, struct block **); 5103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condravoid chvt_reinit(void); 525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void reclaim(void); 535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void remove_temps(struct temp *); 5403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic mksh_uari_t rndsetup(void); 555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef SIGWINCH 565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void x_sigwinch(int); 575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic const char initifs[] = "IFS= \t\n"; 605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic const char initsubs[] = 62c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser "${PS2=> } ${PS3=#? } ${PS4=+ } ${SECONDS=0} ${TMOUT=0} ${EPOCHREALTIME=}"; 635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic const char *initcoms[] = { 6503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Ttypeset, "-r", initvsn, NULL, 66b4542e99ca8562aa584e15df8ef35356ff8c10feElliott Hughes Ttypeset, "-x", "HOME", "PATH", "SHELL", NULL, 67c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser Ttypeset, "-i10", "COLUMNS", "LINES", "SECONDS", "TMOUT", NULL, 6803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Talias, 695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "integer=typeset -i", 7003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Tlocal_typeset, 7103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* not "alias -t --": hash -r needs to work */ 7203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra "hash=alias -t", 735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "type=whence -v", 7403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#if !defined(ANDROID) && !defined(MKSH_UNEMPLOYED) 7503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* not in Android for political reasons */ 7603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* not in ARGE mksh due to no job control */ 7703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra "stop=kill -STOP", 785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "autoload=typeset -fu", 805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "functions=typeset -f", 815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "history=fc -l", 825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "nameref=typeset -n", 835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "nohup=nohup ", 8403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Tr_fc_e_dash, 855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "source=PATH=$PATH:. command .", 865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "login=exec login", 875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru NULL, 885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* this is what AT&T ksh seems to track, with the addition of emacs */ 8903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Talias, "-tU", 905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "cat", "cc", "chmod", "cp", "date", "ed", "emacs", "grep", "ls", 915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "make", "mv", "pr", "rm", "sed", "sh", "vi", "who", NULL, 925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru NULL 935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}; 945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic const char *restr_com[] = { 9603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Ttypeset, "-r", "PATH", "ENV", "SHELL", NULL 9703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra}; 9803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 99c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstatic bool initio_done; 1005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* top-level parsing and execution environment */ 10203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic struct env env; 10303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastruct env *e = &env; 10403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 10503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic mksh_uari_t 10603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrarndsetup(void) 10703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{ 10803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra register uint32_t h; 10903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra struct { 11003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ALLOC_ITEM alloc_INT; 11103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra void *dataptr, *stkptr, *mallocptr; 112c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#if defined(__GLIBC__) && (__GLIBC__ >= 2) 11303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra sigjmp_buf jbuf; 114c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 11503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra struct timeval tv; 11603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } *bufptr; 11703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra char *cp; 11803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 11903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra cp = alloc(sizeof(*bufptr) - ALLOC_SIZE, APERM); 12003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#ifdef DEBUG 12103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* clear the allocated space, for valgrind */ 12203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra memset(cp, 0, sizeof(*bufptr) - ALLOC_SIZE); 12303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 12403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* undo what alloc() did to the malloc result address */ 12503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bufptr = (void *)(cp - ALLOC_SIZE); 12603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* PIE or something similar provides us with deltas here */ 12703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bufptr->dataptr = &rndsetupstate; 12803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* ASLR in at least Windows, Linux, some BSDs */ 12903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bufptr->stkptr = &bufptr; 13003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* randomised malloc in BSD (and possibly others) */ 13103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bufptr->mallocptr = bufptr; 132c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#if defined(__GLIBC__) && (__GLIBC__ >= 2) 13303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* glibc pointer guard */ 13403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra sigsetjmp(bufptr->jbuf, 1); 135c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 136c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* introduce variation (and yes, second arg MBZ for portability) */ 137c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser mksh_TIME(bufptr->tv); 13803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 139811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser h = chvt_rndsetup(bufptr, sizeof(*bufptr)); 140811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser 141811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser afree(cp, APERM); 142811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser return ((mksh_uari_t)h); 143811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser} 144811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser 1455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 1465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruchvt_reinit(void) 1475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 1485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru kshpid = procpid = getpid(); 1495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ksheuid = geteuid(); 1505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru kshpgrp = getpgrp(); 1515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru kshppid = getppid(); 1525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 1535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic const char *empty_argv[] = { 15503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra "mksh", NULL 15603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra}; 15703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 158c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstatic uint8_t 159c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserisuc(const char *cx) { 160c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser char *cp, *x; 161c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser uint8_t rv = 0; 162c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 163c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (!cx || !*cx) 164c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return (0); 165c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 166c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* uppercase a string duplicate */ 167c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser strdupx(x, cx, ATEMP); 168c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser cp = x; 169c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser while ((*cp = ksh_toupper(*cp))) 170c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ++cp; 171c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 172c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* check for UTF-8 */ 173c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (strstr(x, "UTF-8") || strstr(x, "UTF8")) 174c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser rv = 1; 175c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 176c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* free copy and out */ 177c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser afree(x, ATEMP); 178c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return (rv); 179c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser} 180c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 181c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstatic int 182c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glasermain_init(int argc, const char *argv[], Source **sp, struct block **lp) 1835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 1845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int argi, i; 18503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Source *s = NULL; 1865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct block *l; 187b4542e99ca8562aa584e15df8ef35356ff8c10feElliott Hughes unsigned char restricted_shell, errexit, utf_flag; 18803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra char *cp; 18903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra const char *ccp, **wp; 1905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *vp; 1915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct stat s_stdin; 1925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if !defined(_PATH_DEFPATH) && defined(_CS_PATH) 19303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ssize_t k; 1945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 1955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* do things like getpgrp() et al. */ 1975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru chvt_reinit(); 1985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* make sure argv[] is sane */ 2005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!*argv) { 2015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru argv = empty_argv; 2025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru argc = 1; 2035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 20403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra kshname = argv[0]; 2055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 20603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* initialise permanent Area */ 20703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ainit(&aperm); 2085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* set up base environment */ 21003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra env.type = E_NONE; 21103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ainit(&env.area); 21203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* set up global l->vars and l->funs */ 21303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra newblock(); 2145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Do this first so output routines (eg, errorf, shellf) can work */ 2165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru initio(); 2175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 21803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* determine the basename (without '-' or path) of the executable */ 21903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ccp = kshname; 22003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto begin_parse_kshname; 22103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while ((i = ccp[argi++])) { 22203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (i == '/') { 22303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ccp += argi; 22403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra begin_parse_kshname: 22503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra argi = 0; 22603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (*ccp == '-') 22703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++ccp; 22803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 22903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 23003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!*ccp) 23103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ccp = empty_argv[0]; 23203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 233427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes /* 234427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * Turn on nohup by default. (AT&T ksh does not have a nohup 235427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * option - it always sends the hup). 236427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes */ 237427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes Flag(FNOHUP) = 1; 238427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes 239427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes /* 240427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * Turn on brace expansion by default. AT&T kshs that have 241427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * alternation always have it on. 242427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes */ 243427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes Flag(FBRACEEXPAND) = 1; 244427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes 245427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes /* 246427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * Turn on "set -x" inheritance by default. 247427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes */ 248427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes Flag(FXTRACEREC) = 1; 249427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes 25003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* define built-in commands and see if we were called as one */ 25103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ktinit(APERM, &builtins, 252811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser /* currently up to 51 builtins: 75% of 128 = 2^7 */ 253c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 7); 25403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra for (i = 0; mkshbuiltins[i].name != NULL; i++) 25503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!strcmp(ccp, builtin(mkshbuiltins[i].name, 25603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra mkshbuiltins[i].func))) 25703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Flag(FAS_BUILTIN) = 1; 25803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 25903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!Flag(FAS_BUILTIN)) { 26003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* check for -T option early */ 26103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra argi = parse_args(argv, OF_FIRSTTIME, NULL); 26203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (argi < 0) 26303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (1); 26403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 265811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser#if defined(MKSH_BINSHPOSIX) || defined(MKSH_BINSHREDUCED) 266811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser /* are we called as -sh or /bin/sh or so? */ 267811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser if (!strcmp(ccp, "sh")) { 268811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser /* either also turns off braceexpand */ 269811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser#ifdef MKSH_BINSHPOSIX 270811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser /* enable better POSIX conformance */ 271811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser change_flag(FPOSIX, OF_FIRSTTIME, true); 272811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser#endif 27303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#ifdef MKSH_BINSHREDUCED 274811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser /* enable kludge/compat mode */ 275c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser change_flag(FSH, OF_FIRSTTIME, true); 27603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 277811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser } 278811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser#endif 27903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 2805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru initvar(); 2825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru initctypes(); 2845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru inittraps(); 2865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru coproc_init(); 2885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* set up variable and command dictionaries */ 29003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ktinit(APERM, &taliases, 0); 29103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ktinit(APERM, &aliases, 0); 2925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_NOPWNAM 29303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ktinit(APERM, &homedirs, 0); 2945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 2955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* define shell keywords */ 2975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru initkeywords(); 2985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru init_histvec(); 3005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 301c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* initialise tty size before importing environment */ 302c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser change_winsz(); 303c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 3045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef _PATH_DEFPATH 3055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru def_path = _PATH_DEFPATH; 3065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#else 3075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef _CS_PATH 30803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((k = confstr(_CS_PATH, NULL, 0)) > 0 && 3095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru confstr(_CS_PATH, cp = alloc(k + 1, APERM), k + 1) == k + 1) 3105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru def_path = cp; 3115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 3125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 3135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 3145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * this is uniform across all OSes unless it 3155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * breaks somewhere; don't try to optimise, 3165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * e.g. add stuff for Interix or remove /usr 3175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * for HURD, because e.g. Debian GNU/HURD is 3185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * "keeping a regular /usr"; this is supposed 3195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * to be a sane 'basic' default PATH 3205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 3215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru def_path = "/bin:/usr/bin:/sbin:/usr/sbin"; 3225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 3235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 32503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Set PATH to def_path (will set the path global variable). 3265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (import of environment below will probably change this setting). 3275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 3285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp = global("PATH"); 3295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* setstr can't fail here */ 3305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setstr(vp, def_path, KSH_RETURN_ERROR); 3315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 332c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifndef MKSH_NO_CMDLINE_EDITING 33303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 33403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Set edit mode to emacs by default, may be overridden 3355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * by the environment or the user. Also, we want tab completion 33603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * on in vi by default. 33703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra */ 338c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser change_flag(FEMACS, OF_SPECIAL, true); 3395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if !MKSH_S_NOVI 3405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Flag(FVITABCOMPLETE) = 1; 3415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 342c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 3435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* import environment */ 345427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes if (environ != NULL) { 346427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes wp = (const char **)environ; 347427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes while (*wp != NULL) { 348427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes rndpush(*wp); 3495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru typeset(*wp, IMPORT | EXPORT, 0, 0, 0); 350427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes ++wp; 351427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes } 352427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes } 3535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 35403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* for security */ 35503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra typeset(initifs, 0, 0, 0, 0); 3565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* assign default shell variable values */ 3585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru substitute(initsubs, 0); 3595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Figure out the current working directory and set $PWD */ 36103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vp = global("PWD"); 36203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra cp = str_val(vp); 36303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* Try to use existing $PWD if it is valid */ 36403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra set_current_wd((cp[0] == '/' && test_eval(NULL, TO_FILEQ, cp, ".", 36503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra true)) ? cp : NULL); 36603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (current_wd[0]) 36703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra simplify_path(current_wd); 36803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* Only set pwd if we know where we are or if it had a bogus value */ 36903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (current_wd[0] || *cp) 37003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* setstr can't fail here */ 37103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra setstr(vp, current_wd, KSH_RETURN_ERROR); 3725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (wp = initcoms; *wp != NULL; wp++) { 3745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shcomexec(wp); 3755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (*wp != NULL) 3765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp++; 3775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 378c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser setint_n(global("OPTIND"), 1, 10); 37903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 38003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra kshuid = getuid(); 38103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra kshgid = getgid(); 38203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra kshegid = getegid(); 3835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru safe_prompt = ksheuid ? "$ " : "# "; 3855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp = global("PS1"); 3865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Set PS1 if unset or we are root and prompt doesn't contain a # */ 3875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(vp->flag & ISSET) || 3885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (!ksheuid && !strchr(str_val(vp), '#'))) 3895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* setstr can't fail here */ 3905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setstr(vp, safe_prompt, KSH_RETURN_ERROR); 391c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser setint_n((vp = global("BASHPID")), 0, 10); 392c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser vp->flag |= INT_U; 393c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser setint_n((vp = global("PGRP")), (mksh_uari_t)kshpgrp, 10); 3945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag |= INT_U; 395c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser setint_n((vp = global("PPID")), (mksh_uari_t)kshppid, 10); 3965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag |= INT_U; 397c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser setint_n((vp = global("USER_ID")), (mksh_uari_t)ksheuid, 10); 3985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag |= INT_U; 399c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser setint_n((vp = global("KSHUID")), (mksh_uari_t)kshuid, 10); 4005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag |= INT_U; 401c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser setint_n((vp = global("KSHEGID")), (mksh_uari_t)kshegid, 10); 40203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vp->flag |= INT_U; 403c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser setint_n((vp = global("KSHGID")), (mksh_uari_t)kshgid, 10); 40403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vp->flag |= INT_U; 405c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser setint_n((vp = global("RANDOM")), rndsetup(), 10); 40603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vp->flag |= INT_U; 407c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser setint_n((vp_pipest = global("PIPESTATUS")), 0, 10); 4085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Set this before parsing arguments */ 410b4542e99ca8562aa584e15df8ef35356ff8c10feElliott Hughes Flag(FPRIVILEGED) = ( 411b4542e99ca8562aa584e15df8ef35356ff8c10feElliott Hughes#if HAVE_ISSETUGID 412b4542e99ca8562aa584e15df8ef35356ff8c10feElliott Hughes issetugid() || 413b4542e99ca8562aa584e15df8ef35356ff8c10feElliott Hughes#endif 414b4542e99ca8562aa584e15df8ef35356ff8c10feElliott Hughes kshuid != ksheuid || kshgid != kshegid) ? 2 : 0; 4155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* this to note if monitor is set on command line (see below) */ 4175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_UNEMPLOYED 4185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Flag(FMONITOR) = 127; 4195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 4205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* this to note if utf-8 mode is set on command line (see below) */ 4215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru UTFMODE = 2; 4225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 42303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!Flag(FAS_BUILTIN)) { 42403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra argi = parse_args(argv, OF_CMDLINE, NULL); 42503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (argi < 0) 42603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (1); 42703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 42803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 4295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* process this later only, default to off (hysterical raisins) */ 4305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru utf_flag = UTFMODE; 4315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru UTFMODE = 0; 4325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 43303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (Flag(FAS_BUILTIN)) { 43403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* auto-detect from environment variables, always */ 43503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra utf_flag = 3; 43603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else if (Flag(FCOMMAND)) { 437c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser s = pushs(SSTRINGCMDLINE, ATEMP); 4385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(s->start = s->str = argv[argi++])) 43903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra errorf("%s %s", "-c", "requires an argument"); 440c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser while (*s->str) { 441c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (*s->str != ' ' && ctype(*s->str, C_QUOTE)) 442c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser break; 443c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser s->str++; 444c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 445c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (!*s->str) 446c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser s->flags |= SF_MAYEXEC; 447c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser s->str = s->start; 4485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef MKSH_MIDNIGHTBSD01ASH_COMPAT 4495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* compatibility to MidnightBSD 0.1 /bin/sh (kludge) */ 4505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (Flag(FSH) && argv[argi] && !strcmp(argv[argi], "--")) 4515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ++argi; 4525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 4535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (argv[argi]) 4545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru kshname = argv[argi++]; 4555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (argi < argc && !Flag(FSTDIN)) { 4565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = pushs(SFILE, ATEMP); 4575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->file = argv[argi++]; 4585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->u.shf = shf_open(s->file, O_RDONLY, 0, 4595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru SHF_MAPHI | SHF_CLEXEC); 4605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s->u.shf == NULL) { 46103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shl_stdout_ok = false; 462c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser warningf(true, "%s: %s", s->file, cstrerror(errno)); 4635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* mandated by SUSv4 */ 4645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru exstat = 127; 4655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unwind(LERROR); 4665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru kshname = s->file; 4685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 4695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Flag(FSTDIN) = 1; 4705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = pushs(SSTDIN, ATEMP); 4715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->file = "<stdin>"; 4725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->u.shf = shf_fdopen(0, SHF_RD | can_seek(0), 4735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru NULL); 4745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (isatty(0) && isatty(2)) { 4755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Flag(FTALKING) = Flag(FTALKING_I) = 1; 4765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* The following only if isatty(0) */ 4775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->flags |= SF_TTY; 4785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->u.shf->flags |= SHF_INTERRUPT; 4795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->file = NULL; 4805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* this bizarreness is mandated by POSIX */ 4845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (fstat(0, &s_stdin) >= 0 && S_ISCHR(s_stdin.st_mode) && 4855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Flag(FTALKING)) 4865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru reset_nonblock(0); 4875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* initialise job control */ 4895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru j_init(); 490c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* do this after j_init() which calls tty_init_state() */ 4915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (Flag(FTALKING)) { 4925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (utf_flag == 2) { 4935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_ASSUME_UTF8 49403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* auto-detect from locale or environment */ 49503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra utf_flag = 4; 496427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#else /* this may not be an #elif */ 497427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#if MKSH_ASSUME_UTF8 49803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra utf_flag = 1; 4995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#else 50003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* always disable UTF-8 (for interactive) */ 50103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra utf_flag = 0; 5025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 503427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#endif 5045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 505c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifndef MKSH_NO_CMDLINE_EDITING 5065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru x_init(); 507c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 5085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef SIGWINCH 5115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sigtraps[SIGWINCH].flags |= TF_SHELL_USES; 5125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setsig(&sigtraps[SIGWINCH], x_sigwinch, 5135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru SS_RESTORE_ORIG|SS_FORCE|SS_SHTRAP); 5145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 5155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru l = e->loc; 51703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (Flag(FAS_BUILTIN)) { 51803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra l->argc = argc; 51903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra l->argv = argv; 52003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra l->argv[0] = ccp; 52103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else { 52203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra l->argc = argc - argi; 523c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* 524c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * allocate a new array because otherwise, when we modify 525c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * it in-place, ps(1) output changes; the meaning of argc 526c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * here is slightly different as it excludes kshname, and 527c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * we add a trailing NULL sentinel as well 528c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser */ 529c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser l->argv = alloc2(l->argc + 2, sizeof(void *), APERM); 53003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra l->argv[0] = kshname; 531c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser memcpy(&l->argv[1], &argv[argi], l->argc * sizeof(void *)); 532c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser l->argv[l->argc + 1] = NULL; 53303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra getopts_reset(1); 53403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 53503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 53603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* divine the initial state of the utf8-mode Flag */ 53703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ccp = null; 53803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra switch (utf_flag) { 53903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 54003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* auto-detect from locale or environment */ 54103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 4: 54203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#if HAVE_SETLOCALE_CTYPE 54303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ccp = setlocale(LC_CTYPE, ""); 54403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#if HAVE_LANGINFO_CODESET 54503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!isuc(ccp)) 54603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ccp = nl_langinfo(CODESET); 54703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 54803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!isuc(ccp)) 54903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ccp = null; 55003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* FALLTHROUGH */ 55103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 55203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 55303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* auto-detect from environment */ 55403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 3: 55503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* these were imported from environ earlier */ 55603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (ccp == null) 55703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ccp = str_val(global("LC_ALL")); 55803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (ccp == null) 55903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ccp = str_val(global("LC_CTYPE")); 56003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (ccp == null) 56103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ccp = str_val(global("LANG")); 56203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra UTFMODE = isuc(ccp); 56303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 56403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 56503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* not set on command line, not FTALKING */ 56603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 2: 56703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* unknown values */ 56803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra default: 56903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra utf_flag = 0; 57003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* FALLTHROUGH */ 57103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 57203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* known values */ 57303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 1: 57403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 0: 57503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra UTFMODE = utf_flag; 57603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 57703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 5785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Disable during .profile/ENV reading */ 580b4542e99ca8562aa584e15df8ef35356ff8c10feElliott Hughes restricted_shell = Flag(FRESTRICTED); 5815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Flag(FRESTRICTED) = 0; 5825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru errexit = Flag(FERREXIT); 5835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Flag(FERREXIT) = 0; 5845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 58503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 58603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Do this before profile/$ENV so that if it causes problems in them, 5875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * user will know why things broke. 5885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 5895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!current_wd[0] && Flag(FTALKING)) 59003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra warningf(false, "can't determine current directory"); 5915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 592427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes if (Flag(FLOGIN)) 593c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser include(MKSH_SYSTEM_PROFILE, 0, NULL, true); 594427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes if (!Flag(FPRIVILEGED)) { 595427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes if (Flag(FLOGIN)) 596427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes include(substitute("$HOME/.profile", 0), 0, NULL, true); 597427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes if (Flag(FTALKING)) { 598427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes cp = substitute(substitute("${ENV:-" MKSHRC_PATH "}", 599427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes 0), DOTILDE); 600427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes if (cp[0] != '\0') 601427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes include(cp, 0, NULL, true); 602427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes } 603427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes } else { 604c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser include(MKSH_SUID_PROFILE, 0, NULL, true); 605427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes /* turn off -p if not set explicitly */ 606427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes if (Flag(FPRIVILEGED) != 1) 607427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes change_flag(FPRIVILEGED, OF_INTERNAL, false); 6085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 610b4542e99ca8562aa584e15df8ef35356ff8c10feElliott Hughes if (restricted_shell) { 6115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shcomexec(restr_com); 6125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* After typeset command... */ 6135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Flag(FRESTRICTED) = 1; 6145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Flag(FERREXIT) = errexit; 6165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 617c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (Flag(FTALKING) && s) 6185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hist_init(s); 61903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else 62003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* set after ENV */ 62103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Flag(FTRACKALL) = 1; 6225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 62303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra alarm_init(); 6245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 625c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser *sp = s; 626c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser *lp = l; 62703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (0); 6285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 6295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 630c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser/* this indirection barrier reduces stack usage during normal operation */ 631c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 632c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserint 633c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glasermain(int argc, const char *argv[]) 634c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser{ 635c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser int rv; 636c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser Source *s; 637c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser struct block *l; 638c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 639c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((rv = main_init(argc, argv, &s, &l)) == 0) { 640c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (Flag(FAS_BUILTIN)) { 641c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser rv = shcomexec(l->argv); 642c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } else { 643c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shell(s, true); 644c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* NOTREACHED */ 645c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 646c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 647c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return (rv); 648c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser} 649c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 6505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 651c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserinclude(const char *name, int argc, const char **argv, bool intr_ok) 6525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 6535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Source *volatile s = NULL; 6545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct shf *shf; 6555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char **volatile old_argv; 6565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru volatile int old_argc; 6575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int i; 6585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf = shf_open(name, O_RDONLY, 0, SHF_MAPHI | SHF_CLEXEC); 6605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (shf == NULL) 6615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (-1); 6625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (argv) { 6645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru old_argv = e->loc->argv; 6655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru old_argc = e->loc->argc; 6665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 6675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru old_argv = NULL; 6685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru old_argc = 0; 6695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru newenv(E_INCL); 671c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((i = kshsetjmp(e->jbuf))) { 6725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru quitenv(s ? s->u.shf : NULL); 6735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (old_argv) { 6745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru e->loc->argv = old_argv; 6755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru e->loc->argc = old_argc; 6765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (i) { 6785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case LRETURN: 6795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case LERROR: 68003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* see below */ 68103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (exstat & 0xFF); 6825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case LINTR: 68303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 68403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * intr_ok is set if we are including .profile or $ENV. 6855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * If user ^Cs out, we don't want to kill the shell... 6865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 687c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (intr_ok && ((exstat & 0xFF) - 128) != SIGTERM) 6885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 6895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* FALLTHROUGH */ 6905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case LEXIT: 6915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case LLEAVE: 6925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case LSHELL: 6935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unwind(i); 6945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* NOTREACHED */ 6955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 69603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra internal_errorf("%s %d", "include", i); 6975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* NOTREACHED */ 6985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (argv) { 7015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru e->loc->argv = argv; 7025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru e->loc->argc = argc; 7035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = pushs(SFILE, ATEMP); 7055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->u.shf = shf; 7065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strdupx(s->file, name, ATEMP); 7075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru i = shell(s, false); 7085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru quitenv(s->u.shf); 7095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (old_argv) { 7105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru e->loc->argv = old_argv; 7115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru e->loc->argc = old_argc; 7125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 71303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* & 0xff to ensure value not -1 */ 71403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (i & 0xFF); 7155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 7165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* spawn a command into a shell optionally keeping track of the line number */ 7185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 7195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querucommand(const char *comm, int line) 7205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 7215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Source *s; 7225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = pushs(SSTRING, ATEMP); 7245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->start = s->str = comm; 7255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->line = line; 7265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (shell(s, false)); 7275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 7285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 7305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * run the commands from the input source, returning status. 7315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 7325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 733c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glasershell(Source * volatile s, volatile bool toplevel) 7345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 7355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct op *t; 736c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser volatile bool wastty = tobool(s->flags & SF_TTY); 737c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser volatile uint8_t attempts = 13; 738c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser volatile bool interactive = Flag(FTALKING) && toplevel; 73903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra volatile bool sfirst = true; 7405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Source *volatile old_source = source; 7415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int i; 7425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru newenv(E_PARSE); 7445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (interactive) 745c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser really_exit = false; 746c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser switch ((i = kshsetjmp(e->jbuf))) { 747c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case 0: 748c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser break; 749c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case LINTR: 750c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* we get here if SIGINT not caught or ignored */ 751c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case LERROR: 752c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case LSHELL: 753c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (interactive) { 754c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (i == LINTR) 755c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shellf("\n"); 756c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* 757c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * Reset any eof that was read as part of a 758c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * multiline command. 759c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser */ 760c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (Flag(FIGNOREEOF) && s->type == SEOF && wastty) 761c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser s->type = SSTDIN; 762c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* 763c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * Used by exit command to get back to 764c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * top level shell. Kind of strange since 765c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * interactive is set if we are reading from 766c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * a tty, but to have stopped jobs, one only 767c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * needs FMONITOR set (not FTALKING/SF_TTY)... 768c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser */ 769c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* toss any input we have so far */ 770c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser yyrecursive_pop(true); 771c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser s->start = s->str = null; 772c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser retrace_info = NULL; 773c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser herep = heres; 774c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser break; 7755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 776c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* FALLTHROUGH */ 777c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case LEXIT: 778c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case LLEAVE: 779c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case LRETURN: 780c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser source = old_source; 781c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser quitenv(NULL); 782c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* keep on going */ 783c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser unwind(i); 784c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* NOTREACHED */ 785c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser default: 786c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser source = old_source; 787c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser quitenv(NULL); 788c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser internal_errorf("%s %d", "shell", i); 789c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* NOTREACHED */ 7905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 79103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (/* CONSTCOND */ 1) { 7925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (trap) 7935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru runtraps(0); 7945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s->next == NULL) { 7965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (Flag(FVERBOSE)) 7975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->flags |= SF_ECHO; 7985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 7995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->flags &= ~SF_ECHO; 8005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (interactive) { 8025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru j_notify(); 8035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru set_prompt(PS1, s); 8045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 80503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra t = compile(s, sfirst); 80603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra sfirst = false; 807c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (!t) 808c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto source_no_tree; 809c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (t->type == TEOF) { 8105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (wastty && Flag(FIGNOREEOF) && --attempts > 0) { 81103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shellf("Use 'exit' to leave mksh\n"); 8125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->type = SSTDIN; 8135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (wastty && !really_exit && 8145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru j_stopped_running()) { 815c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser really_exit = true; 8165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->type = SSTDIN; 8175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 81803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 81903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * this for POSIX which says EXIT traps 8205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * shall be taken in the environment 8215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * immediately after the last command 8225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * executed. 8235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 8245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (toplevel) 8255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unwind(LEXIT); 8265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 8275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 828427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes } else if ((s->flags & SF_MAYEXEC) && t->type == TCOM) 829c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser t->u.evalflags |= DOTCOMEXEC; 830c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (!Flag(FNOEXEC) || (s->flags & SF_TTY)) 831c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser exstat = execute(t, 0, NULL) & 0xFF; 8325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 833c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (t->type != TEOF && interactive && really_exit) 834c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser really_exit = false; 8355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 836c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser source_no_tree: 8375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru reclaim(); 8385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru quitenv(NULL); 8405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source = old_source; 841c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return (exstat & 0xFF); 8425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 8435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* return to closest error handler or shell(), exit if none found */ 845c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser/* note: i MUST NOT be 0 */ 8465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 8475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruunwind(int i) 8485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 849c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* 850c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * This is a kludge. We need to restore everything that was 851c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * changed in the new environment, see cid 1005090337C7A669439 852c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * and 10050903386452ACBF1, but fail to even save things most of 853c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * the time. funcs.c:c_eval() changes FERREXIT temporarily to 0, 854c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * which needs to be restored thus (related to Debian #696823). 855c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * We did not save the shell flags, so we use a special or'd 856c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * value here... this is mostly to clean up behind *other* 857c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * callers of unwind(LERROR) here; exec.c has the regular case. 858c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser */ 859c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (Flag(FERREXIT) & 0x80) { 860c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* GNU bash does not run this trapsig */ 861c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser trapsig(ksh_SIGERR); 862c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser Flag(FERREXIT) &= ~0x80; 863c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 864c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 8655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* ordering for EXIT vs ERR is a bit odd (this is what AT&T ksh does) */ 866811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser if (i == LEXIT || ((i == LERROR || i == LINTR) && 867811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser sigtraps[ksh_SIGEXIT].trap && 868811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser (!Flag(FTALKING) || Flag(FERREXIT)))) { 86903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++trap_nested; 87003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra runtrap(&sigtraps[ksh_SIGEXIT], trap_nested == 1); 87103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra --trap_nested; 8725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru i = LLEAVE; 873c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } else if (Flag(FERREXIT) == 1 && (i == LERROR || i == LINTR)) { 87403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++trap_nested; 87503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra runtrap(&sigtraps[ksh_SIGERR], trap_nested == 1); 87603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra --trap_nested; 8775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru i = LLEAVE; 8785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 879c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 88003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (/* CONSTCOND */ 1) { 8815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (e->type) { 8825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case E_PARSE: 8835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case E_FUNC: 8845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case E_INCL: 8855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case E_LOOP: 8865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case E_ERRH: 887c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser kshlongjmp(e->jbuf, i); 8885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* NOTREACHED */ 8895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case E_NONE: 8905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (i == LINTR) 8915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru e->flags |= EF_FAKE_SIGDIE; 8925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* FALLTHROUGH */ 8935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 8945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru quitenv(NULL); 8955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 8985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 9005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querunewenv(int type) 9015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 9025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct env *ep; 9035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *cp; 9045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 9065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * struct env includes ALLOC_ITEM for alignment constraints 9075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * so first get the actually used memory, then assign it 9085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 9095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru cp = alloc(sizeof(struct env) - ALLOC_SIZE, ATEMP); 91003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* undo what alloc() did to the malloc result address */ 91103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ep = (void *)(cp - ALLOC_SIZE); 9125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* initialise public members of struct env (not the ALLOC_ITEM) */ 9135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ainit(&ep->area); 9145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ep->oenv = e; 9155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ep->loc = e->loc; 9165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ep->savefd = NULL; 9175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ep->temps = NULL; 918c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ep->yyrecursive_statep = NULL; 9195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ep->type = type; 9205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ep->flags = 0; 9215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* jump buffer is invalid because flags == 0 */ 9225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru e = ep; 9235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 9245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 9265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruquitenv(struct shf *shf) 9275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 9285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct env *ep = e; 9295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *cp; 9305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int fd; 9315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 932c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser yyrecursive_pop(true); 933c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser while (ep->oenv && ep->oenv->loc != ep->loc) 9345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru popblock(); 9355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ep->savefd != NULL) { 9365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (fd = 0; fd < NUFILE; fd++) 9375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* if ep->savefd[fd] < 0, means fd was closed */ 9385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ep->savefd[fd]) 9395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru restfd(fd, ep->savefd[fd]); 94003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (ep->savefd[2]) 94103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* Clear any write errors */ 9425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_reopen(2, SHF_WR, shl_out); 9435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 94403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 94503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Bottom of the stack. 9465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Either main shell is exiting or cleanup_parents_env() was called. 9475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 9485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ep->oenv == NULL) { 949c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef DEBUG_LEAKS 950c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser int i; 951c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 952c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 95303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (ep->type == E_NONE) { 95403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* Main shell exiting? */ 9555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if HAVE_PERSISTENT_HISTORY 9565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (Flag(FTALKING)) 9575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hist_finish(); 9585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 9595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru j_exit(); 9605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ep->flags & EF_FAKE_SIGDIE) { 961c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser int sig = (exstat & 0xFF) - 128; 9625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 96303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 96403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * ham up our death a bit (AT&T ksh 9655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * only seems to do this for SIGTERM) 9665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Don't do it for SIGQUIT, since we'd 9675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * dump a core.. 9685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 9695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((sig == SIGINT || sig == SIGTERM) && 9705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (kshpgrp == kshpid)) { 9715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setsig(&sigtraps[sig], SIG_DFL, 9725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru SS_RESTORE_CURR | SS_FORCE); 9735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru kill(0, sig); 9745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (shf) 9785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_close(shf); 9795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru reclaim(); 980c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef DEBUG_LEAKS 981c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifndef MKSH_NO_CMDLINE_EDITING 982c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser x_done(); 983c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 984811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser#ifndef MKSH_NOPROSPECTOFWORK 985811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser /* block at least SIGCHLD during/after afreeall */ 986811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser sigprocmask(SIG_BLOCK, &sm_sigchld, NULL); 987811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser#endif 988c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser afreeall(APERM); 989c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser for (fd = 3; fd < NUFILE; fd++) 990c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((i = fcntl(fd, F_GETFD, 0)) != -1 && 991c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser (i & FD_CLOEXEC)) 992c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser close(fd); 993c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser close(2); 994c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser close(1); 995c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser close(0); 996c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 997c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser exit(exstat & 0xFF); 9985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (shf) 10005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_close(shf); 10015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru reclaim(); 10025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru e = e->oenv; 10045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* free the struct env - tricky due to the ALLOC_ITEM inside */ 10065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru cp = (void *)ep; 10075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(cp + ALLOC_SIZE, ATEMP); 10085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 10095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Called after a fork to cleanup stuff left over from parents environment */ 10115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 10125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querucleanup_parents_env(void) 10135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 10145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct env *ep; 10155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int fd; 10165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mkssert(e != NULL); 10185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 10205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Don't clean up temporary files - parent will probably need them. 10215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Also, can't easily reclaim memory since variables, etc. could be 10225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * anywhere. 10235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 10245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* close all file descriptors hiding in savefd */ 10265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (ep = e; ep; ep = ep->oenv) { 10275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ep->savefd) { 10285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (fd = 0; fd < NUFILE; fd++) 10295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ep->savefd[fd] > 0) 10305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru close(ep->savefd[fd]); 10315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(ep->savefd, &ep->area); 10325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ep->savefd = NULL; 10335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 1034c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef DEBUG_LEAKS 1035c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (ep->type != E_NONE) 1036c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ep->type = E_GONE; 1037c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 10385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 1039c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifndef DEBUG_LEAKS 10405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru e->oenv = NULL; 1041c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 10425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 10435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Called just before an execve cleanup stuff temporary files */ 10455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 10465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querucleanup_proc_env(void) 10475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 10485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct env *ep; 10495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (ep = e; ep; ep = ep->oenv) 10515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru remove_temps(ep->temps); 10525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 10535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* remove temp files and free ATEMP Area */ 10555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 10565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querureclaim(void) 10575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 1058c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser struct block *l; 1059c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1060c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser while ((l = e->loc) && (!e->oenv || e->oenv->loc != l)) { 1061c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser e->loc = l->next; 1062c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser afreeall(&l->area); 1063c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 1064c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 10655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru remove_temps(e->temps); 10665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru e->temps = NULL; 10675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afreeall(&e->area); 10685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 10695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 10715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruremove_temps(struct temp *tp) 10725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 10735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; tp != NULL; tp = tp->next) 10745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tp->pid == procpid) 1075c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser unlink(tp->tffn); 10765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 10775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 107803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* 1079c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * Initialise tty_fd. Used for tracking the size of the terminal, 1080c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * saving/resetting tty modes upon forground job completion, and 1081c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * for setting up the tty process group. Return values: 1082c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * 0 = got controlling tty 1083c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * 1 = got terminal but no controlling tty 1084c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * 2 = cannot find a terminal 1085c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * 3 = cannot dup fd 1086c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * 4 = cannot make fd close-on-exec 1087c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * An existing tty_fd is cached if no "better" one could be found, 1088c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * i.e. if tty_devtty was already set or the new would not set it. 10895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 1090c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserint 1091c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glasertty_init_fd(void) 10925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 1093c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser int fd, rv, eno = 0; 1094c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bool do_close = false, is_devtty = true; 10955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1096c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (tty_devtty) { 1097c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* already got a tty which is /dev/tty */ 1098c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return (0); 10995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef _UWIN 110203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /*XXX imake style */ 110303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (isatty(3)) { 110403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* fd 3 on UWIN _is_ /dev/tty (or our controlling tty) */ 1105c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser fd = 3; 1106c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto got_fd; 11075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 1108c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 1109c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((fd = open("/dev/tty", O_RDWR, 0)) >= 0) { 1110c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser do_close = true; 1111c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto got_fd; 11125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 1113c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser eno = errno; 11145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tty_fd >= 0) { 1116c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* already got a non-devtty one */ 1117c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser rv = 1; 1118c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto out; 11195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 1120c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser is_devtty = false; 1121c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1122c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (isatty((fd = 0)) || isatty((fd = 2))) 1123c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto got_fd; 1124c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* cannot find one */ 1125c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser rv = 2; 1126c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* assert: do_close == false */ 1127c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto out; 1128c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1129c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser got_fd: 1130c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((rv = fcntl(fd, F_DUPFD, FDBASE)) < 0) { 1131c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser eno = errno; 1132c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser rv = 3; 1133c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto out; 1134c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 1135c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (fcntl(rv, F_SETFD, FD_CLOEXEC) < 0) { 1136c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser eno = errno; 1137c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser close(rv); 1138c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser rv = 4; 1139c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto out; 1140c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 1141c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser tty_fd = rv; 1142c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser tty_devtty = is_devtty; 1143c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser rv = eno = 0; 1144c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser out: 1145c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (do_close) 1146c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser close(fd); 1147c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser errno = eno; 1148c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return (rv); 11495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 11505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* A shell error occurred (eg, syntax error, etc.) */ 115203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 115303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define VWARNINGF_ERRORPREFIX 1 115403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define VWARNINGF_FILELINE 2 115503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define VWARNINGF_BUILTIN 4 115603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define VWARNINGF_INTERNAL 8 115703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 115803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic void vwarningf(unsigned int, const char *, va_list) 115903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra MKSH_A_FORMAT(__printf__, 2, 0); 116003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 116103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic void 116203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condravwarningf(unsigned int flags, const char *fmt, va_list ap) 116303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{ 1164c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (fmt) { 116503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (flags & VWARNINGF_INTERNAL) 116603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shf_fprintf(shl_out, "internal error: "); 116703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (flags & VWARNINGF_ERRORPREFIX) 116803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra error_prefix(tobool(flags & VWARNINGF_FILELINE)); 116903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((flags & VWARNINGF_BUILTIN) && 117003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* not set when main() calls parse_args() */ 117103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra builtin_argv0 && builtin_argv0 != kshname) 117203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shf_fprintf(shl_out, "%s: ", builtin_argv0); 117303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shf_vfprintf(shl_out, fmt, ap); 117403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shf_putchar('\n', shl_out); 117503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 117603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shf_flush(shl_out); 117703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra} 117803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 117903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condravoid 118003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condraerrorfx(int rc, const char *fmt, ...) 118103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{ 118203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra va_list va; 118303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 118403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra exstat = rc; 118503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 118603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* debugging: note that stdout not valid */ 118703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shl_stdout_ok = false; 118803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 118903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra va_start(va, fmt); 119003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vwarningf(VWARNINGF_ERRORPREFIX | VWARNINGF_FILELINE, fmt, va); 119103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra va_end(va); 119203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra unwind(LERROR); 119303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra} 119403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 11955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 11965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruerrorf(const char *fmt, ...) 11975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 11985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_list va; 11995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru exstat = 1; 120103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 120203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* debugging: note that stdout not valid */ 120303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shl_stdout_ok = false; 120403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 120503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra va_start(va, fmt); 120603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vwarningf(VWARNINGF_ERRORPREFIX | VWARNINGF_FILELINE, fmt, va); 120703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra va_end(va); 12085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unwind(LERROR); 12095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 12105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* like errorf(), but no unwind is done */ 12125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 12135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruwarningf(bool fileline, const char *fmt, ...) 12145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 12155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_list va; 12165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_start(va, fmt); 121803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vwarningf(VWARNINGF_ERRORPREFIX | (fileline ? VWARNINGF_FILELINE : 0), 121903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra fmt, va); 12205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_end(va); 12215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 12225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 122303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* 122403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Used by built-in utilities to prefix shell and utility name to message 12255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (also unwinds environments for special builtins). 12265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 12275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 12285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querubi_errorf(const char *fmt, ...) 12295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 12305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_list va; 12315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 123203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* debugging: note that stdout not valid */ 123303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shl_stdout_ok = false; 123403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 12355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru exstat = 1; 123603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 123703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra va_start(va, fmt); 123803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vwarningf(VWARNINGF_ERRORPREFIX | VWARNINGF_FILELINE | 123903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra VWARNINGF_BUILTIN, fmt, va); 124003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra va_end(va); 124103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 124203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 124303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * POSIX special builtins and ksh special builtins cause 12445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * non-interactive shells to exit. 12455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * XXX odd use of KEEPASN; also may not want LERROR here 12465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 12475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (builtin_flag & SPEC_BI) { 12485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru builtin_argv0 = NULL; 12495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unwind(LERROR); 12505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 12515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 12525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Called when something that shouldn't happen does */ 12545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 12555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruinternal_errorf(const char *fmt, ...) 12565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 12575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_list va; 12585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_start(va, fmt); 126003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vwarningf(VWARNINGF_INTERNAL, fmt, va); 12615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_end(va); 12625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unwind(LERROR); 12635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 12645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 12665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruinternal_warningf(const char *fmt, ...) 12675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 12685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_list va; 12695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_start(va, fmt); 127103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vwarningf(VWARNINGF_INTERNAL, fmt, va); 12725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_end(va); 12735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 12745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* used by error reporting functions to print "ksh: .kshrc[25]: " */ 12765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 12775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruerror_prefix(bool fileline) 12785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 12795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Avoid foo: foo[2]: ... */ 12805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!fileline || !source || !source->file || 12815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strcmp(source->file, kshname) != 0) 12825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_fprintf(shl_out, "%s: ", kshname + (*kshname == '-')); 12835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (fileline && source && source->file != NULL) { 12845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_fprintf(shl_out, "%s[%d]: ", source->file, 12855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source->errline > 0 ? source->errline : source->line); 12865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source->errline = 0; 12875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 12885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 12895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* printf to shl_out (stderr) with flush */ 12915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 12925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querushellf(const char *fmt, ...) 12935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 12945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_list va; 12955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 129603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!initio_done) 129703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* shl_out may not be set up yet... */ 12985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return; 12995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_start(va, fmt); 13005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_vfprintf(shl_out, fmt, va); 13015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_end(va); 13025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_flush(shl_out); 13035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 13045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* printf to shl_stdout (stdout) */ 13065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 13075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querushprintf(const char *fmt, ...) 13085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 13095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_list va; 13105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!shl_stdout_ok) 13125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru internal_errorf("shl_stdout not valid"); 13135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_start(va, fmt); 13145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_vfprintf(shl_stdout, fmt, va); 13155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_end(va); 13165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 13175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* test if we can seek backwards fd (returns 0 or SHF_UNBUF) */ 13195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 13205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querucan_seek(int fd) 13215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 13225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct stat statb; 13235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (fstat(fd, &statb) == 0 && !S_ISREG(statb.st_mode) ? 13255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru SHF_UNBUF : 0); 13265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 13275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1328c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef DF 1329c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserint shl_dbg_fd; 1330c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#define NSHF_IOB 4 1331c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#else 1332c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#define NSHF_IOB 3 1333c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 1334c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstruct shf shf_iob[NSHF_IOB]; 13355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 13375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruinitio(void) 13385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 1339c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef DF 1340c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser const char *lfp; 1341c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 1342c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 134303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* force buffer allocation */ 134403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shf_fdopen(1, SHF_WR, shl_stdout); 13455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_fdopen(2, SHF_WR, shl_out); 1346811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser shf_fdopen(2, SHF_WR, shl_xtrace); 1347c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef DF 1348c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((lfp = getenv("SDMKSH_PATH")) == NULL) { 1349c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((lfp = getenv("HOME")) == NULL || *lfp != '/') 1350c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser errorf("cannot get home directory"); 1351c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser lfp = shf_smprintf("%s/mksh-dbg.txt", lfp); 1352c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 1353c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1354c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((shl_dbg_fd = open(lfp, O_WRONLY | O_APPEND | O_CREAT, 0600)) < 0) 1355c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser errorf("cannot open debug output file %s", lfp); 1356c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (shl_dbg_fd < FDBASE) { 1357c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser int nfd; 1358c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1359c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser nfd = fcntl(shl_dbg_fd, F_DUPFD, FDBASE); 1360c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser close(shl_dbg_fd); 1361c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((shl_dbg_fd = nfd) == -1) 1362c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser errorf("cannot dup debug output file"); 1363c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 1364c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser fcntl(shl_dbg_fd, F_SETFD, FD_CLOEXEC); 1365c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shf_fdopen(shl_dbg_fd, SHF_WR, shl_dbg); 1366c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser DF("=== open ==="); 1367c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 1368c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser initio_done = true; 13695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 13705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* A dup2() with error checking */ 13725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 13735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruksh_dup2(int ofd, int nfd, bool errok) 13745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 13755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv; 13765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (((rv = dup2(ofd, nfd)) < 0) && !errok && (errno != EBADF)) 13785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru errorf("too many files open in shell"); 13795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef __ultrix 138103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /*XXX imake style */ 13825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (rv >= 0) 13835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fcntl(nfd, F_SETFD, 0); 13845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 13855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 13875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 13885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 139003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Move fd from user space (0 <= fd < 10) to shell space (fd >= 10), 139103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * set close-on-exec flag. See FDBASE in sh.h, maybe 24 not 10 here. 13925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 13935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querushort 13945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querusavefd(int fd) 13955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 13965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int nfd = fd; 13975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (fd < FDBASE && (nfd = fcntl(fd, F_DUPFD, FDBASE)) < 0 && 13995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru errno == EBADF) 14005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (-1); 14015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (nfd < 0 || nfd > SHRT_MAX) 14025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru errorf("too many files open in shell"); 14035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fcntl(nfd, F_SETFD, FD_CLOEXEC); 14045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return ((short)nfd); 14055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 14065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 14085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querurestfd(int fd, int ofd) 14095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 14105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (fd == 2) 1411c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shf_flush(&shf_iob[/* fd */ 2]); 141203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (ofd < 0) 141303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* original fd closed */ 14145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru close(fd); 14155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (fd != ofd) { 141603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /*XXX: what to do if this dup fails? */ 141703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ksh_dup2(ofd, fd, true); 14185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru close(ofd); 14195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 14215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 14235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruopenpipe(int *pv) 14245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 14255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int lpv[2]; 14265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (pipe(lpv) < 0) 14285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru errorf("can't create pipe - try again"); 14295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru pv[0] = savefd(lpv[0]); 14305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (pv[0] != lpv[0]) 14315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru close(lpv[0]); 14325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru pv[1] = savefd(lpv[1]); 14335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (pv[1] != lpv[1]) 14345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru close(lpv[1]); 14355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 14365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 14385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruclosepipe(int *pv) 14395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 14405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru close(pv[0]); 14415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru close(pv[1]); 14425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 14435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 144403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* 144503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Called by iosetup() (deals with 2>&4, etc.), c_read, c_print to turn 14465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * a string (the X in 2>&X, read -uX, print -uX) into a file descriptor. 14475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 14485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 14495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querucheck_fd(const char *name, int mode, const char **emsgp) 14505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 14515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int fd, fl; 14525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (name[0] == 'p' && !name[1]) 14545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (coproc_getfd(mode, emsgp)); 14555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (fd = 0; ksh_isdigit(*name); ++name) 14565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fd = (fd * 10) + *name - '0'; 14575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*name || fd >= FDBASE) { 14585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (emsgp) 14595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *emsgp = "illegal file descriptor name"; 14605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (-1); 14615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((fl = fcntl(fd, F_GETFL, 0)) < 0) { 14635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (emsgp) 14645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *emsgp = "bad file descriptor"; 14655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (-1); 14665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fl &= O_ACCMODE; 146803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 146903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * X_OK is a kludge to disable this check for dups (x<&1): 14705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * historical shells never did this check (XXX don't know what 14715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * POSIX has to say). 14725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 14735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(mode & X_OK) && fl != O_RDWR && ( 14745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ((mode & R_OK) && fl != O_RDONLY) || 14755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ((mode & W_OK) && fl != O_WRONLY))) { 14765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (emsgp) 14775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *emsgp = (fl == O_WRONLY) ? 14785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "fd not open for reading" : 14795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "fd not open for writing"; 14805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (-1); 14815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (fd); 14835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 14845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Called once from main */ 14865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 14875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querucoproc_init(void) 14885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 14895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru coproc.read = coproc.readw = coproc.write = -1; 14905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru coproc.njobs = 0; 14915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru coproc.id = 0; 14925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 14935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Called by c_read() when eof is read - close fd if it is the co-process fd */ 14955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 14965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querucoproc_read_close(int fd) 14975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 14985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (coproc.read >= 0 && fd == coproc.read) { 14995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru coproc_readw_close(fd); 15005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru close(coproc.read); 15015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru coproc.read = -1; 15025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 15045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 150503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* 150603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Called by c_read() and by iosetup() to close the other side of the 15075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * read pipe, so reads will actually terminate. 15085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 15095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 15105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querucoproc_readw_close(int fd) 15115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 15125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (coproc.readw >= 0 && coproc.read >= 0 && fd == coproc.read) { 15135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru close(coproc.readw); 15145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru coproc.readw = -1; 15155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 15175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 151803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* 151903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Called by c_print when a write to a fd fails with EPIPE and by iosetup 15205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * when co-process input is dup'd 15215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 15225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 15235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querucoproc_write_close(int fd) 15245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 15255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (coproc.write >= 0 && fd == coproc.write) { 15265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru close(coproc.write); 15275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru coproc.write = -1; 15285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 15305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 153103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* 153203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Called to check for existence of/value of the co-process file descriptor. 15335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (Used by check_fd() and by c_read/c_print to deal with -p option). 15345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 15355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 15365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querucoproc_getfd(int mode, const char **emsgp) 15375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 15385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int fd = (mode & R_OK) ? coproc.read : coproc.write; 15395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (fd >= 0) 15415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (fd); 15425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (emsgp) 15435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *emsgp = "no coprocess"; 15445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (-1); 15455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 15465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 154703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* 154803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * called to close file descriptors related to the coprocess (if any) 15495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Should be called with SIGCHLD blocked. 15505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 15515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 15525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querucoproc_cleanup(int reuse) 15535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 15545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* This to allow co-processes to share output pipe */ 15555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!reuse || coproc.readw < 0 || coproc.read < 0) { 15565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (coproc.read >= 0) { 15575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru close(coproc.read); 15585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru coproc.read = -1; 15595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (coproc.readw >= 0) { 15615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru close(coproc.readw); 15625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru coproc.readw = -1; 15635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (coproc.write >= 0) { 15665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru close(coproc.write); 15675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru coproc.write = -1; 15685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 15705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustruct temp * 15725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querumaketemp(Area *ap, Temp_type type, struct temp **tlist) 15735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 1574c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser char *cp; 157503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra size_t len; 1576811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser int i, j; 1577c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser struct temp *tp; 15785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *dir; 1579c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser struct stat sb; 15805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru dir = tmpdir ? tmpdir : MKSH_DEFAULT_TMPDIR; 1582c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* add "/shXXXXXX.tmp" plus NUL */ 1583c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser len = strlen(dir); 1584c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser checkoktoadd(len, offsetof(struct temp, tffn[0]) + 14); 1585c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser tp = alloc(offsetof(struct temp, tffn[0]) + 14 + len, ap); 1586c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 15875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp->shf = NULL; 15885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp->pid = procpid; 1589c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser tp->type = type; 1590c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1591c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (stat(dir, &sb) || !S_ISDIR(sb.st_mode)) { 1592c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser tp->tffn[0] = '\0'; 1593c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto maketemp_out; 1594c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 1595c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1596c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser cp = (void *)tp; 1597c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser cp += offsetof(struct temp, tffn[0]); 1598c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser memcpy(cp, dir, len); 1599c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser cp += len; 1600c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser memcpy(cp, "/shXXXXXX.tmp", 14); 1601c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* point to the first of six Xes */ 1602c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser cp += 3; 1603c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* generate random part of filename */ 1604c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser len = -1; 1605c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser do { 1606c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser i = rndget() % 36; 1607c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser cp[++len] = i < 26 ? 'a' + i : '0' + i - 26; 1608c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } while (len < 5); 1609c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1610c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* cyclically attempt to open a temporary file */ 1611427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes while ((i = open(tp->tffn, O_CREAT | O_EXCL | O_RDWR | O_BINARY, 1612427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes 0600)) < 0) { 1613c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (errno != EEXIST) 1614c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto maketemp_out; 1615c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* count down from z to a then from 9 to 0 */ 1616c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser while (cp[len] == '0') 1617c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (!len--) 1618c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto maketemp_out; 1619c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (cp[len] == 'a') 1620c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser cp[len] = '9'; 1621c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser else 1622c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser --cp[len]; 1623c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* do another cycle */ 1624c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 1625c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1626c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (type == TT_FUNSUB) { 1627c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* map us high and mark as close-on-exec */ 1628811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser if ((j = savefd(i)) != i) { 1629c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser close(i); 1630811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser i = j; 1631c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 1632811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser 1633811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser /* operation mode for the shf */ 1634811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser j = SHF_RD; 1635811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser } else 1636811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser j = SHF_WR; 16375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1638c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* shf_fdopen cannot fail, so no fd leak */ 1639811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser tp->shf = shf_fdopen(i, j, NULL); 1640c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1641c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser maketemp_out: 16425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp->next = *tlist; 16435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *tlist = tp; 16445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (tp); 16455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 16465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 16485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * We use a similar collision resolution algorithm as Python 2.5.4 16495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * but with a slightly tweaked implementation written from scratch. 16505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 16515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 165203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define INIT_TBLSHIFT 3 /* initial table shift (2^3 = 8) */ 16535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define PERTURB_SHIFT 5 /* see Python 2.5.4 Objects/dictobject.c */ 16545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 165503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic void tgrow(struct table *); 16565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int tnamecmp(const void *, const void *); 16575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 165903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condratgrow(struct table *tp) 16605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 166103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra size_t i, j, osize, mask, perturb; 16625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *tblp, **pp; 16635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl **ntblp, **otblp = tp->tbls; 16645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 166503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (tp->tshift > 29) 166603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra internal_errorf("hash table size limit reached"); 166703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 166803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* calculate old size, new shift and new size */ 166903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra osize = (size_t)1 << (tp->tshift++); 167003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra i = osize << 1; 167103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 167203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ntblp = alloc2(i, sizeof(struct tbl *), tp->areap); 167303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* multiplication cannot overflow: alloc2 checked that */ 167403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra memset(ntblp, 0, i * sizeof(struct tbl *)); 167503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 1676c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* table can get very full when reaching its size limit */ 1677c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser tp->nfree = (tp->tshift == 30) ? 0x3FFF0000UL : 1678c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* but otherwise, only 75% */ 1679c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ((i * 3) / 4); 16805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp->tbls = ntblp; 16815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (otblp == NULL) 16825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return; 168303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 168403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra mask = i - 1; 16855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (i = 0; i < osize; i++) 16865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((tblp = otblp[i]) != NULL) { 16875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((tblp->flag & DEFINED)) { 16885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* search for free hash table slot */ 1689c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser j = perturb = tblp->ua.hval; 16905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto find_first_empty_slot; 16915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru find_next_empty_slot: 16925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru j = (j << 2) + j + perturb + 1; 16935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru perturb >>= PERTURB_SHIFT; 16945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru find_first_empty_slot: 169503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra pp = &ntblp[j & mask]; 16965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*pp != NULL) 16975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto find_next_empty_slot; 16985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* found an empty hash table slot */ 16995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *pp = tblp; 17005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp->nfree--; 17015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (!(tblp->flag & FINUSE)) { 17025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(tblp, tp->areap); 17035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(otblp, tp->areap); 17065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 17075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 170903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condraktinit(Area *ap, struct table *tp, uint8_t initshift) 17105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 17115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp->areap = ap; 17125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp->tbls = NULL; 171303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra tp->tshift = ((initshift > INIT_TBLSHIFT) ? 171403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra initshift : INIT_TBLSHIFT) - 1; 171503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra tgrow(tp); 17165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 17175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* table, name (key) to search for, hash(name), rv pointer to tbl ptr */ 171903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastruct tbl * 17205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruktscan(struct table *tp, const char *name, uint32_t h, struct tbl ***ppp) 17215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 17225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru size_t j, perturb, mask; 17235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl **pp, *p; 17245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 172503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra mask = ((size_t)1 << (tp->tshift)) - 1; 17265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* search for hash table slot matching name */ 1727c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser j = perturb = h; 17285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto find_first_slot; 17295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru find_next_slot: 17305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru j = (j << 2) + j + perturb + 1; 17315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru perturb >>= PERTURB_SHIFT; 17325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru find_first_slot: 17335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru pp = &tp->tbls[j & mask]; 17345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((p = *pp) != NULL && (p->ua.hval != h || !(p->flag & DEFINED) || 17355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strcmp(p->name, name))) 17365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto find_next_slot; 17375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* p == NULL if not found, correct found entry otherwise */ 17385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ppp) 17395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *ppp = pp; 17405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (p); 17415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 17425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* table, name (key) to enter, hash(n) */ 17445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustruct tbl * 17455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruktenter(struct table *tp, const char *n, uint32_t h) 17465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 17475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl **pp, *p; 174803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra size_t len; 17495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Search: 17515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((p = ktscan(tp, n, h, &pp))) 17525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (p); 17535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 175403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (tp->nfree == 0) { 17555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* too full */ 175603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra tgrow(tp); 17575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto Search; 17585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* create new tbl entry */ 176103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra len = strlen(n); 176203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra checkoktoadd(len, offsetof(struct tbl, name[0]) + 1); 176303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra p = alloc(offsetof(struct tbl, name[0]) + ++len, tp->areap); 17645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p->flag = 0; 17655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p->type = 0; 17665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p->areap = tp->areap; 17675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p->ua.hval = h; 17685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p->u2.field = 0; 17695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p->u.array = NULL; 17705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru memcpy(p->name, n, len); 17715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* enter in tp->tbls */ 17735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp->nfree--; 17745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *pp = p; 17755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (p); 17765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 17775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 17795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruktwalk(struct tstate *ts, struct table *tp) 17805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 178103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ts->left = (size_t)1 << (tp->tshift); 17825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ts->next = tp->tbls; 17835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 17845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustruct tbl * 17865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruktnext(struct tstate *ts) 17875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 17885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (--ts->left >= 0) { 17895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *p = *ts->next++; 17905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (p != NULL && (p->flag & DEFINED)) 17915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (p); 17925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (NULL); 17945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 17955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 17975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutnamecmp(const void *p1, const void *p2) 17985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 17995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const struct tbl *a = *((const struct tbl * const *)p1); 18005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const struct tbl *b = *((const struct tbl * const *)p2); 18015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 18025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (strcmp(a->name, b->name)); 18035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 18045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 18055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustruct tbl ** 18065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruktsort(struct table *tp) 18075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 18085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru size_t i; 18095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl **p, **sp, **dp; 18105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 181103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 181203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * since the table is never entirely full, no need to reserve 181303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * additional space for the trailing NULL appended below 181403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra */ 181503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra i = (size_t)1 << (tp->tshift); 181603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra p = alloc2(i, sizeof(struct tbl *), ATEMP); 18175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sp = tp->tbls; /* source */ 18185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru dp = p; /* dest */ 18195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (i--) 18205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((*dp = *sp++) != NULL && (((*dp)->flag & DEFINED) || 18215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ((*dp)->flag & ARRAY))) 18225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru dp++; 182303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra qsort(p, (i = dp - p), sizeof(struct tbl *), tnamecmp); 18245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p[i] = NULL; 18255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (p); 18265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 18275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 18285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef SIGWINCH 18295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 18305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querux_sigwinch(int sig MKSH_A_UNUSED) 18315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 18325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* this runs inside interrupt context, with errno saved */ 18335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 18345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru got_winch = 1; 18355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 18365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 1837c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1838c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef DF 1839c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaservoid 1840c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten GlaserDF(const char *fmt, ...) 1841c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser{ 1842c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser va_list args; 1843c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser struct timeval tv; 1844c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser mirtime_mjd mjd; 1845c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1846c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser mksh_lockfd(shl_dbg_fd); 1847c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser mksh_TIME(tv); 1848c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser timet2mjd(&mjd, tv.tv_sec); 1849c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shf_fprintf(shl_dbg, "[%02u:%02u:%02u (%u) %u.%06u] ", 1850c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser (unsigned)mjd.sec / 3600, ((unsigned)mjd.sec / 60) % 60, 1851c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser (unsigned)mjd.sec % 60, (unsigned)getpid(), 1852c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser (unsigned)tv.tv_sec, (unsigned)tv.tv_usec); 1853c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser va_start(args, fmt); 1854c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shf_vfprintf(shl_dbg, fmt, args); 1855c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser va_end(args); 1856c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shf_putc('\n', shl_dbg); 1857c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shf_flush(shl_dbg); 1858c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser mksh_unlkfd(shl_dbg_fd); 1859c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser} 1860c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 1861c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1862c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaservoid 1863c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserx_mkraw(int fd, mksh_ttyst *ocb, bool forread) 1864c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser{ 1865c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser mksh_ttyst cb; 1866c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1867c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (ocb) 1868c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser mksh_tcget(fd, ocb); 1869c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser else 1870c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ocb = &tty_state; 1871c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1872c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser cb = *ocb; 1873c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (forread) { 1874427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes cb.c_iflag &= ~(ISTRIP); 1875c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser cb.c_lflag &= ~(ICANON) | ECHO; 1876c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } else { 1877427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes cb.c_iflag &= ~(INLCR | ICRNL | ISTRIP); 1878c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser cb.c_lflag &= ~(ISIG | ICANON | ECHO); 1879c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 1880c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#if defined(VLNEXT) && defined(_POSIX_VDISABLE) 1881c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* OSF/1 processes lnext when ~icanon */ 1882c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser cb.c_cc[VLNEXT] = _POSIX_VDISABLE; 1883c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 1884c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* SunOS 4.1.x & OSF/1 processes discard(flush) when ~icanon */ 1885c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#if defined(VDISCARD) && defined(_POSIX_VDISABLE) 1886c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser cb.c_cc[VDISCARD] = _POSIX_VDISABLE; 1887c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 1888c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser cb.c_cc[VTIME] = 0; 1889c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser cb.c_cc[VMIN] = 1; 1890c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1891c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser mksh_tcset(fd, &cb); 1892c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser} 1893