main.c revision 966dd55b233982d9657c50b971cfa754d0315c19
1fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes/* $OpenBSD: main.c,v 1.57 2015/09/10 22:48:58 nicm Exp $ */ 256b517d46cdf4f6ccd6b62b207110e2afc3db30bElliott Hughes/* $OpenBSD: tty.c,v 1.10 2014/08/10 02:44:26 guenther Exp $ */ 3fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes/* $OpenBSD: io.c,v 1.26 2015/09/11 08:00:27 guenther Exp $ */ 4fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes/* $OpenBSD: table.c,v 1.16 2015/09/01 13:12:31 tedu Exp $ */ 55155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 65155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/*- 7c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 877740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes * 2011, 2012, 2013, 2014, 2015, 2016 9fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes * mirabilos <m@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 37966dd55b233982d9657c50b971cfa754d0315c19Elliott Hughes__RCSID("$MirOS: src/bin/mksh/main.c,v 1.322 2016/11/11 23:48:30 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 4696b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes#define MKSH_DEFAULT_TMPDIR MKSH_UNIXROOT "/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[] = 62966dd55b233982d9657c50b971cfa754d0315c19Elliott Hughes "${PS2=> }" 63966dd55b233982d9657c50b971cfa754d0315c19Elliott Hughes "${PS3=#? }" 64966dd55b233982d9657c50b971cfa754d0315c19Elliott Hughes "${PS4=+ }" 65966dd55b233982d9657c50b971cfa754d0315c19Elliott Hughes "${SECONDS=0}" 66966dd55b233982d9657c50b971cfa754d0315c19Elliott Hughes "${TMOUT=0}" 67966dd55b233982d9657c50b971cfa754d0315c19Elliott Hughes "${EPOCHREALTIME=}"; 685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic const char *initcoms[] = { 7003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Ttypeset, "-r", initvsn, NULL, 7177740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes Ttypeset, "-x", "HOME", TPATH, TSHELL, NULL, 72c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser Ttypeset, "-i10", "COLUMNS", "LINES", "SECONDS", "TMOUT", NULL, 7303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Talias, 7496b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes "integer=\\typeset -i", 7596b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes "local=\\typeset", 7603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* not "alias -t --": hash -r needs to work */ 7796b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes "hash=\\builtin alias -t", 7896b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes "type=\\builtin whence -v", 7996b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes "autoload=\\typeset -fu", 8096b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes "functions=\\typeset -f", 8196b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes "history=\\builtin fc -l", 8296b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes "nameref=\\typeset -n", 835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "nohup=nohup ", 8496b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes "r=\\builtin fc -e -", 8596b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes "login=\\exec login", 865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru NULL, 875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* this is what AT&T ksh seems to track, with the addition of emacs */ 8803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Talias, "-tU", 8996b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes Tcat, "cc", "chmod", "cp", "date", "ed", "emacs", "grep", "ls", 9077740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes "make", "mv", "pr", "rm", "sed", Tsh, "vi", "who", NULL, 915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru NULL 925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}; 935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic const char *restr_com[] = { 9577740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes Ttypeset, "-r", TPATH, "ENV", TSHELL, NULL 9603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra}; 9703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 98c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstatic bool initio_done; 995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* top-level parsing and execution environment */ 10103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic struct env env; 10203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastruct env *e = &env; 10303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 10403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic mksh_uari_t 10503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrarndsetup(void) 10603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{ 10703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra register uint32_t h; 10803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra struct { 10903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ALLOC_ITEM alloc_INT; 11003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra void *dataptr, *stkptr, *mallocptr; 111c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#if defined(__GLIBC__) && (__GLIBC__ >= 2) 11203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra sigjmp_buf jbuf; 113c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 11403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra struct timeval tv; 11503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } *bufptr; 11603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra char *cp; 11703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 11877740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes cp = alloc(sizeof(*bufptr) - sizeof(ALLOC_ITEM), APERM); 119966dd55b233982d9657c50b971cfa754d0315c19Elliott Hughes /* clear the allocated space, for valgrind and to avoid UB */ 12077740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes memset(cp, 0, sizeof(*bufptr) - sizeof(ALLOC_ITEM)); 12103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* undo what alloc() did to the malloc result address */ 12277740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes bufptr = (void *)(cp - sizeof(ALLOC_ITEM)); 12303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* PIE or something similar provides us with deltas here */ 12403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bufptr->dataptr = &rndsetupstate; 12503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* ASLR in at least Windows, Linux, some BSDs */ 12603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bufptr->stkptr = &bufptr; 12703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* randomised malloc in BSD (and possibly others) */ 12803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bufptr->mallocptr = bufptr; 129c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#if defined(__GLIBC__) && (__GLIBC__ >= 2) 13003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* glibc pointer guard */ 13103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra sigsetjmp(bufptr->jbuf, 1); 132c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 133c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* introduce variation (and yes, second arg MBZ for portability) */ 134c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser mksh_TIME(bufptr->tv); 13503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 13677740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes#ifdef MKSH_ALLOC_CATCH_UNDERRUNS 13777740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes mprotect(((char *)bufptr) + 4096, 4096, PROT_READ | PROT_WRITE); 13877740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes#endif 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[] = { 15577740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes Tmksh, 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; 18756b517d46cdf4f6ccd6b62b207110e2afc3db30bElliott 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 19696b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes#ifdef __OS2__ 19796b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes for (i = 0; i < 3; ++i) 19896b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes if (!isatty(i)) 19996b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes setmode(i, O_BINARY); 20096b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes#endif 20196b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes 2025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* do things like getpgrp() et al. */ 2035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru chvt_reinit(); 2045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 205fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes /* make sure argv[] is sane, for weird OSes */ 2065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!*argv) { 2075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru argv = empty_argv; 2085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru argc = 1; 2095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 21003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra kshname = argv[0]; 2115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 21203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* initialise permanent Area */ 21303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ainit(&aperm); 21477740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes /* max. name length: -2147483648 = 11 (+ NUL) */ 21577740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes vtemp = alloc(offsetof(struct tbl, name[0]) + 12, APERM); 2165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* set up base environment */ 21803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra env.type = E_NONE; 21903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ainit(&env.area); 22003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* set up global l->vars and l->funs */ 22103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra newblock(); 2225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Do this first so output routines (eg, errorf, shellf) can work */ 2245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru initio(); 2255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 22603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* determine the basename (without '-' or path) of the executable */ 22703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ccp = kshname; 228966dd55b233982d9657c50b971cfa754d0315c19Elliott Hughes goto begin_parsing_kshname; 22903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while ((i = ccp[argi++])) { 230966dd55b233982d9657c50b971cfa754d0315c19Elliott Hughes if (mksh_cdirsep(i)) { 23103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ccp += argi; 232966dd55b233982d9657c50b971cfa754d0315c19Elliott Hughes begin_parsing_kshname: 23303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra argi = 0; 23403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (*ccp == '-') 23503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++ccp; 23603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 23703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 23803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!*ccp) 23903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ccp = empty_argv[0]; 24003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 241737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes /* 242737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes * Turn on nohup by default. (AT&T ksh does not have a nohup 243737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes * option - it always sends the hup). 244737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes */ 245737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes Flag(FNOHUP) = 1; 246737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes 247737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes /* 248737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes * Turn on brace expansion by default. AT&T kshs that have 249737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes * alternation always have it on. 250737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes */ 251737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes Flag(FBRACEEXPAND) = 1; 252737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes 253737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes /* 254737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes * Turn on "set -x" inheritance by default. 255737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes */ 256737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes Flag(FXTRACEREC) = 1; 257737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes 25803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* define built-in commands and see if we were called as one */ 25903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ktinit(APERM, &builtins, 260fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes /* currently up to 54 builtins: 75% of 128 = 2^7 */ 261c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 7); 26203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra for (i = 0; mkshbuiltins[i].name != NULL; i++) 26303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!strcmp(ccp, builtin(mkshbuiltins[i].name, 26403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra mkshbuiltins[i].func))) 26503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Flag(FAS_BUILTIN) = 1; 26603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 26703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!Flag(FAS_BUILTIN)) { 26803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* check for -T option early */ 26903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra argi = parse_args(argv, OF_FIRSTTIME, NULL); 27003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (argi < 0) 27103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (1); 27203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 273811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser#if defined(MKSH_BINSHPOSIX) || defined(MKSH_BINSHREDUCED) 274811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser /* are we called as -sh or /bin/sh or so? */ 27596b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes if (!strcmp(ccp, "sh" MKSH_EXE_EXT)) { 276811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser /* either also turns off braceexpand */ 277811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser#ifdef MKSH_BINSHPOSIX 278811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser /* enable better POSIX conformance */ 279811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser change_flag(FPOSIX, OF_FIRSTTIME, true); 280811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser#endif 28103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#ifdef MKSH_BINSHREDUCED 282811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser /* enable kludge/compat mode */ 283c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser change_flag(FSH, OF_FIRSTTIME, true); 28403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 285811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser } 286811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser#endif 28703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 2885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru initvar(); 2905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru initctypes(); 2925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru inittraps(); 2945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru coproc_init(); 2965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* set up variable and command dictionaries */ 29803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ktinit(APERM, &taliases, 0); 29903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ktinit(APERM, &aliases, 0); 3005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_NOPWNAM 30103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ktinit(APERM, &homedirs, 0); 3025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 3035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* define shell keywords */ 3055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru initkeywords(); 3065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru init_histvec(); 3085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 309c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* initialise tty size before importing environment */ 310c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser change_winsz(); 311c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 3125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef _PATH_DEFPATH 3135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru def_path = _PATH_DEFPATH; 3145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#else 3155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef _CS_PATH 31603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((k = confstr(_CS_PATH, NULL, 0)) > 0 && 3175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru confstr(_CS_PATH, cp = alloc(k + 1, APERM), k + 1) == k + 1) 3185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru def_path = cp; 3195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 3205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 3215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 3225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * this is uniform across all OSes unless it 32377740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes * breaks somewhere hard; don't try to optimise, 3245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * e.g. add stuff for Interix or remove /usr 3255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * for HURD, because e.g. Debian GNU/HURD is 3265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * "keeping a regular /usr"; this is supposed 3275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * to be a sane 'basic' default PATH 3285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 32996b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes def_path = MKSH_UNIXROOT "/bin" MKSH_PATHSEPS 33096b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes MKSH_UNIXROOT "/usr/bin" MKSH_PATHSEPS 33196b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes MKSH_UNIXROOT "/sbin" MKSH_PATHSEPS 33296b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes MKSH_UNIXROOT "/usr/sbin"; 3335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 3345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 33503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 33603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Set PATH to def_path (will set the path global variable). 3375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (import of environment below will probably change this setting). 3385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 33977740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes vp = global(TPATH); 3405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* setstr can't fail here */ 3415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setstr(vp, def_path, KSH_RETURN_ERROR); 3425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 343c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifndef MKSH_NO_CMDLINE_EDITING 34403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 34503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Set edit mode to emacs by default, may be overridden 3465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * by the environment or the user. Also, we want tab completion 34703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * on in vi by default. 34803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra */ 349c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser change_flag(FEMACS, OF_SPECIAL, true); 3505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if !MKSH_S_NOVI 3515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Flag(FVITABCOMPLETE) = 1; 3525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 353c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 3545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* import environment */ 356737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes if (environ != NULL) { 357737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes wp = (const char **)environ; 358737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes while (*wp != NULL) { 359737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes rndpush(*wp); 3605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru typeset(*wp, IMPORT | EXPORT, 0, 0, 0); 361737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes ++wp; 362737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes } 363737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes } 3645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 36503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* for security */ 36603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra typeset(initifs, 0, 0, 0, 0); 3675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* assign default shell variable values */ 3695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru substitute(initsubs, 0); 3705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Figure out the current working directory and set $PWD */ 37277740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes vp = global(TPWD); 37303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra cp = str_val(vp); 37403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* Try to use existing $PWD if it is valid */ 37577740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes set_current_wd((mksh_abspath(cp) && test_eval(NULL, TO_FILEQ, cp, 37677740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes Tdot, true)) ? cp : NULL); 37703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (current_wd[0]) 37803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra simplify_path(current_wd); 37903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* Only set pwd if we know where we are or if it had a bogus value */ 38003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (current_wd[0] || *cp) 38103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* setstr can't fail here */ 38203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra setstr(vp, current_wd, KSH_RETURN_ERROR); 3835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (wp = initcoms; *wp != NULL; wp++) { 3855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shcomexec(wp); 3865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (*wp != NULL) 3875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp++; 3885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 389c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser setint_n(global("OPTIND"), 1, 10); 39003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 39103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra kshuid = getuid(); 39203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra kshgid = getgid(); 39303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra kshegid = getegid(); 3945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru safe_prompt = ksheuid ? "$ " : "# "; 3965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp = global("PS1"); 3975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Set PS1 if unset or we are root and prompt doesn't contain a # */ 3985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(vp->flag & ISSET) || 3995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (!ksheuid && !strchr(str_val(vp), '#'))) 4005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* setstr can't fail here */ 4015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setstr(vp, safe_prompt, KSH_RETURN_ERROR); 402c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser setint_n((vp = global("BASHPID")), 0, 10); 403c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser vp->flag |= INT_U; 404c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser setint_n((vp = global("PGRP")), (mksh_uari_t)kshpgrp, 10); 4055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag |= INT_U; 406c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser setint_n((vp = global("PPID")), (mksh_uari_t)kshppid, 10); 4075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag |= INT_U; 408c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser setint_n((vp = global("USER_ID")), (mksh_uari_t)ksheuid, 10); 4095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag |= INT_U; 410c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser setint_n((vp = global("KSHUID")), (mksh_uari_t)kshuid, 10); 4115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag |= INT_U; 412c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser setint_n((vp = global("KSHEGID")), (mksh_uari_t)kshegid, 10); 41303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vp->flag |= INT_U; 414c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser setint_n((vp = global("KSHGID")), (mksh_uari_t)kshgid, 10); 41503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vp->flag |= INT_U; 416c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser setint_n((vp = global("RANDOM")), rndsetup(), 10); 41703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vp->flag |= INT_U; 418c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser setint_n((vp_pipest = global("PIPESTATUS")), 0, 10); 4195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Set this before parsing arguments */ 421fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes Flag(FPRIVILEGED) = (kshuid != ksheuid || kshgid != kshegid) ? 2 : 0; 4225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* this to note if monitor is set on command line (see below) */ 4245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_UNEMPLOYED 4255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Flag(FMONITOR) = 127; 4265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 4275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* this to note if utf-8 mode is set on command line (see below) */ 4285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru UTFMODE = 2; 4295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 43003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!Flag(FAS_BUILTIN)) { 43103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra argi = parse_args(argv, OF_CMDLINE, NULL); 43203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (argi < 0) 43303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (1); 43403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 43503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 4365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* process this later only, default to off (hysterical raisins) */ 4375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru utf_flag = UTFMODE; 4385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru UTFMODE = 0; 4395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 44003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (Flag(FAS_BUILTIN)) { 44103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* auto-detect from environment variables, always */ 44203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra utf_flag = 3; 44303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else if (Flag(FCOMMAND)) { 444c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser s = pushs(SSTRINGCMDLINE, ATEMP); 4455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(s->start = s->str = argv[argi++])) 44677740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes errorf(Tf_optfoo, "", "", 'c', Treq_arg); 447c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser while (*s->str) { 448c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (*s->str != ' ' && ctype(*s->str, C_QUOTE)) 449c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser break; 450c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser s->str++; 451c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 452c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (!*s->str) 453c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser s->flags |= SF_MAYEXEC; 454c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser s->str = s->start; 4555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef MKSH_MIDNIGHTBSD01ASH_COMPAT 4565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* compatibility to MidnightBSD 0.1 /bin/sh (kludge) */ 4575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (Flag(FSH) && argv[argi] && !strcmp(argv[argi], "--")) 4585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ++argi; 4595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 4605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (argv[argi]) 4615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru kshname = argv[argi++]; 4625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (argi < argc && !Flag(FSTDIN)) { 4635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = pushs(SFILE, ATEMP); 46496b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes#ifdef __OS2__ 46596b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes /* 46696b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes * A bug in OS/2 extproc (like shebang) handling makes 46796b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes * it not pass the full pathname of a script, so we need 46896b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes * to search for it. This changes the behaviour of a 46996b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes * simple "mksh foo", but can't be helped. 47096b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes */ 47196b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes s->file = search_path(argv[argi++], path, X_OK, NULL); 47296b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes if (!s->file || !*s->file) 47396b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes s->file = argv[argi - 1]; 47496b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes#else 4755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->file = argv[argi++]; 47696b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes#endif 4775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->u.shf = shf_open(s->file, O_RDONLY, 0, 4785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru SHF_MAPHI | SHF_CLEXEC); 4795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s->u.shf == NULL) { 48003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shl_stdout_ok = false; 48177740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes warningf(true, Tf_sD_s, s->file, cstrerror(errno)); 4825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* mandated by SUSv4 */ 4835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru exstat = 127; 4845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unwind(LERROR); 4855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru kshname = s->file; 4875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 4885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Flag(FSTDIN) = 1; 4895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = pushs(SSTDIN, ATEMP); 4905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->file = "<stdin>"; 4915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->u.shf = shf_fdopen(0, SHF_RD | can_seek(0), 4925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru NULL); 4935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (isatty(0) && isatty(2)) { 4945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Flag(FTALKING) = Flag(FTALKING_I) = 1; 4955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* The following only if isatty(0) */ 4965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->flags |= SF_TTY; 4975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->u.shf->flags |= SHF_INTERRUPT; 4985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->file = NULL; 4995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* this bizarreness is mandated by POSIX */ 5035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (fstat(0, &s_stdin) >= 0 && S_ISCHR(s_stdin.st_mode) && 5045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Flag(FTALKING)) 5055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru reset_nonblock(0); 5065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* initialise job control */ 5085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru j_init(); 509c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* do this after j_init() which calls tty_init_state() */ 5105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (Flag(FTALKING)) { 5115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (utf_flag == 2) { 5125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_ASSUME_UTF8 51303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* auto-detect from locale or environment */ 51403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra utf_flag = 4; 515737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes#else /* this may not be an #elif */ 516737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes#if MKSH_ASSUME_UTF8 51703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra utf_flag = 1; 5185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#else 51903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* always disable UTF-8 (for interactive) */ 52003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra utf_flag = 0; 5215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 522737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes#endif 5235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 524c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifndef MKSH_NO_CMDLINE_EDITING 5255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru x_init(); 526c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 5275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef SIGWINCH 5305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sigtraps[SIGWINCH].flags |= TF_SHELL_USES; 5315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setsig(&sigtraps[SIGWINCH], x_sigwinch, 5325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru SS_RESTORE_ORIG|SS_FORCE|SS_SHTRAP); 5335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 5345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru l = e->loc; 53603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (Flag(FAS_BUILTIN)) { 53703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra l->argc = argc; 53803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra l->argv = argv; 53903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra l->argv[0] = ccp; 54003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else { 54103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra l->argc = argc - argi; 542c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* 543c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * allocate a new array because otherwise, when we modify 544c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * it in-place, ps(1) output changes; the meaning of argc 545c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * here is slightly different as it excludes kshname, and 546c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * we add a trailing NULL sentinel as well 547c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser */ 548c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser l->argv = alloc2(l->argc + 2, sizeof(void *), APERM); 54903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra l->argv[0] = kshname; 550c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser memcpy(&l->argv[1], &argv[argi], l->argc * sizeof(void *)); 551c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser l->argv[l->argc + 1] = NULL; 55203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra getopts_reset(1); 55303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 55403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 55503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* divine the initial state of the utf8-mode Flag */ 55603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ccp = null; 55703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra switch (utf_flag) { 55803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 55903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* auto-detect from locale or environment */ 56003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 4: 56103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#if HAVE_SETLOCALE_CTYPE 56203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ccp = setlocale(LC_CTYPE, ""); 56303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#if HAVE_LANGINFO_CODESET 56403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!isuc(ccp)) 56503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ccp = nl_langinfo(CODESET); 56603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 56703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!isuc(ccp)) 56803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ccp = null; 56903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 570966dd55b233982d9657c50b971cfa754d0315c19Elliott Hughes /* FALLTHROUGH */ 57103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 57203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* auto-detect from environment */ 57303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 3: 57403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* these were imported from environ earlier */ 57503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (ccp == null) 57603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ccp = str_val(global("LC_ALL")); 57703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (ccp == null) 57803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ccp = str_val(global("LC_CTYPE")); 57903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (ccp == null) 58003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ccp = str_val(global("LANG")); 58103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra UTFMODE = isuc(ccp); 58203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 58303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 58403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* not set on command line, not FTALKING */ 58503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 2: 58603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* unknown values */ 58703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra default: 58803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra utf_flag = 0; 58903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* FALLTHROUGH */ 59003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 59103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* known values */ 59203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 1: 59303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 0: 59403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra UTFMODE = utf_flag; 59503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 59603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 5975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Disable during .profile/ENV reading */ 59956b517d46cdf4f6ccd6b62b207110e2afc3db30bElliott Hughes restricted_shell = Flag(FRESTRICTED); 6005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Flag(FRESTRICTED) = 0; 6015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru errexit = Flag(FERREXIT); 6025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Flag(FERREXIT) = 0; 6035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 60403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 60503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Do this before profile/$ENV so that if it causes problems in them, 6065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * user will know why things broke. 6075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 6085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!current_wd[0] && Flag(FTALKING)) 60903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra warningf(false, "can't determine current directory"); 6105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 611737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes if (Flag(FLOGIN)) 612c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser include(MKSH_SYSTEM_PROFILE, 0, NULL, true); 613737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes if (!Flag(FPRIVILEGED)) { 614737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes if (Flag(FLOGIN)) 615737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes include(substitute("$HOME/.profile", 0), 0, NULL, true); 616737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes if (Flag(FTALKING)) { 617737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes cp = substitute(substitute("${ENV:-" MKSHRC_PATH "}", 618737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes 0), DOTILDE); 619737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes if (cp[0] != '\0') 620737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes include(cp, 0, NULL, true); 621737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes } 622737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes } else { 623c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser include(MKSH_SUID_PROFILE, 0, NULL, true); 624737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes /* turn off -p if not set explicitly */ 625737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes if (Flag(FPRIVILEGED) != 1) 626737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes change_flag(FPRIVILEGED, OF_INTERNAL, false); 6275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 62956b517d46cdf4f6ccd6b62b207110e2afc3db30bElliott Hughes if (restricted_shell) { 6305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shcomexec(restr_com); 6315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* After typeset command... */ 6325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Flag(FRESTRICTED) = 1; 6335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Flag(FERREXIT) = errexit; 6355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 636c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (Flag(FTALKING) && s) 6375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hist_init(s); 63803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else 63903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* set after ENV */ 64003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Flag(FTRACKALL) = 1; 6415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 64203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra alarm_init(); 6435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 644c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser *sp = s; 645c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser *lp = l; 64603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (0); 6475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 6485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 649c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser/* this indirection barrier reduces stack usage during normal operation */ 650c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 651c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserint 652c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glasermain(int argc, const char *argv[]) 653c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser{ 654c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser int rv; 655c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser Source *s; 656c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser struct block *l; 657c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 658c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((rv = main_init(argc, argv, &s, &l)) == 0) { 659c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (Flag(FAS_BUILTIN)) { 660c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser rv = shcomexec(l->argv); 661c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } else { 662c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shell(s, true); 663c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* NOTREACHED */ 664c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 665c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 666c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return (rv); 667c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser} 668c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 6695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 670c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserinclude(const char *name, int argc, const char **argv, bool intr_ok) 6715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 6725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Source *volatile s = NULL; 6735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct shf *shf; 6745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char **volatile old_argv; 6755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru volatile int old_argc; 6765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int i; 6775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf = shf_open(name, O_RDONLY, 0, SHF_MAPHI | SHF_CLEXEC); 6795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (shf == NULL) 6805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (-1); 6815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (argv) { 6835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru old_argv = e->loc->argv; 6845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru old_argc = e->loc->argc; 6855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 6865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru old_argv = NULL; 6875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru old_argc = 0; 6885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru newenv(E_INCL); 690c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((i = kshsetjmp(e->jbuf))) { 6915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru quitenv(s ? s->u.shf : NULL); 6925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (old_argv) { 6935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru e->loc->argv = old_argv; 6945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru e->loc->argc = old_argc; 6955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (i) { 6975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case LRETURN: 6985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case LERROR: 69903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* see below */ 70003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (exstat & 0xFF); 7015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case LINTR: 70203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 70303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * intr_ok is set if we are including .profile or $ENV. 7045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * If user ^Cs out, we don't want to kill the shell... 7055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 706c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (intr_ok && ((exstat & 0xFF) - 128) != SIGTERM) 7075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 7085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* FALLTHROUGH */ 7095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case LEXIT: 7105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case LLEAVE: 7115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case LSHELL: 7125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unwind(i); 7135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* NOTREACHED */ 7145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 71577740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes internal_errorf("include %d", i); 7165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* NOTREACHED */ 7175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (argv) { 7205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru e->loc->argv = argv; 7215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru e->loc->argc = argc; 7225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = pushs(SFILE, ATEMP); 7245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->u.shf = shf; 7255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strdupx(s->file, name, ATEMP); 7265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru i = shell(s, false); 7275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru quitenv(s->u.shf); 7285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (old_argv) { 7295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru e->loc->argv = old_argv; 7305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru e->loc->argc = old_argc; 7315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 73203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* & 0xff to ensure value not -1 */ 73303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (i & 0xFF); 7345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 7355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* spawn a command into a shell optionally keeping track of the line number */ 7375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 7385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querucommand(const char *comm, int line) 7395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 74077740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes Source *s, *sold = source; 74177740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes int rv; 7425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = pushs(SSTRING, ATEMP); 7445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->start = s->str = comm; 7455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->line = line; 74677740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes rv = shell(s, false); 74777740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes source = sold; 74877740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes return (rv); 7495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 7505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 7525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * run the commands from the input source, returning status. 7535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 7545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 755c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glasershell(Source * volatile s, volatile bool toplevel) 7565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 7575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct op *t; 758c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser volatile bool wastty = tobool(s->flags & SF_TTY); 759c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser volatile uint8_t attempts = 13; 760c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser volatile bool interactive = Flag(FTALKING) && toplevel; 76103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra volatile bool sfirst = true; 7625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Source *volatile old_source = source; 7635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int i; 7645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru newenv(E_PARSE); 7665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (interactive) 767c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser really_exit = false; 768c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser switch ((i = kshsetjmp(e->jbuf))) { 769c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case 0: 770c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser break; 771c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case LINTR: 772c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* we get here if SIGINT not caught or ignored */ 773c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case LERROR: 774c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case LSHELL: 775c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (interactive) { 776c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (i == LINTR) 777c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shellf("\n"); 778c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* 779c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * Reset any eof that was read as part of a 780c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * multiline command. 781c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser */ 782c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (Flag(FIGNOREEOF) && s->type == SEOF && wastty) 783c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser s->type = SSTDIN; 784c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* 785c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * Used by exit command to get back to 786c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * top level shell. Kind of strange since 787c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * interactive is set if we are reading from 788c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * a tty, but to have stopped jobs, one only 789c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * needs FMONITOR set (not FTALKING/SF_TTY)... 790c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser */ 791c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* toss any input we have so far */ 792c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser yyrecursive_pop(true); 793c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser s->start = s->str = null; 794c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser retrace_info = NULL; 795c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser herep = heres; 796c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser break; 7975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 798c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* FALLTHROUGH */ 799c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case LEXIT: 800c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case LLEAVE: 801c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case LRETURN: 802c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser source = old_source; 803c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser quitenv(NULL); 804c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* keep on going */ 805c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser unwind(i); 806c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* NOTREACHED */ 807c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser default: 808c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser source = old_source; 809c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser quitenv(NULL); 81077740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes internal_errorf("shell %d", i); 811c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* NOTREACHED */ 8125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 81303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (/* CONSTCOND */ 1) { 8145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (trap) 8155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru runtraps(0); 8165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s->next == NULL) { 8185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (Flag(FVERBOSE)) 8195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->flags |= SF_ECHO; 8205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 8215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->flags &= ~SF_ECHO; 8225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (interactive) { 8245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru j_notify(); 8255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru set_prompt(PS1, s); 8265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 82703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra t = compile(s, sfirst); 82896b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes if (interactive) 82996b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes histsave(&s->line, NULL, HIST_FLUSH, true); 83003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra sfirst = false; 831c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (!t) 832c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto source_no_tree; 833c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (t->type == TEOF) { 8345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (wastty && Flag(FIGNOREEOF) && --attempts > 0) { 83503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shellf("Use 'exit' to leave mksh\n"); 8365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->type = SSTDIN; 8375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (wastty && !really_exit && 8385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru j_stopped_running()) { 839c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser really_exit = true; 8405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->type = SSTDIN; 8415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 84203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 84303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * this for POSIX which says EXIT traps 8445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * shall be taken in the environment 8455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * immediately after the last command 8465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * executed. 8475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 8485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (toplevel) 8495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unwind(LEXIT); 8505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 8515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 852737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes } else if ((s->flags & SF_MAYEXEC) && t->type == TCOM) 853c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser t->u.evalflags |= DOTCOMEXEC; 854c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (!Flag(FNOEXEC) || (s->flags & SF_TTY)) 855c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser exstat = execute(t, 0, NULL) & 0xFF; 8565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 857c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (t->type != TEOF && interactive && really_exit) 858c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser really_exit = false; 8595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 860c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser source_no_tree: 8615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru reclaim(); 8625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru quitenv(NULL); 8645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source = old_source; 865c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return (exstat & 0xFF); 8665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 8675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* return to closest error handler or shell(), exit if none found */ 869c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser/* note: i MUST NOT be 0 */ 8705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 8715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruunwind(int i) 8725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 873c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* 874c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * This is a kludge. We need to restore everything that was 875c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * changed in the new environment, see cid 1005090337C7A669439 876c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * and 10050903386452ACBF1, but fail to even save things most of 877c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * the time. funcs.c:c_eval() changes FERREXIT temporarily to 0, 878c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * which needs to be restored thus (related to Debian #696823). 879c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * We did not save the shell flags, so we use a special or'd 880c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * value here... this is mostly to clean up behind *other* 881c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * callers of unwind(LERROR) here; exec.c has the regular case. 882c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser */ 883c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (Flag(FERREXIT) & 0x80) { 884c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* GNU bash does not run this trapsig */ 885c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser trapsig(ksh_SIGERR); 886c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser Flag(FERREXIT) &= ~0x80; 887c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 888c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 8895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* ordering for EXIT vs ERR is a bit odd (this is what AT&T ksh does) */ 890811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser if (i == LEXIT || ((i == LERROR || i == LINTR) && 891811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser sigtraps[ksh_SIGEXIT].trap && 892811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser (!Flag(FTALKING) || Flag(FERREXIT)))) { 89303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++trap_nested; 89403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra runtrap(&sigtraps[ksh_SIGEXIT], trap_nested == 1); 89503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra --trap_nested; 8965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru i = LLEAVE; 897c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } else if (Flag(FERREXIT) == 1 && (i == LERROR || i == LINTR)) { 89803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++trap_nested; 89903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra runtrap(&sigtraps[ksh_SIGERR], trap_nested == 1); 90003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra --trap_nested; 9015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru i = LLEAVE; 9025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 903c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 90403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (/* CONSTCOND */ 1) { 9055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (e->type) { 9065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case E_PARSE: 9075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case E_FUNC: 9085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case E_INCL: 9095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case E_LOOP: 9105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case E_ERRH: 911c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser kshlongjmp(e->jbuf, i); 9125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* NOTREACHED */ 9135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case E_NONE: 9145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (i == LINTR) 9155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru e->flags |= EF_FAKE_SIGDIE; 9165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* FALLTHROUGH */ 9175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 9185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru quitenv(NULL); 9195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 9225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 9245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querunewenv(int type) 9255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 9265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct env *ep; 9275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *cp; 9285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 9305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * struct env includes ALLOC_ITEM for alignment constraints 9315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * so first get the actually used memory, then assign it 9325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 93377740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes cp = alloc(sizeof(struct env) - sizeof(ALLOC_ITEM), ATEMP); 93403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* undo what alloc() did to the malloc result address */ 93577740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes ep = (void *)(cp - sizeof(ALLOC_ITEM)); 9365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* initialise public members of struct env (not the ALLOC_ITEM) */ 9375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ainit(&ep->area); 9385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ep->oenv = e; 9395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ep->loc = e->loc; 9405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ep->savefd = NULL; 9415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ep->temps = NULL; 942c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ep->yyrecursive_statep = NULL; 9435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ep->type = type; 9445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ep->flags = 0; 9455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* jump buffer is invalid because flags == 0 */ 9465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru e = ep; 9475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 9485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 9505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruquitenv(struct shf *shf) 9515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 9525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct env *ep = e; 9535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *cp; 9545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int fd; 9555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 956c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser yyrecursive_pop(true); 957c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser while (ep->oenv && ep->oenv->loc != ep->loc) 9585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru popblock(); 9595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ep->savefd != NULL) { 9605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (fd = 0; fd < NUFILE; fd++) 9615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* if ep->savefd[fd] < 0, means fd was closed */ 9625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ep->savefd[fd]) 9635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru restfd(fd, ep->savefd[fd]); 96403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (ep->savefd[2]) 96503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* Clear any write errors */ 9665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_reopen(2, SHF_WR, shl_out); 9675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 96803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 96903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Bottom of the stack. 9705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Either main shell is exiting or cleanup_parents_env() was called. 9715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 9725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ep->oenv == NULL) { 973c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef DEBUG_LEAKS 974c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser int i; 975c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 976c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 97703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (ep->type == E_NONE) { 97803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* Main shell exiting? */ 9795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if HAVE_PERSISTENT_HISTORY 9805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (Flag(FTALKING)) 9815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hist_finish(); 9825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 9835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru j_exit(); 9845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ep->flags & EF_FAKE_SIGDIE) { 985c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser int sig = (exstat & 0xFF) - 128; 9865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 98703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 98803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * ham up our death a bit (AT&T ksh 9895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * only seems to do this for SIGTERM) 9905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Don't do it for SIGQUIT, since we'd 9915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * dump a core.. 9925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 9935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((sig == SIGINT || sig == SIGTERM) && 9945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (kshpgrp == kshpid)) { 9955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setsig(&sigtraps[sig], SIG_DFL, 9965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru SS_RESTORE_CURR | SS_FORCE); 9975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru kill(0, sig); 9985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (shf) 10025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_close(shf); 10035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru reclaim(); 1004c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef DEBUG_LEAKS 1005c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifndef MKSH_NO_CMDLINE_EDITING 1006c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser x_done(); 1007c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 1008811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser#ifndef MKSH_NOPROSPECTOFWORK 1009811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser /* block at least SIGCHLD during/after afreeall */ 1010811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser sigprocmask(SIG_BLOCK, &sm_sigchld, NULL); 1011811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser#endif 1012c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser afreeall(APERM); 1013c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser for (fd = 3; fd < NUFILE; fd++) 1014c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((i = fcntl(fd, F_GETFD, 0)) != -1 && 1015c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser (i & FD_CLOEXEC)) 1016c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser close(fd); 1017c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser close(2); 1018c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser close(1); 1019c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser close(0); 1020c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 1021c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser exit(exstat & 0xFF); 10225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (shf) 10245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_close(shf); 10255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru reclaim(); 10265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru e = e->oenv; 10285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* free the struct env - tricky due to the ALLOC_ITEM inside */ 10305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru cp = (void *)ep; 103177740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes afree(cp + sizeof(ALLOC_ITEM), ATEMP); 10325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 10335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Called after a fork to cleanup stuff left over from parents environment */ 10355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 10365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querucleanup_parents_env(void) 10375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 10385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct env *ep; 10395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int fd; 10405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 10425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Don't clean up temporary files - parent will probably need them. 10435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Also, can't easily reclaim memory since variables, etc. could be 10445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * anywhere. 10455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 10465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* close all file descriptors hiding in savefd */ 10485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (ep = e; ep; ep = ep->oenv) { 10495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ep->savefd) { 10505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (fd = 0; fd < NUFILE; fd++) 10515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ep->savefd[fd] > 0) 10525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru close(ep->savefd[fd]); 10535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(ep->savefd, &ep->area); 10545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ep->savefd = NULL; 10555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 1056c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef DEBUG_LEAKS 1057c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (ep->type != E_NONE) 1058c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ep->type = E_GONE; 1059c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 10605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 1061c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifndef DEBUG_LEAKS 10625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru e->oenv = NULL; 1063c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 10645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 10655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Called just before an execve cleanup stuff temporary files */ 10675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 10685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querucleanup_proc_env(void) 10695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 10705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct env *ep; 10715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (ep = e; ep; ep = ep->oenv) 10735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru remove_temps(ep->temps); 10745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 10755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* remove temp files and free ATEMP Area */ 10775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 10785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querureclaim(void) 10795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 1080c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser struct block *l; 1081c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1082c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser while ((l = e->loc) && (!e->oenv || e->oenv->loc != l)) { 1083c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser e->loc = l->next; 1084c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser afreeall(&l->area); 1085c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 1086c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 10875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru remove_temps(e->temps); 10885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru e->temps = NULL; 108977740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes 109077740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes /* 109177740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes * if the memory backing source is reclaimed, things 109277740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes * will end up badly when a function expecting it to 109377740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes * be valid is run; a NULL pointer is easily debugged 109477740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes */ 109577740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes if (source && source->areap == &e->area) 109677740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes source = NULL; 10975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afreeall(&e->area); 10985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 10995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 11015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruremove_temps(struct temp *tp) 11025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 110377740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes while (tp) { 11045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tp->pid == procpid) 1105c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser unlink(tp->tffn); 110677740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes tp = tp->next; 110777740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes } 11085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 11095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 111003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* 1111c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * Initialise tty_fd. Used for tracking the size of the terminal, 1112c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * saving/resetting tty modes upon forground job completion, and 1113c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * for setting up the tty process group. Return values: 1114c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * 0 = got controlling tty 1115c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * 1 = got terminal but no controlling tty 1116c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * 2 = cannot find a terminal 1117c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * 3 = cannot dup fd 1118c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * 4 = cannot make fd close-on-exec 1119c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * An existing tty_fd is cached if no "better" one could be found, 1120c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * i.e. if tty_devtty was already set or the new would not set it. 11215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 1122c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserint 1123c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glasertty_init_fd(void) 11245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 1125c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser int fd, rv, eno = 0; 1126c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bool do_close = false, is_devtty = true; 11275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1128c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (tty_devtty) { 1129c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* already got a tty which is /dev/tty */ 1130c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return (0); 11315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef _UWIN 113403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /*XXX imake style */ 113503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (isatty(3)) { 113603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* fd 3 on UWIN _is_ /dev/tty (or our controlling tty) */ 1137c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser fd = 3; 1138c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto got_fd; 11395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 1140c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 114177740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes if ((fd = open(T_devtty, O_RDWR, 0)) >= 0) { 1142c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser do_close = true; 1143c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto got_fd; 11445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 1145c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser eno = errno; 11465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tty_fd >= 0) { 1148c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* already got a non-devtty one */ 1149c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser rv = 1; 1150c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto out; 11515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 1152c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser is_devtty = false; 1153c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1154c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (isatty((fd = 0)) || isatty((fd = 2))) 1155c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto got_fd; 1156c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* cannot find one */ 1157c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser rv = 2; 1158c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* assert: do_close == false */ 1159c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto out; 1160c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1161c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser got_fd: 1162c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((rv = fcntl(fd, F_DUPFD, FDBASE)) < 0) { 1163c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser eno = errno; 1164c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser rv = 3; 1165c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto out; 1166c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 1167c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (fcntl(rv, F_SETFD, FD_CLOEXEC) < 0) { 1168c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser eno = errno; 1169c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser close(rv); 1170c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser rv = 4; 1171c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto out; 1172c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 1173c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser tty_fd = rv; 1174c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser tty_devtty = is_devtty; 1175c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser rv = eno = 0; 1176c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser out: 1177c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (do_close) 1178c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser close(fd); 1179c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser errno = eno; 1180c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return (rv); 11815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 11825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* A shell error occurred (eg, syntax error, etc.) */ 118403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 118503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define VWARNINGF_ERRORPREFIX 1 118603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define VWARNINGF_FILELINE 2 118703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define VWARNINGF_BUILTIN 4 118803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define VWARNINGF_INTERNAL 8 118903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 119003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic void vwarningf(unsigned int, const char *, va_list) 119103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra MKSH_A_FORMAT(__printf__, 2, 0); 119203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 119303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic void 119403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condravwarningf(unsigned int flags, const char *fmt, va_list ap) 119503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{ 1196c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (fmt) { 119703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (flags & VWARNINGF_INTERNAL) 119877740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes shf_fprintf(shl_out, Tf_sD_, "internal error"); 119903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (flags & VWARNINGF_ERRORPREFIX) 120003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra error_prefix(tobool(flags & VWARNINGF_FILELINE)); 120103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((flags & VWARNINGF_BUILTIN) && 120203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* not set when main() calls parse_args() */ 120303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra builtin_argv0 && builtin_argv0 != kshname) 120477740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes shf_fprintf(shl_out, Tf_sD_, builtin_argv0); 120503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shf_vfprintf(shl_out, fmt, ap); 120603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shf_putchar('\n', shl_out); 120703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 120803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shf_flush(shl_out); 120903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra} 121003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 121103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condravoid 121203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condraerrorfx(int rc, const char *fmt, ...) 121303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{ 121403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra va_list va; 121503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 121603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra exstat = rc; 121703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 121803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* debugging: note that stdout not valid */ 121903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shl_stdout_ok = false; 122003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 122103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra va_start(va, fmt); 122203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vwarningf(VWARNINGF_ERRORPREFIX | VWARNINGF_FILELINE, fmt, va); 122303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra va_end(va); 122403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra unwind(LERROR); 122503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra} 122603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 12275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 12285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruerrorf(const char *fmt, ...) 12295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 12305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_list va; 12315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru exstat = 1; 123303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 123403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* debugging: note that stdout not valid */ 123503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shl_stdout_ok = false; 123603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 123703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra va_start(va, fmt); 123803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vwarningf(VWARNINGF_ERRORPREFIX | VWARNINGF_FILELINE, fmt, va); 123903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra va_end(va); 12405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unwind(LERROR); 12415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 12425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* like errorf(), but no unwind is done */ 12445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 12455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruwarningf(bool fileline, const char *fmt, ...) 12465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 12475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_list va; 12485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_start(va, fmt); 125003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vwarningf(VWARNINGF_ERRORPREFIX | (fileline ? VWARNINGF_FILELINE : 0), 125103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra fmt, va); 12525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_end(va); 12535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 12545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 125503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* 125603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Used by built-in utilities to prefix shell and utility name to message 12575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (also unwinds environments for special builtins). 12585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 12595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 12605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querubi_errorf(const char *fmt, ...) 12615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 12625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_list va; 12635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 126403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* debugging: note that stdout not valid */ 126503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shl_stdout_ok = false; 126603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 12675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru exstat = 1; 126803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 126903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra va_start(va, fmt); 127003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vwarningf(VWARNINGF_ERRORPREFIX | VWARNINGF_FILELINE | 127103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra VWARNINGF_BUILTIN, fmt, va); 127203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra va_end(va); 127303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 127403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 127503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * POSIX special builtins and ksh special builtins cause 1276fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes * non-interactive shells to exit. XXX may not want LERROR here 12775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 127850012061ca3ad8e8a7f88c72130a5e22d797897eElliott Hughes if (builtin_spec) { 12795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru builtin_argv0 = NULL; 12805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unwind(LERROR); 12815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 12825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 12835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Called when something that shouldn't happen does */ 12855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 12865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruinternal_errorf(const char *fmt, ...) 12875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 12885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_list va; 12895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_start(va, fmt); 129103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vwarningf(VWARNINGF_INTERNAL, fmt, va); 12925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_end(va); 12935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unwind(LERROR); 12945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 12955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 12975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruinternal_warningf(const char *fmt, ...) 12985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 12995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_list va; 13005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_start(va, fmt); 130203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vwarningf(VWARNINGF_INTERNAL, fmt, va); 13035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_end(va); 13045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 13055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* used by error reporting functions to print "ksh: .kshrc[25]: " */ 13075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 13085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruerror_prefix(bool fileline) 13095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 13105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Avoid foo: foo[2]: ... */ 13115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!fileline || !source || !source->file || 13125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strcmp(source->file, kshname) != 0) 131377740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes shf_fprintf(shl_out, Tf_sD_, kshname + (*kshname == '-')); 13145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (fileline && source && source->file != NULL) { 1315b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes shf_fprintf(shl_out, "%s[%lu]: ", source->file, 1316b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes (unsigned long)(source->errline ? 1317b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes source->errline : source->line)); 13185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source->errline = 0; 13195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 13215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* printf to shl_out (stderr) with flush */ 13235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 13245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querushellf(const char *fmt, ...) 13255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 13265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_list va; 13275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 132803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!initio_done) 132903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* shl_out may not be set up yet... */ 13305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return; 13315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_start(va, fmt); 13325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_vfprintf(shl_out, fmt, va); 13335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_end(va); 13345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_flush(shl_out); 13355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 13365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* printf to shl_stdout (stdout) */ 13385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 13395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querushprintf(const char *fmt, ...) 13405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 13415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_list va; 13425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!shl_stdout_ok) 13445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru internal_errorf("shl_stdout not valid"); 13455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_start(va, fmt); 13465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_vfprintf(shl_stdout, fmt, va); 13475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_end(va); 13485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 13495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* test if we can seek backwards fd (returns 0 or SHF_UNBUF) */ 13515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 13525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querucan_seek(int fd) 13535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 13545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct stat statb; 13555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (fstat(fd, &statb) == 0 && !S_ISREG(statb.st_mode) ? 13575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru SHF_UNBUF : 0); 13585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 13595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1360c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef DF 1361c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserint shl_dbg_fd; 1362c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#define NSHF_IOB 4 1363c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#else 1364c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#define NSHF_IOB 3 1365c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 1366c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstruct shf shf_iob[NSHF_IOB]; 13675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 13695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruinitio(void) 13705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 1371c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef DF 1372c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser const char *lfp; 1373c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 1374c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 137503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* force buffer allocation */ 137603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shf_fdopen(1, SHF_WR, shl_stdout); 13775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_fdopen(2, SHF_WR, shl_out); 1378811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser shf_fdopen(2, SHF_WR, shl_xtrace); 1379c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef DF 1380c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((lfp = getenv("SDMKSH_PATH")) == NULL) { 138196b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes if ((lfp = getenv("HOME")) == NULL || !mksh_abspath(lfp)) 1382c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser errorf("cannot get home directory"); 138377740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes lfp = shf_smprintf(Tf_sSs, lfp, "mksh-dbg.txt"); 1384c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 1385c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1386c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((shl_dbg_fd = open(lfp, O_WRONLY | O_APPEND | O_CREAT, 0600)) < 0) 1387c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser errorf("cannot open debug output file %s", lfp); 1388c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (shl_dbg_fd < FDBASE) { 1389c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser int nfd; 1390c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1391c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser nfd = fcntl(shl_dbg_fd, F_DUPFD, FDBASE); 1392c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser close(shl_dbg_fd); 1393c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((shl_dbg_fd = nfd) == -1) 1394c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser errorf("cannot dup debug output file"); 1395c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 1396c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser fcntl(shl_dbg_fd, F_SETFD, FD_CLOEXEC); 1397c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shf_fdopen(shl_dbg_fd, SHF_WR, shl_dbg); 1398c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser DF("=== open ==="); 1399c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 1400c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser initio_done = true; 14015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 14025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* A dup2() with error checking */ 14045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 14055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruksh_dup2(int ofd, int nfd, bool errok) 14065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 14075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv; 14085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (((rv = dup2(ofd, nfd)) < 0) && !errok && (errno != EBADF)) 14105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru errorf("too many files open in shell"); 14115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef __ultrix 141303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /*XXX imake style */ 14145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (rv >= 0) 14155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fcntl(nfd, F_SETFD, 0); 14165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 14175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 14195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 14205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 142203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Move fd from user space (0 <= fd < 10) to shell space (fd >= 10), 142303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * set close-on-exec flag. See FDBASE in sh.h, maybe 24 not 10 here. 14245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 14255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querushort 14265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querusavefd(int fd) 14275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 14285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int nfd = fd; 14295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (fd < FDBASE && (nfd = fcntl(fd, F_DUPFD, FDBASE)) < 0 && 143196b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes (errno == EBADF || errno == EPERM)) 14325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (-1); 14335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (nfd < 0 || nfd > SHRT_MAX) 14345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru errorf("too many files open in shell"); 14355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fcntl(nfd, F_SETFD, FD_CLOEXEC); 14365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return ((short)nfd); 14375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 14385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 14405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querurestfd(int fd, int ofd) 14415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 14425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (fd == 2) 1443c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shf_flush(&shf_iob[/* fd */ 2]); 144403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (ofd < 0) 144503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* original fd closed */ 14465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru close(fd); 14475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (fd != ofd) { 144803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /*XXX: what to do if this dup fails? */ 144903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ksh_dup2(ofd, fd, true); 14505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru close(ofd); 14515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 14535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 14555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruopenpipe(int *pv) 14565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 14575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int lpv[2]; 14585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (pipe(lpv) < 0) 14605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru errorf("can't create pipe - try again"); 14615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru pv[0] = savefd(lpv[0]); 14625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (pv[0] != lpv[0]) 14635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru close(lpv[0]); 14645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru pv[1] = savefd(lpv[1]); 14655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (pv[1] != lpv[1]) 14665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru close(lpv[1]); 14675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 14685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 14705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruclosepipe(int *pv) 14715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 14725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru close(pv[0]); 14735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru close(pv[1]); 14745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 14755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 147603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* 147703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Called by iosetup() (deals with 2>&4, etc.), c_read, c_print to turn 14785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * a string (the X in 2>&X, read -uX, print -uX) into a file descriptor. 14795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 14805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 14815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querucheck_fd(const char *name, int mode, const char **emsgp) 14825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 148377740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes int fd, fl; 14845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 148577740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes if (!name[0] || name[1]) 148677740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes goto illegal_fd_name; 148777740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes if (name[0] == 'p') 14885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (coproc_getfd(mode, emsgp)); 148977740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes if (!ksh_isdigit(name[0])) { 149077740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes illegal_fd_name: 14915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (emsgp) 14925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *emsgp = "illegal file descriptor name"; 14935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (-1); 14945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 149577740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes 149677740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes if ((fl = fcntl((fd = ksh_numdig(name[0])), F_GETFL, 0)) < 0) { 14975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (emsgp) 14985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *emsgp = "bad file descriptor"; 14995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (-1); 15005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fl &= O_ACCMODE; 150203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 150303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * X_OK is a kludge to disable this check for dups (x<&1): 15045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * historical shells never did this check (XXX don't know what 15055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * POSIX has to say). 15065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 15075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(mode & X_OK) && fl != O_RDWR && ( 15085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ((mode & R_OK) && fl != O_RDONLY) || 15095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ((mode & W_OK) && fl != O_WRONLY))) { 15105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (emsgp) 15115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *emsgp = (fl == O_WRONLY) ? 15125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "fd not open for reading" : 15135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "fd not open for writing"; 15145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (-1); 15155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (fd); 15175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 15185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Called once from main */ 15205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 15215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querucoproc_init(void) 15225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 15235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru coproc.read = coproc.readw = coproc.write = -1; 15245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru coproc.njobs = 0; 15255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru coproc.id = 0; 15265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 15275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Called by c_read() when eof is read - close fd if it is the co-process fd */ 15295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 15305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querucoproc_read_close(int fd) 15315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 15325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (coproc.read >= 0 && fd == coproc.read) { 15335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru coproc_readw_close(fd); 15345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru close(coproc.read); 15355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru coproc.read = -1; 15365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 15385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 153903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* 154003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Called by c_read() and by iosetup() to close the other side of the 15415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * read pipe, so reads will actually terminate. 15425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 15435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 15445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querucoproc_readw_close(int fd) 15455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 15465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (coproc.readw >= 0 && coproc.read >= 0 && fd == coproc.read) { 15475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru close(coproc.readw); 15485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru coproc.readw = -1; 15495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 15515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 155203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* 155303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Called by c_print when a write to a fd fails with EPIPE and by iosetup 15545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * when co-process input is dup'd 15555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 15565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 15575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querucoproc_write_close(int fd) 15585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 15595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (coproc.write >= 0 && fd == coproc.write) { 15605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru close(coproc.write); 15615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru coproc.write = -1; 15625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 15645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 156503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* 156603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Called to check for existence of/value of the co-process file descriptor. 15675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (Used by check_fd() and by c_read/c_print to deal with -p option). 15685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 15695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 15705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querucoproc_getfd(int mode, const char **emsgp) 15715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 15725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int fd = (mode & R_OK) ? coproc.read : coproc.write; 15735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (fd >= 0) 15755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (fd); 15765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (emsgp) 15775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *emsgp = "no coprocess"; 15785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (-1); 15795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 15805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 158103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* 158203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * called to close file descriptors related to the coprocess (if any) 15835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Should be called with SIGCHLD blocked. 15845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 15855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 15865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querucoproc_cleanup(int reuse) 15875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 15885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* This to allow co-processes to share output pipe */ 15895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!reuse || coproc.readw < 0 || coproc.read < 0) { 15905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (coproc.read >= 0) { 15915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru close(coproc.read); 15925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru coproc.read = -1; 15935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (coproc.readw >= 0) { 15955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru close(coproc.readw); 15965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru coproc.readw = -1; 15975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (coproc.write >= 0) { 16005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru close(coproc.write); 16015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru coproc.write = -1; 16025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 16035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 16045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustruct temp * 16065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querumaketemp(Area *ap, Temp_type type, struct temp **tlist) 16075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 1608c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser char *cp; 160903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra size_t len; 1610811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser int i, j; 1611c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser struct temp *tp; 16125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *dir; 1613c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser struct stat sb; 16145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru dir = tmpdir ? tmpdir : MKSH_DEFAULT_TMPDIR; 1616c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* add "/shXXXXXX.tmp" plus NUL */ 1617c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser len = strlen(dir); 1618c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser checkoktoadd(len, offsetof(struct temp, tffn[0]) + 14); 1619c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser tp = alloc(offsetof(struct temp, tffn[0]) + 14 + len, ap); 1620c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 16215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp->shf = NULL; 16225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp->pid = procpid; 1623c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser tp->type = type; 1624c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1625c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (stat(dir, &sb) || !S_ISDIR(sb.st_mode)) { 1626c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser tp->tffn[0] = '\0'; 1627c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto maketemp_out; 1628c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 1629c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1630c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser cp = (void *)tp; 1631c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser cp += offsetof(struct temp, tffn[0]); 1632c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser memcpy(cp, dir, len); 1633c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser cp += len; 1634c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser memcpy(cp, "/shXXXXXX.tmp", 14); 1635c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* point to the first of six Xes */ 1636c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser cp += 3; 1637c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1638c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* cyclically attempt to open a temporary file */ 163996b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes do { 164096b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes /* generate random part of filename */ 164196b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes len = 0; 164296b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes do { 164396b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes cp[len++] = digits_lc[rndget() % 36]; 164496b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes } while (len < 6); 164596b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes 164696b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes /* check if this one works */ 164796b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes if ((i = binopen3(tp->tffn, O_CREAT | O_EXCL | O_RDWR, 164896b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes 0600)) < 0 && errno != EEXIST) 1649c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto maketemp_out; 165096b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes } while (i < 0); 1651c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1652c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (type == TT_FUNSUB) { 1653c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* map us high and mark as close-on-exec */ 1654811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser if ((j = savefd(i)) != i) { 1655c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser close(i); 1656811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser i = j; 1657c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 1658811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser 1659811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser /* operation mode for the shf */ 1660811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser j = SHF_RD; 1661811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser } else 1662811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser j = SHF_WR; 16635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1664c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* shf_fdopen cannot fail, so no fd leak */ 1665811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser tp->shf = shf_fdopen(i, j, NULL); 1666c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1667c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser maketemp_out: 16685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp->next = *tlist; 16695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *tlist = tp; 16705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (tp); 16715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 16725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 16745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * We use a similar collision resolution algorithm as Python 2.5.4 16755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * but with a slightly tweaked implementation written from scratch. 16765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 16775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 167803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define INIT_TBLSHIFT 3 /* initial table shift (2^3 = 8) */ 16795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define PERTURB_SHIFT 5 /* see Python 2.5.4 Objects/dictobject.c */ 16805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 168103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic void tgrow(struct table *); 16825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int tnamecmp(const void *, const void *); 16835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 168503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condratgrow(struct table *tp) 16865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 168703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra size_t i, j, osize, mask, perturb; 16885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *tblp, **pp; 16895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl **ntblp, **otblp = tp->tbls; 16905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 169103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (tp->tshift > 29) 169203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra internal_errorf("hash table size limit reached"); 169303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 169403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* calculate old size, new shift and new size */ 169503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra osize = (size_t)1 << (tp->tshift++); 169603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra i = osize << 1; 169703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 169803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ntblp = alloc2(i, sizeof(struct tbl *), tp->areap); 169903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* multiplication cannot overflow: alloc2 checked that */ 170003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra memset(ntblp, 0, i * sizeof(struct tbl *)); 170103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 1702c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* table can get very full when reaching its size limit */ 1703c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser tp->nfree = (tp->tshift == 30) ? 0x3FFF0000UL : 1704c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* but otherwise, only 75% */ 1705c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ((i * 3) / 4); 17065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp->tbls = ntblp; 17075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (otblp == NULL) 17085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return; 170903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 171003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra mask = i - 1; 17115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (i = 0; i < osize; i++) 17125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((tblp = otblp[i]) != NULL) { 17135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((tblp->flag & DEFINED)) { 17145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* search for free hash table slot */ 1715c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser j = perturb = tblp->ua.hval; 17165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto find_first_empty_slot; 17175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru find_next_empty_slot: 17185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru j = (j << 2) + j + perturb + 1; 17195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru perturb >>= PERTURB_SHIFT; 17205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru find_first_empty_slot: 172103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra pp = &ntblp[j & mask]; 17225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*pp != NULL) 17235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto find_next_empty_slot; 17245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* found an empty hash table slot */ 17255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *pp = tblp; 17265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp->nfree--; 17275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (!(tblp->flag & FINUSE)) { 17285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(tblp, tp->areap); 17295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(otblp, tp->areap); 17325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 17335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 173503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condraktinit(Area *ap, struct table *tp, uint8_t initshift) 17365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 17375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp->areap = ap; 17385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp->tbls = NULL; 173903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra tp->tshift = ((initshift > INIT_TBLSHIFT) ? 174003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra initshift : INIT_TBLSHIFT) - 1; 174103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra tgrow(tp); 17425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 17435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* table, name (key) to search for, hash(name), rv pointer to tbl ptr */ 174503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastruct tbl * 17465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruktscan(struct table *tp, const char *name, uint32_t h, struct tbl ***ppp) 17475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 17485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru size_t j, perturb, mask; 17495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl **pp, *p; 17505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 175103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra mask = ((size_t)1 << (tp->tshift)) - 1; 17525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* search for hash table slot matching name */ 1753c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser j = perturb = h; 17545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto find_first_slot; 17555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru find_next_slot: 17565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru j = (j << 2) + j + perturb + 1; 17575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru perturb >>= PERTURB_SHIFT; 17585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru find_first_slot: 17595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru pp = &tp->tbls[j & mask]; 17605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((p = *pp) != NULL && (p->ua.hval != h || !(p->flag & DEFINED) || 17615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strcmp(p->name, name))) 17625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto find_next_slot; 17635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* p == NULL if not found, correct found entry otherwise */ 17645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ppp) 17655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *ppp = pp; 17665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (p); 17675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 17685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* table, name (key) to enter, hash(n) */ 17705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustruct tbl * 17715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruktenter(struct table *tp, const char *n, uint32_t h) 17725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 17735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl **pp, *p; 177403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra size_t len; 17755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Search: 17775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((p = ktscan(tp, n, h, &pp))) 17785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (p); 17795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 178003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (tp->nfree == 0) { 17815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* too full */ 178203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra tgrow(tp); 17835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto Search; 17845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* create new tbl entry */ 178703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra len = strlen(n); 178803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra checkoktoadd(len, offsetof(struct tbl, name[0]) + 1); 178903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra p = alloc(offsetof(struct tbl, name[0]) + ++len, tp->areap); 17905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p->flag = 0; 17915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p->type = 0; 17925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p->areap = tp->areap; 17935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p->ua.hval = h; 17945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p->u2.field = 0; 17955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p->u.array = NULL; 17965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru memcpy(p->name, n, len); 17975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* enter in tp->tbls */ 17995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp->nfree--; 18005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *pp = p; 18015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (p); 18025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 18035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 18045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 18055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruktwalk(struct tstate *ts, struct table *tp) 18065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 180703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ts->left = (size_t)1 << (tp->tshift); 18085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ts->next = tp->tbls; 18095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 18105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 18115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustruct tbl * 18125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruktnext(struct tstate *ts) 18135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 18145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (--ts->left >= 0) { 18155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *p = *ts->next++; 18165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (p != NULL && (p->flag & DEFINED)) 18175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (p); 18185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 18195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (NULL); 18205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 18215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 18225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 18235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutnamecmp(const void *p1, const void *p2) 18245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 18255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const struct tbl *a = *((const struct tbl * const *)p1); 18265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const struct tbl *b = *((const struct tbl * const *)p2); 18275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 18285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (strcmp(a->name, b->name)); 18295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 18305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 18315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustruct tbl ** 18325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruktsort(struct table *tp) 18335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 18345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru size_t i; 18355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl **p, **sp, **dp; 18365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 183703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 183803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * since the table is never entirely full, no need to reserve 183903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * additional space for the trailing NULL appended below 184003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra */ 184103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra i = (size_t)1 << (tp->tshift); 184203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra p = alloc2(i, sizeof(struct tbl *), ATEMP); 18435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sp = tp->tbls; /* source */ 18445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru dp = p; /* dest */ 18455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (i--) 18465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((*dp = *sp++) != NULL && (((*dp)->flag & DEFINED) || 18475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ((*dp)->flag & ARRAY))) 18485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru dp++; 184903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra qsort(p, (i = dp - p), sizeof(struct tbl *), tnamecmp); 18505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p[i] = NULL; 18515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (p); 18525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 18535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 18545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef SIGWINCH 18555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 18565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querux_sigwinch(int sig MKSH_A_UNUSED) 18575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 18585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* this runs inside interrupt context, with errno saved */ 18595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 18605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru got_winch = 1; 18615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 18625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 1863c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1864c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef DF 1865c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaservoid 1866c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten GlaserDF(const char *fmt, ...) 1867c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser{ 1868c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser va_list args; 1869c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser struct timeval tv; 1870c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser mirtime_mjd mjd; 1871c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1872c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser mksh_lockfd(shl_dbg_fd); 1873c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser mksh_TIME(tv); 1874c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser timet2mjd(&mjd, tv.tv_sec); 1875c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shf_fprintf(shl_dbg, "[%02u:%02u:%02u (%u) %u.%06u] ", 1876c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser (unsigned)mjd.sec / 3600, ((unsigned)mjd.sec / 60) % 60, 1877c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser (unsigned)mjd.sec % 60, (unsigned)getpid(), 1878c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser (unsigned)tv.tv_sec, (unsigned)tv.tv_usec); 1879c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser va_start(args, fmt); 1880c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shf_vfprintf(shl_dbg, fmt, args); 1881c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser va_end(args); 1882c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shf_putc('\n', shl_dbg); 1883c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shf_flush(shl_dbg); 1884c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser mksh_unlkfd(shl_dbg_fd); 1885c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser} 1886c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 1887c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1888c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaservoid 1889c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserx_mkraw(int fd, mksh_ttyst *ocb, bool forread) 1890c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser{ 1891c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser mksh_ttyst cb; 1892c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1893c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (ocb) 1894c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser mksh_tcget(fd, ocb); 1895c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser else 1896c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ocb = &tty_state; 1897c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1898c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser cb = *ocb; 1899c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (forread) { 1900737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes cb.c_iflag &= ~(ISTRIP); 1901c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser cb.c_lflag &= ~(ICANON) | ECHO; 1902c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } else { 1903737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes cb.c_iflag &= ~(INLCR | ICRNL | ISTRIP); 1904c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser cb.c_lflag &= ~(ISIG | ICANON | ECHO); 1905c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 1906c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#if defined(VLNEXT) && defined(_POSIX_VDISABLE) 1907c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* OSF/1 processes lnext when ~icanon */ 1908c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser cb.c_cc[VLNEXT] = _POSIX_VDISABLE; 1909c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 1910c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* SunOS 4.1.x & OSF/1 processes discard(flush) when ~icanon */ 1911c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#if defined(VDISCARD) && defined(_POSIX_VDISABLE) 1912c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser cb.c_cc[VDISCARD] = _POSIX_VDISABLE; 1913c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 1914c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser cb.c_cc[VTIME] = 0; 1915c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser cb.c_cc[VMIN] = 1; 1916c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1917c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser mksh_tcset(fd, &cb); 1918c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser} 1919