1427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes/* $OpenBSD: c_ksh.c,v 1.34 2013/12/17 16:37:05 deraadt Exp $ */ 2b4542e99ca8562aa584e15df8ef35356ff8c10feElliott Hughes/* $OpenBSD: c_sh.c,v 1.45 2014/08/27 08:26:04 jmc Exp $ */ 35155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* $OpenBSD: c_test.c,v 1.18 2009/03/01 20:11:06 otto Exp $ */ 4427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes/* $OpenBSD: c_ulimit.c,v 1.19 2013/11/28 10:33:37 sobrado Exp $ */ 55155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 65155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/*- 703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 8427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * 2010, 2011, 2012, 2013, 2014 95155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Thorsten Glaser <tg@mirbsd.org> 105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Provided that these terms and disclaimer and all copyright notices 125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * are retained or reproduced in an accompanying document, permission 135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * is granted to deal in this work without restriction, including un- 145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * limited rights to use, publicly perform, distribute, sell, modify, 155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * merge, give away, or sublicence. 165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to 185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * the utmost extent permitted by applicable law, neither express nor 195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * implied; without malicious intent or gross negligence. In no event 205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * may a licensor, author or contributor be held liable for indirect, 215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * direct, other damage, loss, or other issues arising in any way out 225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * of dealing in the work, even if advised of the possibility of such 235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * damage or existence of a defect, except proven that it results out 245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * of said person's immediate fault when using the work as intended. 255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#include "sh.h" 285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#if HAVE_SELECT 3003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#if HAVE_SYS_BSDTYPES_H 3103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#include <sys/bsdtypes.h> 3203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 3303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#if HAVE_SYS_SELECT_H 3403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#include <sys/select.h> 3503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 3603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#if HAVE_BSTRING_H 3703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#include <bstring.h> 3803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 3903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 4003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 41b4542e99ca8562aa584e15df8ef35356ff8c10feElliott Hughes__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.258 2014/09/03 19:55:51 tg Exp $"); 425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if HAVE_KILLPG 445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * use killpg if < -1 since -1 does special things 465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * for some non-killpg-endowed kills 475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define mksh_kill(p,s) ((p) < -1 ? killpg(-(p), (s)) : kill((p), (s))) 495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#else 505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* cross fingers and hope kill is killpg-endowed */ 515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define mksh_kill kill 525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* XXX conditions correct? */ 555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if !defined(RLIM_INFINITY) && !defined(MKSH_NO_LIMITS) 5603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define MKSH_NO_LIMITS 1 575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef MKSH_NO_LIMITS 6003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define c_ulimit c_true 6103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 6203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 63427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#if !defined(MKSH_UNEMPLOYED) && HAVE_GETSID 64427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughesstatic int c_suspend(const char **); 65427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#endif 66427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes 67c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser/* getn() that prints error */ 68c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstatic int 69c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserbi_getn(const char *as, int *ai) 70c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser{ 71c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser int rv; 72c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 73c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (!(rv = getn(as, ai))) 74c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bi_errorf("%s: %s", as, "bad number"); 75c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return (rv); 76c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser} 775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic int 7903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrac_true(const char **wp MKSH_A_UNUSED) 8003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{ 8103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (0); 8203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra} 835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic int 8503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrac_false(const char **wp MKSH_A_UNUSED) 8603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{ 8703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (1); 8803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra} 8903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 9003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* 91811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser * A leading = means assignments before command are kept. 92811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser * A leading * means a POSIX special builtin. 935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruconst struct builtin mkshbuiltins[] = { 955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"*=.", c_dot}, 9603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra {"*=:", c_true}, 975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"[", c_test}, 98811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser /* no =: AT&T manual wrong */ 99811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser {Talias, c_alias}, 1005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"*=break", c_brkcont}, 10103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra {Tgbuiltin, c_builtin}, 102811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser {"cat", c_cat}, 103811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser {"cd", c_cd}, 104811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser /* dash compatibility hack */ 105811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser {"chdir", c_cd}, 106811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser {"command", c_command}, 1075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"*=continue", c_brkcont}, 108811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser {"echo", c_print}, 1095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"*=eval", c_eval}, 1105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"*=exec", c_exec}, 1115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"*=exit", c_exitreturn}, 112c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser {Tsgexport, c_typeset}, 113811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser {"false", c_false}, 114811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser {"fc", c_fc}, 115811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser {"getopts", c_getopts}, 11603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra {"=global", c_typeset}, 117811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser {"jobs", c_jobs}, 118811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser {"kill", c_kill}, 1195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"let", c_let}, 120811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser {"let]", c_let}, 1215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"print", c_print}, 1225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"pwd", c_pwd}, 123811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser {"read", c_read}, 124c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser {Tsgreadonly, c_typeset}, 125811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser {"realpath", c_realpath}, 126811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser {"rename", c_rename}, 127811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser {"*=return", c_exitreturn}, 128811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser {Tsgset, c_set}, 129811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser {"*=shift", c_shift}, 130427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#if !defined(MKSH_UNEMPLOYED) && HAVE_GETSID 131427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes {"suspend", c_suspend}, 132427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#endif 133811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser {"test", c_test}, 134811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser {"*=times", c_times}, 135811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser {"*=trap", c_trap}, 136811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser {"true", c_true}, 13703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra {T_typeset, c_typeset}, 138811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser {"ulimit", c_ulimit}, 139811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser {"umask", c_umask}, 140811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser {Tunalias, c_unalias}, 141811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser {Tsgunset, c_unset}, 142811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser {"=wait", c_wait}, 1435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"whence", c_whence}, 1445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_UNEMPLOYED 145811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser {"bg", c_fgbg}, 146811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser {"fg", c_fgbg}, 1475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 148c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifndef MKSH_NO_CMDLINE_EDITING 1495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"bind", c_bind}, 150c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 1515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if HAVE_MKNOD 1525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"mknod", c_mknod}, 1535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 154811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser#ifdef MKSH_PRINTF_BUILTIN 155811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser {"printf", c_printf}, 156811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser#endif 15703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#if HAVE_SELECT 15803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra {"sleep", c_sleep}, 15903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 16003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#ifdef __MirBSD__ 16103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* alias to "true" for historical reasons */ 16203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra {"domainname", c_true}, 16303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 1645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {NULL, (int (*)(const char **))NULL} 1655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}; 1665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustruct kill_info { 1685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int num_width; 1695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int name_width; 1705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}; 1715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic const struct t_op { 1735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char op_text[4]; 1745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Test_op op_num; 1755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} u_ops[] = { 1765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-a", TO_FILAXST }, 1775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-b", TO_FILBDEV }, 1785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-c", TO_FILCDEV }, 1795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-d", TO_FILID }, 1805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-e", TO_FILEXST }, 1815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-f", TO_FILREG }, 1825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-G", TO_FILGID }, 1835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-g", TO_FILSETG }, 1845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-h", TO_FILSYM }, 1855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-H", TO_FILCDF }, 1865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-k", TO_FILSTCK }, 1875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-L", TO_FILSYM }, 1885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-n", TO_STNZE }, 1895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-O", TO_FILUID }, 1905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-o", TO_OPTION }, 1915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-p", TO_FILFIFO }, 1925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-r", TO_FILRD }, 1935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-s", TO_FILGZ }, 1945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-S", TO_FILSOCK }, 1955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-t", TO_FILTT }, 1965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-u", TO_FILSETU }, 1975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-w", TO_FILWR }, 1985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-x", TO_FILEX }, 1995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-z", TO_STZER }, 2005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"", TO_NONOP } 2015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}; 2025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic const struct t_op b_ops[] = { 2035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"=", TO_STEQL }, 2045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"==", TO_STEQL }, 2055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"!=", TO_STNEQ }, 2065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"<", TO_STLT }, 2075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {">", TO_STGT }, 2085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-eq", TO_INTEQ }, 2095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-ne", TO_INTNE }, 2105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-gt", TO_INTGT }, 2115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-ge", TO_INTGE }, 2125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-lt", TO_INTLT }, 2135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-le", TO_INTLE }, 2145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-ef", TO_FILEQ }, 2155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-nt", TO_FILNT }, 2165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-ot", TO_FILOT }, 2175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"", TO_NONOP } 2185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}; 2195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int test_oexpr(Test_env *, bool); 2215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int test_aexpr(Test_env *, bool); 2225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int test_nexpr(Test_env *, bool); 2235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int test_primary(Test_env *, bool); 2245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic Test_op ptest_isa(Test_env *, Test_meta); 2255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic const char *ptest_getopnd(Test_env *, Test_op, bool); 2265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void ptest_error(Test_env *, int, const char *); 227c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstatic char *kill_fmt_entry(char *, size_t, unsigned int, const void *); 2285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void p_time(struct shf *, bool, long, int, int, 229c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser const char *, const char *); 2305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 2325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_pwd(const char **wp) 2335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 2345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int optc; 23503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bool physical = tobool(Flag(FPHYSICAL)); 2365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *p, *allocd = NULL; 2375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt(wp, &builtin_opt, "LP")) != -1) 2395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 2405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'L': 2415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru physical = false; 2425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 2435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'P': 2445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru physical = true; 2455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 2465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 2475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 2485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 2505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (wp[0]) { 2525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("too many arguments"); 2535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 2545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p = current_wd[0] ? (physical ? allocd = do_realpath(current_wd) : 2565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru current_wd) : NULL; 25703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* LINTED use of access */ 2585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (p && access(p, R_OK) < 0) 2595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p = NULL; 26003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!p && !(p = allocd = ksh_get_wd())) { 26103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", "can't determine current directory", 262c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser cstrerror(errno)); 2635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 2645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shprintf("%s\n", p); 2665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(allocd, ATEMP); 2675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 2685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 2695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic const char *s_ptr; 2715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int s_get(void); 2725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void s_put(int); 2735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 2755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_print(const char **wp) 2765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 2775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define PO_NL BIT(0) /* print newline */ 2785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define PO_EXPAND BIT(1) /* expand backslash sequences */ 2795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define PO_PMINUSMINUS BIT(2) /* print a -- argument */ 2805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define PO_HIST BIT(3) /* print to history instead of stdout */ 2815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define PO_COPROC BIT(4) /* printing to coprocess: block SIGPIPE */ 2825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int fd = 1, c; 283c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser int flags = PO_EXPAND | PO_NL; 2845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *s, *emsg; 2855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XString xs; 2865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *xp; 2875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (wp[0][0] == 'e') { 2895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* echo builtin */ 2905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp++; 291c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef MKSH_MIDNIGHTBSD01ASH_COMPAT 292c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (Flag(FSH)) { 293c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* 294c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * MidnightBSD /bin/sh needs a BSD echo, that is, 295c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * one that supports -e but does not enable it by 296c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * default 297c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser */ 298c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser flags = PO_NL; 299c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 300c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 301c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (Flag(FPOSIX) || 302c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifndef MKSH_MIDNIGHTBSD01ASH_COMPAT 303c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser Flag(FSH) || 304c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 305c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser Flag(FAS_BUILTIN)) { 3065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Debian Policy 10.4 compliant "echo" builtin */ 3075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*wp && !strcmp(*wp, "-n")) { 3085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* we recognise "-n" only as the first arg */ 3095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flags = 0; 3105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp++; 3115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 3125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* otherwise, we print everything as-is */ 3135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flags = PO_NL; 3145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 3155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int nflags = flags; 3165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /** 3185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * a compromise between sysV and BSD echo commands: 3195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * escape sequences are enabled by default, and -n, 3205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * -e and -E are recognised if they appear in argu- 3215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * ments with no illegal options (ie, echo -nq will 3225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * print -nq). 3235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Different from sysV echo since options are reco- 3245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * gnised, different from BSD echo since escape se- 3255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * quences are enabled by default. 3265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 3275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((s = *wp) && *s == '-' && s[1]) { 3295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (*++s) 3305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*s == 'n') 3315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nflags &= ~PO_NL; 3325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (*s == 'e') 3335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nflags |= PO_EXPAND; 3345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (*s == 'E') 3355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nflags &= ~PO_EXPAND; 3365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 3375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 3385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * bad option: don't use 3395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * nflags, print argument 3405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 3415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*s) 3445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp++; 3465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flags = nflags; 3475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 3505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int optc; 3515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *opts = "Rnprsu,"; 3525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt(wp, &builtin_opt, opts)) != -1) 3545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 35503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'R': 35603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* fake BSD echo command */ 3575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flags |= PO_PMINUSMINUS; 3585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flags &= ~PO_EXPAND; 3595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru opts = "ne"; 3605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'e': 3625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flags |= PO_EXPAND; 3635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'n': 3655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flags &= ~PO_NL; 3665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'p': 3685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((fd = coproc_getfd(W_OK, &emsg)) < 0) { 36903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", "-p", emsg); 3705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 3715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'r': 3745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flags &= ~PO_EXPAND; 3755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 's': 3775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flags |= PO_HIST; 3785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'u': 3805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!*(s = builtin_opt.optarg)) 3815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fd = 0; 3825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if ((fd = check_fd(s, W_OK, &emsg)) < 0) { 38303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s: %s", "-u", s, emsg); 3845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 3855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 3885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 3895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(builtin_opt.info & GI_MINUSMINUS)) { 3925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* treat a lone - like -- */ 3935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (wp[builtin_opt.optind] && 3945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ksh_isdash(wp[builtin_opt.optind])) 3955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru builtin_opt.optind++; 3965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (flags & PO_PMINUSMINUS) 3975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru builtin_opt.optind--; 3985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 3995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xinit(xs, xp, 128, ATEMP); 4025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (*wp != NULL) { 4045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = *wp; 4055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((c = *s++) != '\0') { 4065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xcheck(xs, xp); 4075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((flags & PO_EXPAND) && c == '\\') { 4085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s_ptr = s; 4095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = unbksl(false, s_get, s_put); 4105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = s_ptr; 4115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == -1) { 4125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* rejected by generic function */ 4135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch ((c = *s++)) { 4145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'c': 4155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flags &= ~PO_NL; 4165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* AT&T brain damage */ 4175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 4185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '\0': 4195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s--; 4205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = '\\'; 4215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 4225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 4235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xput(xs, xp, '\\'); 4245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if ((unsigned int)c > 0xFF) { 4265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* generic function returned Unicode */ 4275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char ts[4]; 4285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 42903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ts[utf_wctomb(ts, c - 0x100)] = 0; 4305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (c = 0; ts[c]; ++c) 4315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xput(xs, xp, ts[c]); 4325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 4335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xput(xs, xp, c); 4365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*++wp != NULL) 4385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xput(xs, xp, ' '); 4395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (flags & PO_NL) 4415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xput(xs, xp, '\n'); 4425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (flags & PO_HIST) { 4445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xput(xs, xp, '\0'); 4455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru histsave(&source->line, Xstring(xs, xp), true, false); 4465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xfree(xs, xp); 4475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 4485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int len = Xlength(xs, xp); 4495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int opipe = 0; 4505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 45103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 45203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Ensure we aren't killed by a SIGPIPE while writing to 4535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * a coprocess. AT&T ksh doesn't seem to do this (seems 4545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * to just check that the co-process is alive which is 4555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * not enough). 4565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 4575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (coproc.write >= 0 && coproc.write == fd) { 4585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flags |= PO_COPROC; 4595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru opipe = block_pipe(); 4605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (s = Xstring(xs, xp); len > 0; ) { 4625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c = write(fd, s, len)) < 0) { 4635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (flags & PO_COPROC) 4645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru restore_pipe(opipe); 4655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (errno == EINTR) { 4665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* allow user to ^C out */ 4675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru intrcheck(); 4685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (flags & PO_COPROC) 4695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru opipe = block_pipe(); 4705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 4715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 4735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s += c; 4755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru len -= c; 4765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (flags & PO_COPROC) 4785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru restore_pipe(opipe); 4795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 4825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 4835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 4855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querus_get(void) 4865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 4875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (*s_ptr++); 4885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 4895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 4915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querus_put(int c MKSH_A_UNUSED) 4925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 4935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru --s_ptr; 4945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 4955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 4975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_whence(const char **wp) 4985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 4995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *tp; 5005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *id; 5015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool pflag = false, vflag = false, Vflag = false; 5025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv = 0, optc, fcflags; 5035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool iam_whence = wp[0][0] == 'w'; 5045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *opts = iam_whence ? "pv" : "pvV"; 5055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt(wp, &builtin_opt, opts)) != -1) 5075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 5085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'p': 5095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru pflag = true; 5105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'v': 5125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vflag = true; 5135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'V': 5155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Vflag = true; 5165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 5185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 5195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 5215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fcflags = FC_BI | FC_PATH | FC_FUNC; 5235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!iam_whence) { 5245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Note that -p on its own is deal with in comexec() */ 5255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (pflag) 5265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fcflags |= FC_DEFPATH; 52703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 52803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Convert command options to whence options - note that 5295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * command -pV uses a different path search than whence -v 5305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * or whence -pv. This should be considered a feature. 5315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 5325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vflag = Vflag; 5335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (pflag) 5355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fcflags &= ~(FC_BI | FC_FUNC); 5365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((vflag || rv == 0) && (id = *wp++) != NULL) { 5385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru uint32_t h = 0; 5395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp = NULL; 5415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((iam_whence || vflag) && !pflag) 5425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp = ktsearch(&keywords, id, h = hash(id)); 5435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!tp && !pflag) { 5445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp = ktsearch(&aliases, id, h ? h : hash(id)); 5455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tp && !(tp->flag & ISSET)) 5465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp = NULL; 5475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!tp) 5495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp = findcom(id, fcflags); 5505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vflag || (tp->type != CALIAS && tp->type != CEXEC && 5515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp->type != CTALIAS)) 5525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts(id, shl_stdout); 55303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (vflag) 55403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra switch (tp->type) { 55503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case CKEYWD: 55603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case CALIAS: 55703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case CFUNC: 55803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case CSHELL: 55903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shf_puts(" is a", shl_stdout); 56003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 56103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 56203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 5635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (tp->type) { 5645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case CKEYWD: 5655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vflag) 56603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shf_puts(" reserved word", shl_stdout); 5675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case CALIAS: 5695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vflag) 57003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shprintf("n %s%s for ", 57103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra (tp->flag & EXPORT) ? "exported " : null, 57203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Talias); 5735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!iam_whence && !vflag) 57403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shprintf("%s %s=", Talias, id); 575c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser print_value_quoted(shl_stdout, tp->val.s); 5765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case CFUNC: 5785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vflag) { 5795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tp->flag & EXPORT) 5805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts("n exported", shl_stdout); 5815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tp->flag & TRACE) 5825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts(" traced", shl_stdout); 5835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(tp->flag & ISSET)) { 5845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts(" undefined", shl_stdout); 5855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tp->u.fpath) 5865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shprintf(" (autoload from %s)", 5875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp->u.fpath); 5885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 58903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shf_puts(T_function, shl_stdout); 5905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case CSHELL: 5935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vflag) 59403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shprintf("%s %s %s", 59503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra (tp->flag & SPEC_BI) ? " special" : null, 59603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra "shell", Tbuiltin); 5975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case CTALIAS: 5995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case CEXEC: 6005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tp->flag & ISSET) { 6015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vflag) { 6025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts(" is ", shl_stdout); 6035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tp->type == CTALIAS) 60403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shprintf("a tracked %s%s for ", 6055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (tp->flag & EXPORT) ? 60603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra "exported " : null, 60703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Talias); 6085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts(tp->val.s, shl_stdout); 6105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 6115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vflag) 61203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shprintf(" %s\n", "not found"); 6135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 1; 6145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 6165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 6175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shprintf("%s is *GOK*", id); 6185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 6195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vflag || !rv) 6215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_putc('\n', shl_stdout); 6225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 6245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 6255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Deal with command -vV - command -p dealt with in comexec() */ 6275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 6285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_command(const char **wp) 6295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 63003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 63103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Let c_whence do the work. Note that c_command() must be 6325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * a distinct function from c_whence() (tested in comexec()). 6335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 6345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (c_whence(wp)); 6355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 6365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 63703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* typeset, global, export, and readonly */ 638c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstatic void c_typeset_vardump(struct tbl *, uint32_t, int, bool, bool); 639c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstatic void c_typeset_vardump_recursive(struct block *, uint32_t, int, bool, 640c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bool); 6415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 6425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_typeset(const char **wp) 6435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 6445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *vp, **p; 64503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra uint32_t fset = 0, fclr = 0, flag; 646c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser int thing = 0, field = 0, base = 0, i; 647c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser struct block *l; 6485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *opts; 649c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser const char *fieldstr = NULL, *basestr = NULL; 6505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool localv = false, func = false, pflag = false, istset = true; 651427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes enum namerefflag new_refflag = SRF_NOP; 6525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (**wp) { 65403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 65503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* export */ 65603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'e': 6575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fset |= EXPORT; 6585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru istset = false; 6595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 66003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 66103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* readonly */ 66203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'r': 6635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fset |= RDONLY; 6645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru istset = false; 6655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 66603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 66703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* set */ 66803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 's': 6695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* called with 'typeset -' */ 6705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 67103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 67203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* typeset */ 67303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 't': 6745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru localv = true; 6755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 6765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* see comment below regarding possible opions */ 6795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru opts = istset ? "L#R#UZ#afi#lnprtux" : "p"; 6805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru builtin_opt.flags |= GF_PLUSOPT; 68203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 68303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * AT&T ksh seems to have 0-9 as options which are multiplied 6845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * to get a number that is used with -L, -R, -Z or -i (eg, -1R2 6855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * sets right justify in a field of 12). This allows options 6865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * to be grouped in an order (eg, -Lu12), but disallows -i8 -L3 and 6875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * does not allow the number to be specified as a separate argument 6885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Here, the number must follow the RLZi option, but is optional 6895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (see the # kludge in ksh_getopt()). 6905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 691c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser while ((i = ksh_getopt(wp, &builtin_opt, opts)) != -1) { 6925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flag = 0; 693c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser switch (i) { 6945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'L': 6955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flag = LJUST; 6965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fieldstr = builtin_opt.optarg; 6975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 6985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'R': 6995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flag = RJUST; 7005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fieldstr = builtin_opt.optarg; 7015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'U': 70303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 70403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * AT&T ksh uses u, but this conflicts with 7055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * upper/lower case. If this option is changed, 7065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * need to change the -U below as well 7075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 7085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flag = INT_U; 7095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'Z': 7115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flag = ZEROFIL; 7125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fieldstr = builtin_opt.optarg; 7135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'a': 7155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 7165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * this is supposed to set (-a) or unset (+a) the 7175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * indexed array attribute; it does nothing on an 7185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * existing regular string or indexed array though 7195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 7205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'f': 7225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru func = true; 7235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'i': 7255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flag = INTEGER; 7265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru basestr = builtin_opt.optarg; 7275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'l': 7295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flag = LCASEV; 7305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'n': 732427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes new_refflag = (builtin_opt.info & GI_PLUS) ? 73303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra SRF_DISABLE : SRF_ENABLE; 7345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 73503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* export, readonly: POSIX -p flag */ 7365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'p': 7375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* typeset: show values as well */ 7385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru pflag = true; 7395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (istset) 7405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 7415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'r': 7435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flag = RDONLY; 7445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 't': 7465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flag = TRACE; 7475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'u': 74903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* upper case / autoload */ 75003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra flag = UCASEV_AL; 7515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'x': 7535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flag = EXPORT; 7545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 7565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 7575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (builtin_opt.info & GI_PLUS) { 7595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fclr |= flag; 7605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fset &= ~flag; 7615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru thing = '+'; 7625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 7635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fset |= flag; 7645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fclr &= ~flag; 7655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru thing = '-'; 7665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (fieldstr && !bi_getn(fieldstr, &field)) 770427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes return (1); 771c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (basestr && (!bi_getn(basestr, &base) || base < 1 || base > 36)) { 772c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bi_errorf("%s: %s", "bad integer base", basestr); 773427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes return (1); 774c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 7755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(builtin_opt.info & GI_MINUSMINUS) && wp[builtin_opt.optind] && 7775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (wp[builtin_opt.optind][0] == '-' || 7785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp[builtin_opt.optind][0] == '+') && 7795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp[builtin_opt.optind][1] == '\0') { 7805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru thing = wp[builtin_opt.optind][0]; 7815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru builtin_opt.optind++; 7825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 78403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (func && (((fset|fclr) & ~(TRACE|UCASEV_AL|EXPORT)) || 785427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes new_refflag != SRF_NOP)) { 7865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("only -t, -u and -x options may be used with -f"); 787427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes return (1); 7885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (wp[builtin_opt.optind]) { 79003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 79103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Take care of exclusions. 7925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * At this point, flags in fset are cleared in fclr and vice 7935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * versa. This property should be preserved. 7945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 79503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (fset & LCASEV) 79603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* LCASEV has priority over UCASEV_AL */ 7975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fset &= ~UCASEV_AL; 79803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (fset & LJUST) 79903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* LJUST has priority over RJUST */ 8005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fset &= ~RJUST; 80103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((fset & (ZEROFIL|LJUST)) == ZEROFIL) { 80203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -Z implies -ZR */ 8035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fset |= RJUST; 8045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fclr &= ~RJUST; 8055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 80603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 80703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Setting these attributes clears the others, unless they 8085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * are also set in this command 8095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 8105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((fset & (LJUST | RJUST | ZEROFIL | UCASEV_AL | LCASEV | 811427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes INTEGER | INT_U | INT_L)) || new_refflag != SRF_NOP) 8125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fclr |= ~fset & (LJUST | RJUST | ZEROFIL | UCASEV_AL | 8135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru LCASEV | INTEGER | INT_U | INT_L); 8145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 815427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes if (new_refflag != SRF_NOP) { 816427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes fclr &= ~(ARRAY | ASSOC); 817427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes fset &= ~(ARRAY | ASSOC); 818427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes fclr |= EXPORT; 819427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes fset |= ASSOC; 820427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes if (new_refflag == SRF_DISABLE) 821427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes fclr |= ASSOC; 822427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes } 8235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* set variables and attributes */ 825c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (wp[builtin_opt.optind] && 826c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* not "typeset -p varname" */ 827c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser !(!func && pflag && !(fset | fclr))) { 828c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser int rv = 0; 8295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *f; 8305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (localv && !func) 8325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fset |= LOCAL; 8335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (i = builtin_opt.optind; wp[i]; i++) { 8345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (func) { 8355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru f = findfunc(wp[i], hash(wp[i]), 83603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra tobool(fset & UCASEV_AL)); 8375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!f) { 8385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* AT&T ksh does ++rv: bogus */ 8395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 1; 8405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 8415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (fset | fclr) { 8435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru f->flag |= fset; 8445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru f->flag &= ~fclr; 84503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else { 84603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra fpFUNCTf(shl_stdout, 0, 84703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra tobool(f->flag & FKSH), 84803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra wp[i], f->val.t); 84903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shf_putc('\n', shl_stdout); 85003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 8515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (!typeset(wp[i], fset, fclr, field, base)) { 852811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser bi_errorf("%s: %s", wp[i], "is not an identifier"); 853427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes return (1); 8545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 8575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* list variables and attributes */ 86003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 86103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* no difference at this point.. */ 86203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra flag = fset | fclr; 8635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (func) { 8645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (l = e->loc; l; l = l->next) { 8655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (p = ktsort(&l->funs); (vp = *p++); ) { 8665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (flag && (vp->flag & flag) == 0) 8675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 8685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (thing == '-') 86903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra fpFUNCTf(shl_stdout, 0, 87003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra tobool(vp->flag & FKSH), 8715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->name, vp->val.t); 8725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 87303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shf_puts(vp->name, shl_stdout); 87403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shf_putc('\n', shl_stdout); 8755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 877c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } else if (wp[builtin_opt.optind]) { 878c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser for (i = builtin_opt.optind; wp[i]; i++) { 879c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser varsearch(e->loc, &vp, wp[i], hash(wp[i])); 880c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser c_typeset_vardump(vp, flag, thing, pflag, istset); 8815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 882c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } else 883c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser c_typeset_vardump_recursive(e->loc, flag, thing, pflag, istset); 8845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 8855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 8865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 887c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstatic void 888c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserc_typeset_vardump_recursive(struct block *l, uint32_t flag, int thing, 889c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bool pflag, bool istset) 890c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser{ 891c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser struct tbl **blockvars, *vp; 892c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 893c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (l->next) 894c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser c_typeset_vardump_recursive(l->next, flag, thing, pflag, istset); 895c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser blockvars = ktsort(&l->vars); 896c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser while ((vp = *blockvars++)) 897c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser c_typeset_vardump(vp, flag, thing, pflag, istset); 898c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /*XXX doesn’t this leak? */ 899c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser} 900c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 901c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstatic void 902c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserc_typeset_vardump(struct tbl *vp, uint32_t flag, int thing, bool pflag, 903c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bool istset) 904c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser{ 905c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser struct tbl *tvp; 906c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser int any_set = 0; 907c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser char *s; 908c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 909c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (!vp) 910c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return; 911c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 912c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* 913c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * See if the parameter is set (for arrays, if any 914c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * element is set). 915c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser */ 916c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser for (tvp = vp; tvp; tvp = tvp->u.array) 917c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (tvp->flag & ISSET) { 918c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser any_set = 1; 919c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser break; 920c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 921c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 922c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* 923c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * Check attributes - note that all array elements 924c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * have (should have?) the same attributes, so checking 925c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * the first is sufficient. 926c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * 927c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * Report an unset param only if the user has 928c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * explicitly given it some attribute (like export); 929c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * otherwise, after "echo $FOO", we would report FOO... 930c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser */ 931c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (!any_set && !(vp->flag & USERATTRIB)) 932c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return; 933c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (flag && (vp->flag & flag) == 0) 934c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return; 935c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (!(vp->flag & ARRAY)) 936c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* optimise later conditionals */ 937c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser any_set = 0; 938c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser do { 939c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* 940c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * Ignore array elements that aren't set unless there 941c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * are no set elements, in which case the first is 942c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * reported on 943c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser */ 944c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (any_set && !(vp->flag & ISSET)) 945c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser continue; 946c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* no arguments */ 947c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (!thing && !flag) { 948c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (any_set == 1) { 949c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shprintf("%s %s %s\n", Tset, "-A", vp->name); 950c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser any_set = 2; 951c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 952c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* 953c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * AT&T ksh prints things like export, integer, 954c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * leftadj, zerofill, etc., but POSIX says must 955c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * be suitable for re-entry... 956c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser */ 957c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shprintf("%s %s", Ttypeset, ""); 958c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (((vp->flag & (ARRAY | ASSOC)) == ASSOC)) 959c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shprintf("%s ", "-n"); 960c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((vp->flag & INTEGER)) 961c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shprintf("%s ", "-i"); 962c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((vp->flag & EXPORT)) 963c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shprintf("%s ", "-x"); 964c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((vp->flag & RDONLY)) 965c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shprintf("%s ", "-r"); 966c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((vp->flag & TRACE)) 967c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shprintf("%s ", "-t"); 968c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((vp->flag & LJUST)) 969c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shprintf("-L%d ", vp->u2.field); 970c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((vp->flag & RJUST)) 971c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shprintf("-R%d ", vp->u2.field); 972c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((vp->flag & ZEROFIL)) 973c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shprintf("%s ", "-Z"); 974c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((vp->flag & LCASEV)) 975c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shprintf("%s ", "-l"); 976c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((vp->flag & UCASEV_AL)) 977c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shprintf("%s ", "-u"); 978c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((vp->flag & INT_U)) 979c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shprintf("%s ", "-U"); 980c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } else if (pflag) { 981c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shprintf("%s %s", istset ? Ttypeset : 982c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser (flag & EXPORT) ? Texport : Treadonly, ""); 983c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 984c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (any_set) 985c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shprintf("%s[%lu]", vp->name, arrayindex(vp)); 986c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser else 987c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shf_puts(vp->name, shl_stdout); 988c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((!thing && !flag && pflag) || 989c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser (thing == '-' && (vp->flag & ISSET))) { 990c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser s = str_val(vp); 991c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shf_putc('=', shl_stdout); 992c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* AT&T ksh can't have justified integers... */ 993c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((vp->flag & (INTEGER | LJUST | RJUST)) == INTEGER) 994c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shf_puts(s, shl_stdout); 995c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser else 996c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser print_value_quoted(shl_stdout, s); 997c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 998c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shf_putc('\n', shl_stdout); 999c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1000c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* 1001c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * Only report first 'element' of an array with 1002c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * no set elements. 1003c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser */ 1004c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (!any_set) 1005c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return; 1006c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } while ((vp = vp->u.array)); 1007c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser} 1008c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 10095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 10105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_alias(const char **wp) 10115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 10125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct table *t = &aliases; 10135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv = 0, prefix = 0; 10145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool rflag = false, tflag, Uflag = false, pflag = false; 101503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra uint32_t xflag = 0; 10165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int optc; 10175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru builtin_opt.flags |= GF_PLUSOPT; 10195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt(wp, &builtin_opt, "dprtUx")) != -1) { 10205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru prefix = builtin_opt.info & GI_PLUS ? '+' : '-'; 10215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 10225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'd': 10235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef MKSH_NOPWNAM 10245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = NULL; /* fix "alias -dt" */ 10255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#else 10265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = &homedirs; 10275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 10285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 10295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'p': 10305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru pflag = true; 10315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 10325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'r': 10335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rflag = true; 10345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 10355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 't': 10365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = &taliases; 10375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 10385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'U': 10395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 10405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * kludge for tracked alias initialization 10415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (don't do a path search, just make an entry) 10425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 10435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Uflag = true; 10445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 10455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'x': 10465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru xflag = EXPORT; 10475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 10485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 10495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 10505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef MKSH_NOPWNAM 10535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (t == NULL) 10545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 10555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 10565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 10575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(builtin_opt.info & GI_MINUSMINUS) && *wp && 10595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (wp[0][0] == '-' || wp[0][0] == '+') && wp[0][1] == '\0') { 10605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru prefix = wp[0][0]; 10615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp++; 10625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tflag = t == &taliases; 10655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* "hash -r" means reset all the tracked aliases.. */ 10675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (rflag) { 10685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru static const char *args[] = { 106903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Tunalias, "-ta", NULL 10705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru }; 10715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!tflag || *wp) { 107303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shprintf("%s: -r flag can only be used with -t" 107403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra " and without arguments\n", Talias); 10755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 10765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ksh_getopt_reset(&builtin_opt, GF_ERROR); 10785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (c_unalias(args)); 10795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*wp == NULL) { 10825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *ap, **p; 10835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (p = ktsort(t); (ap = *p++) != NULL; ) 10855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((ap->flag & (ISSET|xflag)) == (ISSET|xflag)) { 10865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (pflag) 108703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shprintf("%s ", Talias); 10885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts(ap->name, shl_stdout); 10895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (prefix != '+') { 10905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_putc('=', shl_stdout); 1091c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser print_value_quoted(shl_stdout, ap->val.s); 10925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_putc('\n', shl_stdout); 10945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; *wp != NULL; wp++) { 10985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *alias = *wp, *val, *newval; 10995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *xalias = NULL; 11005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *ap; 11015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru uint32_t h; 11025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((val = cstrchr(alias, '='))) { 11045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strndupx(xalias, alias, val++ - alias, ATEMP); 11055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru alias = xalias; 11065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru h = hash(alias); 11085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (val == NULL && !tflag && !xflag) { 11095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap = ktsearch(t, alias, h); 11105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ap != NULL && (ap->flag&ISSET)) { 11115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (pflag) 111203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shprintf("%s ", Talias); 11135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts(ap->name, shl_stdout); 11145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (prefix != '+') { 11155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_putc('=', shl_stdout); 1116c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser print_value_quoted(shl_stdout, ap->val.s); 11175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_putc('\n', shl_stdout); 11195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 112003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shprintf("%s %s %s\n", alias, Talias, 112103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra "not found"); 11225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 1; 11235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 11255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap = ktenter(t, alias, h); 11275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap->type = tflag ? CTALIAS : CALIAS; 11285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Are we setting the value or just some flags? */ 11295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((val && !tflag) || (!val && tflag && !Uflag)) { 11305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ap->flag&ALLOC) { 11315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap->flag &= ~(ALLOC|ISSET); 11325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(ap->val.s, APERM); 11335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* ignore values for -t (AT&T ksh does this) */ 113503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra newval = tflag ? 113603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra search_path(alias, path, X_OK, NULL) : 113703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra val; 11385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (newval) { 11395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strdupx(ap->val.s, newval, APERM); 11405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap->flag |= ALLOC|ISSET; 11415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 11425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap->flag &= ~ISSET; 11435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap->flag |= DEFINED; 11455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (prefix == '+') 11465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap->flag &= ~xflag; 11475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 11485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap->flag |= xflag; 11495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(xalias, ATEMP); 11505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 11535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 11545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 11565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_unalias(const char **wp) 11575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 11585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct table *t = &aliases; 11595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *ap; 11605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int optc, rv = 0; 11615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool all = false; 11625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt(wp, &builtin_opt, "adt")) != -1) 11645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 11655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'a': 11665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru all = true; 11675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 11685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'd': 11695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef MKSH_NOPWNAM 117003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* fix "unalias -dt" */ 117103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra t = NULL; 11725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#else 11735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = &homedirs; 11745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 11755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 11765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 't': 11775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = &taliases; 11785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 11795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 11805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 11815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef MKSH_NOPWNAM 11835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (t == NULL) 11845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 11855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 11865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 11875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; *wp != NULL; wp++) { 11895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap = ktsearch(t, *wp, hash(*wp)); 11905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ap == NULL) { 119103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* POSIX */ 119203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 1; 11935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 11945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ap->flag&ALLOC) { 11965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap->flag &= ~(ALLOC|ISSET); 11975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(ap->val.s, APERM); 11985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap->flag &= ~(DEFINED|ISSET|EXPORT); 12005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 12015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (all) { 12035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tstate ts; 12045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (ktwalk(&ts, t); (ap = ktnext(&ts)); ) { 12065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ap->flag&ALLOC) { 12075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap->flag &= ~(ALLOC|ISSET); 12085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(ap->val.s, APERM); 12095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 12105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap->flag &= ~(DEFINED|ISSET|EXPORT); 12115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 12125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 12135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 12155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 12165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 12185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_let(const char **wp) 12195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 12205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv = 1; 12215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mksh_ari_t val; 12225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 122303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (wp[1] == NULL) 122403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* AT&T ksh does this */ 12255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("no arguments"); 12265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 12275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (wp++; *wp; wp++) 12285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!evaluate(*wp, &val, KSH_RETURN_ERROR, true)) { 122903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* distinguish error from zero result */ 123003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 2; 12315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 12335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = val == 0; 12345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 12355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 12365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 12385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_jobs(const char **wp) 12395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 12405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int optc, flag = 0, nflag = 0, rv = 0; 12415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt(wp, &builtin_opt, "lpnz")) != -1) 12435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 12445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'l': 12455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flag = 1; 12465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'p': 12485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flag = 2; 12495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'n': 12515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nflag = 1; 12525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 125303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'z': 125403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* debugging: print zombies */ 12555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nflag = -1; 12565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 12585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 12595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 12605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 12615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!*wp) { 12625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (j_jobs(NULL, flag, nflag)) 12635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 1; 12645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 12655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; *wp; wp++) 12665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (j_jobs(*wp, flag, nflag)) 12675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 1; 12685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 12695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 12705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 12715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_UNEMPLOYED 12735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 12745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_fgbg(const char **wp) 12755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 12765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool bg = strcmp(*wp, "bg") == 0; 12775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv = 0; 12785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!Flag(FMONITOR)) { 12805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("job control not enabled"); 12815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 12825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 12835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_getopt(wp, &builtin_opt, null) == '?') 12845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 12855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 12865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*wp) 12875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; *wp; wp++) 12885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = j_resume(*wp, bg); 12895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 12905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = j_resume("%%", bg); 12915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (bg ? 0 : rv); 12925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 12935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 12945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* format a single kill item */ 12965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic char * 1297c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserkill_fmt_entry(char *buf, size_t buflen, unsigned int i, const void *arg) 12985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 12995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const struct kill_info *ki = (const struct kill_info *)arg; 13005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru i++; 1302c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shf_snprintf(buf, buflen, "%*u %*s %s", 13035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ki->num_width, i, 13045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ki->name_width, sigtraps[i].name, 13055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sigtraps[i].mess); 13065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (buf); 13075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 13085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 13105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_kill(const char **wp) 13115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 13125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Trap *t = NULL; 13135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *p; 13145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool lflag = false; 13155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int i, n, rv, sig; 13165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* assume old style options if -digits or -UPPERCASE */ 13185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((p = wp[1]) && *p == '-' && (ksh_isdigit(p[1]) || 13195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ksh_isupper(p[1]))) { 1320c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (!(t = gettrap(p + 1, false))) { 13215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("bad signal '%s'", p + 1); 13225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 13235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru i = (wp[2] && strcmp(wp[2], "--") == 0) ? 3 : 2; 13255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 13265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int optc; 13275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt(wp, &builtin_opt, "ls:")) != -1) 13295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 13305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'l': 13315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru lflag = true; 13325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 13335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 's': 13345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(t = gettrap(builtin_opt.optarg, true))) { 13355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("bad signal '%s'", 13365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru builtin_opt.optarg); 13375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 13385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 13405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 13415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 13425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru i = builtin_opt.optind; 13445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((lflag && t) || (!wp[i] && !lflag)) { 13465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_SMALL 13475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts("usage:\tkill [-s signame | -signum | -signame]" 13485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru " { job | pid | pgrp } ...\n" 13495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "\tkill -l [exit_status ...]\n", shl_out); 13505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 13515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorfz(); 13525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 13535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (lflag) { 13565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (wp[i]) { 13575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; wp[i]; i++) { 13585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!bi_getn(wp[i], &n)) 13595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 1360427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#if (NSIG < 128) 13615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (n > 128 && n < 128 + NSIG) 13625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru n -= 128; 1363427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#endif 13645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (n > 0 && n < NSIG) 13655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shprintf("%s\n", sigtraps[n].name); 13665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 13675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shprintf("%d\n", n); 13685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 137003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ssize_t w, mess_cols, mess_octs; 137103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra int j; 13725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct kill_info ki; 13735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (j = NSIG, ki.num_width = 1; j >= 10; j /= 10) 13755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ki.num_width++; 13765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ki.name_width = mess_cols = mess_octs = 0; 13775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (j = 0; j < NSIG; j++) { 13785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru w = strlen(sigtraps[j].name); 13795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (w > ki.name_width) 13805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ki.name_width = w; 13815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru w = strlen(sigtraps[j].mess); 13825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (w > mess_octs) 13835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mess_octs = w; 13845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru w = utf_mbswidth(sigtraps[j].mess); 13855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (w > mess_cols) 13865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mess_cols = w; 13875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1389c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser print_columns(shl_stdout, (unsigned int)(NSIG - 1), 13905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru kill_fmt_entry, (void *)&ki, 13915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ki.num_width + 1 + ki.name_width + 1 + mess_octs, 13925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ki.num_width + 1 + ki.name_width + 1 + mess_cols, 13935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru true); 13945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 13965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 0; 13985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sig = t ? t->signal : SIGTERM; 13995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; (p = wp[i]); i++) { 14005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*p == '%') { 14015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (j_kill(p, sig)) 14025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 1; 14035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (!getn(p, &n)) { 140403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", p, 140503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra "arguments must be jobs or process IDs"); 14065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 1; 14075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 14085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (mksh_kill(n, sig) < 0) { 1409c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bi_errorf("%s: %s", p, cstrerror(errno)); 14105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 1; 14115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 14155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 14165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 14185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querugetopts_reset(int val) 14195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 14205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (val >= 1) { 14215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ksh_getopt_reset(&user_opt, GF_NONAME | GF_PLUSOPT); 14225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru user_opt.optind = user_opt.uoptind = val; 14235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 14255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 14275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_getopts(const char **wp) 14285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 14295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int argc, optc, rv; 14305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *opts, *var; 14315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char buf[3]; 14325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *vq, *voptarg; 14335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_getopt(wp, &builtin_opt, null) == '?') 14355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 14365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 14375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru opts = *wp++; 14395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!opts) { 144003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("missing %s argument", "options"); 14415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 14425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru var = *wp++; 14455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!var) { 144603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("missing %s argument", "name"); 14475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 14485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!*var || *skip_varname(var, true)) { 145003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", var, "is not an identifier"); 14515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 14525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (e->loc->next == NULL) { 145503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra internal_warningf("%s: %s", "c_getopts", "no argv"); 14565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 14575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Which arguments are we parsing... */ 14595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*wp == NULL) 14605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp = e->loc->next->argv; 14615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 14625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *--wp = e->loc->next->argv[0]; 14635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Check that our saved state won't cause a core dump... */ 14655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (argc = 0; wp[argc]; argc++) 14665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 14675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (user_opt.optind > argc || 14685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (user_opt.p != 0 && 14695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru user_opt.p > strlen(wp[user_opt.optind - 1]))) { 14705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("arguments changed since last call"); 14715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 14725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru user_opt.optarg = NULL; 14755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru optc = ksh_getopt(wp, &user_opt, opts); 14765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (optc >= 0 && optc != '?' && (user_opt.info & GI_PLUS)) { 14785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru buf[0] = '+'; 14795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru buf[1] = optc; 14805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru buf[2] = '\0'; 14815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 148203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 148303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * POSIX says var is set to ? at end-of-options, AT&T ksh 14845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * sets it to null - we go with POSIX... 14855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 14865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru buf[0] = optc < 0 ? '?' : optc; 14875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru buf[1] = '\0'; 14885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* AT&T ksh93 in fact does change OPTIND for unknown options too */ 14915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru user_opt.uoptind = user_opt.optind; 14925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru voptarg = global("OPTARG"); 149403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* AT&T ksh clears ro and int */ 149503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra voptarg->flag &= ~RDONLY; 14965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Paranoia: ensure no bizarre results. */ 14975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (voptarg->flag & INTEGER) 14985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru typeset("OPTARG", 0, INTEGER, 0, 0); 14995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (user_opt.optarg == NULL) 15005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unset(voptarg, 1); 15015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 15025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* This can't fail (have cleared readonly/integer) */ 15035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setstr(voptarg, user_opt.optarg, KSH_RETURN_ERROR); 15045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 0; 15065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vq = global(var); 15085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Error message already printed (integer, readonly) */ 15095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!setstr(vq, buf, KSH_RETURN_ERROR)) 151003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 2; 15115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (Flag(FEXPORT)) 15125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru typeset(var, EXPORT, 0, 0, 0); 15135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (optc < 0 ? 1 : rv); 15155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 15165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1517c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifndef MKSH_NO_CMDLINE_EDITING 15185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 15195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_bind(const char **wp) 15205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 15215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int optc, rv = 0; 15225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_SMALL 15235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool macro = false; 15245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 15255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool list = false; 15265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *cp; 15275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *up; 15285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt(wp, &builtin_opt, 15305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_SMALL 15315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "lm" 15325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#else 15335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "l" 15345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 15355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru )) != -1) 15365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 15375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'l': 15385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru list = true; 15395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 15405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_SMALL 15415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'm': 15425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru macro = true; 15435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 15445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 15455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 15465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 15475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 15495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 155003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (*wp == NULL) 155103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* list all */ 15525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = x_bind(NULL, NULL, 15535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_SMALL 15545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru false, 15555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 15565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru list); 15575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; *wp != NULL; wp++) { 15595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((cp = cstrchr(*wp, '=')) == NULL) 15605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru up = NULL; 15615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else { 15625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strdupx(up, *wp, ATEMP); 15635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru up[cp++ - *wp] = '\0'; 15645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (x_bind(up ? up : *wp, cp, 15665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_SMALL 15675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru macro, 15685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 15695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru false)) 15705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 1; 15715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(up, ATEMP); 15725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 15755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 1576c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 15775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 15795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_shift(const char **wp) 15805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 15815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct block *l = e->loc; 15825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int n; 15835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mksh_ari_t val; 15845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *arg; 15855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_getopt(wp, &builtin_opt, null) == '?') 15875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 15885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru arg = wp[builtin_opt.optind]; 15895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (arg) { 15915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru evaluate(arg, &val, KSH_UNWIND_ERROR, false); 15925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru n = val; 15935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 15945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru n = 1; 15955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (n < 0) { 159603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", arg, "bad number"); 15975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 15985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (l->argc < n) { 16005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("nothing to shift"); 16015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 16025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 16035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru l->argv[n] = l->argv[0]; 16045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru l->argv += n; 16055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru l->argc -= n; 16065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 16075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 16085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 16105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_umask(const char **wp) 16115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 16125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int i, optc; 16135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *cp; 16145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool symbolic = false; 16155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mode_t old_umask; 16165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt(wp, &builtin_opt, "S")) != -1) 16185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 16195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'S': 16205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru symbolic = true; 16215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 16235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 16245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 16255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru cp = wp[builtin_opt.optind]; 16265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (cp == NULL) { 16275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru old_umask = umask((mode_t)0); 16285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru umask(old_umask); 16295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (symbolic) { 16305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char buf[18], *p; 16315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int j; 16325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru old_umask = ~old_umask; 16345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p = buf; 16355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (i = 0; i < 3; i++) { 16365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *p++ = "ugo"[i]; 16375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *p++ = '='; 16385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (j = 0; j < 3; j++) 16395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (old_umask & (1 << (8 - (3*i + j)))) 16405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *p++ = "rwx"[j]; 16415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *p++ = ','; 16425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 16435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p[-1] = '\0'; 16445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shprintf("%s\n", buf); 16455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 16465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shprintf("%#3.3o\n", (unsigned int)old_umask); 16475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 16485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mode_t new_umask; 16495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_isdigit(*cp)) { 16515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (new_umask = 0; *cp >= '0' && *cp <= '7'; cp++) 16525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru new_umask = new_umask * 8 + (*cp - '0'); 16535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*cp) { 16545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("bad number"); 16555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 16565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 16575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 16585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* symbolic format */ 16595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int positions, new_val; 16605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char op; 16615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru old_umask = umask((mode_t)0); 166303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* in case of error */ 166403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra umask(old_umask); 16655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru old_umask = ~old_umask; 16665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru new_umask = old_umask; 16675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru positions = 0; 16685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (*cp) { 16695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (*cp && vstrchr("augo", *cp)) 16705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (*cp++) { 16715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'a': 16725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru positions |= 0111; 16735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'u': 16755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru positions |= 0100; 16765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'g': 16785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru positions |= 0010; 16795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'o': 16815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru positions |= 0001; 16825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 16845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!positions) 168503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* default is a */ 168603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra positions = 0111; 16875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!vstrchr("=+-", op = *cp)) 16885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru cp++; 16905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru new_val = 0; 16915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (*cp && vstrchr("rwxugoXs", *cp)) 16925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (*cp++) { 16935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'r': new_val |= 04; break; 16945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'w': new_val |= 02; break; 16955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'x': new_val |= 01; break; 16965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'u': 16975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru new_val |= old_umask >> 6; 16985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'g': 17005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru new_val |= old_umask >> 3; 17015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 17025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'o': 17035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru new_val |= old_umask >> 0; 17045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 17055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'X': 17065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (old_umask & 0111) 17075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru new_val |= 01; 17085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 17095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 's': 17105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* ignored */ 17115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 17125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru new_val = (new_val & 07) * positions; 17145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (op) { 17155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '-': 17165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru new_umask &= ~new_val; 17175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 17185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '=': 17195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru new_umask = new_val | 17205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (new_umask & ~(positions * 07)); 17215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 17225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '+': 17235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru new_umask |= new_val; 17245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*cp == ',') { 17265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru positions = 0; 17275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru cp++; 17285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (!vstrchr("=+-", *cp)) 17295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 17305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*cp) { 17325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("bad mask"); 17335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 17345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru new_umask = ~new_umask; 17365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru umask(new_umask); 17385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 17405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 17415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 17435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_dot(const char **wp) 17445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 17455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *file, *cp, **argv; 17465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int argc, i, errcode; 17475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_getopt(wp, &builtin_opt, null) == '?') 17495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 17505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((cp = wp[builtin_opt.optind]) == NULL) { 17525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("missing argument"); 17535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 17545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 175503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((file = search_path(cp, path, R_OK, &errcode)) == NULL) { 1756c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bi_errorf("%s: %s", cp, cstrerror(errcode)); 17575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 17585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Set positional parameters? */ 17615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (wp[builtin_opt.optind + 1]) { 17625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru argv = wp + builtin_opt.optind; 176303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* preserve $0 */ 176403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra argv[0] = e->loc->argv[0]; 17655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (argc = 0; argv[argc + 1]; argc++) 17665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 17675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 17685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru argc = 0; 17695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru argv = NULL; 17705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 1771c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((i = include(file, argc, argv, false)) < 0) { 17725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* should not happen */ 1773c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bi_errorf("%s: %s", cp, cstrerror(errno)); 17745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 17755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (i); 17775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 17785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 17805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_wait(const char **wp) 17815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 17825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv = 0, sig; 17835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_getopt(wp, &builtin_opt, null) == '?') 17855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 17865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 17875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*wp == NULL) { 17885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (waitfor(NULL, &sig) >= 0) 17895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 17905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = sig; 17915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 17925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; *wp; wp++) 17935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = waitfor(*wp, &sig); 17945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (rv < 0) 179503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* magic exit code: bad job-id */ 179603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = sig ? sig : 127; 17975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 17995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 18005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1801c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstatic char REPLY[] = "REPLY"; 18025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 18035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_read(const char **wp) 18045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 180503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define is_ifsws(c) (ctype((c), C_IFS) && ctype((c), C_IFSWS)) 180603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra int c, fd = 0, rv = 0, lastparm = 0; 180703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bool savehist = false, intoarray = false, aschars = false; 180803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bool rawmode = false, expanding = false; 180903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra enum { LINES, BYTES, UPTO, READALL } readmode = LINES; 181003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra char delim = '\n'; 181103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra size_t bytesleft = 128, bytesread; 181203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra struct tbl *vp /* FU gcc */ = NULL, *vq; 181303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra char *cp, *allocd = NULL, *xp; 181403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra const char *ccp; 181503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra XString xs; 181603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ptrdiff_t xsave = 0; 1817c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser mksh_ttyst tios; 181803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bool restore_tios = false; 181903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#if HAVE_SELECT 182003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bool hastimeout = false; 182103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra struct timeval tv, tvlim; 182203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define c_read_opts "Aad:N:n:prst:u," 182303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#else 182403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define c_read_opts "Aad:N:n:prsu," 182503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 18265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 182703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while ((c = ksh_getopt(wp, &builtin_opt, c_read_opts)) != -1) 182803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra switch (c) { 182903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'a': 183003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra aschars = true; 183103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* FALLTHROUGH */ 183203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'A': 183303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra intoarray = true; 183403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 183503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'd': 183603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra delim = builtin_opt.optarg[0]; 183703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 183803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'N': 183903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'n': 184003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra readmode = c == 'N' ? BYTES : UPTO; 184103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!bi_getn(builtin_opt.optarg, &c)) 184203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (2); 184303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (c == -1) { 184403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra readmode = READALL; 184503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bytesleft = 1024; 184603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else 184703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bytesleft = (unsigned int)c; 184803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 184903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'p': 185003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((fd = coproc_getfd(R_OK, &ccp)) < 0) { 185103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", "-p", ccp); 185203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (2); 18535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 185403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 185503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'r': 185603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rawmode = true; 185703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 185803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 's': 185903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra savehist = true; 186003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 186103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#if HAVE_SELECT 186203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 't': 186303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (parse_usec(builtin_opt.optarg, &tv)) { 1864c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bi_errorf("%s: %s '%s'", Tsynerr, cstrerror(errno), 186503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra builtin_opt.optarg); 186603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (2); 186703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 186803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra hastimeout = true; 186903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 187003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 187103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'u': 187203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!builtin_opt.optarg[0]) 187303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra fd = 0; 187403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else if ((fd = check_fd(builtin_opt.optarg, R_OK, &ccp)) < 0) { 187503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s: %s", "-u", builtin_opt.optarg, ccp); 187603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (2); 187703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 187803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 187903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case '?': 188003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (2); 188103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 18825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 18835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*wp == NULL) 18845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *--wp = REPLY; 18855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 188603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (intoarray && wp[1] != NULL) { 188703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("too many arguments"); 188803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (2); 188903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 18905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 189103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((ccp = cstrchr(*wp, '?')) != NULL) { 189203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra strdupx(allocd, *wp, ATEMP); 189303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra allocd[ccp - *wp] = '\0'; 189403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra *wp = allocd; 18955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (isatty(fd)) { 189603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 189703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * AT&T ksh says it prints prompt on fd if it's open 18985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * for writing and is a tty, but it doesn't do it 18995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (it also doesn't check the interactive flag, 190003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * as is indicated in the Korn Shell book). 19015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 190203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shf_puts(ccp + 1, shl_out); 190303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shf_flush(shl_out); 19045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 19055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 19065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 190703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xinit(xs, xp, bytesleft, ATEMP); 19085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 190903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (readmode == LINES) 191003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bytesleft = 1; 191103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else if (isatty(fd)) { 191203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra x_mkraw(fd, &tios, true); 191303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra restore_tios = true; 191403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 19155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 191603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#if HAVE_SELECT 191703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (hastimeout) { 1918c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser mksh_TIME(tvlim); 191903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra timeradd(&tvlim, &tv, &tvlim); 192003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 192103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 192203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 192303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c_read_readloop: 192403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#if HAVE_SELECT 192503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (hastimeout) { 192603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra fd_set fdset; 192703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 192803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra FD_ZERO(&fdset); 1929c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser FD_SET((unsigned int)fd, &fdset); 1930c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser mksh_TIME(tv); 193103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra timersub(&tvlim, &tv, &tv); 193203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (tv.tv_sec < 0) { 193303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* timeout expired globally */ 193403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 1; 193503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_out; 193603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 193703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 193803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra switch (select(fd + 1, &fdset, NULL, NULL, &tv)) { 193903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 1: 194003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 194103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 0: 194203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* timeout expired for this call */ 194303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 1; 194403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_out; 194503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra default: 1946c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bi_errorf("%s: %s", Tselect, cstrerror(errno)); 194703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 2; 194803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_out; 194903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 195003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 195103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 195203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 195303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bytesread = blocking_read(fd, xp, bytesleft); 195403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (bytesread == (size_t)-1) { 195503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* interrupted */ 195603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (errno == EINTR && fatal_trap_check()) { 195703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 195803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Was the offending signal one that would 195903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * normally kill a process? If so, pretend 196003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * the read was killed. 196103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra */ 196203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 2; 196303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_out; 196403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 196503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* just ignore the signal */ 196603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_readloop; 196703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 196803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 196903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra switch (readmode) { 197003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case READALL: 197103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (bytesread == 0) { 197203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* end of file reached */ 197303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 1; 197403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_readdone; 197503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 197603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xp += bytesread; 197703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra XcheckN(xs, xp, bytesleft); 197803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 197903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 198003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case UPTO: 198103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (bytesread == 0) 198203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* end of file reached */ 198303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 1; 198403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xp += bytesread; 198503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_readdone; 198603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 198703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case BYTES: 198803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (bytesread == 0) { 198903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* end of file reached */ 199003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 1; 199103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xp = Xstring(xs, xp); 199203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_readdone; 199303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 199403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xp += bytesread; 199503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((bytesleft -= bytesread) == 0) 199603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_readdone; 199703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 199803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case LINES: 199903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (bytesread == 0) { 200003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* end of file reached */ 200103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 1; 200203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_readdone; 200303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 200403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((c = *xp) == '\0' && !aschars && delim != '\0') { 200503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* skip any read NULs unless delimiter */ 200603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 200703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 200803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (expanding) { 200903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra expanding = false; 201003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (c == delim) { 201103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (Flag(FTALKING_I) && isatty(fd)) { 201203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 201303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * set prompt in case this is 201403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * called from .profile or $ENV 201503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra */ 201603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra set_prompt(PS2, NULL); 201703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra pprompt(prompt, 0); 20185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 201903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* drop the backslash */ 202003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra --xp; 202103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* and the delimiter */ 20225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 20235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 202403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else if (c == delim) { 202503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_readdone; 202603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else if (!rawmode && c == '\\') { 202703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra expanding = true; 202803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 202903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xcheck(xs, xp); 203003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++xp; 203103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 203203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 203303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_readloop; 203403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 203503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c_read_readdone: 203603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bytesread = Xlength(xs, xp); 203703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xput(xs, xp, '\0'); 203803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 203903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /*- 204003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * state: we finished reading the input and NUL terminated it 204103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Xstring(xs, xp) -> xp-1 = input string without trailing delim 204203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * rv = 1 if EOF, 0 otherwise (errors handled already) 204303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra */ 204403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 204503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (rv == 1) { 204603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* clean up coprocess if needed, on EOF */ 204703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra coproc_read_close(fd); 204803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (readmode == READALL) 204903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* EOF is no error here */ 205003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 0; 205103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 205203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 205303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (savehist) 205403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra histsave(&source->line, Xstring(xs, xp), true, false); 205503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 205603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ccp = cp = Xclose(xs, xp); 205703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra expanding = false; 205803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra XinitN(xs, 128, ATEMP); 205903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (intoarray) { 20605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp = global(*wp); 20615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vp->flag & RDONLY) { 206203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c_read_splitro: 2063c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bi_errorf("read-only: %s", *wp); 206403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c_read_spliterr: 206503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 2; 206603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra afree(cp, ATEMP); 206703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_out; 206803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 206903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* exporting an array is currently pointless */ 207003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra unset(vp, 1); 207103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* counter for array index */ 207203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c = 0; 207303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 207403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!aschars) { 207503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* skip initial IFS whitespace */ 207603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (bytesread && is_ifsws(*ccp)) { 207703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++ccp; 207803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra --bytesread; 207903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 208003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* trim trailing IFS whitespace */ 208103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (bytesread && is_ifsws(ccp[bytesread - 1])) { 208203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra --bytesread; 208303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 208403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 208503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c_read_splitloop: 208603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xp = Xstring(xs, xp); 208703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* generate next word */ 208803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!bytesread) { 208903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* no more input */ 209003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (intoarray) 209103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_splitdone; 209203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* zero out next parameters */ 209303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_gotword; 209403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 209503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (aschars) { 209603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xput(xs, xp, '1'); 209703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xput(xs, xp, '#'); 209803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bytesleft = utf_ptradj(ccp); 209903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (bytesleft && bytesread) { 210003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra *xp++ = *ccp++; 210103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra --bytesleft; 210203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra --bytesread; 210303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 210403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (xp[-1] == '\0') { 210503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xp[-1] = '0'; 210603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xp[-3] = '2'; 210703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 210803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_gotword; 210903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 211003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 211103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!intoarray && wp[1] == NULL) 211203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra lastparm = 1; 211303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 211403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c_read_splitlast: 211503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* copy until IFS character */ 211603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (bytesread) { 211703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra char ch; 211803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 211903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ch = *ccp; 212003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (expanding) { 212103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra expanding = false; 212203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_splitcopy; 212303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else if (ctype(ch, C_IFS)) { 212403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 212503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else if (!rawmode && ch == '\\') { 212603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra expanding = true; 212703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else { 212803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c_read_splitcopy: 212903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xcheck(xs, xp); 213003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xput(xs, xp, ch); 21315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 213203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++ccp; 213303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra --bytesread; 213403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 213503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xsave = Xsavepos(xs, xp); 213603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* copy word delimiter: IFSWS+IFS,IFSWS */ 213703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (bytesread) { 213803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra char ch; 213903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 214003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ch = *ccp; 214103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!ctype(ch, C_IFS)) 214203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 214303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xcheck(xs, xp); 214403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xput(xs, xp, ch); 214503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++ccp; 214603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra --bytesread; 214703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!ctype(ch, C_IFSWS)) 214803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 214903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 215003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (bytesread && is_ifsws(*ccp)) { 215103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xcheck(xs, xp); 215203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xput(xs, xp, *ccp); 215303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++ccp; 215403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra --bytesread; 215503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 215603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* if no more parameters, rinse and repeat */ 215703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (lastparm && bytesread) { 215803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++lastparm; 215903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_splitlast; 216003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 216103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* get rid of the delimiter unless we pack the rest */ 216203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (lastparm < 2) 216303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xp = Xrestpos(xs, xp, xsave); 216403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c_read_gotword: 216503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xput(xs, xp, '\0'); 216603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (intoarray) { 216703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vq = arraysearch(vp, c++); 216803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else { 216903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vq = global(*wp); 217003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* must be checked before exporting */ 217103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (vq->flag & RDONLY) 217203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_splitro; 21735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (Flag(FEXPORT)) 21745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru typeset(*wp, EXPORT, 0, 0, 0); 21755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 217603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!setstr(vq, Xstring(xs, xp), KSH_RETURN_ERROR)) 217703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_spliterr; 217803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (aschars) { 217903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra setint_v(vq, vq, false); 218003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* protect from UTFMODE changes */ 218103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vq->type = 0; 21825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 218303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (intoarray || *++wp != NULL) 218403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_splitloop; 218503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 218603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c_read_splitdone: 218703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* free up */ 218803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra afree(cp, ATEMP); 21895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 219003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c_read_out: 219103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra afree(allocd, ATEMP); 219203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xfree(xs, xp); 219303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (restore_tios) 2194c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser mksh_tcset(fd, &tios); 219503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (rv); 219603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#undef is_ifsws 21975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 21985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 21995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 22005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_eval(const char **wp) 22015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 22025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct source *s, *saves = source; 22035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unsigned char savef; 22045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv; 22055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 22065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_getopt(wp, &builtin_opt, null) == '?') 22075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 22085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = pushs(SWORDS, ATEMP); 22095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->u.strv = wp + builtin_opt.optind; 22105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 22115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /*- 22125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * The following code handles the case where the command is 22135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * empty due to failed command substitution, for example by 22145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * eval "$(false)" 22155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * This has historically returned 1 by AT&T ksh88. In this 22165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * case, shell() will not set or change exstat because the 22175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * compiled tree is empty, so it will use the value we pass 22185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * from subst_exstat, which is cleared in execute(), so it 22195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * should have been 0 if there were no substitutions. 22205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 22215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * POSIX however says we don't do this, even though it is 22225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * traditionally done. AT&T ksh93 agrees with POSIX, so we 22235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * do. The following is an excerpt from SUSv4 [1003.2-2008]: 22245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 22255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 2.9.1: Simple Commands 22265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * ... If there is a command name, execution shall 22275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * continue as described in 2.9.1.1 [Command Search 22285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * and Execution]. If there is no command name, but 22295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * the command contained a command substitution, the 22305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * command shall complete with the exit status of the 22315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * last command substitution performed. 22325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 2.9.1.1: Command Search and Execution 22335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (1) a. If the command name matches the name of a 22345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * special built-in utility, that special built-in 22355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * utility shall be invoked. 22365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 2.14.5: eval 22375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * If there are no arguments, or only null arguments, 22385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * eval shall return a zero exit status; ... 22395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 2240c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* AT&T ksh88: use subst_exstat */ 2241c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* exstat = subst_exstat; */ 2242c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* SUSv4: OR with a high value never written otherwise */ 2243c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser exstat |= 0x4000; 22445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 22455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru savef = Flag(FERREXIT); 2246c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser Flag(FERREXIT) |= 0x80; 22475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = shell(s, false); 22485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Flag(FERREXIT) = savef; 22495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source = saves; 22505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(s, ATEMP); 2251c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (exstat & 0x4000) 2252c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* detect old exstat, use 0 in that case */ 2253c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser rv = 0; 22545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 22555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 22565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 22575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 22585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_trap(const char **wp) 22595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 22605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int i; 22615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *s; 22625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Trap *p; 22635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 22645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_getopt(wp, &builtin_opt, null) == '?') 22655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 22665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 22675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 22685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*wp == NULL) { 2269811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser for (p = sigtraps, i = NSIG + 1; --i >= 0; p++) 22705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (p->trap != NULL) { 22715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts("trap -- ", shl_stdout); 2272c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser print_value_quoted(shl_stdout, p->trap); 22735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shprintf(" %s\n", p->name); 22745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 22755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 22765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 22775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 22785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 22795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Use case sensitive lookup for first arg so the 22805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * command 'exit' isn't confused with the pseudo-signal 22815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 'EXIT'. 22825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 228303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* get command */ 228403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra s = (gettrap(*wp, false) == NULL) ? *wp++ : NULL; 22855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s != NULL && s[0] == '-' && s[1] == '\0') 22865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = NULL; 22875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 22885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* set/clear traps */ 228903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra i = 0; 229003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (*wp != NULL) 229103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((p = gettrap(*wp++, true)) == NULL) { 229203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra warningf(true, "%s: %s '%s'", builtin_argv0, 229303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra "bad signal", wp[-1]); 229403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++i; 229503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else 229603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra settrap(p, s); 229703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (i); 22985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 22995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 23005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 23015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_exitreturn(const char **wp) 23025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 23035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int n, how = LEXIT; 23045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *arg; 23055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 23065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_getopt(wp, &builtin_opt, null) == '?') 2307c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto c_exitreturn_err; 23085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru arg = wp[builtin_opt.optind]; 23095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 23105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (arg) { 23115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!getn(arg, &n)) { 23125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru exstat = 1; 231303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra warningf(true, "%s: %s", arg, "bad number"); 23145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 2315c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser exstat = n & 0xFF; 231603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else if (trap_exstat != -1) 231703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra exstat = trap_exstat; 231803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (wp[0][0] == 'r') { 231903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* return */ 23205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct env *ep; 23215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 232203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 232303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * need to tell if this is exit or return so trap exit will 23245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * work right (POSIX) 23255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 23265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (ep = e; ep; ep = ep->oenv) 23275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (STOP_RETURN(ep->type)) { 23285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru how = LRETURN; 23295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 23305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 23315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 23325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 23335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (how == LEXIT && !really_exit && j_stopped_running()) { 2334c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser really_exit = true; 23355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru how = LSHELL; 23365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 23375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 233803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* get rid of any i/o redirections */ 233903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra quitenv(NULL); 23405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unwind(how); 23415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* NOTREACHED */ 2342c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 2343c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser c_exitreturn_err: 2344c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return (1); 23455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 23465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 23475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 23485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_brkcont(const char **wp) 23495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 2350c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser unsigned int quit; 2351c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser int n; 23525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct env *ep, *last_ep = NULL; 23535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *arg; 23545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 23555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_getopt(wp, &builtin_opt, null) == '?') 2356c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto c_brkcont_err; 23575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru arg = wp[builtin_opt.optind]; 23585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 23595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!arg) 23605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru n = 1; 23615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (!bi_getn(arg, &n)) 2362c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto c_brkcont_err; 2363c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (n <= 0) { 23645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* AT&T ksh does this for non-interactive shells only - weird */ 236503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", arg, "bad value"); 2366c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto c_brkcont_err; 23675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2368c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser quit = (unsigned int)n; 23695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 23705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Stop at E_NONE, E_PARSE, E_FUNC, or E_INCL */ 23715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (ep = e; ep && !STOP_BRKCONT(ep->type); ep = ep->oenv) 23725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ep->type == E_LOOP) { 23735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (--quit == 0) 23745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 23755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ep->flags |= EF_BRKCONT_PASS; 23765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru last_ep = ep; 23775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 23785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 23795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (quit) { 238003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 238103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * AT&T ksh doesn't print a message - just does what it 23825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * can. We print a message 'cause it helps in debugging 23835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * scripts, but don't generate an error (ie, keep going). 23845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 2385c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((unsigned int)n == quit) { 238603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra warningf(true, "%s: %s %s", wp[0], "can't", wp[0]); 23875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 23885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 238903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 239003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * POSIX says if n is too big, the last enclosing loop 23915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * shall be used. Doesn't say to print an error but we 23925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * do anyway 'cause the user messed up. 23935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 23945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (last_ep) 23955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru last_ep->flags &= ~EF_BRKCONT_PASS; 2396c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser warningf(true, "%s: can only %s %u level(s)", 2397c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser wp[0], wp[0], (unsigned int)n - quit); 23985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 23995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 24005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unwind(*wp[0] == 'b' ? LBREAK : LCONTIN); 24015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* NOTREACHED */ 2402c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 2403c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser c_brkcont_err: 2404c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return (1); 24055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 24065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 24075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 24085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_set(const char **wp) 24095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 24105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int argi; 24115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool setargs; 24125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct block *l = e->loc; 24135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char **owp; 24145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 24155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (wp[1] == NULL) { 241603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra static const char *args[] = { Tset, "-", NULL }; 24175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (c_typeset(args)); 24185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 24195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 24205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru argi = parse_args(wp, OF_SET, &setargs); 24215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (argi < 0) 24225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 24235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* set $# and $* */ 24245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (setargs) { 24255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += argi - 1; 24265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru owp = wp; 242703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* save $0 */ 242803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra wp[0] = l->argv[0]; 24295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (*++wp != NULL) 24305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strdupx(*wp, *wp, &l->area); 24315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru l->argc = wp - owp - 1; 243203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra l->argv = alloc2(l->argc + 2, sizeof(char *), &l->area); 24335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (wp = l->argv; (*wp++ = *owp++) != NULL; ) 24345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 24355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 24365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /*- 24375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * POSIX says set exit status is 0, but old scripts that use 24385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * getopt(1) use the construct 24395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * set -- $(getopt ab:c "$@") 24405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * which assumes the exit value set will be that of the $() 24415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (subst_exstat is cleared in execute() so that it will be 0 24425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * if there are no command substitutions). 24435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 2444c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef MKSH_LEGACY_MODE 2445811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser /* traditional behaviour, unless set -o posix */ 2446811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser return (Flag(FPOSIX) ? 0 : subst_exstat); 2447c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#else 2448811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser /* conformant behaviour, unless set -o sh +o posix */ 2449811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser return (Flag(FSH) && !Flag(FPOSIX) ? subst_exstat : 0); 2450c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 24515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 24525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 24535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 24545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_unset(const char **wp) 24555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 24565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *id; 245703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra int optc, rv = 0; 24585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool unset_var = true; 24595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 24605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt(wp, &builtin_opt, "fv")) != -1) 24615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 24625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'f': 24635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unset_var = false; 24645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 24655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'v': 24665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unset_var = true; 24675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 24685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 246903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /*XXX not reached due to GF_ERROR */ 247003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (2); 24715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 24725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 24735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; (id = *wp) != NULL; wp++) 247403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (unset_var) { 247503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* unset variable */ 24765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *vp; 24775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *cp = NULL; 24785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru size_t n; 24795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 24805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru n = strlen(id); 24815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (n > 3 && id[n-3] == '[' && id[n-2] == '*' && 24825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru id[n-1] == ']') { 24835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strndupx(cp, id, n - 3, ATEMP); 24845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru id = cp; 24855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru optc = 3; 24865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 24875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru optc = vstrchr(id, '[') ? 0 : 1; 24885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 24895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp = global(id); 24905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(cp, ATEMP); 24915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 24925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vp->flag&RDONLY)) { 2493c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser warningf(true, "read-only: %s", vp->name); 249403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 1; 249503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else 249603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra unset(vp, optc); 249703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else 249803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* unset function */ 24995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru define(id, NULL); 250003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (rv); 25015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 25025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 25035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 25045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querup_time(struct shf *shf, bool posix, long tv_sec, int tv_usec, int width, 25055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *prefix, const char *suffix) 25065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 25075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tv_usec /= 10000; 25085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (posix) 25095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_fprintf(shf, "%s%*ld.%02d%s", prefix, width, 25105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tv_sec, tv_usec, suffix); 25115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 25125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_fprintf(shf, "%s%*ldm%d.%02ds%s", prefix, width, 25135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tv_sec / 60, (int)(tv_sec % 60), tv_usec, suffix); 25145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 25155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 25165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 25175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_times(const char **wp MKSH_A_UNUSED) 25185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 25195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct rusage usage; 25205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 25215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru getrusage(RUSAGE_SELF, &usage); 25225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p_time(shl_stdout, false, usage.ru_utime.tv_sec, 25235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru usage.ru_utime.tv_usec, 0, null, " "); 25245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p_time(shl_stdout, false, usage.ru_stime.tv_sec, 25255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru usage.ru_stime.tv_usec, 0, null, "\n"); 25265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 25275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru getrusage(RUSAGE_CHILDREN, &usage); 25285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p_time(shl_stdout, false, usage.ru_utime.tv_sec, 25295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru usage.ru_utime.tv_usec, 0, null, " "); 25305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p_time(shl_stdout, false, usage.ru_stime.tv_sec, 25315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru usage.ru_stime.tv_usec, 0, null, "\n"); 25325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 25335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 25345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 25355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 25365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 25375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * time pipeline (really a statement, not a built-in command) 25385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 25395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 25405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutimex(struct op *t, int f, volatile int *xerrok) 25415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 25425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define TF_NOARGS BIT(0) 25435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define TF_NOREAL BIT(1) /* don't report real time */ 25445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define TF_POSIX BIT(2) /* report in POSIX format */ 25455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv = 0, tf = 0; 25465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct rusage ru0, ru1, cru0, cru1; 25475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct timeval usrtime, systime, tv0, tv1; 25485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2549c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser mksh_TIME(tv0); 25505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru getrusage(RUSAGE_SELF, &ru0); 25515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru getrusage(RUSAGE_CHILDREN, &cru0); 25525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (t->left) { 25535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 25545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Two ways of getting cpu usage of a command: just use t0 25555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * and t1 (which will get cpu usage from other jobs that 25565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * finish while we are executing t->left), or get the 25575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * cpu usage of t->left. AT&T ksh does the former, while 25585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * pdksh tries to do the later (the j_usrtime hack doesn't 25595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * really work as it only counts the last job). 25605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 25615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru timerclear(&j_usrtime); 25625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru timerclear(&j_systime); 25635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = execute(t->left, f | XTIME, xerrok); 25645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (t->left->type == TCOM) 25655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tf |= t->left->str[0]; 2566c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser mksh_TIME(tv1); 25675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru getrusage(RUSAGE_SELF, &ru1); 25685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru getrusage(RUSAGE_CHILDREN, &cru1); 25695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 25705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tf = TF_NOARGS; 25715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 257203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (tf & TF_NOARGS) { 257303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* ksh93 - report shell times (shell+kids) */ 25745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tf |= TF_NOREAL; 25755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru timeradd(&ru0.ru_utime, &cru0.ru_utime, &usrtime); 25765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru timeradd(&ru0.ru_stime, &cru0.ru_stime, &systime); 25775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 25785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru timersub(&ru1.ru_utime, &ru0.ru_utime, &usrtime); 25795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru timeradd(&usrtime, &j_usrtime, &usrtime); 25805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru timersub(&ru1.ru_stime, &ru0.ru_stime, &systime); 25815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru timeradd(&systime, &j_systime, &systime); 25825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 25835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 25845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(tf & TF_NOREAL)) { 25855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru timersub(&tv1, &tv0, &tv1); 25865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tf & TF_POSIX) 25875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p_time(shl_out, true, tv1.tv_sec, tv1.tv_usec, 25885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5, "real ", "\n"); 25895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 25905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p_time(shl_out, false, tv1.tv_sec, tv1.tv_usec, 25915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5, null, " real "); 25925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 25935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tf & TF_POSIX) 25945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p_time(shl_out, true, usrtime.tv_sec, usrtime.tv_usec, 25955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5, "user ", "\n"); 25965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 25975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p_time(shl_out, false, usrtime.tv_sec, usrtime.tv_usec, 25985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5, null, " user "); 25995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tf & TF_POSIX) 26005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p_time(shl_out, true, systime.tv_sec, systime.tv_usec, 26015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5, "sys ", "\n"); 26025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 26035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p_time(shl_out, false, systime.tv_sec, systime.tv_usec, 26045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5, null, " system\n"); 26055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_flush(shl_out); 26065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 26075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 26085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 26095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 26105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 26115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutimex_hook(struct op *t, char **volatile *app) 26125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 26135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char **wp = *app; 26145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int optc, i, j; 26155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Getopt opt; 26165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 26175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ksh_getopt_reset(&opt, 0); 261803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* start at the start */ 261903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra opt.optind = 0; 26205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt((const char **)wp, &opt, ":p")) != -1) 26215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 26225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'p': 26235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->str[0] |= TF_POSIX; 26245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 26255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 262603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra errorf("time: -%s %s", opt.optarg, 262703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra "unknown option"); 26285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case ':': 262903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra errorf("time: -%s %s", opt.optarg, 263003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra "requires an argument"); 26315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 26325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Copy command words down over options. */ 26335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (opt.optind != 0) { 26345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (i = 0; i < opt.optind; i++) 26355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(wp[i], ATEMP); 26365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (i = 0, j = opt.optind; (wp[i] = wp[j]); i++, j++) 26375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 26385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 26395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!wp[0]) 26405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->str[0] |= TF_NOARGS; 26415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *app = wp; 26425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 26435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 26445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* exec with no args - args case is taken care of in comexec() */ 26455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 26465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_exec(const char **wp MKSH_A_UNUSED) 26475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 26485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int i; 26495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 26505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* make sure redirects stay in place */ 26515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (e->savefd != NULL) { 26525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (i = 0; i < NUFILE; i++) { 26535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (e->savefd[i] > 0) 26545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru close(e->savefd[i]); 2655c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifndef MKSH_LEGACY_MODE 26565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 26575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * keep all file descriptors > 2 private for ksh, 26585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * but not for POSIX or legacy/kludge sh 26595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 26605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!Flag(FPOSIX) && !Flag(FSH) && i > 2 && 26615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru e->savefd[i]) 26625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fcntl(i, F_SETFD, FD_CLOEXEC); 2663c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 26645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 26655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru e->savefd = NULL; 26665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 26675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 26685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 26695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 26705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if HAVE_MKNOD 26715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 26725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_mknod(const char **wp) 26735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 26745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int argc, optc, rv = 0; 26755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool ismkfifo = false; 26765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char **argv; 26775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru void *set = NULL; 26785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mode_t mode = 0, oldmode = 0; 26795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 26805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt(wp, &builtin_opt, "m:")) != -1) { 26815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 26825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'm': 26835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru set = setmode(builtin_opt.optarg); 26845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (set == NULL) { 26855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("invalid file mode"); 26865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 26875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 26885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mode = getmode(set, (mode_t)(DEFFILEMODE)); 268903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra free_ossetmode(set); 26905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 26915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 26925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto c_mknod_usage; 26935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 26945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 26955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru argv = &wp[builtin_opt.optind]; 26965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (argv[0] == NULL) 26975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto c_mknod_usage; 26985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (argc = 0; argv[argc]; argc++) 26995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 27005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (argc == 2 && argv[1][0] == 'p') 27015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ismkfifo = true; 27025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (argc != 4 || (argv[1][0] != 'b' && argv[1][0] != 'c')) 27035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto c_mknod_usage; 27045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 27055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (set != NULL) 27065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru oldmode = umask((mode_t)0); 27075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 27085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mode = DEFFILEMODE; 27095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 27105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mode |= (argv[1][0] == 'b') ? S_IFBLK : 27115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (argv[1][0] == 'c') ? S_IFCHR : 0; 27125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 27135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!ismkfifo) { 27145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unsigned long majnum, minnum; 27155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru dev_t dv; 27165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *c; 27175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 27185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru majnum = strtoul(argv[2], &c, 0); 27195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c == argv[2]) || (*c != '\0')) { 272003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("non-numeric %s %s '%s'", "device", "major", argv[2]); 27215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto c_mknod_err; 27225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 27235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru minnum = strtoul(argv[3], &c, 0); 27245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c == argv[3]) || (*c != '\0')) { 272503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("non-numeric %s %s '%s'", "device", "minor", argv[3]); 27265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto c_mknod_err; 27275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 27285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru dv = makedev(majnum, minnum); 27295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((unsigned long)(major(dv)) != majnum) { 273003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s %s too large: %lu", "device", "major", majnum); 27315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto c_mknod_err; 27325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 27335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((unsigned long)(minor(dv)) != minnum) { 273403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s %s too large: %lu", "device", "minor", minnum); 27355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto c_mknod_err; 27365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 27375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (mknod(argv[0], mode, dv)) 27385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto c_mknod_failed; 27395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (mkfifo(argv[0], mode)) { 27405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c_mknod_failed: 2741c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bi_errorf("%s: %s", argv[0], cstrerror(errno)); 27425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c_mknod_err: 27435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 1; 27445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 27455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 27465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (set) 27475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru umask(oldmode); 27485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 27495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c_mknod_usage: 275003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", "usage", "mknod [-m mode] name b|c major minor"); 275103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", "usage", "mknod [-m mode] name p"); 27525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 27535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 27545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 27555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 275603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/*- 2757c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser test(1) roughly accepts the following grammar: 27585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru oexpr ::= aexpr | aexpr "-o" oexpr ; 27595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru aexpr ::= nexpr | nexpr "-a" aexpr ; 27605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nexpr ::= primary | "!" nexpr ; 27615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru primary ::= unary-operator operand 27625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru | operand binary-operator operand 27635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru | operand 27645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru | "(" oexpr ")" 27655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 27665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 27675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unary-operator ::= "-a"|"-r"|"-w"|"-x"|"-e"|"-f"|"-d"|"-c"|"-b"|"-p"| 27685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "-u"|"-g"|"-k"|"-s"|"-t"|"-z"|"-n"|"-o"|"-O"|"-G"| 27695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "-L"|"-h"|"-S"|"-H"; 27705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 27715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru binary-operator ::= "="|"=="|"!="|"-eq"|"-ne"|"-ge"|"-gt"|"-le"|"-lt"| 27725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "-nt"|"-ot"|"-ef"| 2773c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser "<"|">" # rules used for [[ ... ]] expressions 27745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 2775c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser operand ::= <anything> 27765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru*/ 27775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 277803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* POSIX says > 1 for errors */ 2779c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#define T_ERR_EXIT 2 27805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 27815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 27825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_test(const char **wp) 27835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 2784c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser int argc, rv, invert = 0; 27855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Test_env te; 2786c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser Test_op op; 2787c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser const char *lhs, **swp; 27885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 27895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te.flags = 0; 27905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te.isa = ptest_isa; 27915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te.getopnd = ptest_getopnd; 27925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te.eval = test_eval; 27935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te.error = ptest_error; 27945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 27955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (argc = 0; wp[argc]; argc++) 27965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 2797c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser mkssert(argc > 0); 2798c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser mkssert(wp[0] != NULL); 27995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 28005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (strcmp(wp[0], "[") == 0) { 28015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (strcmp(wp[--argc], "]") != 0) { 28025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("missing ]"); 28035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (T_ERR_EXIT); 28045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 28055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 28065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 28075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te.pos.wp = wp + 1; 28085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te.wp_end = wp + argc; 28095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 28105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 2811c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * Attempt to conform to POSIX special cases. This is pretty 2812c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * dumb code straight-forward from the 2008 spec, but unless 2813c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * the old pdksh code doesn't live from so many assumptions. 2814c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * It does, though, inline some calls to '(*te.funcname)()'. 28155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 2816c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser switch (argc - 1) { 2817c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case 0: 2818c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return (1); 2819c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case 1: 2820c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ptest_one: 2821c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser op = TO_STNZE; 2822c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto ptest_unary; 2823c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case 2: 2824c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ptest_two: 2825c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (ptest_isa(&te, TM_NOT)) { 2826c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ++invert; 2827c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto ptest_one; 2828c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 2829c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((op = ptest_isa(&te, TM_UNOP))) { 2830c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ptest_unary: 2831c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser rv = test_eval(&te, op, *te.pos.wp++, NULL, true); 2832c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ptest_out: 2833c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return ((invert & 1) ? rv : !rv); 2834c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 2835c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* let the parser deal with anything else */ 2836c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser break; 2837c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case 3: 2838c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ptest_three: 2839c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser swp = te.pos.wp; 2840c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* use inside knowledge of ptest_getopnd inlined below */ 2841c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser lhs = *te.pos.wp++; 2842c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((op = ptest_isa(&te, TM_BINOP))) { 2843c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* test lhs op rhs */ 2844c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser rv = test_eval(&te, op, lhs, *te.pos.wp++, true); 2845c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto ptest_out; 2846c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 2847c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* back up to lhs */ 2848c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser te.pos.wp = swp; 2849c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (ptest_isa(&te, TM_NOT)) { 2850c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ++invert; 2851c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto ptest_two; 2852c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 2853c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (ptest_isa(&te, TM_OPAREN)) { 2854c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser swp = te.pos.wp; 2855c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* skip operand, without evaluation */ 2856c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser te.pos.wp++; 2857c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* check for closing parenthesis */ 2858c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser op = ptest_isa(&te, TM_CPAREN); 2859c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* back up to operand */ 2860c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser te.pos.wp = swp; 2861c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* if there was a closing paren, handle it */ 2862c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (op) 2863c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto ptest_one; 2864c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* backing up is done before calling the parser */ 2865c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 2866c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* let the parser deal with it */ 2867c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser break; 2868c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case 4: 2869c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (ptest_isa(&te, TM_NOT)) { 2870c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ++invert; 2871c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto ptest_three; 2872c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 2873c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (ptest_isa(&te, TM_OPAREN)) { 2874c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser swp = te.pos.wp; 2875c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* skip two operands, without evaluation */ 2876c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser te.pos.wp++; 2877c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser te.pos.wp++; 2878c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* check for closing parenthesis */ 2879c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser op = ptest_isa(&te, TM_CPAREN); 2880c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* back up to first operand */ 2881c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser te.pos.wp = swp; 2882c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* if there was a closing paren, handle it */ 2883c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (op) 2884c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto ptest_two; 2885c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* backing up is done before calling the parser */ 2886c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 2887c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* defer this to the parser */ 2888c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser break; 28895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 28905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2891c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* "The results are unspecified." */ 2892c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser te.pos.wp = wp + 1; 28935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (test_parse(&te)); 28945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 28955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 28965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 28975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Generic test routines. 28985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 28995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 29005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste QueruTest_op 29015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutest_isop(Test_meta meta, const char *s) 29025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 29035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char sc1; 29045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const struct t_op *tbl; 29055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 29065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tbl = meta == TM_UNOP ? u_ops : b_ops; 29075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*s) { 29085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sc1 = s[1]; 29095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; tbl->op_text[0]; tbl++) 29105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (sc1 == tbl->op_text[1] && !strcmp(s, tbl->op_text)) 29115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (tbl->op_num); 29125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 29135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (TO_NONOP); 29145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 29155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 29165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 29175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutest_eval(Test_env *te, Test_op op, const char *opnd1, const char *opnd2, 29185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool do_eval) 29195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 29205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int i, s; 29215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru size_t k; 29225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct stat b1, b2; 29235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mksh_ari_t v1, v2; 29245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 29255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!do_eval) 29265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 29275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2928c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef DEBUG 2929c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser switch (op) { 2930c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* Binary operators */ 2931c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case TO_STEQL: 2932c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case TO_STNEQ: 2933c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case TO_STLT: 2934c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case TO_STGT: 2935c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case TO_INTEQ: 2936c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case TO_INTNE: 2937c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case TO_INTGT: 2938c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case TO_INTGE: 2939c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case TO_INTLT: 2940c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case TO_INTLE: 2941c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case TO_FILEQ: 2942c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case TO_FILNT: 2943c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case TO_FILOT: 2944c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* consistency check, but does not happen in practice */ 2945c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (!opnd2) { 2946c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser te->flags |= TEF_ERROR; 2947c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return (1); 2948c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 2949c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser break; 2950c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser default: 2951c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* for completeness of switch */ 2952c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser break; 2953c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 2954c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 2955c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 295603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra switch (op) { 295703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 29585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 29595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Unary Operators 29605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 296103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 296203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -n */ 296303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_STNZE: 29645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (*opnd1 != '\0'); 296503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 296603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -z */ 296703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_STZER: 29685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (*opnd1 == '\0'); 296903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 297003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -o */ 297103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_OPTION: 29725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((i = *opnd1) == '!' || i == '?') 29735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru opnd1++; 29745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((k = option(opnd1)) == (size_t)-1) 29755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 29765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (i == '?' ? 1 : i == '!' ? !Flag(k) : Flag(k)); 297703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 297803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -r */ 297903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILRD: 298003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* LINTED use of access */ 298103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (access(opnd1, R_OK) == 0); 298203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 298303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -w */ 298403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILWR: 298503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* LINTED use of access */ 298603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (access(opnd1, W_OK) == 0); 298703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 298803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -x */ 298903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILEX: 299003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (ksh_access(opnd1, X_OK) == 0); 299103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 299203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -a */ 299303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILAXST: 299403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -e */ 299503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILEXST: 29965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd1, &b1) == 0); 299703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 299803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -r */ 299903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILREG: 30005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd1, &b1) == 0 && S_ISREG(b1.st_mode)); 300103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 300203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -d */ 300303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILID: 30045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd1, &b1) == 0 && S_ISDIR(b1.st_mode)); 300503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 300603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -c */ 300703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILCDEV: 30085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd1, &b1) == 0 && S_ISCHR(b1.st_mode)); 300903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 301003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -b */ 301103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILBDEV: 30125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd1, &b1) == 0 && S_ISBLK(b1.st_mode)); 301303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 301403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -p */ 301503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILFIFO: 30165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd1, &b1) == 0 && S_ISFIFO(b1.st_mode)); 301703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 301803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -h or -L */ 301903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILSYM: 3020c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef MKSH__NO_SYMLINK 3021c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return (0); 3022c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#else 30235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (lstat(opnd1, &b1) == 0 && S_ISLNK(b1.st_mode)); 3024c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 302503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 302603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -S */ 302703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILSOCK: 30285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd1, &b1) == 0 && S_ISSOCK(b1.st_mode)); 302903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 303003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -H => HP context dependent files (directories) */ 303103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILCDF: 303203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#ifdef S_ISCDF 303303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra { 303403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra char *nv; 303503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 303603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 303703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Append a + to filename and check to see if result is 303803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * a setuid directory. CDF stuff in general is hookey, 303903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * since it breaks for, e.g., the following sequence: 304003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * echo hi >foo+; mkdir foo; echo bye >foo/default; 304103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * chmod u+s foo (foo+ refers to the file with hi in it, 304203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * there is no way to get at the file with bye in it; 304303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * please correct me if I'm wrong about this). 304403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra */ 304503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 304603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra nv = shf_smprintf("%s+", opnd1); 304703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra i = (stat(nv, &b1) == 0 && S_ISCDF(b1.st_mode)); 304803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra afree(nv, ATEMP); 304903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (i); 305003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 305103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#else 30525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 305303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 305403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 305503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -u */ 305603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILSETU: 30575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd1, &b1) == 0 && 30585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (b1.st_mode & S_ISUID) == S_ISUID); 305903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 306003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -g */ 306103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILSETG: 30625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd1, &b1) == 0 && 30635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (b1.st_mode & S_ISGID) == S_ISGID); 306403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 306503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -k */ 306603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILSTCK: 30675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef S_ISVTX 30685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd1, &b1) == 0 && 30695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (b1.st_mode & S_ISVTX) == S_ISVTX); 30705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#else 30715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 30725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 307303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 307403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -s */ 307503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILGZ: 3076c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return (stat(opnd1, &b1) == 0 && (off_t)b1.st_size > (off_t)0); 307703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 307803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -t */ 307903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILTT: 30805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (opnd1 && !bi_getn(opnd1, &i)) { 30815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te->flags |= TEF_ERROR; 30825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru i = 0; 30835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 30845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru i = isatty(opnd1 ? i : 0); 30855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (i); 308603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 308703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -O */ 308803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILUID: 3089c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return (stat(opnd1, &b1) == 0 && (uid_t)b1.st_uid == ksheuid); 309003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 309103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -G */ 309203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILGID: 3093c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return (stat(opnd1, &b1) == 0 && (gid_t)b1.st_gid == getegid()); 309403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 30955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 30965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Binary Operators 30975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 309803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 309903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* = */ 310003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_STEQL: 31015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (te->flags & TEF_DBRACKET) 31025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (gmatchx(opnd1, opnd2, false)); 31035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (strcmp(opnd1, opnd2) == 0); 310403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 310503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* != */ 310603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_STNEQ: 31075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (te->flags & TEF_DBRACKET) 31085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (!gmatchx(opnd1, opnd2, false)); 31095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (strcmp(opnd1, opnd2) != 0); 311003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 311103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* < */ 311203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_STLT: 31135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (strcmp(opnd1, opnd2) < 0); 311403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 311503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* > */ 311603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_STGT: 31175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (strcmp(opnd1, opnd2) > 0); 311803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 311903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -eq */ 312003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_INTEQ: 312103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -ne */ 312203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_INTNE: 312303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -ge */ 312403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_INTGE: 312503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -gt */ 312603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_INTGT: 312703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -le */ 312803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_INTLE: 312903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -lt */ 313003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_INTLT: 31315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!evaluate(opnd1, &v1, KSH_RETURN_ERROR, false) || 31325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru !evaluate(opnd2, &v2, KSH_RETURN_ERROR, false)) { 31335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* error already printed.. */ 31345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te->flags |= TEF_ERROR; 31355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 31365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 313703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra switch (op) { 31385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case TO_INTEQ: 31395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (v1 == v2); 31405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case TO_INTNE: 31415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (v1 != v2); 31425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case TO_INTGE: 31435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (v1 >= v2); 31445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case TO_INTGT: 31455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (v1 > v2); 31465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case TO_INTLE: 31475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (v1 <= v2); 31485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case TO_INTLT: 31495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (v1 < v2); 315003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra default: 315103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* NOTREACHED */ 315203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 31535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 315403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* NOTREACHED */ 315503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 315603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -nt */ 315703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILNT: 315803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 315903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * ksh88/ksh93 succeed if file2 can't be stated 31605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (subtly different from 'does not exist'). 31615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 31625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd1, &b1) == 0 && 31635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (((s = stat(opnd2, &b2)) == 0 && 31645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru b1.st_mtime > b2.st_mtime) || s < 0)); 316503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 316603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -ot */ 316703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILOT: 316803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 316903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * ksh88/ksh93 succeed if file1 can't be stated 31705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (subtly different from 'does not exist'). 31715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 31725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd2, &b2) == 0 && 31735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (((s = stat(opnd1, &b1)) == 0 && 31745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru b1.st_mtime < b2.st_mtime) || s < 0)); 317503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 317603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -ef */ 317703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILEQ: 31785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat (opnd1, &b1) == 0 && stat (opnd2, &b2) == 0 && 31795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru b1.st_dev == b2.st_dev && b1.st_ino == b2.st_ino); 318003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 318103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* all other cases */ 318203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_NONOP: 318303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_NONNULL: 318403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* throw the error */ 318503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 31865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 31875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (*te->error)(te, 0, "internal error: unknown op"); 31885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 31895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 31905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 31915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 31925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutest_parse(Test_env *te) 31935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 31945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv; 31955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 31965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = test_oexpr(te, 1); 31975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 31985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(te->flags & TEF_ERROR) && !(*te->isa)(te, TM_END)) 31995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (*te->error)(te, 0, "unexpected operator/operand"); 32005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return ((te->flags & TEF_ERROR) ? T_ERR_EXIT : !rv); 32025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 32035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 32055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutest_oexpr(Test_env *te, bool do_eval) 32065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 32075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv; 32085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((rv = test_aexpr(te, do_eval))) 32105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru do_eval = false; 32115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(te->flags & TEF_ERROR) && (*te->isa)(te, TM_OR)) 32125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (test_oexpr(te, do_eval) || rv); 32135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 32145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 32155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 32175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutest_aexpr(Test_env *te, bool do_eval) 32185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 32195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv; 32205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(rv = test_nexpr(te, do_eval))) 32225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru do_eval = false; 32235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(te->flags & TEF_ERROR) && (*te->isa)(te, TM_AND)) 32245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (test_aexpr(te, do_eval) && rv); 32255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 32265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 32275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 32295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutest_nexpr(Test_env *te, bool do_eval) 32305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 32315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(te->flags & TEF_ERROR) && (*te->isa)(te, TM_NOT)) 32325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (!test_nexpr(te, do_eval)); 32335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (test_primary(te, do_eval)); 32345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 32355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 32375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutest_primary(Test_env *te, bool do_eval) 32385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 32395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *opnd1, *opnd2; 32405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv; 32415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Test_op op; 32425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (te->flags & TEF_ERROR) 32445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 32455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((*te->isa)(te, TM_OPAREN)) { 32465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = test_oexpr(te, do_eval); 32475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (te->flags & TEF_ERROR) 32485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 32495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(*te->isa)(te, TM_CPAREN)) { 325003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra (*te->error)(te, 0, "missing )"); 32515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 32525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 32535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 32545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 32555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 32565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Binary should have precedence over unary in this case 32575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * so that something like test \( -f = -f \) is accepted 32585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 32595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((te->flags & TEF_DBRACKET) || (&te->pos.wp[1] < te->wp_end && 32605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru !test_isop(TM_BINOP, te->pos.wp[1]))) { 32615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((op = (*te->isa)(te, TM_UNOP))) { 32625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* unary expression */ 32635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru opnd1 = (*te->getopnd)(te, op, do_eval); 32645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!opnd1) { 32655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (*te->error)(te, -1, "missing argument"); 32665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 32675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 32685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return ((*te->eval)(te, op, opnd1, NULL, do_eval)); 32705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 32715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 32725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru opnd1 = (*te->getopnd)(te, TO_NONOP, do_eval); 32735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!opnd1) { 32745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (*te->error)(te, 0, "expression expected"); 32755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 32765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 32775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((op = (*te->isa)(te, TM_BINOP))) { 32785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* binary expression */ 32795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru opnd2 = (*te->getopnd)(te, op, do_eval); 32805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!opnd2) { 32815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (*te->error)(te, -1, "missing second argument"); 32825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 32835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 32845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return ((*te->eval)(te, op, opnd1, opnd2, do_eval)); 32865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 32875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return ((*te->eval)(te, TO_STNZE, opnd1, NULL, do_eval)); 32885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 32895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 32915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Plain test (test and [ .. ]) specific routines. 32925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 32935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 32955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Test if the current token is a whatever. Accepts the current token if 32965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * it is. Returns 0 if it is not, non-zero if it is (in the case of 32975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * TM_UNOP and TM_BINOP, the returned value is a Test_op). 32985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 32995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic Test_op 33005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruptest_isa(Test_env *te, Test_meta meta) 33015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 33025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Order important - indexed by Test_meta values */ 3303c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser static const char * const tokens[] = { 33045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "-o", "-a", "!", "(", ")" 33055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru }; 33065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Test_op rv; 33075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 33085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (te->pos.wp >= te->wp_end) 33095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (meta == TM_END ? TO_NONNULL : TO_NONOP); 33105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 33115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (meta == TM_UNOP || meta == TM_BINOP) 33125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = test_isop(meta, *te->pos.wp); 33135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (meta == TM_END) 33145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = TO_NONOP; 33155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 33165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = !strcmp(*te->pos.wp, tokens[(int)meta]) ? 33175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru TO_NONNULL : TO_NONOP; 33185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 33195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Accept the token? */ 33205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (rv != TO_NONOP) 33215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te->pos.wp++; 33225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 33235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 33245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 33255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 33265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic const char * 33275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruptest_getopnd(Test_env *te, Test_op op, bool do_eval MKSH_A_UNUSED) 33285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 33295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (te->pos.wp >= te->wp_end) 33305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (op == TO_FILTT ? "1" : NULL); 33315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (*te->pos.wp++); 33325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 33335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 33345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 33355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruptest_error(Test_env *te, int ofs, const char *msg) 33365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 33375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *op; 33385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 33395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te->flags |= TEF_ERROR; 33405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((op = te->pos.wp + ofs >= te->wp_end ? NULL : te->pos.wp[ofs])) 33415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("%s: %s", op, msg); 33425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 33435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("%s", msg); 33445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 33455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 33465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_NO_LIMITS 33475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define SOFT 0x1 33485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define HARD 0x2 33495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 33505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Magic to divine the 'm' and 'v' limits */ 33515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 33525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_AS 33535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if !defined(RLIMIT_VMEM) || (RLIMIT_VMEM == RLIMIT_AS) || \ 33545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru !defined(RLIMIT_RSS) || (RLIMIT_VMEM == RLIMIT_RSS) 33555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define ULIMIT_V_IS_AS 33565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#elif defined(RLIMIT_VMEM) 33575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if !defined(RLIMIT_RSS) || (RLIMIT_RSS == RLIMIT_AS) 33585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define ULIMIT_V_IS_AS 33595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#else 33605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define ULIMIT_V_IS_VMEM 33615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 33655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_RSS 33665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef ULIMIT_V_IS_VMEM 33675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define ULIMIT_M_IS_RSS 33685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#elif defined(RLIMIT_VMEM) && (RLIMIT_VMEM == RLIMIT_RSS) 33695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define ULIMIT_M_IS_VMEM 33705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#else 33715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define ULIMIT_M_IS_RSS 33725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if defined(ULIMIT_M_IS_RSS) && defined(RLIMIT_AS) && (RLIMIT_RSS == RLIMIT_AS) 33745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#undef ULIMIT_M_IS_RSS 33755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 33785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if !defined(RLIMIT_AS) && !defined(ULIMIT_M_IS_VMEM) && defined(RLIMIT_VMEM) 33795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define ULIMIT_V_IS_VMEM 33805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 33825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if !defined(ULIMIT_V_IS_VMEM) && defined(RLIMIT_VMEM) && \ 33835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (!defined(RLIMIT_RSS) || (defined(RLIMIT_AS) && (RLIMIT_RSS == RLIMIT_AS))) 33845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define ULIMIT_M_IS_VMEM 33855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 33875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if defined(ULIMIT_M_IS_VMEM) && defined(RLIMIT_AS) && \ 33885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (RLIMIT_VMEM == RLIMIT_AS) 33895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#undef ULIMIT_M_IS_VMEM 33905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3392427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#if defined(ULIMIT_M_IS_RSS) && defined(ULIMIT_M_IS_VMEM) 3393427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes# error nonsensical m ulimit 3394427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#endif 3395427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes 3396427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#if defined(ULIMIT_V_IS_VMEM) && defined(ULIMIT_V_IS_AS) 3397427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes# error nonsensical v ulimit 3398427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#endif 3399427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes 3400427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#define RLIMITS_DEFNS 3401427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#include "rlimits.gen" 3402427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes 3403427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughesstatic void print_ulimit(const struct limits *, int); 3404427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughesstatic int set_ulimit(const struct limits *, const char *, int); 3405427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes 3406427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughesstatic const struct limits * const rlimits[] = { 3407427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#define RLIMITS_ITEMS 3408427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#include "rlimits.gen" 3409427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes}; 3410427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes 3411427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughesstatic const char rlimits_opts[] = 3412427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#define RLIMITS_OPTCS 3413427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#include "rlimits.gen" 3414427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes ; 34155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 34165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 34175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_ulimit(const char **wp) 34185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 3419427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes size_t i = 0; 34205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int how = SOFT | HARD, optc, what = 'f'; 34215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool all = false; 34225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3423427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes while ((optc = ksh_getopt(wp, &builtin_opt, rlimits_opts)) != -1) 34245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 34255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'H': 34265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru how = HARD; 34275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 34285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'S': 34295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru how = SOFT; 34305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 34315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'a': 34325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru all = true; 34335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 34345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 3435427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes bi_errorf("usage: ulimit [-%s] [value]", rlimits_opts); 34365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 34375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 34385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru what = optc; 34395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 34405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3441427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes while (i < NELEM(rlimits)) { 3442427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes if (rlimits[i]->optchar == what) 3443427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes goto found; 3444427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes ++i; 34455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3446427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes internal_warningf("ulimit: %c", what); 3447427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes return (1); 3448427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes found: 34495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (wp[builtin_opt.optind]) { 34505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (all || wp[builtin_opt.optind + 1]) { 34515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("too many arguments"); 34525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 34535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3454427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes return (set_ulimit(rlimits[i], wp[builtin_opt.optind], how)); 34555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 34565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!all) 3457427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes print_ulimit(rlimits[i], how); 3458427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes else for (i = 0; i < NELEM(rlimits); ++i) { 3459427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes shprintf("%-20s ", rlimits[i]->name); 3460427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes print_ulimit(rlimits[i], how); 34615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 34625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 34635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 34645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 34655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 34665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruset_ulimit(const struct limits *l, const char *v, int how) 34675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 34685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rlim_t val = (rlim_t)0; 34695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct rlimit limit; 34705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 34715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (strcmp(v, "unlimited") == 0) 34725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru val = (rlim_t)RLIM_INFINITY; 34735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else { 3474c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser mksh_uari_t rval; 34755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3476c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (!evaluate(v, (mksh_ari_t *)&rval, KSH_RETURN_ERROR, false)) 34775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 34785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 34795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Avoid problems caused by typos that evaluate misses due 34805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * to evaluating unset parameters to 0... 34815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * If this causes problems, will have to add parameter to 34825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * evaluate() to control if unset params are 0 or an error. 34835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 34845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!rval && !ksh_isdigit(v[0])) { 34855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("invalid %s limit: %s", l->name, v); 34865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 34875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 34885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru val = (rlim_t)((rlim_t)rval * l->factor); 34895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 34905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 34915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (getrlimit(l->resource, &limit) < 0) { 3492427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#ifndef MKSH_SMALL 3493427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes bi_errorf("limit %s could not be read, contact the mksh developers: %s", 3494427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes l->name, cstrerror(errno)); 3495427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#endif 3496427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes /* some can't be read */ 34975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru limit.rlim_cur = RLIM_INFINITY; 34985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru limit.rlim_max = RLIM_INFINITY; 34995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 35005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (how & SOFT) 35015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru limit.rlim_cur = val; 35025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (how & HARD) 35035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru limit.rlim_max = val; 35045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!setrlimit(l->resource, &limit)) 35055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 35065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (errno == EPERM) 35075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("%s exceeds allowable %s limit", v, l->name); 35085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 3509c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bi_errorf("bad %s limit: %s", l->name, cstrerror(errno)); 35105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 35115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 35125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 35135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 35145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruprint_ulimit(const struct limits *l, int how) 35155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 35165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rlim_t val = (rlim_t)0; 35175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct rlimit limit; 35185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 35195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (getrlimit(l->resource, &limit)) { 35205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts("unknown\n", shl_stdout); 35215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return; 35225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 35235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (how & SOFT) 35245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru val = limit.rlim_cur; 35255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (how & HARD) 35265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru val = limit.rlim_max; 35275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (val == (rlim_t)RLIM_INFINITY) 35285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts("unlimited\n", shl_stdout); 35295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 3530c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shprintf("%lu\n", (unsigned long)(val / l->factor)); 35315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 35325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 35335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 35345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 35355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_rename(const char **wp) 35365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 35375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv = 1; 35385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 353903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* skip argv[0] */ 354003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++wp; 354103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (wp[0] && !strcmp(wp[0], "--")) 354203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* skip "--" (options separator) */ 354303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++wp; 354403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 354503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* check for exactly two arguments */ 354603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (wp[0] == NULL /* first argument */ || 354703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra wp[1] == NULL /* second argument */ || 354803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra wp[2] != NULL /* no further args please */) 354903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf(Tsynerr); 355003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else if ((rv = rename(wp[0], wp[1])) != 0) { 35515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = errno; 3552c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bi_errorf("%s: %s", "failed", cstrerror(rv)); 35535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 35545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 35555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 35565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 35575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 35585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 35595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_realpath(const char **wp) 35605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 35615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv = 1; 35625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *buf; 35635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 356403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* skip argv[0] */ 356503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++wp; 356603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (wp[0] && !strcmp(wp[0], "--")) 356703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* skip "--" (options separator) */ 356803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++wp; 35695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 357003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* check for exactly one argument */ 357103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (wp[0] == NULL || wp[1] != NULL) 357203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf(Tsynerr); 357303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else if ((buf = do_realpath(wp[0])) == NULL) { 35745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = errno; 3575c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bi_errorf("%s: %s", wp[0], cstrerror(rv)); 35765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((unsigned int)rv > 255) 35775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 255; 35785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 35795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shprintf("%s\n", buf); 35805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(buf, ATEMP); 358103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 0; 35825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 35835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 35845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 35855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 358603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 358703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condraint 358803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrac_cat(const char **wp) 358903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{ 3590c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser int fd = STDIN_FILENO, rv, eno; 359103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ssize_t n, w; 359203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra const char *fn = "<stdin>"; 359303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra char *buf, *cp; 359403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define MKSH_CAT_BUFSIZ 4096 359503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 359603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* parse options: POSIX demands we support "-u" as no-op */ 359703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while ((rv = ksh_getopt(wp, &builtin_opt, "u")) != -1) { 359803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra switch (rv) { 359903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'u': 360003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* we already operate unbuffered */ 360103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 360203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra default: 360303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf(Tsynerr); 360403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (1); 360503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 360603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 360703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra wp += builtin_opt.optind; 360803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 0; 360903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 3610c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((buf = malloc_osfunc(MKSH_CAT_BUFSIZ)) == NULL) { 3611811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser bi_errorf(Toomem, (size_t)MKSH_CAT_BUFSIZ); 3612c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return (1); 3613c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 3614c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 361503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra do { 361603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (*wp) { 361703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra fn = *wp++; 361803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (fn[0] == '-' && fn[1] == '\0') 361903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra fd = STDIN_FILENO; 3620427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes else if ((fd = open(fn, O_RDONLY | O_BINARY)) < 0) { 3621c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser eno = errno; 3622c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bi_errorf("%s: %s", fn, cstrerror(eno)); 362303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 1; 362403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra continue; 362503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 362603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 362703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (/* CONSTCOND */ 1) { 362803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra n = blocking_read(fd, (cp = buf), MKSH_CAT_BUFSIZ); 3629c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser eno = errno; 3630c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* give the user a chance to ^C out */ 3631c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser intrcheck(); 363203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (n == -1) { 3633c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (eno == EINTR) { 363403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* interrupted, try again */ 363503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra continue; 363603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 363703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* an error occured during reading */ 3638c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bi_errorf("%s: %s", fn, cstrerror(eno)); 363903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 1; 364003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 364103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else if (n == 0) 364203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* end of file reached */ 364303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 364403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (n) { 364503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra w = write(STDOUT_FILENO, cp, n); 3646b4542e99ca8562aa584e15df8ef35356ff8c10feElliott Hughes eno = errno; 3647b4542e99ca8562aa584e15df8ef35356ff8c10feElliott Hughes /* give the user a chance to ^C out */ 3648b4542e99ca8562aa584e15df8ef35356ff8c10feElliott Hughes intrcheck(); 364903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (w == -1) { 3650b4542e99ca8562aa584e15df8ef35356ff8c10feElliott Hughes if (eno == EINTR) 365103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* interrupted, try again */ 365203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra continue; 365303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* an error occured during writing */ 365403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", "<stdout>", 3655c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser cstrerror(eno)); 365603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 1; 365703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (fd != STDIN_FILENO) 365803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra close(fd); 365903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto out; 366003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 366103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra n -= w; 366203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra cp += w; 366303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 366403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 366503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (fd != STDIN_FILENO) 366603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra close(fd); 366703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } while (*wp); 366803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 366903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra out: 367003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra free_osfunc(buf); 367103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (rv); 367203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra} 367303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 367403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#if HAVE_SELECT 367503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condraint 367603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrac_sleep(const char **wp) 367703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{ 367803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra struct timeval tv; 367903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra int rv = 1; 368003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 368103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* skip argv[0] */ 368203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++wp; 368303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (wp[0] && !strcmp(wp[0], "--")) 368403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* skip "--" (options separator) */ 368503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++wp; 368603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 368703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!wp[0] || wp[1]) 368803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf(Tsynerr); 368903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else if (parse_usec(wp[0], &tv)) 3690c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bi_errorf("%s: %s '%s'", Tsynerr, cstrerror(errno), wp[0]); 369103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else { 369203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#ifndef MKSH_NOPROSPECTOFWORK 3693c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser sigset_t omask, bmask; 369403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 3695c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* block a number of signals from interrupting us, though */ 3696c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser (void)sigemptyset(&bmask); 3697c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser (void)sigaddset(&bmask, SIGPIPE); 3698c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser (void)sigaddset(&bmask, SIGCHLD); 3699c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef SIGWINCH 3700c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser (void)sigaddset(&bmask, SIGWINCH); 3701c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 3702c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef SIGINFO 3703c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser (void)sigaddset(&bmask, SIGINFO); 3704c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 3705c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef SIGUSR1 3706c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser (void)sigaddset(&bmask, SIGUSR1); 3707c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 3708c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef SIGUSR2 3709c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser (void)sigaddset(&bmask, SIGUSR2); 3710c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 3711c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser sigprocmask(SIG_BLOCK, &bmask, &omask); 371203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 3713c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (select(1, NULL, NULL, NULL, &tv) == 0 || errno == EINTR) 371403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 371503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * strictly speaking only for SIGALRM, but the 371603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * execution may be interrupted by other signals 371703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra */ 371803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 0; 371903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else 3720c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bi_errorf("%s: %s", Tselect, cstrerror(errno)); 372103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#ifndef MKSH_NOPROSPECTOFWORK 3722c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* this will re-schedule signal delivery */ 372303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra sigprocmask(SIG_SETMASK, &omask, NULL); 372403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 372503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 372603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (rv); 372703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra} 372803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 3729427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes 3730427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#if !defined(MKSH_UNEMPLOYED) && HAVE_GETSID 3731427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughesstatic int 3732427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughesc_suspend(const char **wp) 3733427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes{ 3734427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes if (wp[1] != NULL) { 3735427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes bi_errorf("too many arguments"); 3736427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes return (1); 3737427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes } 3738427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes if (Flag(FLOGIN)) { 3739427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes /* Can't suspend an orphaned process group. */ 3740427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes if (getpgid(kshppid) == getpgid(0) || 3741427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes getsid(kshppid) != getsid(0)) { 3742427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes bi_errorf("can't suspend a login shell"); 3743427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes return (1); 3744427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes } 3745427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes } 3746427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes j_suspend(); 3747427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes return (0); 3748427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes} 3749427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#endif 3750