15155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* $OpenBSD: c_ksh.c,v 1.33 2009/02/07 14:03:24 kili Exp $ */ 25155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* $OpenBSD: c_sh.c,v 1.41 2010/03/27 09:10:01 jmc Exp $ */ 35155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* $OpenBSD: c_test.c,v 1.18 2009/03/01 20:11:06 otto Exp $ */ 45155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* $OpenBSD: c_ulimit.c,v 1.17 2008/03/21 12:51:19 millert Exp $ */ 55155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 65155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/*- 703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 8c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * 2010, 2011, 2012, 2013 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 41c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.238 2013/02/18 22:47:32 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 63c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser/* getn() that prints error */ 64c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstatic int 65c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserbi_getn(const char *as, int *ai) 66c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser{ 67c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser int rv; 68c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 69c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (!(rv = getn(as, ai))) 70c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bi_errorf("%s: %s", as, "bad number"); 71c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return (rv); 72c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser} 735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic int 7503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrac_true(const char **wp MKSH_A_UNUSED) 7603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{ 7703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (0); 7803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra} 795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic int 8103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrac_false(const char **wp MKSH_A_UNUSED) 8203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{ 8303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (1); 8403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra} 8503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 8603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* 8703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * A leading = means assignments before command are kept; 885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * a leading * means a POSIX special builtin; 895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * a leading + means a POSIX regular builtin 905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (* and + should not be combined). 915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruconst struct builtin mkshbuiltins[] = { 935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"*=.", c_dot}, 9403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra {"*=:", c_true}, 955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"[", c_test}, 965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"*=break", c_brkcont}, 9703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra {Tgbuiltin, c_builtin}, 985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"*=continue", c_brkcont}, 995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"*=eval", c_eval}, 1005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"*=exec", c_exec}, 1015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"*=exit", c_exitreturn}, 10203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra {"+false", c_false}, 1035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"*=return", c_exitreturn}, 10403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra {Tsgset, c_set}, 1055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"*=shift", c_shift}, 1065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"=times", c_times}, 1075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"*=trap", c_trap}, 1085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"+=wait", c_wait}, 1095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"+read", c_read}, 1105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"test", c_test}, 11103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra {"+true", c_true}, 1125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"ulimit", c_ulimit}, 1135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"+umask", c_umask}, 114c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser {Tsgunset, c_unset}, 11503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* no =: AT&T manual wrong */ 11603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra {Tpalias, c_alias}, 1175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"+cd", c_cd}, 11803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* dash compatibility hack */ 11903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra {"chdir", c_cd}, 1205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"+command", c_command}, 1215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"echo", c_print}, 122c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser {Tsgexport, c_typeset}, 1235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"+fc", c_fc}, 1245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"+getopts", c_getopts}, 12503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra {"=global", c_typeset}, 1265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"+jobs", c_jobs}, 1275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"+kill", c_kill}, 1285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"let", c_let}, 1295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"print", c_print}, 1305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef MKSH_PRINTF_BUILTIN 1315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"printf", c_printf}, 1325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 1335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"pwd", c_pwd}, 134c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser {Tsgreadonly, c_typeset}, 13503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra {T_typeset, c_typeset}, 13603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra {Tpunalias, c_unalias}, 1375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"whence", c_whence}, 1385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_UNEMPLOYED 1395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"+bg", c_fgbg}, 1405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"+fg", c_fgbg}, 1415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 142c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifndef MKSH_NO_CMDLINE_EDITING 1435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"bind", c_bind}, 144c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 14503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra {"cat", c_cat}, 1465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if HAVE_MKNOD 1475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"mknod", c_mknod}, 1485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 1495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"realpath", c_realpath}, 1505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"rename", c_rename}, 15103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#if HAVE_SELECT 15203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra {"sleep", c_sleep}, 15303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 15403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#ifdef __MirBSD__ 15503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* alias to "true" for historical reasons */ 15603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra {"domainname", c_true}, 15703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 1585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {NULL, (int (*)(const char **))NULL} 1595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}; 1605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustruct kill_info { 1625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int num_width; 1635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int name_width; 1645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}; 1655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic const struct t_op { 1675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char op_text[4]; 1685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Test_op op_num; 1695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} u_ops[] = { 1705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-a", TO_FILAXST }, 1715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-b", TO_FILBDEV }, 1725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-c", TO_FILCDEV }, 1735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-d", TO_FILID }, 1745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-e", TO_FILEXST }, 1755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-f", TO_FILREG }, 1765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-G", TO_FILGID }, 1775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-g", TO_FILSETG }, 1785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-h", TO_FILSYM }, 1795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-H", TO_FILCDF }, 1805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-k", TO_FILSTCK }, 1815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-L", TO_FILSYM }, 1825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-n", TO_STNZE }, 1835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-O", TO_FILUID }, 1845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-o", TO_OPTION }, 1855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-p", TO_FILFIFO }, 1865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-r", TO_FILRD }, 1875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-s", TO_FILGZ }, 1885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-S", TO_FILSOCK }, 1895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-t", TO_FILTT }, 1905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-u", TO_FILSETU }, 1915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-w", TO_FILWR }, 1925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-x", TO_FILEX }, 1935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-z", TO_STZER }, 1945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"", TO_NONOP } 1955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}; 1965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic const struct t_op b_ops[] = { 1975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"=", TO_STEQL }, 1985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"==", TO_STEQL }, 1995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"!=", TO_STNEQ }, 2005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"<", TO_STLT }, 2015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {">", TO_STGT }, 2025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-eq", TO_INTEQ }, 2035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-ne", TO_INTNE }, 2045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-gt", TO_INTGT }, 2055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-ge", TO_INTGE }, 2065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-lt", TO_INTLT }, 2075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-le", TO_INTLE }, 2085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-ef", TO_FILEQ }, 2095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-nt", TO_FILNT }, 2105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-ot", TO_FILOT }, 2115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"", TO_NONOP } 2125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}; 2135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int test_oexpr(Test_env *, bool); 2155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int test_aexpr(Test_env *, bool); 2165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int test_nexpr(Test_env *, bool); 2175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int test_primary(Test_env *, bool); 2185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic Test_op ptest_isa(Test_env *, Test_meta); 2195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic const char *ptest_getopnd(Test_env *, Test_op, bool); 2205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void ptest_error(Test_env *, int, const char *); 221c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstatic char *kill_fmt_entry(char *, size_t, unsigned int, const void *); 2225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void p_time(struct shf *, bool, long, int, int, 223c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser const char *, const char *); 2245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 2265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_pwd(const char **wp) 2275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 2285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int optc; 22903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bool physical = tobool(Flag(FPHYSICAL)); 2305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *p, *allocd = NULL; 2315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt(wp, &builtin_opt, "LP")) != -1) 2335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 2345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'L': 2355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru physical = false; 2365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 2375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'P': 2385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru physical = true; 2395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 2405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 2415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 2425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 2445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (wp[0]) { 2465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("too many arguments"); 2475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 2485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p = current_wd[0] ? (physical ? allocd = do_realpath(current_wd) : 2505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru current_wd) : NULL; 25103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* LINTED use of access */ 2525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (p && access(p, R_OK) < 0) 2535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p = NULL; 25403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!p && !(p = allocd = ksh_get_wd())) { 25503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", "can't determine current directory", 256c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser cstrerror(errno)); 2575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 2585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shprintf("%s\n", p); 2605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(allocd, ATEMP); 2615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 2625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 2635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic const char *s_ptr; 2655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int s_get(void); 2665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void s_put(int); 2675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 2695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_print(const char **wp) 2705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 2715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define PO_NL BIT(0) /* print newline */ 2725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define PO_EXPAND BIT(1) /* expand backslash sequences */ 2735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define PO_PMINUSMINUS BIT(2) /* print a -- argument */ 2745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define PO_HIST BIT(3) /* print to history instead of stdout */ 2755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define PO_COPROC BIT(4) /* printing to coprocess: block SIGPIPE */ 2765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int fd = 1, c; 277c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser int flags = PO_EXPAND | PO_NL; 2785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *s, *emsg; 2795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XString xs; 2805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *xp; 2815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (wp[0][0] == 'e') { 2835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* echo builtin */ 2845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp++; 285c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef MKSH_MIDNIGHTBSD01ASH_COMPAT 286c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (Flag(FSH)) { 287c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* 288c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * MidnightBSD /bin/sh needs a BSD echo, that is, 289c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * one that supports -e but does not enable it by 290c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * default 291c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser */ 292c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser flags = PO_NL; 293c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 294c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 295c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (Flag(FPOSIX) || 296c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifndef MKSH_MIDNIGHTBSD01ASH_COMPAT 297c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser Flag(FSH) || 298c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 299c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser Flag(FAS_BUILTIN)) { 3005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Debian Policy 10.4 compliant "echo" builtin */ 3015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*wp && !strcmp(*wp, "-n")) { 3025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* we recognise "-n" only as the first arg */ 3035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flags = 0; 3045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp++; 3055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 3065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* otherwise, we print everything as-is */ 3075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flags = PO_NL; 3085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 3095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int nflags = flags; 3105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /** 3125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * a compromise between sysV and BSD echo commands: 3135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * escape sequences are enabled by default, and -n, 3145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * -e and -E are recognised if they appear in argu- 3155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * ments with no illegal options (ie, echo -nq will 3165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * print -nq). 3175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Different from sysV echo since options are reco- 3185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * gnised, different from BSD echo since escape se- 3195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * quences are enabled by default. 3205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 3215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((s = *wp) && *s == '-' && s[1]) { 3235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (*++s) 3245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*s == 'n') 3255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nflags &= ~PO_NL; 3265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (*s == 'e') 3275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nflags |= PO_EXPAND; 3285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (*s == 'E') 3295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nflags &= ~PO_EXPAND; 3305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 3315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 3325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * bad option: don't use 3335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * nflags, print argument 3345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 3355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*s) 3385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp++; 3405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flags = nflags; 3415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 3445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int optc; 3455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *opts = "Rnprsu,"; 3465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt(wp, &builtin_opt, opts)) != -1) 3485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 34903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'R': 35003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* fake BSD echo command */ 3515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flags |= PO_PMINUSMINUS; 3525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flags &= ~PO_EXPAND; 3535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru opts = "ne"; 3545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'e': 3565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flags |= PO_EXPAND; 3575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'n': 3595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flags &= ~PO_NL; 3605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'p': 3625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((fd = coproc_getfd(W_OK, &emsg)) < 0) { 36303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", "-p", emsg); 3645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 3655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'r': 3685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flags &= ~PO_EXPAND; 3695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 's': 3715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flags |= PO_HIST; 3725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'u': 3745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!*(s = builtin_opt.optarg)) 3755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fd = 0; 3765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if ((fd = check_fd(s, W_OK, &emsg)) < 0) { 37703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s: %s", "-u", s, emsg); 3785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 3795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 3825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 3835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(builtin_opt.info & GI_MINUSMINUS)) { 3865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* treat a lone - like -- */ 3875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (wp[builtin_opt.optind] && 3885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ksh_isdash(wp[builtin_opt.optind])) 3895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru builtin_opt.optind++; 3905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (flags & PO_PMINUSMINUS) 3915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru builtin_opt.optind--; 3925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 3935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xinit(xs, xp, 128, ATEMP); 3965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (*wp != NULL) { 3985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = *wp; 3995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((c = *s++) != '\0') { 4005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xcheck(xs, xp); 4015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((flags & PO_EXPAND) && c == '\\') { 4025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s_ptr = s; 4035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = unbksl(false, s_get, s_put); 4045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = s_ptr; 4055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == -1) { 4065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* rejected by generic function */ 4075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch ((c = *s++)) { 4085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'c': 4095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flags &= ~PO_NL; 4105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* AT&T brain damage */ 4115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 4125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '\0': 4135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s--; 4145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = '\\'; 4155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 4165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 4175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xput(xs, xp, '\\'); 4185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if ((unsigned int)c > 0xFF) { 4205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* generic function returned Unicode */ 4215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char ts[4]; 4225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 42303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ts[utf_wctomb(ts, c - 0x100)] = 0; 4245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (c = 0; ts[c]; ++c) 4255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xput(xs, xp, ts[c]); 4265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 4275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xput(xs, xp, c); 4305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*++wp != NULL) 4325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xput(xs, xp, ' '); 4335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (flags & PO_NL) 4355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xput(xs, xp, '\n'); 4365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (flags & PO_HIST) { 4385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xput(xs, xp, '\0'); 4395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru histsave(&source->line, Xstring(xs, xp), true, false); 4405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xfree(xs, xp); 4415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 4425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int len = Xlength(xs, xp); 4435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int opipe = 0; 4445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 44503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 44603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Ensure we aren't killed by a SIGPIPE while writing to 4475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * a coprocess. AT&T ksh doesn't seem to do this (seems 4485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * to just check that the co-process is alive which is 4495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * not enough). 4505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 4515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (coproc.write >= 0 && coproc.write == fd) { 4525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flags |= PO_COPROC; 4535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru opipe = block_pipe(); 4545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (s = Xstring(xs, xp); len > 0; ) { 4565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c = write(fd, s, len)) < 0) { 4575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (flags & PO_COPROC) 4585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru restore_pipe(opipe); 4595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (errno == EINTR) { 4605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* allow user to ^C out */ 4615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru intrcheck(); 4625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (flags & PO_COPROC) 4635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru opipe = block_pipe(); 4645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 4655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 4675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s += c; 4695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru len -= c; 4705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (flags & PO_COPROC) 4725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru restore_pipe(opipe); 4735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 4765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 4775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 4795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querus_get(void) 4805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 4815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (*s_ptr++); 4825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 4835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 4855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querus_put(int c MKSH_A_UNUSED) 4865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 4875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru --s_ptr; 4885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 4895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 4915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_whence(const char **wp) 4925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 4935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *tp; 4945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *id; 4955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool pflag = false, vflag = false, Vflag = false; 4965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv = 0, optc, fcflags; 4975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool iam_whence = wp[0][0] == 'w'; 4985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *opts = iam_whence ? "pv" : "pvV"; 4995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt(wp, &builtin_opt, opts)) != -1) 5015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 5025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'p': 5035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru pflag = true; 5045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'v': 5065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vflag = true; 5075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'V': 5095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Vflag = true; 5105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 5125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 5135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 5155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fcflags = FC_BI | FC_PATH | FC_FUNC; 5175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!iam_whence) { 5185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Note that -p on its own is deal with in comexec() */ 5195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (pflag) 5205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fcflags |= FC_DEFPATH; 52103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 52203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Convert command options to whence options - note that 5235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * command -pV uses a different path search than whence -v 5245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * or whence -pv. This should be considered a feature. 5255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 5265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vflag = Vflag; 5275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (pflag) 5295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fcflags &= ~(FC_BI | FC_FUNC); 5305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((vflag || rv == 0) && (id = *wp++) != NULL) { 5325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru uint32_t h = 0; 5335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp = NULL; 5355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((iam_whence || vflag) && !pflag) 5365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp = ktsearch(&keywords, id, h = hash(id)); 5375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!tp && !pflag) { 5385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp = ktsearch(&aliases, id, h ? h : hash(id)); 5395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tp && !(tp->flag & ISSET)) 5405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp = NULL; 5415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!tp) 5435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp = findcom(id, fcflags); 5445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vflag || (tp->type != CALIAS && tp->type != CEXEC && 5455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp->type != CTALIAS)) 5465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts(id, shl_stdout); 54703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (vflag) 54803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra switch (tp->type) { 54903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case CKEYWD: 55003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case CALIAS: 55103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case CFUNC: 55203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case CSHELL: 55303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shf_puts(" is a", shl_stdout); 55403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 55503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 55603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 5575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (tp->type) { 5585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case CKEYWD: 5595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vflag) 56003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shf_puts(" reserved word", shl_stdout); 5615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case CALIAS: 5635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vflag) 56403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shprintf("n %s%s for ", 56503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra (tp->flag & EXPORT) ? "exported " : null, 56603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Talias); 5675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!iam_whence && !vflag) 56803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shprintf("%s %s=", Talias, id); 569c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser print_value_quoted(shl_stdout, tp->val.s); 5705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case CFUNC: 5725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vflag) { 5735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tp->flag & EXPORT) 5745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts("n exported", shl_stdout); 5755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tp->flag & TRACE) 5765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts(" traced", shl_stdout); 5775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(tp->flag & ISSET)) { 5785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts(" undefined", shl_stdout); 5795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tp->u.fpath) 5805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shprintf(" (autoload from %s)", 5815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp->u.fpath); 5825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 58303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shf_puts(T_function, shl_stdout); 5845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case CSHELL: 5875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vflag) 58803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shprintf("%s %s %s", 58903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra (tp->flag & SPEC_BI) ? " special" : null, 59003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra "shell", Tbuiltin); 5915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case CTALIAS: 5935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case CEXEC: 5945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tp->flag & ISSET) { 5955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vflag) { 5965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts(" is ", shl_stdout); 5975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tp->type == CTALIAS) 59803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shprintf("a tracked %s%s for ", 5995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (tp->flag & EXPORT) ? 60003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra "exported " : null, 60103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Talias); 6025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts(tp->val.s, shl_stdout); 6045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 6055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vflag) 60603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shprintf(" %s\n", "not found"); 6075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 1; 6085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 6105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 6115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shprintf("%s is *GOK*", id); 6125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 6135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vflag || !rv) 6155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_putc('\n', shl_stdout); 6165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 6185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 6195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Deal with command -vV - command -p dealt with in comexec() */ 6215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 6225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_command(const char **wp) 6235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 62403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 62503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Let c_whence do the work. Note that c_command() must be 6265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * a distinct function from c_whence() (tested in comexec()). 6275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 6285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (c_whence(wp)); 6295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 6305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 63103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* typeset, global, export, and readonly */ 632c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstatic void c_typeset_vardump(struct tbl *, uint32_t, int, bool, bool); 633c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstatic void c_typeset_vardump_recursive(struct block *, uint32_t, int, bool, 634c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bool); 6355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 6365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_typeset(const char **wp) 6375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 6385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *vp, **p; 63903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra uint32_t fset = 0, fclr = 0, flag; 640c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser int thing = 0, field = 0, base = 0, i; 641c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser struct block *l; 6425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *opts; 643c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser const char *fieldstr = NULL, *basestr = NULL; 6445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool localv = false, func = false, pflag = false, istset = true; 6455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (**wp) { 64703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 64803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* export */ 64903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'e': 6505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fset |= EXPORT; 6515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru istset = false; 6525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 65303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 65403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* readonly */ 65503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'r': 6565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fset |= RDONLY; 6575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru istset = false; 6585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 65903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 66003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* set */ 66103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 's': 6625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* called with 'typeset -' */ 6635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 66403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 66503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* typeset */ 66603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 't': 6675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru localv = true; 6685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 6695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* see comment below regarding possible opions */ 6725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru opts = istset ? "L#R#UZ#afi#lnprtux" : "p"; 6735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru builtin_opt.flags |= GF_PLUSOPT; 67503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 67603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * AT&T ksh seems to have 0-9 as options which are multiplied 6775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * to get a number that is used with -L, -R, -Z or -i (eg, -1R2 6785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * sets right justify in a field of 12). This allows options 6795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * to be grouped in an order (eg, -Lu12), but disallows -i8 -L3 and 6805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * does not allow the number to be specified as a separate argument 6815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Here, the number must follow the RLZi option, but is optional 6825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (see the # kludge in ksh_getopt()). 6835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 684c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser while ((i = ksh_getopt(wp, &builtin_opt, opts)) != -1) { 6855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flag = 0; 686c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser switch (i) { 6875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'L': 6885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flag = LJUST; 6895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fieldstr = builtin_opt.optarg; 6905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 6915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'R': 6925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flag = RJUST; 6935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fieldstr = builtin_opt.optarg; 6945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 6955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'U': 69603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 69703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * AT&T ksh uses u, but this conflicts with 6985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * upper/lower case. If this option is changed, 6995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * need to change the -U below as well 7005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 7015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flag = INT_U; 7025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'Z': 7045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flag = ZEROFIL; 7055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fieldstr = builtin_opt.optarg; 7065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'a': 7085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 7095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * this is supposed to set (-a) or unset (+a) the 7105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * indexed array attribute; it does nothing on an 7115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * existing regular string or indexed array though 7125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 7135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'f': 7155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru func = true; 7165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'i': 7185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flag = INTEGER; 7195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru basestr = builtin_opt.optarg; 7205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'l': 7225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flag = LCASEV; 7235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'n': 72503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra set_refflag = (builtin_opt.info & GI_PLUS) ? 72603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra SRF_DISABLE : SRF_ENABLE; 7275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 72803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* export, readonly: POSIX -p flag */ 7295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'p': 7305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* typeset: show values as well */ 7315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru pflag = true; 7325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (istset) 7335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 7345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'r': 7365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flag = RDONLY; 7375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 't': 7395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flag = TRACE; 7405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'u': 74203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* upper case / autoload */ 74303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra flag = UCASEV_AL; 7445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'x': 7465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flag = EXPORT; 7475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 749c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser errout: 750c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser set_refflag = SRF_NOP; 7515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 7525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (builtin_opt.info & GI_PLUS) { 7545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fclr |= flag; 7555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fset &= ~flag; 7565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru thing = '+'; 7575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 7585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fset |= flag; 7595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fclr &= ~flag; 7605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru thing = '-'; 7615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (fieldstr && !bi_getn(fieldstr, &field)) 765c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto errout; 766c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (basestr && (!bi_getn(basestr, &base) || base < 1 || base > 36)) { 767c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bi_errorf("%s: %s", "bad integer base", basestr); 768c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto errout; 769c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 7705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(builtin_opt.info & GI_MINUSMINUS) && wp[builtin_opt.optind] && 7725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (wp[builtin_opt.optind][0] == '-' || 7735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp[builtin_opt.optind][0] == '+') && 7745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp[builtin_opt.optind][1] == '\0') { 7755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru thing = wp[builtin_opt.optind][0]; 7765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru builtin_opt.optind++; 7775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 77903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (func && (((fset|fclr) & ~(TRACE|UCASEV_AL|EXPORT)) || 78003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra set_refflag != SRF_NOP)) { 7815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("only -t, -u and -x options may be used with -f"); 782c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto errout; 7835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (wp[builtin_opt.optind]) { 78503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 78603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Take care of exclusions. 7875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * At this point, flags in fset are cleared in fclr and vice 7885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * versa. This property should be preserved. 7895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 79003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (fset & LCASEV) 79103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* LCASEV has priority over UCASEV_AL */ 7925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fset &= ~UCASEV_AL; 79303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (fset & LJUST) 79403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* LJUST has priority over RJUST */ 7955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fset &= ~RJUST; 79603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((fset & (ZEROFIL|LJUST)) == ZEROFIL) { 79703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -Z implies -ZR */ 7985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fset |= RJUST; 7995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fclr &= ~RJUST; 8005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 80103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 80203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Setting these attributes clears the others, unless they 8035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * are also set in this command 8045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 8055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((fset & (LJUST | RJUST | ZEROFIL | UCASEV_AL | LCASEV | 80603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra INTEGER | INT_U | INT_L)) || set_refflag != SRF_NOP) 8075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fclr |= ~fset & (LJUST | RJUST | ZEROFIL | UCASEV_AL | 8085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru LCASEV | INTEGER | INT_U | INT_L); 8095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* set variables and attributes */ 812c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (wp[builtin_opt.optind] && 813c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* not "typeset -p varname" */ 814c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser !(!func && pflag && !(fset | fclr))) { 815c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser int rv = 0; 8165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *f; 8175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (localv && !func) 8195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fset |= LOCAL; 8205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (i = builtin_opt.optind; wp[i]; i++) { 8215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (func) { 8225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru f = findfunc(wp[i], hash(wp[i]), 82303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra tobool(fset & UCASEV_AL)); 8245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!f) { 8255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* AT&T ksh does ++rv: bogus */ 8265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 1; 8275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 8285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (fset | fclr) { 8305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru f->flag |= fset; 8315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru f->flag &= ~fclr; 83203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else { 83303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra fpFUNCTf(shl_stdout, 0, 83403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra tobool(f->flag & FKSH), 83503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra wp[i], f->val.t); 83603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shf_putc('\n', shl_stdout); 83703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 8385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (!typeset(wp[i], fset, fclr, field, base)) { 83903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", wp[i], "not identifier"); 840c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto errout; 8415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 84303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra set_refflag = SRF_NOP; 8445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 8455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 847c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser set_refflag = SRF_NOP; 8485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* list variables and attributes */ 84903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 85003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* no difference at this point.. */ 85103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra flag = fset | fclr; 8525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (func) { 8535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (l = e->loc; l; l = l->next) { 8545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (p = ktsort(&l->funs); (vp = *p++); ) { 8555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (flag && (vp->flag & flag) == 0) 8565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 8575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (thing == '-') 85803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra fpFUNCTf(shl_stdout, 0, 85903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra tobool(vp->flag & FKSH), 8605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->name, vp->val.t); 8615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 86203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shf_puts(vp->name, shl_stdout); 86303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shf_putc('\n', shl_stdout); 8645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 866c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } else if (wp[builtin_opt.optind]) { 867c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser for (i = builtin_opt.optind; wp[i]; i++) { 868c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser varsearch(e->loc, &vp, wp[i], hash(wp[i])); 869c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser c_typeset_vardump(vp, flag, thing, pflag, istset); 8705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 871c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } else 872c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser c_typeset_vardump_recursive(e->loc, flag, thing, pflag, istset); 8735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 8745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 8755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 876c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstatic void 877c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserc_typeset_vardump_recursive(struct block *l, uint32_t flag, int thing, 878c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bool pflag, bool istset) 879c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser{ 880c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser struct tbl **blockvars, *vp; 881c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 882c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (l->next) 883c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser c_typeset_vardump_recursive(l->next, flag, thing, pflag, istset); 884c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser blockvars = ktsort(&l->vars); 885c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser while ((vp = *blockvars++)) 886c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser c_typeset_vardump(vp, flag, thing, pflag, istset); 887c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /*XXX doesn’t this leak? */ 888c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser} 889c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 890c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstatic void 891c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserc_typeset_vardump(struct tbl *vp, uint32_t flag, int thing, bool pflag, 892c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bool istset) 893c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser{ 894c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser struct tbl *tvp; 895c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser int any_set = 0; 896c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser char *s; 897c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 898c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (!vp) 899c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return; 900c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 901c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* 902c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * See if the parameter is set (for arrays, if any 903c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * element is set). 904c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser */ 905c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser for (tvp = vp; tvp; tvp = tvp->u.array) 906c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (tvp->flag & ISSET) { 907c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser any_set = 1; 908c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser break; 909c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 910c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 911c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* 912c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * Check attributes - note that all array elements 913c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * have (should have?) the same attributes, so checking 914c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * the first is sufficient. 915c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * 916c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * Report an unset param only if the user has 917c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * explicitly given it some attribute (like export); 918c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * otherwise, after "echo $FOO", we would report FOO... 919c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser */ 920c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (!any_set && !(vp->flag & USERATTRIB)) 921c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return; 922c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (flag && (vp->flag & flag) == 0) 923c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return; 924c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (!(vp->flag & ARRAY)) 925c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* optimise later conditionals */ 926c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser any_set = 0; 927c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser do { 928c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* 929c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * Ignore array elements that aren't set unless there 930c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * are no set elements, in which case the first is 931c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * reported on 932c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser */ 933c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (any_set && !(vp->flag & ISSET)) 934c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser continue; 935c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* no arguments */ 936c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (!thing && !flag) { 937c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (any_set == 1) { 938c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shprintf("%s %s %s\n", Tset, "-A", vp->name); 939c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser any_set = 2; 940c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 941c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* 942c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * AT&T ksh prints things like export, integer, 943c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * leftadj, zerofill, etc., but POSIX says must 944c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * be suitable for re-entry... 945c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser */ 946c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shprintf("%s %s", Ttypeset, ""); 947c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (((vp->flag & (ARRAY | ASSOC)) == ASSOC)) 948c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shprintf("%s ", "-n"); 949c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((vp->flag & INTEGER)) 950c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shprintf("%s ", "-i"); 951c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((vp->flag & EXPORT)) 952c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shprintf("%s ", "-x"); 953c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((vp->flag & RDONLY)) 954c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shprintf("%s ", "-r"); 955c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((vp->flag & TRACE)) 956c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shprintf("%s ", "-t"); 957c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((vp->flag & LJUST)) 958c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shprintf("-L%d ", vp->u2.field); 959c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((vp->flag & RJUST)) 960c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shprintf("-R%d ", vp->u2.field); 961c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((vp->flag & ZEROFIL)) 962c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shprintf("%s ", "-Z"); 963c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((vp->flag & LCASEV)) 964c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shprintf("%s ", "-l"); 965c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((vp->flag & UCASEV_AL)) 966c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shprintf("%s ", "-u"); 967c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((vp->flag & INT_U)) 968c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shprintf("%s ", "-U"); 969c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } else if (pflag) { 970c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shprintf("%s %s", istset ? Ttypeset : 971c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser (flag & EXPORT) ? Texport : Treadonly, ""); 972c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 973c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (any_set) 974c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shprintf("%s[%lu]", vp->name, arrayindex(vp)); 975c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser else 976c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shf_puts(vp->name, shl_stdout); 977c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((!thing && !flag && pflag) || 978c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser (thing == '-' && (vp->flag & ISSET))) { 979c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser s = str_val(vp); 980c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shf_putc('=', shl_stdout); 981c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* AT&T ksh can't have justified integers... */ 982c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((vp->flag & (INTEGER | LJUST | RJUST)) == INTEGER) 983c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shf_puts(s, shl_stdout); 984c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser else 985c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser print_value_quoted(shl_stdout, s); 986c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 987c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shf_putc('\n', shl_stdout); 988c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 989c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* 990c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * Only report first 'element' of an array with 991c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * no set elements. 992c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser */ 993c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (!any_set) 994c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return; 995c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } while ((vp = vp->u.array)); 996c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser} 997c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 9985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 9995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_alias(const char **wp) 10005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 10015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct table *t = &aliases; 10025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv = 0, prefix = 0; 10035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool rflag = false, tflag, Uflag = false, pflag = false; 100403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra uint32_t xflag = 0; 10055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int optc; 10065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru builtin_opt.flags |= GF_PLUSOPT; 10085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt(wp, &builtin_opt, "dprtUx")) != -1) { 10095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru prefix = builtin_opt.info & GI_PLUS ? '+' : '-'; 10105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 10115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'd': 10125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef MKSH_NOPWNAM 10135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = NULL; /* fix "alias -dt" */ 10145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#else 10155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = &homedirs; 10165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 10175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 10185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'p': 10195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru pflag = true; 10205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 10215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'r': 10225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rflag = true; 10235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 10245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 't': 10255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = &taliases; 10265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 10275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'U': 10285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 10295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * kludge for tracked alias initialization 10305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (don't do a path search, just make an entry) 10315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 10325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Uflag = true; 10335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 10345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'x': 10355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru xflag = EXPORT; 10365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 10375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 10385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 10395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef MKSH_NOPWNAM 10425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (t == NULL) 10435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 10445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 10455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 10465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(builtin_opt.info & GI_MINUSMINUS) && *wp && 10485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (wp[0][0] == '-' || wp[0][0] == '+') && wp[0][1] == '\0') { 10495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru prefix = wp[0][0]; 10505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp++; 10515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tflag = t == &taliases; 10545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* "hash -r" means reset all the tracked aliases.. */ 10565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (rflag) { 10575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru static const char *args[] = { 105803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Tunalias, "-ta", NULL 10595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru }; 10605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!tflag || *wp) { 106203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shprintf("%s: -r flag can only be used with -t" 106303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra " and without arguments\n", Talias); 10645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 10655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ksh_getopt_reset(&builtin_opt, GF_ERROR); 10675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (c_unalias(args)); 10685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*wp == NULL) { 10715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *ap, **p; 10725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (p = ktsort(t); (ap = *p++) != NULL; ) 10745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((ap->flag & (ISSET|xflag)) == (ISSET|xflag)) { 10755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (pflag) 107603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shprintf("%s ", Talias); 10775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts(ap->name, shl_stdout); 10785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (prefix != '+') { 10795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_putc('=', shl_stdout); 1080c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser print_value_quoted(shl_stdout, ap->val.s); 10815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_putc('\n', shl_stdout); 10835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; *wp != NULL; wp++) { 10875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *alias = *wp, *val, *newval; 10885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *xalias = NULL; 10895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *ap; 10905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru uint32_t h; 10915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((val = cstrchr(alias, '='))) { 10935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strndupx(xalias, alias, val++ - alias, ATEMP); 10945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru alias = xalias; 10955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru h = hash(alias); 10975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (val == NULL && !tflag && !xflag) { 10985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap = ktsearch(t, alias, h); 10995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ap != NULL && (ap->flag&ISSET)) { 11005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (pflag) 110103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shprintf("%s ", Talias); 11025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts(ap->name, shl_stdout); 11035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (prefix != '+') { 11045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_putc('=', shl_stdout); 1105c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser print_value_quoted(shl_stdout, ap->val.s); 11065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_putc('\n', shl_stdout); 11085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 110903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shprintf("%s %s %s\n", alias, Talias, 111003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra "not found"); 11115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 1; 11125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 11145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap = ktenter(t, alias, h); 11165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap->type = tflag ? CTALIAS : CALIAS; 11175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Are we setting the value or just some flags? */ 11185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((val && !tflag) || (!val && tflag && !Uflag)) { 11195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ap->flag&ALLOC) { 11205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap->flag &= ~(ALLOC|ISSET); 11215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(ap->val.s, APERM); 11225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* ignore values for -t (AT&T ksh does this) */ 112403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra newval = tflag ? 112503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra search_path(alias, path, X_OK, NULL) : 112603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra val; 11275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (newval) { 11285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strdupx(ap->val.s, newval, APERM); 11295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap->flag |= ALLOC|ISSET; 11305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 11315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap->flag &= ~ISSET; 11325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap->flag |= DEFINED; 11345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (prefix == '+') 11355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap->flag &= ~xflag; 11365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 11375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap->flag |= xflag; 11385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(xalias, ATEMP); 11395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 11425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 11435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 11455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_unalias(const char **wp) 11465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 11475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct table *t = &aliases; 11485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *ap; 11495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int optc, rv = 0; 11505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool all = false; 11515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt(wp, &builtin_opt, "adt")) != -1) 11535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 11545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'a': 11555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru all = true; 11565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 11575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'd': 11585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef MKSH_NOPWNAM 115903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* fix "unalias -dt" */ 116003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra t = NULL; 11615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#else 11625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = &homedirs; 11635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 11645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 11655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 't': 11665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = &taliases; 11675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 11685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 11695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 11705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef MKSH_NOPWNAM 11725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (t == NULL) 11735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 11745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 11755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 11765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; *wp != NULL; wp++) { 11785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap = ktsearch(t, *wp, hash(*wp)); 11795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ap == NULL) { 118003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* POSIX */ 118103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 1; 11825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 11835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ap->flag&ALLOC) { 11855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap->flag &= ~(ALLOC|ISSET); 11865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(ap->val.s, APERM); 11875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap->flag &= ~(DEFINED|ISSET|EXPORT); 11895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (all) { 11925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tstate ts; 11935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (ktwalk(&ts, t); (ap = ktnext(&ts)); ) { 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 12035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 12045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 12055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 12075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_let(const char **wp) 12085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 12095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv = 1; 12105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mksh_ari_t val; 12115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 121203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (wp[1] == NULL) 121303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* AT&T ksh does this */ 12145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("no arguments"); 12155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 12165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (wp++; *wp; wp++) 12175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!evaluate(*wp, &val, KSH_RETURN_ERROR, true)) { 121803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* distinguish error from zero result */ 121903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 2; 12205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 12225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = val == 0; 12235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 12245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 12255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 12275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_jobs(const char **wp) 12285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 12295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int optc, flag = 0, nflag = 0, rv = 0; 12305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt(wp, &builtin_opt, "lpnz")) != -1) 12325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 12335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'l': 12345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flag = 1; 12355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'p': 12375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flag = 2; 12385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'n': 12405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nflag = 1; 12415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 124203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'z': 124303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* debugging: print zombies */ 12445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nflag = -1; 12455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 12475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 12485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 12495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 12505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!*wp) { 12515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (j_jobs(NULL, flag, nflag)) 12525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 1; 12535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 12545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; *wp; wp++) 12555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (j_jobs(*wp, flag, nflag)) 12565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 1; 12575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 12585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 12595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 12605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_UNEMPLOYED 12625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 12635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_fgbg(const char **wp) 12645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 12655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool bg = strcmp(*wp, "bg") == 0; 12665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv = 0; 12675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!Flag(FMONITOR)) { 12695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("job control not enabled"); 12705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 12715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 12725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_getopt(wp, &builtin_opt, null) == '?') 12735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 12745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 12755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*wp) 12765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; *wp; wp++) 12775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = j_resume(*wp, bg); 12785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 12795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = j_resume("%%", bg); 12805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (bg ? 0 : rv); 12815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 12825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 12835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* format a single kill item */ 12855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic char * 1286c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserkill_fmt_entry(char *buf, size_t buflen, unsigned int i, const void *arg) 12875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 12885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const struct kill_info *ki = (const struct kill_info *)arg; 12895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru i++; 1291c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shf_snprintf(buf, buflen, "%*u %*s %s", 12925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ki->num_width, i, 12935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ki->name_width, sigtraps[i].name, 12945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sigtraps[i].mess); 12955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (buf); 12965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 12975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 12995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_kill(const char **wp) 13005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 13015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Trap *t = NULL; 13025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *p; 13035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool lflag = false; 13045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int i, n, rv, sig; 13055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* assume old style options if -digits or -UPPERCASE */ 13075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((p = wp[1]) && *p == '-' && (ksh_isdigit(p[1]) || 13085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ksh_isupper(p[1]))) { 1309c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (!(t = gettrap(p + 1, false))) { 13105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("bad signal '%s'", p + 1); 13115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 13125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru i = (wp[2] && strcmp(wp[2], "--") == 0) ? 3 : 2; 13145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 13155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int optc; 13165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt(wp, &builtin_opt, "ls:")) != -1) 13185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 13195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'l': 13205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru lflag = true; 13215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 13225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 's': 13235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(t = gettrap(builtin_opt.optarg, true))) { 13245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("bad signal '%s'", 13255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru builtin_opt.optarg); 13265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 13275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 13295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 13305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 13315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru i = builtin_opt.optind; 13335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((lflag && t) || (!wp[i] && !lflag)) { 13355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_SMALL 13365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts("usage:\tkill [-s signame | -signum | -signame]" 13375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru " { job | pid | pgrp } ...\n" 13385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "\tkill -l [exit_status ...]\n", shl_out); 13395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 13405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorfz(); 13415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 13425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (lflag) { 13455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (wp[i]) { 13465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; wp[i]; i++) { 13475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!bi_getn(wp[i], &n)) 13485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 13495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (n > 128 && n < 128 + NSIG) 13505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru n -= 128; 13515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (n > 0 && n < NSIG) 13525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shprintf("%s\n", sigtraps[n].name); 13535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 13545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shprintf("%d\n", n); 13555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 135703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ssize_t w, mess_cols, mess_octs; 135803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra int j; 13595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct kill_info ki; 13605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (j = NSIG, ki.num_width = 1; j >= 10; j /= 10) 13625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ki.num_width++; 13635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ki.name_width = mess_cols = mess_octs = 0; 13645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (j = 0; j < NSIG; j++) { 13655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru w = strlen(sigtraps[j].name); 13665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (w > ki.name_width) 13675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ki.name_width = w; 13685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru w = strlen(sigtraps[j].mess); 13695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (w > mess_octs) 13705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mess_octs = w; 13715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru w = utf_mbswidth(sigtraps[j].mess); 13725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (w > mess_cols) 13735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mess_cols = w; 13745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1376c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser print_columns(shl_stdout, (unsigned int)(NSIG - 1), 13775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru kill_fmt_entry, (void *)&ki, 13785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ki.num_width + 1 + ki.name_width + 1 + mess_octs, 13795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ki.num_width + 1 + ki.name_width + 1 + mess_cols, 13805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru true); 13815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 13835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 0; 13855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sig = t ? t->signal : SIGTERM; 13865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; (p = wp[i]); i++) { 13875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*p == '%') { 13885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (j_kill(p, sig)) 13895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 1; 13905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (!getn(p, &n)) { 139103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", p, 139203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra "arguments must be jobs or process IDs"); 13935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 1; 13945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 13955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (mksh_kill(n, sig) < 0) { 1396c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bi_errorf("%s: %s", p, cstrerror(errno)); 13975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 1; 13985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 14025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 14035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 14055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querugetopts_reset(int val) 14065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 14075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (val >= 1) { 14085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ksh_getopt_reset(&user_opt, GF_NONAME | GF_PLUSOPT); 14095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru user_opt.optind = user_opt.uoptind = val; 14105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 14125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 14145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_getopts(const char **wp) 14155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 14165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int argc, optc, rv; 14175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *opts, *var; 14185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char buf[3]; 14195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *vq, *voptarg; 14205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_getopt(wp, &builtin_opt, null) == '?') 14225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 14235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 14245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru opts = *wp++; 14265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!opts) { 142703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("missing %s argument", "options"); 14285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 14295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru var = *wp++; 14325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!var) { 143303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("missing %s argument", "name"); 14345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 14355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!*var || *skip_varname(var, true)) { 143703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", var, "is not an identifier"); 14385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 14395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (e->loc->next == NULL) { 144203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra internal_warningf("%s: %s", "c_getopts", "no argv"); 14435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 14445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Which arguments are we parsing... */ 14465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*wp == NULL) 14475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp = e->loc->next->argv; 14485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 14495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *--wp = e->loc->next->argv[0]; 14505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Check that our saved state won't cause a core dump... */ 14525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (argc = 0; wp[argc]; argc++) 14535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 14545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (user_opt.optind > argc || 14555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (user_opt.p != 0 && 14565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru user_opt.p > strlen(wp[user_opt.optind - 1]))) { 14575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("arguments changed since last call"); 14585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 14595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru user_opt.optarg = NULL; 14625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru optc = ksh_getopt(wp, &user_opt, opts); 14635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (optc >= 0 && optc != '?' && (user_opt.info & GI_PLUS)) { 14655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru buf[0] = '+'; 14665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru buf[1] = optc; 14675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru buf[2] = '\0'; 14685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 146903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 147003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * POSIX says var is set to ? at end-of-options, AT&T ksh 14715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * sets it to null - we go with POSIX... 14725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 14735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru buf[0] = optc < 0 ? '?' : optc; 14745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru buf[1] = '\0'; 14755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* AT&T ksh93 in fact does change OPTIND for unknown options too */ 14785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru user_opt.uoptind = user_opt.optind; 14795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru voptarg = global("OPTARG"); 148103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* AT&T ksh clears ro and int */ 148203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra voptarg->flag &= ~RDONLY; 14835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Paranoia: ensure no bizarre results. */ 14845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (voptarg->flag & INTEGER) 14855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru typeset("OPTARG", 0, INTEGER, 0, 0); 14865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (user_opt.optarg == NULL) 14875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unset(voptarg, 1); 14885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 14895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* This can't fail (have cleared readonly/integer) */ 14905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setstr(voptarg, user_opt.optarg, KSH_RETURN_ERROR); 14915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 0; 14935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vq = global(var); 14955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Error message already printed (integer, readonly) */ 14965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!setstr(vq, buf, KSH_RETURN_ERROR)) 149703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 2; 14985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (Flag(FEXPORT)) 14995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru typeset(var, EXPORT, 0, 0, 0); 15005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (optc < 0 ? 1 : rv); 15025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 15035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1504c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifndef MKSH_NO_CMDLINE_EDITING 15055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 15065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_bind(const char **wp) 15075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 15085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int optc, rv = 0; 15095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_SMALL 15105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool macro = false; 15115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 15125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool list = false; 15135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *cp; 15145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *up; 15155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt(wp, &builtin_opt, 15175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_SMALL 15185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "lm" 15195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#else 15205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "l" 15215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 15225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru )) != -1) 15235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 15245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'l': 15255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru list = true; 15265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 15275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_SMALL 15285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'm': 15295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru macro = true; 15305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 15315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 15325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 15335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 15345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 15365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 153703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (*wp == NULL) 153803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* list all */ 15395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = x_bind(NULL, NULL, 15405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_SMALL 15415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru false, 15425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 15435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru list); 15445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; *wp != NULL; wp++) { 15465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((cp = cstrchr(*wp, '=')) == NULL) 15475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru up = NULL; 15485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else { 15495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strdupx(up, *wp, ATEMP); 15505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru up[cp++ - *wp] = '\0'; 15515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (x_bind(up ? up : *wp, cp, 15535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_SMALL 15545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru macro, 15555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 15565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru false)) 15575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 1; 15585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(up, ATEMP); 15595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 15625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 1563c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 15645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 15665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_shift(const char **wp) 15675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 15685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct block *l = e->loc; 15695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int n; 15705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mksh_ari_t val; 15715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *arg; 15725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_getopt(wp, &builtin_opt, null) == '?') 15745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 15755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru arg = wp[builtin_opt.optind]; 15765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (arg) { 15785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru evaluate(arg, &val, KSH_UNWIND_ERROR, false); 15795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru n = val; 15805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 15815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru n = 1; 15825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (n < 0) { 158303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", arg, "bad number"); 15845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 15855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (l->argc < n) { 15875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("nothing to shift"); 15885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 15895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru l->argv[n] = l->argv[0]; 15915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru l->argv += n; 15925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru l->argc -= n; 15935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 15945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 15955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 15975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_umask(const char **wp) 15985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 15995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int i, optc; 16005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *cp; 16015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool symbolic = false; 16025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mode_t old_umask; 16035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt(wp, &builtin_opt, "S")) != -1) 16055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 16065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'S': 16075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru symbolic = true; 16085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 16105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 16115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 16125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru cp = wp[builtin_opt.optind]; 16135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (cp == NULL) { 16145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru old_umask = umask((mode_t)0); 16155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru umask(old_umask); 16165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (symbolic) { 16175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char buf[18], *p; 16185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int j; 16195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru old_umask = ~old_umask; 16215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p = buf; 16225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (i = 0; i < 3; i++) { 16235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *p++ = "ugo"[i]; 16245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *p++ = '='; 16255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (j = 0; j < 3; j++) 16265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (old_umask & (1 << (8 - (3*i + j)))) 16275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *p++ = "rwx"[j]; 16285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *p++ = ','; 16295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 16305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p[-1] = '\0'; 16315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shprintf("%s\n", buf); 16325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 16335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shprintf("%#3.3o\n", (unsigned int)old_umask); 16345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 16355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mode_t new_umask; 16365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_isdigit(*cp)) { 16385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (new_umask = 0; *cp >= '0' && *cp <= '7'; cp++) 16395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru new_umask = new_umask * 8 + (*cp - '0'); 16405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*cp) { 16415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("bad number"); 16425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 16435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 16445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 16455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* symbolic format */ 16465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int positions, new_val; 16475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char op; 16485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru old_umask = umask((mode_t)0); 165003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* in case of error */ 165103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra umask(old_umask); 16525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru old_umask = ~old_umask; 16535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru new_umask = old_umask; 16545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru positions = 0; 16555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (*cp) { 16565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (*cp && vstrchr("augo", *cp)) 16575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (*cp++) { 16585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'a': 16595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru positions |= 0111; 16605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'u': 16625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru positions |= 0100; 16635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'g': 16655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru positions |= 0010; 16665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'o': 16685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru positions |= 0001; 16695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 16715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!positions) 167203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* default is a */ 167303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra positions = 0111; 16745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!vstrchr("=+-", op = *cp)) 16755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru cp++; 16775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru new_val = 0; 16785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (*cp && vstrchr("rwxugoXs", *cp)) 16795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (*cp++) { 16805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'r': new_val |= 04; break; 16815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'w': new_val |= 02; break; 16825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'x': new_val |= 01; break; 16835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'u': 16845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru new_val |= old_umask >> 6; 16855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'g': 16875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru new_val |= old_umask >> 3; 16885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'o': 16905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru new_val |= old_umask >> 0; 16915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'X': 16935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (old_umask & 0111) 16945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru new_val |= 01; 16955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 's': 16975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* ignored */ 16985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru new_val = (new_val & 07) * positions; 17015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (op) { 17025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '-': 17035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru new_umask &= ~new_val; 17045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 17055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '=': 17065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru new_umask = new_val | 17075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (new_umask & ~(positions * 07)); 17085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 17095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '+': 17105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru new_umask |= new_val; 17115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*cp == ',') { 17135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru positions = 0; 17145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru cp++; 17155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (!vstrchr("=+-", *cp)) 17165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 17175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*cp) { 17195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("bad mask"); 17205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 17215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru new_umask = ~new_umask; 17235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru umask(new_umask); 17255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 17275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 17285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 17305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_dot(const char **wp) 17315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 17325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *file, *cp, **argv; 17335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int argc, i, errcode; 17345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_getopt(wp, &builtin_opt, null) == '?') 17365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 17375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((cp = wp[builtin_opt.optind]) == NULL) { 17395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("missing argument"); 17405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 17415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 174203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((file = search_path(cp, path, R_OK, &errcode)) == NULL) { 1743c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bi_errorf("%s: %s", cp, cstrerror(errcode)); 17445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 17455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Set positional parameters? */ 17485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (wp[builtin_opt.optind + 1]) { 17495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru argv = wp + builtin_opt.optind; 175003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* preserve $0 */ 175103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra argv[0] = e->loc->argv[0]; 17525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (argc = 0; argv[argc + 1]; argc++) 17535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 17545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 17555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru argc = 0; 17565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru argv = NULL; 17575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 1758c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((i = include(file, argc, argv, false)) < 0) { 17595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* should not happen */ 1760c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bi_errorf("%s: %s", cp, cstrerror(errno)); 17615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 17625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (i); 17645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 17655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 17675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_wait(const char **wp) 17685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 17695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv = 0, sig; 17705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_getopt(wp, &builtin_opt, null) == '?') 17725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 17735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 17745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*wp == NULL) { 17755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (waitfor(NULL, &sig) >= 0) 17765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 17775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = sig; 17785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 17795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; *wp; wp++) 17805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = waitfor(*wp, &sig); 17815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (rv < 0) 178203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* magic exit code: bad job-id */ 178303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = sig ? sig : 127; 17845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 17865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 17875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1788c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstatic char REPLY[] = "REPLY"; 17895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 17905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_read(const char **wp) 17915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 179203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define is_ifsws(c) (ctype((c), C_IFS) && ctype((c), C_IFSWS)) 179303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra int c, fd = 0, rv = 0, lastparm = 0; 179403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bool savehist = false, intoarray = false, aschars = false; 179503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bool rawmode = false, expanding = false; 179603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra enum { LINES, BYTES, UPTO, READALL } readmode = LINES; 179703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra char delim = '\n'; 179803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra size_t bytesleft = 128, bytesread; 179903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra struct tbl *vp /* FU gcc */ = NULL, *vq; 180003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra char *cp, *allocd = NULL, *xp; 180103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra const char *ccp; 180203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra XString xs; 180303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ptrdiff_t xsave = 0; 1804c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser mksh_ttyst tios; 180503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bool restore_tios = false; 180603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#if HAVE_SELECT 180703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bool hastimeout = false; 180803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra struct timeval tv, tvlim; 180903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define c_read_opts "Aad:N:n:prst:u," 181003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#else 181103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define c_read_opts "Aad:N:n:prsu," 181203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 18135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 181403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while ((c = ksh_getopt(wp, &builtin_opt, c_read_opts)) != -1) 181503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra switch (c) { 181603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'a': 181703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra aschars = true; 181803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* FALLTHROUGH */ 181903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'A': 182003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra intoarray = true; 182103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 182203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'd': 182303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra delim = builtin_opt.optarg[0]; 182403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 182503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'N': 182603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'n': 182703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra readmode = c == 'N' ? BYTES : UPTO; 182803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!bi_getn(builtin_opt.optarg, &c)) 182903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (2); 183003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (c == -1) { 183103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra readmode = READALL; 183203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bytesleft = 1024; 183303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else 183403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bytesleft = (unsigned int)c; 183503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 183603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'p': 183703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((fd = coproc_getfd(R_OK, &ccp)) < 0) { 183803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", "-p", ccp); 183903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (2); 18405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 184103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 184203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'r': 184303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rawmode = true; 184403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 184503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 's': 184603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra savehist = true; 184703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 184803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#if HAVE_SELECT 184903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 't': 185003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (parse_usec(builtin_opt.optarg, &tv)) { 1851c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bi_errorf("%s: %s '%s'", Tsynerr, cstrerror(errno), 185203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra builtin_opt.optarg); 185303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (2); 185403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 185503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra hastimeout = true; 185603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 185703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 185803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'u': 185903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!builtin_opt.optarg[0]) 186003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra fd = 0; 186103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else if ((fd = check_fd(builtin_opt.optarg, R_OK, &ccp)) < 0) { 186203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s: %s", "-u", builtin_opt.optarg, ccp); 186303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (2); 186403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 186503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 186603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case '?': 186703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (2); 186803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 18695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 18705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*wp == NULL) 18715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *--wp = REPLY; 18725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 187303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (intoarray && wp[1] != NULL) { 187403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("too many arguments"); 187503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (2); 187603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 18775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 187803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((ccp = cstrchr(*wp, '?')) != NULL) { 187903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra strdupx(allocd, *wp, ATEMP); 188003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra allocd[ccp - *wp] = '\0'; 188103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra *wp = allocd; 18825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (isatty(fd)) { 188303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 188403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * AT&T ksh says it prints prompt on fd if it's open 18855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * for writing and is a tty, but it doesn't do it 18865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (it also doesn't check the interactive flag, 188703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * as is indicated in the Korn Shell book). 18885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 188903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shf_puts(ccp + 1, shl_out); 189003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shf_flush(shl_out); 18915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 18925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 18935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 189403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xinit(xs, xp, bytesleft, ATEMP); 18955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 189603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (readmode == LINES) 189703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bytesleft = 1; 189803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else if (isatty(fd)) { 189903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra x_mkraw(fd, &tios, true); 190003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra restore_tios = true; 190103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 19025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 190303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#if HAVE_SELECT 190403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (hastimeout) { 1905c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser mksh_TIME(tvlim); 190603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra timeradd(&tvlim, &tv, &tvlim); 190703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 190803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 190903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 191003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c_read_readloop: 191103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#if HAVE_SELECT 191203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (hastimeout) { 191303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra fd_set fdset; 191403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 191503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra FD_ZERO(&fdset); 1916c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser FD_SET((unsigned int)fd, &fdset); 1917c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser mksh_TIME(tv); 191803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra timersub(&tvlim, &tv, &tv); 191903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (tv.tv_sec < 0) { 192003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* timeout expired globally */ 192103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 1; 192203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_out; 192303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 192403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 192503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra switch (select(fd + 1, &fdset, NULL, NULL, &tv)) { 192603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 1: 192703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 192803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 0: 192903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* timeout expired for this call */ 193003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 1; 193103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_out; 193203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra default: 1933c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bi_errorf("%s: %s", Tselect, cstrerror(errno)); 193403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 2; 193503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_out; 193603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 193703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 193803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 193903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 194003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bytesread = blocking_read(fd, xp, bytesleft); 194103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (bytesread == (size_t)-1) { 194203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* interrupted */ 194303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (errno == EINTR && fatal_trap_check()) { 194403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 194503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Was the offending signal one that would 194603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * normally kill a process? If so, pretend 194703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * the read was killed. 194803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra */ 194903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 2; 195003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_out; 195103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 195203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* just ignore the signal */ 195303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_readloop; 195403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 195503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 195603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra switch (readmode) { 195703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case READALL: 195803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (bytesread == 0) { 195903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* end of file reached */ 196003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 1; 196103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_readdone; 196203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 196303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xp += bytesread; 196403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra XcheckN(xs, xp, bytesleft); 196503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 196603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 196703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case UPTO: 196803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (bytesread == 0) 196903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* end of file reached */ 197003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 1; 197103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xp += bytesread; 197203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_readdone; 197303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 197403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case BYTES: 197503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (bytesread == 0) { 197603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* end of file reached */ 197703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 1; 197803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xp = Xstring(xs, xp); 197903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_readdone; 198003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 198103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xp += bytesread; 198203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((bytesleft -= bytesread) == 0) 198303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_readdone; 198403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 198503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case LINES: 198603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (bytesread == 0) { 198703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* end of file reached */ 198803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 1; 198903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_readdone; 199003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 199103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((c = *xp) == '\0' && !aschars && delim != '\0') { 199203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* skip any read NULs unless delimiter */ 199303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 199403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 199503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (expanding) { 199603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra expanding = false; 199703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (c == delim) { 199803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (Flag(FTALKING_I) && isatty(fd)) { 199903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 200003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * set prompt in case this is 200103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * called from .profile or $ENV 200203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra */ 200303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra set_prompt(PS2, NULL); 200403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra pprompt(prompt, 0); 20055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 200603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* drop the backslash */ 200703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra --xp; 200803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* and the delimiter */ 20095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 20105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 201103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else if (c == delim) { 201203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_readdone; 201303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else if (!rawmode && c == '\\') { 201403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra expanding = true; 201503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 201603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xcheck(xs, xp); 201703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++xp; 201803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 201903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 202003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_readloop; 202103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 202203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c_read_readdone: 202303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bytesread = Xlength(xs, xp); 202403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xput(xs, xp, '\0'); 202503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 202603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /*- 202703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * state: we finished reading the input and NUL terminated it 202803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Xstring(xs, xp) -> xp-1 = input string without trailing delim 202903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * rv = 1 if EOF, 0 otherwise (errors handled already) 203003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra */ 203103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 203203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (rv == 1) { 203303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* clean up coprocess if needed, on EOF */ 203403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra coproc_read_close(fd); 203503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (readmode == READALL) 203603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* EOF is no error here */ 203703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 0; 203803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 203903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 204003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (savehist) 204103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra histsave(&source->line, Xstring(xs, xp), true, false); 204203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 204303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ccp = cp = Xclose(xs, xp); 204403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra expanding = false; 204503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra XinitN(xs, 128, ATEMP); 204603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (intoarray) { 20475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp = global(*wp); 20485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vp->flag & RDONLY) { 204903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c_read_splitro: 2050c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bi_errorf("read-only: %s", *wp); 205103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c_read_spliterr: 205203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 2; 205303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra afree(cp, ATEMP); 205403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_out; 205503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 205603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* exporting an array is currently pointless */ 205703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra unset(vp, 1); 205803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* counter for array index */ 205903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c = 0; 206003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 206103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!aschars) { 206203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* skip initial IFS whitespace */ 206303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (bytesread && is_ifsws(*ccp)) { 206403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++ccp; 206503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra --bytesread; 206603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 206703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* trim trailing IFS whitespace */ 206803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (bytesread && is_ifsws(ccp[bytesread - 1])) { 206903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra --bytesread; 207003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 207103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 207203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c_read_splitloop: 207303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xp = Xstring(xs, xp); 207403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* generate next word */ 207503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!bytesread) { 207603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* no more input */ 207703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (intoarray) 207803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_splitdone; 207903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* zero out next parameters */ 208003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_gotword; 208103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 208203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (aschars) { 208303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xput(xs, xp, '1'); 208403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xput(xs, xp, '#'); 208503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bytesleft = utf_ptradj(ccp); 208603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (bytesleft && bytesread) { 208703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra *xp++ = *ccp++; 208803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra --bytesleft; 208903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra --bytesread; 209003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 209103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (xp[-1] == '\0') { 209203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xp[-1] = '0'; 209303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xp[-3] = '2'; 209403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 209503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_gotword; 209603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 209703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 209803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!intoarray && wp[1] == NULL) 209903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra lastparm = 1; 210003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 210103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c_read_splitlast: 210203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* copy until IFS character */ 210303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (bytesread) { 210403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra char ch; 210503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 210603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ch = *ccp; 210703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (expanding) { 210803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra expanding = false; 210903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_splitcopy; 211003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else if (ctype(ch, C_IFS)) { 211103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 211203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else if (!rawmode && ch == '\\') { 211303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra expanding = true; 211403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else { 211503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c_read_splitcopy: 211603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xcheck(xs, xp); 211703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xput(xs, xp, ch); 21185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 211903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++ccp; 212003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra --bytesread; 212103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 212203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xsave = Xsavepos(xs, xp); 212303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* copy word delimiter: IFSWS+IFS,IFSWS */ 212403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (bytesread) { 212503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra char ch; 212603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 212703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ch = *ccp; 212803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!ctype(ch, C_IFS)) 212903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 213003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xcheck(xs, xp); 213103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xput(xs, xp, ch); 213203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++ccp; 213303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra --bytesread; 213403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!ctype(ch, C_IFSWS)) 213503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 213603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 213703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (bytesread && is_ifsws(*ccp)) { 213803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xcheck(xs, xp); 213903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xput(xs, xp, *ccp); 214003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++ccp; 214103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra --bytesread; 214203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 214303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* if no more parameters, rinse and repeat */ 214403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (lastparm && bytesread) { 214503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++lastparm; 214603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_splitlast; 214703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 214803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* get rid of the delimiter unless we pack the rest */ 214903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (lastparm < 2) 215003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xp = Xrestpos(xs, xp, xsave); 215103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c_read_gotword: 215203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xput(xs, xp, '\0'); 215303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (intoarray) { 215403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vq = arraysearch(vp, c++); 215503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else { 215603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vq = global(*wp); 215703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* must be checked before exporting */ 215803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (vq->flag & RDONLY) 215903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_splitro; 21605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (Flag(FEXPORT)) 21615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru typeset(*wp, EXPORT, 0, 0, 0); 21625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 216303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!setstr(vq, Xstring(xs, xp), KSH_RETURN_ERROR)) 216403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_spliterr; 216503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (aschars) { 216603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra setint_v(vq, vq, false); 216703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* protect from UTFMODE changes */ 216803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vq->type = 0; 21695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 217003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (intoarray || *++wp != NULL) 217103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_splitloop; 217203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 217303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c_read_splitdone: 217403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* free up */ 217503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra afree(cp, ATEMP); 21765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 217703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c_read_out: 217803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra afree(allocd, ATEMP); 217903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xfree(xs, xp); 218003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (restore_tios) 2181c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser mksh_tcset(fd, &tios); 218203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (rv); 218303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#undef is_ifsws 21845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 21855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 21865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 21875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_eval(const char **wp) 21885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 21895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct source *s, *saves = source; 21905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unsigned char savef; 21915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv; 21925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 21935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_getopt(wp, &builtin_opt, null) == '?') 21945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 21955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = pushs(SWORDS, ATEMP); 21965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->u.strv = wp + builtin_opt.optind; 21975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 21985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /*- 21995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * The following code handles the case where the command is 22005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * empty due to failed command substitution, for example by 22015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * eval "$(false)" 22025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * This has historically returned 1 by AT&T ksh88. In this 22035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * case, shell() will not set or change exstat because the 22045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * compiled tree is empty, so it will use the value we pass 22055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * from subst_exstat, which is cleared in execute(), so it 22065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * should have been 0 if there were no substitutions. 22075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 22085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * POSIX however says we don't do this, even though it is 22095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * traditionally done. AT&T ksh93 agrees with POSIX, so we 22105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * do. The following is an excerpt from SUSv4 [1003.2-2008]: 22115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 22125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 2.9.1: Simple Commands 22135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * ... If there is a command name, execution shall 22145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * continue as described in 2.9.1.1 [Command Search 22155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * and Execution]. If there is no command name, but 22165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * the command contained a command substitution, the 22175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * command shall complete with the exit status of the 22185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * last command substitution performed. 22195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 2.9.1.1: Command Search and Execution 22205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (1) a. If the command name matches the name of a 22215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * special built-in utility, that special built-in 22225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * utility shall be invoked. 22235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 2.14.5: eval 22245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * If there are no arguments, or only null arguments, 22255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * eval shall return a zero exit status; ... 22265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 2227c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* AT&T ksh88: use subst_exstat */ 2228c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* exstat = subst_exstat; */ 2229c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* SUSv4: OR with a high value never written otherwise */ 2230c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser exstat |= 0x4000; 22315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 22325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru savef = Flag(FERREXIT); 2233c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser Flag(FERREXIT) |= 0x80; 22345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = shell(s, false); 22355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Flag(FERREXIT) = savef; 22365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source = saves; 22375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(s, ATEMP); 2238c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (exstat & 0x4000) 2239c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* detect old exstat, use 0 in that case */ 2240c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser rv = 0; 22415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 22425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 22435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 22445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 22455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_trap(const char **wp) 22465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 22475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int i; 22485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *s; 22495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Trap *p; 22505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 22515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_getopt(wp, &builtin_opt, null) == '?') 22525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 22535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 22545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 22555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*wp == NULL) { 22565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (p = sigtraps, i = NSIG+1; --i >= 0; p++) 22575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (p->trap != NULL) { 22585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts("trap -- ", shl_stdout); 2259c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser print_value_quoted(shl_stdout, p->trap); 22605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shprintf(" %s\n", p->name); 22615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 22625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 22635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 22645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 22655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 22665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Use case sensitive lookup for first arg so the 22675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * command 'exit' isn't confused with the pseudo-signal 22685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 'EXIT'. 22695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 227003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* get command */ 227103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra s = (gettrap(*wp, false) == NULL) ? *wp++ : NULL; 22725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s != NULL && s[0] == '-' && s[1] == '\0') 22735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = NULL; 22745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 22755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* set/clear traps */ 227603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra i = 0; 227703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (*wp != NULL) 227803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((p = gettrap(*wp++, true)) == NULL) { 227903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra warningf(true, "%s: %s '%s'", builtin_argv0, 228003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra "bad signal", wp[-1]); 228103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++i; 228203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else 228303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra settrap(p, s); 228403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (i); 22855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 22865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 22875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 22885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_exitreturn(const char **wp) 22895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 22905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int n, how = LEXIT; 22915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *arg; 22925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 22935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_getopt(wp, &builtin_opt, null) == '?') 2294c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto c_exitreturn_err; 22955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru arg = wp[builtin_opt.optind]; 22965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 22975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (arg) { 22985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!getn(arg, &n)) { 22995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru exstat = 1; 230003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra warningf(true, "%s: %s", arg, "bad number"); 23015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 2302c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser exstat = n & 0xFF; 230303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else if (trap_exstat != -1) 230403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra exstat = trap_exstat; 230503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (wp[0][0] == 'r') { 230603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* return */ 23075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct env *ep; 23085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 230903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 231003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * need to tell if this is exit or return so trap exit will 23115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * work right (POSIX) 23125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 23135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (ep = e; ep; ep = ep->oenv) 23145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (STOP_RETURN(ep->type)) { 23155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru how = LRETURN; 23165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 23175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 23185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 23195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 23205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (how == LEXIT && !really_exit && j_stopped_running()) { 2321c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser really_exit = true; 23225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru how = LSHELL; 23235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 23245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 232503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* get rid of any i/o redirections */ 232603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra quitenv(NULL); 23275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unwind(how); 23285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* NOTREACHED */ 2329c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 2330c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser c_exitreturn_err: 2331c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return (1); 23325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 23335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 23345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 23355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_brkcont(const char **wp) 23365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 2337c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser unsigned int quit; 2338c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser int n; 23395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct env *ep, *last_ep = NULL; 23405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *arg; 23415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 23425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_getopt(wp, &builtin_opt, null) == '?') 2343c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto c_brkcont_err; 23445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru arg = wp[builtin_opt.optind]; 23455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 23465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!arg) 23475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru n = 1; 23485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (!bi_getn(arg, &n)) 2349c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto c_brkcont_err; 2350c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (n <= 0) { 23515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* AT&T ksh does this for non-interactive shells only - weird */ 235203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", arg, "bad value"); 2353c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto c_brkcont_err; 23545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2355c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser quit = (unsigned int)n; 23565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 23575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Stop at E_NONE, E_PARSE, E_FUNC, or E_INCL */ 23585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (ep = e; ep && !STOP_BRKCONT(ep->type); ep = ep->oenv) 23595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ep->type == E_LOOP) { 23605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (--quit == 0) 23615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 23625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ep->flags |= EF_BRKCONT_PASS; 23635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru last_ep = ep; 23645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 23655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 23665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (quit) { 236703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 236803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * AT&T ksh doesn't print a message - just does what it 23695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * can. We print a message 'cause it helps in debugging 23705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * scripts, but don't generate an error (ie, keep going). 23715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 2372c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((unsigned int)n == quit) { 237303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra warningf(true, "%s: %s %s", wp[0], "can't", wp[0]); 23745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 23755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 237603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 237703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * POSIX says if n is too big, the last enclosing loop 23785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * shall be used. Doesn't say to print an error but we 23795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * do anyway 'cause the user messed up. 23805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 23815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (last_ep) 23825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru last_ep->flags &= ~EF_BRKCONT_PASS; 2383c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser warningf(true, "%s: can only %s %u level(s)", 2384c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser wp[0], wp[0], (unsigned int)n - quit); 23855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 23865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 23875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unwind(*wp[0] == 'b' ? LBREAK : LCONTIN); 23885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* NOTREACHED */ 2389c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 2390c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser c_brkcont_err: 2391c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return (1); 23925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 23935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 23945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 23955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_set(const char **wp) 23965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 23975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int argi; 23985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool setargs; 23995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct block *l = e->loc; 24005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char **owp; 24015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 24025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (wp[1] == NULL) { 240303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra static const char *args[] = { Tset, "-", NULL }; 24045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (c_typeset(args)); 24055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 24065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 24075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru argi = parse_args(wp, OF_SET, &setargs); 24085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (argi < 0) 24095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 24105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* set $# and $* */ 24115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (setargs) { 24125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += argi - 1; 24135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru owp = wp; 241403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* save $0 */ 241503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra wp[0] = l->argv[0]; 24165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (*++wp != NULL) 24175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strdupx(*wp, *wp, &l->area); 24185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru l->argc = wp - owp - 1; 241903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra l->argv = alloc2(l->argc + 2, sizeof(char *), &l->area); 24205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (wp = l->argv; (*wp++ = *owp++) != NULL; ) 24215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 24225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 24235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /*- 24245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * POSIX says set exit status is 0, but old scripts that use 24255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * getopt(1) use the construct 24265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * set -- $(getopt ab:c "$@") 24275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * which assumes the exit value set will be that of the $() 24285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (subst_exstat is cleared in execute() so that it will be 0 24295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * if there are no command substitutions). 24305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Switched ksh (!posix !sh) to POSIX in mksh R39b. 24315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 2432c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef MKSH_LEGACY_MODE 2433c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return (subst_exstat); 2434c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#else 24355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (Flag(FSH) ? subst_exstat : 0); 2436c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 24375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 24385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 24395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 24405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_unset(const char **wp) 24415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 24425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *id; 244303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra int optc, rv = 0; 24445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool unset_var = true; 24455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 24465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt(wp, &builtin_opt, "fv")) != -1) 24475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 24485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'f': 24495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unset_var = false; 24505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 24515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'v': 24525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unset_var = true; 24535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 24545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 245503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /*XXX not reached due to GF_ERROR */ 245603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (2); 24575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 24585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 24595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; (id = *wp) != NULL; wp++) 246003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (unset_var) { 246103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* unset variable */ 24625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *vp; 24635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *cp = NULL; 24645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru size_t n; 24655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 24665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru n = strlen(id); 24675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (n > 3 && id[n-3] == '[' && id[n-2] == '*' && 24685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru id[n-1] == ']') { 24695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strndupx(cp, id, n - 3, ATEMP); 24705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru id = cp; 24715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru optc = 3; 24725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 24735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru optc = vstrchr(id, '[') ? 0 : 1; 24745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 24755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp = global(id); 24765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(cp, ATEMP); 24775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 24785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vp->flag&RDONLY)) { 2479c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser warningf(true, "read-only: %s", vp->name); 248003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 1; 248103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else 248203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra unset(vp, optc); 248303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else 248403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* unset function */ 24855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru define(id, NULL); 248603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (rv); 24875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 24885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 24895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 24905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querup_time(struct shf *shf, bool posix, long tv_sec, int tv_usec, int width, 24915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *prefix, const char *suffix) 24925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 24935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tv_usec /= 10000; 24945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (posix) 24955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_fprintf(shf, "%s%*ld.%02d%s", prefix, width, 24965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tv_sec, tv_usec, suffix); 24975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 24985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_fprintf(shf, "%s%*ldm%d.%02ds%s", prefix, width, 24995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tv_sec / 60, (int)(tv_sec % 60), tv_usec, suffix); 25005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 25015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 25025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 25035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_times(const char **wp MKSH_A_UNUSED) 25045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 25055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct rusage usage; 25065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 25075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru getrusage(RUSAGE_SELF, &usage); 25085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p_time(shl_stdout, false, usage.ru_utime.tv_sec, 25095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru usage.ru_utime.tv_usec, 0, null, " "); 25105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p_time(shl_stdout, false, usage.ru_stime.tv_sec, 25115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru usage.ru_stime.tv_usec, 0, null, "\n"); 25125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 25135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru getrusage(RUSAGE_CHILDREN, &usage); 25145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p_time(shl_stdout, false, usage.ru_utime.tv_sec, 25155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru usage.ru_utime.tv_usec, 0, null, " "); 25165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p_time(shl_stdout, false, usage.ru_stime.tv_sec, 25175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru usage.ru_stime.tv_usec, 0, null, "\n"); 25185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 25195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 25205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 25215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 25225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 25235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * time pipeline (really a statement, not a built-in command) 25245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 25255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 25265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutimex(struct op *t, int f, volatile int *xerrok) 25275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 25285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define TF_NOARGS BIT(0) 25295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define TF_NOREAL BIT(1) /* don't report real time */ 25305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define TF_POSIX BIT(2) /* report in POSIX format */ 25315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv = 0, tf = 0; 25325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct rusage ru0, ru1, cru0, cru1; 25335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct timeval usrtime, systime, tv0, tv1; 25345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2535c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser mksh_TIME(tv0); 25365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru getrusage(RUSAGE_SELF, &ru0); 25375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru getrusage(RUSAGE_CHILDREN, &cru0); 25385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (t->left) { 25395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 25405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Two ways of getting cpu usage of a command: just use t0 25415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * and t1 (which will get cpu usage from other jobs that 25425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * finish while we are executing t->left), or get the 25435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * cpu usage of t->left. AT&T ksh does the former, while 25445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * pdksh tries to do the later (the j_usrtime hack doesn't 25455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * really work as it only counts the last job). 25465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 25475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru timerclear(&j_usrtime); 25485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru timerclear(&j_systime); 25495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = execute(t->left, f | XTIME, xerrok); 25505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (t->left->type == TCOM) 25515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tf |= t->left->str[0]; 2552c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser mksh_TIME(tv1); 25535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru getrusage(RUSAGE_SELF, &ru1); 25545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru getrusage(RUSAGE_CHILDREN, &cru1); 25555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 25565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tf = TF_NOARGS; 25575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 255803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (tf & TF_NOARGS) { 255903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* ksh93 - report shell times (shell+kids) */ 25605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tf |= TF_NOREAL; 25615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru timeradd(&ru0.ru_utime, &cru0.ru_utime, &usrtime); 25625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru timeradd(&ru0.ru_stime, &cru0.ru_stime, &systime); 25635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 25645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru timersub(&ru1.ru_utime, &ru0.ru_utime, &usrtime); 25655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru timeradd(&usrtime, &j_usrtime, &usrtime); 25665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru timersub(&ru1.ru_stime, &ru0.ru_stime, &systime); 25675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru timeradd(&systime, &j_systime, &systime); 25685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 25695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 25705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(tf & TF_NOREAL)) { 25715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru timersub(&tv1, &tv0, &tv1); 25725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tf & TF_POSIX) 25735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p_time(shl_out, true, tv1.tv_sec, tv1.tv_usec, 25745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5, "real ", "\n"); 25755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 25765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p_time(shl_out, false, tv1.tv_sec, tv1.tv_usec, 25775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5, null, " real "); 25785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 25795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tf & TF_POSIX) 25805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p_time(shl_out, true, usrtime.tv_sec, usrtime.tv_usec, 25815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5, "user ", "\n"); 25825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 25835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p_time(shl_out, false, usrtime.tv_sec, usrtime.tv_usec, 25845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5, null, " user "); 25855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tf & TF_POSIX) 25865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p_time(shl_out, true, systime.tv_sec, systime.tv_usec, 25875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5, "sys ", "\n"); 25885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 25895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p_time(shl_out, false, systime.tv_sec, systime.tv_usec, 25905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5, null, " system\n"); 25915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_flush(shl_out); 25925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 25935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 25945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 25955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 25965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 25975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutimex_hook(struct op *t, char **volatile *app) 25985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 25995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char **wp = *app; 26005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int optc, i, j; 26015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Getopt opt; 26025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 26035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ksh_getopt_reset(&opt, 0); 260403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* start at the start */ 260503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra opt.optind = 0; 26065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt((const char **)wp, &opt, ":p")) != -1) 26075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 26085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'p': 26095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->str[0] |= TF_POSIX; 26105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 26115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 261203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra errorf("time: -%s %s", opt.optarg, 261303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra "unknown option"); 26145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case ':': 261503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra errorf("time: -%s %s", opt.optarg, 261603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra "requires an argument"); 26175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 26185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Copy command words down over options. */ 26195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (opt.optind != 0) { 26205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (i = 0; i < opt.optind; i++) 26215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(wp[i], ATEMP); 26225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (i = 0, j = opt.optind; (wp[i] = wp[j]); i++, j++) 26235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 26245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 26255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!wp[0]) 26265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->str[0] |= TF_NOARGS; 26275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *app = wp; 26285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 26295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 26305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* exec with no args - args case is taken care of in comexec() */ 26315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 26325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_exec(const char **wp MKSH_A_UNUSED) 26335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 26345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int i; 26355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 26365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* make sure redirects stay in place */ 26375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (e->savefd != NULL) { 26385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (i = 0; i < NUFILE; i++) { 26395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (e->savefd[i] > 0) 26405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru close(e->savefd[i]); 2641c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifndef MKSH_LEGACY_MODE 26425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 26435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * keep all file descriptors > 2 private for ksh, 26445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * but not for POSIX or legacy/kludge sh 26455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 26465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!Flag(FPOSIX) && !Flag(FSH) && i > 2 && 26475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru e->savefd[i]) 26485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fcntl(i, F_SETFD, FD_CLOEXEC); 2649c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 26505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 26515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru e->savefd = NULL; 26525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 26535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 26545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 26555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 26565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if HAVE_MKNOD 26575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 26585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_mknod(const char **wp) 26595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 26605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int argc, optc, rv = 0; 26615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool ismkfifo = false; 26625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char **argv; 26635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru void *set = NULL; 26645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mode_t mode = 0, oldmode = 0; 26655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 26665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt(wp, &builtin_opt, "m:")) != -1) { 26675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 26685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'm': 26695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru set = setmode(builtin_opt.optarg); 26705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (set == NULL) { 26715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("invalid file mode"); 26725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 26735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 26745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mode = getmode(set, (mode_t)(DEFFILEMODE)); 267503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra free_ossetmode(set); 26765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 26775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 26785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto c_mknod_usage; 26795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 26805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 26815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru argv = &wp[builtin_opt.optind]; 26825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (argv[0] == NULL) 26835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto c_mknod_usage; 26845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (argc = 0; argv[argc]; argc++) 26855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 26865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (argc == 2 && argv[1][0] == 'p') 26875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ismkfifo = true; 26885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (argc != 4 || (argv[1][0] != 'b' && argv[1][0] != 'c')) 26895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto c_mknod_usage; 26905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 26915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (set != NULL) 26925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru oldmode = umask((mode_t)0); 26935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 26945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mode = DEFFILEMODE; 26955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 26965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mode |= (argv[1][0] == 'b') ? S_IFBLK : 26975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (argv[1][0] == 'c') ? S_IFCHR : 0; 26985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 26995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!ismkfifo) { 27005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unsigned long majnum, minnum; 27015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru dev_t dv; 27025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *c; 27035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 27045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru majnum = strtoul(argv[2], &c, 0); 27055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c == argv[2]) || (*c != '\0')) { 270603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("non-numeric %s %s '%s'", "device", "major", argv[2]); 27075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto c_mknod_err; 27085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 27095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru minnum = strtoul(argv[3], &c, 0); 27105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c == argv[3]) || (*c != '\0')) { 271103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("non-numeric %s %s '%s'", "device", "minor", argv[3]); 27125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto c_mknod_err; 27135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 27145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru dv = makedev(majnum, minnum); 27155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((unsigned long)(major(dv)) != majnum) { 271603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s %s too large: %lu", "device", "major", majnum); 27175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto c_mknod_err; 27185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 27195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((unsigned long)(minor(dv)) != minnum) { 272003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s %s too large: %lu", "device", "minor", minnum); 27215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto c_mknod_err; 27225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 27235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (mknod(argv[0], mode, dv)) 27245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto c_mknod_failed; 27255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (mkfifo(argv[0], mode)) { 27265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c_mknod_failed: 2727c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bi_errorf("%s: %s", argv[0], cstrerror(errno)); 27285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c_mknod_err: 27295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 1; 27305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 27315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 27325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (set) 27335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru umask(oldmode); 27345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 27355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c_mknod_usage: 273603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", "usage", "mknod [-m mode] name b|c major minor"); 273703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", "usage", "mknod [-m mode] name p"); 27385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 27395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 27405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 27415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 274203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/*- 2743c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser test(1) roughly accepts the following grammar: 27445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru oexpr ::= aexpr | aexpr "-o" oexpr ; 27455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru aexpr ::= nexpr | nexpr "-a" aexpr ; 27465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nexpr ::= primary | "!" nexpr ; 27475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru primary ::= unary-operator operand 27485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru | operand binary-operator operand 27495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru | operand 27505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru | "(" oexpr ")" 27515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 27525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 27535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unary-operator ::= "-a"|"-r"|"-w"|"-x"|"-e"|"-f"|"-d"|"-c"|"-b"|"-p"| 27545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "-u"|"-g"|"-k"|"-s"|"-t"|"-z"|"-n"|"-o"|"-O"|"-G"| 27555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "-L"|"-h"|"-S"|"-H"; 27565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 27575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru binary-operator ::= "="|"=="|"!="|"-eq"|"-ne"|"-ge"|"-gt"|"-le"|"-lt"| 27585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "-nt"|"-ot"|"-ef"| 2759c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser "<"|">" # rules used for [[ ... ]] expressions 27605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 2761c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser operand ::= <anything> 27625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru*/ 27635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 276403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* POSIX says > 1 for errors */ 2765c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#define T_ERR_EXIT 2 27665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 27675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 27685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_test(const char **wp) 27695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 2770c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser int argc, rv, invert = 0; 27715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Test_env te; 2772c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser Test_op op; 2773c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser const char *lhs, **swp; 27745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 27755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te.flags = 0; 27765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te.isa = ptest_isa; 27775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te.getopnd = ptest_getopnd; 27785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te.eval = test_eval; 27795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te.error = ptest_error; 27805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 27815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (argc = 0; wp[argc]; argc++) 27825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 2783c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser mkssert(argc > 0); 2784c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser mkssert(wp[0] != NULL); 27855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 27865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (strcmp(wp[0], "[") == 0) { 27875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (strcmp(wp[--argc], "]") != 0) { 27885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("missing ]"); 27895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (T_ERR_EXIT); 27905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 27915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 27925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 27935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te.pos.wp = wp + 1; 27945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te.wp_end = wp + argc; 27955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 27965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 2797c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * Attempt to conform to POSIX special cases. This is pretty 2798c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * dumb code straight-forward from the 2008 spec, but unless 2799c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * the old pdksh code doesn't live from so many assumptions. 2800c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * It does, though, inline some calls to '(*te.funcname)()'. 28015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 2802c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser switch (argc - 1) { 2803c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case 0: 2804c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return (1); 2805c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case 1: 2806c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ptest_one: 2807c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser op = TO_STNZE; 2808c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto ptest_unary; 2809c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case 2: 2810c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ptest_two: 2811c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (ptest_isa(&te, TM_NOT)) { 2812c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ++invert; 2813c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto ptest_one; 2814c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 2815c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((op = ptest_isa(&te, TM_UNOP))) { 2816c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ptest_unary: 2817c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser rv = test_eval(&te, op, *te.pos.wp++, NULL, true); 2818c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ptest_out: 2819c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return ((invert & 1) ? rv : !rv); 2820c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 2821c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* let the parser deal with anything else */ 2822c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser break; 2823c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case 3: 2824c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ptest_three: 2825c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser swp = te.pos.wp; 2826c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* use inside knowledge of ptest_getopnd inlined below */ 2827c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser lhs = *te.pos.wp++; 2828c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((op = ptest_isa(&te, TM_BINOP))) { 2829c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* test lhs op rhs */ 2830c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser rv = test_eval(&te, op, lhs, *te.pos.wp++, true); 2831c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto ptest_out; 2832c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 2833c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* back up to lhs */ 2834c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser te.pos.wp = swp; 2835c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (ptest_isa(&te, TM_NOT)) { 2836c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ++invert; 2837c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto ptest_two; 2838c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 2839c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (ptest_isa(&te, TM_OPAREN)) { 2840c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser swp = te.pos.wp; 2841c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* skip operand, without evaluation */ 2842c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser te.pos.wp++; 2843c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* check for closing parenthesis */ 2844c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser op = ptest_isa(&te, TM_CPAREN); 2845c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* back up to operand */ 2846c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser te.pos.wp = swp; 2847c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* if there was a closing paren, handle it */ 2848c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (op) 2849c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto ptest_one; 2850c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* backing up is done before calling the parser */ 2851c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 2852c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* let the parser deal with it */ 2853c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser break; 2854c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case 4: 2855c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (ptest_isa(&te, TM_NOT)) { 2856c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ++invert; 2857c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto ptest_three; 2858c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 2859c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (ptest_isa(&te, TM_OPAREN)) { 2860c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser swp = te.pos.wp; 2861c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* skip two operands, without evaluation */ 2862c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser te.pos.wp++; 2863c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser te.pos.wp++; 2864c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* check for closing parenthesis */ 2865c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser op = ptest_isa(&te, TM_CPAREN); 2866c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* back up to first operand */ 2867c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser te.pos.wp = swp; 2868c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* if there was a closing paren, handle it */ 2869c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (op) 2870c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto ptest_two; 2871c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* backing up is done before calling the parser */ 2872c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 2873c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* defer this to the parser */ 2874c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser break; 28755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 28765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2877c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* "The results are unspecified." */ 2878c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser te.pos.wp = wp + 1; 28795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (test_parse(&te)); 28805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 28815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 28825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 28835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Generic test routines. 28845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 28855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 28865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste QueruTest_op 28875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutest_isop(Test_meta meta, const char *s) 28885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 28895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char sc1; 28905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const struct t_op *tbl; 28915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 28925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tbl = meta == TM_UNOP ? u_ops : b_ops; 28935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*s) { 28945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sc1 = s[1]; 28955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; tbl->op_text[0]; tbl++) 28965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (sc1 == tbl->op_text[1] && !strcmp(s, tbl->op_text)) 28975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (tbl->op_num); 28985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 28995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (TO_NONOP); 29005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 29015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 29025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 29035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutest_eval(Test_env *te, Test_op op, const char *opnd1, const char *opnd2, 29045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool do_eval) 29055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 29065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int i, s; 29075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru size_t k; 29085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct stat b1, b2; 29095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mksh_ari_t v1, v2; 29105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 29115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!do_eval) 29125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 29135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2914c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef DEBUG 2915c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser switch (op) { 2916c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* Binary operators */ 2917c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case TO_STEQL: 2918c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case TO_STNEQ: 2919c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case TO_STLT: 2920c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case TO_STGT: 2921c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case TO_INTEQ: 2922c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case TO_INTNE: 2923c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case TO_INTGT: 2924c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case TO_INTGE: 2925c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case TO_INTLT: 2926c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case TO_INTLE: 2927c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case TO_FILEQ: 2928c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case TO_FILNT: 2929c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case TO_FILOT: 2930c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* consistency check, but does not happen in practice */ 2931c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (!opnd2) { 2932c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser te->flags |= TEF_ERROR; 2933c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return (1); 2934c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 2935c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser break; 2936c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser default: 2937c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* for completeness of switch */ 2938c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser break; 2939c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 2940c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 2941c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 294203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra switch (op) { 294303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 29445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 29455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Unary Operators 29465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 294703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 294803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -n */ 294903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_STNZE: 29505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (*opnd1 != '\0'); 295103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 295203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -z */ 295303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_STZER: 29545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (*opnd1 == '\0'); 295503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 295603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -o */ 295703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_OPTION: 29585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((i = *opnd1) == '!' || i == '?') 29595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru opnd1++; 29605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((k = option(opnd1)) == (size_t)-1) 29615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 29625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (i == '?' ? 1 : i == '!' ? !Flag(k) : Flag(k)); 296303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 296403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -r */ 296503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILRD: 296603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* LINTED use of access */ 296703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (access(opnd1, R_OK) == 0); 296803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 296903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -w */ 297003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILWR: 297103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* LINTED use of access */ 297203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (access(opnd1, W_OK) == 0); 297303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 297403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -x */ 297503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILEX: 297603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (ksh_access(opnd1, X_OK) == 0); 297703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 297803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -a */ 297903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILAXST: 298003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -e */ 298103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILEXST: 29825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd1, &b1) == 0); 298303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 298403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -r */ 298503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILREG: 29865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd1, &b1) == 0 && S_ISREG(b1.st_mode)); 298703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 298803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -d */ 298903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILID: 29905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd1, &b1) == 0 && S_ISDIR(b1.st_mode)); 299103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 299203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -c */ 299303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILCDEV: 29945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd1, &b1) == 0 && S_ISCHR(b1.st_mode)); 299503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 299603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -b */ 299703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILBDEV: 29985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd1, &b1) == 0 && S_ISBLK(b1.st_mode)); 299903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 300003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -p */ 300103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILFIFO: 30025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd1, &b1) == 0 && S_ISFIFO(b1.st_mode)); 300303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 300403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -h or -L */ 300503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILSYM: 3006c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef MKSH__NO_SYMLINK 3007c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return (0); 3008c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#else 30095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (lstat(opnd1, &b1) == 0 && S_ISLNK(b1.st_mode)); 3010c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 301103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 301203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -S */ 301303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILSOCK: 30145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd1, &b1) == 0 && S_ISSOCK(b1.st_mode)); 301503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 301603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -H => HP context dependent files (directories) */ 301703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILCDF: 301803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#ifdef S_ISCDF 301903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra { 302003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra char *nv; 302103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 302203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 302303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Append a + to filename and check to see if result is 302403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * a setuid directory. CDF stuff in general is hookey, 302503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * since it breaks for, e.g., the following sequence: 302603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * echo hi >foo+; mkdir foo; echo bye >foo/default; 302703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * chmod u+s foo (foo+ refers to the file with hi in it, 302803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * there is no way to get at the file with bye in it; 302903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * please correct me if I'm wrong about this). 303003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra */ 303103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 303203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra nv = shf_smprintf("%s+", opnd1); 303303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra i = (stat(nv, &b1) == 0 && S_ISCDF(b1.st_mode)); 303403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra afree(nv, ATEMP); 303503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (i); 303603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 303703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#else 30385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 303903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 304003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 304103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -u */ 304203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILSETU: 30435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd1, &b1) == 0 && 30445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (b1.st_mode & S_ISUID) == S_ISUID); 304503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 304603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -g */ 304703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILSETG: 30485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd1, &b1) == 0 && 30495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (b1.st_mode & S_ISGID) == S_ISGID); 305003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 305103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -k */ 305203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILSTCK: 30535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef S_ISVTX 30545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd1, &b1) == 0 && 30555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (b1.st_mode & S_ISVTX) == S_ISVTX); 30565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#else 30575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 30585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 305903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 306003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -s */ 306103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILGZ: 3062c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return (stat(opnd1, &b1) == 0 && (off_t)b1.st_size > (off_t)0); 306303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 306403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -t */ 306503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILTT: 30665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (opnd1 && !bi_getn(opnd1, &i)) { 30675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te->flags |= TEF_ERROR; 30685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru i = 0; 30695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 30705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru i = isatty(opnd1 ? i : 0); 30715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (i); 307203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 307303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -O */ 307403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILUID: 3075c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return (stat(opnd1, &b1) == 0 && (uid_t)b1.st_uid == ksheuid); 307603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 307703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -G */ 307803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILGID: 3079c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return (stat(opnd1, &b1) == 0 && (gid_t)b1.st_gid == getegid()); 308003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 30815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 30825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Binary Operators 30835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 308403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 308503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* = */ 308603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_STEQL: 30875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (te->flags & TEF_DBRACKET) 30885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (gmatchx(opnd1, opnd2, false)); 30895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (strcmp(opnd1, opnd2) == 0); 309003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 309103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* != */ 309203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_STNEQ: 30935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (te->flags & TEF_DBRACKET) 30945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (!gmatchx(opnd1, opnd2, false)); 30955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (strcmp(opnd1, opnd2) != 0); 309603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 309703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* < */ 309803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_STLT: 30995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (strcmp(opnd1, opnd2) < 0); 310003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 310103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* > */ 310203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_STGT: 31035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (strcmp(opnd1, opnd2) > 0); 310403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 310503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -eq */ 310603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_INTEQ: 310703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -ne */ 310803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_INTNE: 310903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -ge */ 311003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_INTGE: 311103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -gt */ 311203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_INTGT: 311303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -le */ 311403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_INTLE: 311503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -lt */ 311603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_INTLT: 31175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!evaluate(opnd1, &v1, KSH_RETURN_ERROR, false) || 31185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru !evaluate(opnd2, &v2, KSH_RETURN_ERROR, false)) { 31195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* error already printed.. */ 31205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te->flags |= TEF_ERROR; 31215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 31225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 312303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra switch (op) { 31245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case TO_INTEQ: 31255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (v1 == v2); 31265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case TO_INTNE: 31275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (v1 != v2); 31285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case TO_INTGE: 31295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (v1 >= v2); 31305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case TO_INTGT: 31315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (v1 > v2); 31325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case TO_INTLE: 31335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (v1 <= v2); 31345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case TO_INTLT: 31355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (v1 < v2); 313603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra default: 313703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* NOTREACHED */ 313803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 31395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 314003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* NOTREACHED */ 314103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 314203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -nt */ 314303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILNT: 314403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 314503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * ksh88/ksh93 succeed if file2 can't be stated 31465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (subtly different from 'does not exist'). 31475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 31485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd1, &b1) == 0 && 31495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (((s = stat(opnd2, &b2)) == 0 && 31505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru b1.st_mtime > b2.st_mtime) || s < 0)); 315103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 315203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -ot */ 315303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILOT: 315403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 315503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * ksh88/ksh93 succeed if file1 can't be stated 31565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (subtly different from 'does not exist'). 31575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 31585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd2, &b2) == 0 && 31595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (((s = stat(opnd1, &b1)) == 0 && 31605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru b1.st_mtime < b2.st_mtime) || s < 0)); 316103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 316203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -ef */ 316303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILEQ: 31645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat (opnd1, &b1) == 0 && stat (opnd2, &b2) == 0 && 31655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru b1.st_dev == b2.st_dev && b1.st_ino == b2.st_ino); 316603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 316703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* all other cases */ 316803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_NONOP: 316903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_NONNULL: 317003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* throw the error */ 317103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 31725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 31735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (*te->error)(te, 0, "internal error: unknown op"); 31745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 31755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 31765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 31775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 31785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutest_parse(Test_env *te) 31795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 31805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv; 31815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 31825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = test_oexpr(te, 1); 31835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 31845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(te->flags & TEF_ERROR) && !(*te->isa)(te, TM_END)) 31855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (*te->error)(te, 0, "unexpected operator/operand"); 31865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 31875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return ((te->flags & TEF_ERROR) ? T_ERR_EXIT : !rv); 31885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 31895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 31905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 31915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutest_oexpr(Test_env *te, bool do_eval) 31925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 31935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv; 31945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 31955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((rv = test_aexpr(te, do_eval))) 31965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru do_eval = false; 31975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(te->flags & TEF_ERROR) && (*te->isa)(te, TM_OR)) 31985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (test_oexpr(te, do_eval) || rv); 31995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 32005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 32015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 32035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutest_aexpr(Test_env *te, bool do_eval) 32045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 32055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv; 32065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(rv = test_nexpr(te, do_eval))) 32085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru do_eval = false; 32095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(te->flags & TEF_ERROR) && (*te->isa)(te, TM_AND)) 32105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (test_aexpr(te, do_eval) && rv); 32115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 32125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 32135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 32155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutest_nexpr(Test_env *te, bool do_eval) 32165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 32175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(te->flags & TEF_ERROR) && (*te->isa)(te, TM_NOT)) 32185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (!test_nexpr(te, do_eval)); 32195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (test_primary(te, do_eval)); 32205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 32215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 32235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutest_primary(Test_env *te, bool do_eval) 32245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 32255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *opnd1, *opnd2; 32265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv; 32275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Test_op op; 32285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (te->flags & TEF_ERROR) 32305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 32315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((*te->isa)(te, TM_OPAREN)) { 32325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = test_oexpr(te, do_eval); 32335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (te->flags & TEF_ERROR) 32345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 32355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(*te->isa)(te, TM_CPAREN)) { 323603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra (*te->error)(te, 0, "missing )"); 32375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 32385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 32395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 32405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 32415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 32425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Binary should have precedence over unary in this case 32435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * so that something like test \( -f = -f \) is accepted 32445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 32455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((te->flags & TEF_DBRACKET) || (&te->pos.wp[1] < te->wp_end && 32465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru !test_isop(TM_BINOP, te->pos.wp[1]))) { 32475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((op = (*te->isa)(te, TM_UNOP))) { 32485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* unary expression */ 32495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru opnd1 = (*te->getopnd)(te, op, do_eval); 32505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!opnd1) { 32515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (*te->error)(te, -1, "missing argument"); 32525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 32535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 32545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return ((*te->eval)(te, op, opnd1, NULL, do_eval)); 32565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 32575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 32585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru opnd1 = (*te->getopnd)(te, TO_NONOP, do_eval); 32595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!opnd1) { 32605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (*te->error)(te, 0, "expression expected"); 32615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 32625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 32635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((op = (*te->isa)(te, TM_BINOP))) { 32645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* binary expression */ 32655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru opnd2 = (*te->getopnd)(te, op, do_eval); 32665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!opnd2) { 32675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (*te->error)(te, -1, "missing second argument"); 32685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 32695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 32705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return ((*te->eval)(te, op, opnd1, opnd2, do_eval)); 32725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 32735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return ((*te->eval)(te, TO_STNZE, opnd1, NULL, do_eval)); 32745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 32755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 32775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Plain test (test and [ .. ]) specific routines. 32785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 32795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 32815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Test if the current token is a whatever. Accepts the current token if 32825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * it is. Returns 0 if it is not, non-zero if it is (in the case of 32835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * TM_UNOP and TM_BINOP, the returned value is a Test_op). 32845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 32855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic Test_op 32865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruptest_isa(Test_env *te, Test_meta meta) 32875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 32885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Order important - indexed by Test_meta values */ 3289c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser static const char * const tokens[] = { 32905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "-o", "-a", "!", "(", ")" 32915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru }; 32925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Test_op rv; 32935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (te->pos.wp >= te->wp_end) 32955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (meta == TM_END ? TO_NONNULL : TO_NONOP); 32965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (meta == TM_UNOP || meta == TM_BINOP) 32985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = test_isop(meta, *te->pos.wp); 32995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (meta == TM_END) 33005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = TO_NONOP; 33015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 33025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = !strcmp(*te->pos.wp, tokens[(int)meta]) ? 33035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru TO_NONNULL : TO_NONOP; 33045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 33055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Accept the token? */ 33065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (rv != TO_NONOP) 33075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te->pos.wp++; 33085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 33095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 33105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 33115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 33125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic const char * 33135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruptest_getopnd(Test_env *te, Test_op op, bool do_eval MKSH_A_UNUSED) 33145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 33155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (te->pos.wp >= te->wp_end) 33165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (op == TO_FILTT ? "1" : NULL); 33175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (*te->pos.wp++); 33185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 33195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 33205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 33215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruptest_error(Test_env *te, int ofs, const char *msg) 33225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 33235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *op; 33245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 33255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te->flags |= TEF_ERROR; 33265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((op = te->pos.wp + ofs >= te->wp_end ? NULL : te->pos.wp[ofs])) 33275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("%s: %s", op, msg); 33285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 33295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("%s", msg); 33305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 33315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 33325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_NO_LIMITS 33335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define SOFT 0x1 33345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define HARD 0x2 33355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 33365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustruct limits { 33375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *name; 33385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int resource; /* resource to get/set */ 3339c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser unsigned int factor; /* multiply by to get rlim_{cur,max} values */ 33405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char option; 33415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}; 33425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 33435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void print_ulimit(const struct limits *, int); 33445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int set_ulimit(const struct limits *, const char *, int); 33455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 33465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Magic to divine the 'm' and 'v' limits */ 33475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 33485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_AS 33495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if !defined(RLIMIT_VMEM) || (RLIMIT_VMEM == RLIMIT_AS) || \ 33505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru !defined(RLIMIT_RSS) || (RLIMIT_VMEM == RLIMIT_RSS) 33515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define ULIMIT_V_IS_AS 33525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#elif defined(RLIMIT_VMEM) 33535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if !defined(RLIMIT_RSS) || (RLIMIT_RSS == RLIMIT_AS) 33545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define ULIMIT_V_IS_AS 33555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#else 33565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define ULIMIT_V_IS_VMEM 33575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 33615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_RSS 33625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef ULIMIT_V_IS_VMEM 33635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define ULIMIT_M_IS_RSS 33645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#elif defined(RLIMIT_VMEM) && (RLIMIT_VMEM == RLIMIT_RSS) 33655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define ULIMIT_M_IS_VMEM 33665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#else 33675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define ULIMIT_M_IS_RSS 33685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if defined(ULIMIT_M_IS_RSS) && defined(RLIMIT_AS) && (RLIMIT_RSS == RLIMIT_AS) 33705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#undef ULIMIT_M_IS_RSS 33715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 33745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if !defined(RLIMIT_AS) && !defined(ULIMIT_M_IS_VMEM) && defined(RLIMIT_VMEM) 33755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define ULIMIT_V_IS_VMEM 33765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 33785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if !defined(ULIMIT_V_IS_VMEM) && defined(RLIMIT_VMEM) && \ 33795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (!defined(RLIMIT_RSS) || (defined(RLIMIT_AS) && (RLIMIT_RSS == RLIMIT_AS))) 33805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define ULIMIT_M_IS_VMEM 33815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 33835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if defined(ULIMIT_M_IS_VMEM) && defined(RLIMIT_AS) && \ 33845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (RLIMIT_VMEM == RLIMIT_AS) 33855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#undef ULIMIT_M_IS_VMEM 33865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 33885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 33895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 33905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_ulimit(const char **wp) 33915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 33925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru static const struct limits limits[] = { 33935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* do not use options -H, -S or -a or change the order */ 33945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_CPU 33955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "time(cpu-seconds)", RLIMIT_CPU, 1, 't' }, 33965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_FSIZE 33985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "file(blocks)", RLIMIT_FSIZE, 512, 'f' }, 33995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 34005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_CORE 34015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "coredump(blocks)", RLIMIT_CORE, 512, 'c' }, 34025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 34035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_DATA 34045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "data(KiB)", RLIMIT_DATA, 1024, 'd' }, 34055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 34065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_STACK 34075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "stack(KiB)", RLIMIT_STACK, 1024, 's' }, 34085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 34095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_MEMLOCK 34105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "lockedmem(KiB)", RLIMIT_MEMLOCK, 1024, 'l' }, 34115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 34125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_NOFILE 34135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "nofiles(descriptors)", RLIMIT_NOFILE, 1, 'n' }, 34145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 34155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_NPROC 34165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "processes", RLIMIT_NPROC, 1, 'p' }, 34175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 34185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_SWAP 34195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "swap(KiB)", RLIMIT_SWAP, 1024, 'w' }, 34205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 34215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_LOCKS 34225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "flocks", RLIMIT_LOCKS, -1, 'L' }, 34235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 34245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_TIME 34255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "humantime(seconds)", RLIMIT_TIME, 1, 'T' }, 34265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 34275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_NOVMON 34285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "vnodemonitors", RLIMIT_NOVMON, 1, 'V' }, 34295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 34305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_SIGPENDING 34315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "sigpending", RLIMIT_SIGPENDING, 1, 'i' }, 34325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 34335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_MSGQUEUE 34345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "msgqueue(bytes)", RLIMIT_MSGQUEUE, 1, 'q' }, 34355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 34365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_AIO_MEM 34375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "AIOlockedmem(KiB)", RLIMIT_AIO_MEM, 1024, 'M' }, 34385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 34395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_AIO_OPS 34405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "AIOoperations", RLIMIT_AIO_OPS, 1, 'O' }, 34415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 34425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_TCACHE 34435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "cachedthreads", RLIMIT_TCACHE, 1, 'C' }, 34445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 34455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_SBSIZE 34465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "sockbufsiz(KiB)", RLIMIT_SBSIZE, 1024, 'B' }, 34475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 34485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_PTHREAD 34495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "threadsperprocess", RLIMIT_PTHREAD, 1, 'P' }, 34505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 34515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_NICE 34525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "maxnice", RLIMIT_NICE, 1, 'e' }, 34535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 34545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_RTPRIO 34555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "maxrtprio", RLIMIT_RTPRIO, 1, 'r' }, 34565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 34575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if defined(ULIMIT_M_IS_RSS) 34585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "resident-set(KiB)", RLIMIT_RSS, 1024, 'm' }, 34595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#elif defined(ULIMIT_M_IS_VMEM) 34605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "memory(KiB)", RLIMIT_VMEM, 1024, 'm' }, 34615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 34625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if defined(ULIMIT_V_IS_VMEM) 34635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "virtual-memory(KiB)", RLIMIT_VMEM, 1024, 'v' }, 34645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#elif defined(ULIMIT_V_IS_AS) 34655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "address-space(KiB)", RLIMIT_AS, 1024, 'v' }, 34665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 34675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { NULL, 0, 0, 0 } 34685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru }; 3469c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser static const char opts[] = "a" 3470c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef RLIMIT_SBSIZE 3471c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser "B" 3472c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 3473c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef RLIMIT_TCACHE 3474c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser "C" 3475c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 3476c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef RLIMIT_CORE 3477c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser "c" 3478c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 3479c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef RLIMIT_DATA 3480c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser "d" 3481c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 3482c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef RLIMIT_NICE 3483c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser "e" 3484c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 3485c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef RLIMIT_FSIZE 3486c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser "f" 3487c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 3488c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser "H" 3489c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef RLIMIT_SIGPENDING 3490c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser "i" 3491c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 3492c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef RLIMIT_LOCKS 3493c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser "L" 3494c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 3495c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef RLIMIT_MEMLOCK 3496c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser "l" 3497c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 3498c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef RLIMIT_AIO_MEM 3499c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser "M" 3500c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 3501c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#if defined(ULIMIT_M_IS_RSS) || defined(ULIMIT_M_IS_VMEM) 3502c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser "m" 3503c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 3504c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef RLIMIT_NOFILE 3505c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser "n" 3506c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 3507c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef RLIMIT_AIO_OPS 3508c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser "O" 3509c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 3510c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef RLIMIT_PTHREAD 3511c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser "P" 3512c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 3513c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef RLIMIT_NPROC 3514c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser "p" 3515c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 3516c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef RLIMIT_MSGQUEUE 3517c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser "q" 3518c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 3519c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef RLIMIT_RTPRIO 3520c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser "r" 3521c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 3522c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser "S" 3523c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef RLIMIT_STACK 3524c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser "s" 3525c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 3526c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef RLIMIT_TIME 3527c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser "T" 3528c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 3529c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef RLIMIT_CPU 3530c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser "t" 3531c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 3532c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef RLIMIT_NOVMON 3533c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser "V" 3534c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 3535c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#if defined(ULIMIT_V_IS_VMEM) || defined(ULIMIT_V_IS_AS) 3536c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser "v" 3537c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 3538c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef RLIMIT_SWAP 3539c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser "w" 3540c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 3541c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ; 35425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int how = SOFT | HARD, optc, what = 'f'; 35435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool all = false; 35445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const struct limits *l; 35455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 35465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt(wp, &builtin_opt, opts)) != -1) 35475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 35485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'H': 35495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru how = HARD; 35505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 35515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'S': 35525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru how = SOFT; 35535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 35545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'a': 35555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru all = true; 35565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 35575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 3558c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bi_errorf("usage: ulimit [-%s] [value]", opts); 35595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 35605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 35615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru what = optc; 35625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 35635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 35645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (l = limits; l->name && l->option != what; l++) 35655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 35665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!l->name) { 35675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru internal_warningf("ulimit: %c", what); 35685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 35695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 35705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 35715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (wp[builtin_opt.optind]) { 35725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (all || wp[builtin_opt.optind + 1]) { 35735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("too many arguments"); 35745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 35755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 35765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (set_ulimit(l, wp[builtin_opt.optind], how)); 35775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 35785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!all) 35795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru print_ulimit(l, how); 35805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else for (l = limits; l->name; l++) { 35815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shprintf("%-20s ", l->name); 35825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru print_ulimit(l, how); 35835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 35845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 35855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 35865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 35875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 35885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruset_ulimit(const struct limits *l, const char *v, int how) 35895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 35905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rlim_t val = (rlim_t)0; 35915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct rlimit limit; 35925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 35935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (strcmp(v, "unlimited") == 0) 35945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru val = (rlim_t)RLIM_INFINITY; 35955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else { 3596c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser mksh_uari_t rval; 35975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3598c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (!evaluate(v, (mksh_ari_t *)&rval, KSH_RETURN_ERROR, false)) 35995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 36005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 36015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Avoid problems caused by typos that evaluate misses due 36025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * to evaluating unset parameters to 0... 36035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * If this causes problems, will have to add parameter to 36045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * evaluate() to control if unset params are 0 or an error. 36055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 36065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!rval && !ksh_isdigit(v[0])) { 36075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("invalid %s limit: %s", l->name, v); 36085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 36095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 36105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru val = (rlim_t)((rlim_t)rval * l->factor); 36115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 36125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 36135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (getrlimit(l->resource, &limit) < 0) { 361403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* some can't be read, e.g. Linux RLIMIT_LOCKS */ 36155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru limit.rlim_cur = RLIM_INFINITY; 36165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru limit.rlim_max = RLIM_INFINITY; 36175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 36185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (how & SOFT) 36195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru limit.rlim_cur = val; 36205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (how & HARD) 36215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru limit.rlim_max = val; 36225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!setrlimit(l->resource, &limit)) 36235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 36245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (errno == EPERM) 36255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("%s exceeds allowable %s limit", v, l->name); 36265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 3627c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bi_errorf("bad %s limit: %s", l->name, cstrerror(errno)); 36285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 36295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 36305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 36315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 36325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruprint_ulimit(const struct limits *l, int how) 36335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 36345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rlim_t val = (rlim_t)0; 36355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct rlimit limit; 36365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 36375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (getrlimit(l->resource, &limit)) { 36385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts("unknown\n", shl_stdout); 36395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return; 36405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 36415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (how & SOFT) 36425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru val = limit.rlim_cur; 36435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (how & HARD) 36445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru val = limit.rlim_max; 36455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (val == (rlim_t)RLIM_INFINITY) 36465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts("unlimited\n", shl_stdout); 36475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 3648c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shprintf("%lu\n", (unsigned long)(val / l->factor)); 36495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 36505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 36515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 36525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 36535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_rename(const char **wp) 36545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 36555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv = 1; 36565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 365703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* skip argv[0] */ 365803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++wp; 365903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (wp[0] && !strcmp(wp[0], "--")) 366003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* skip "--" (options separator) */ 366103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++wp; 366203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 366303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* check for exactly two arguments */ 366403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (wp[0] == NULL /* first argument */ || 366503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra wp[1] == NULL /* second argument */ || 366603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra wp[2] != NULL /* no further args please */) 366703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf(Tsynerr); 366803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else if ((rv = rename(wp[0], wp[1])) != 0) { 36695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = errno; 3670c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bi_errorf("%s: %s", "failed", cstrerror(rv)); 36715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 36725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 36735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 36745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 36755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 36765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 36775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_realpath(const char **wp) 36785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 36795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv = 1; 36805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *buf; 36815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 368203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* skip argv[0] */ 368303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++wp; 368403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (wp[0] && !strcmp(wp[0], "--")) 368503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* skip "--" (options separator) */ 368603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++wp; 36875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 368803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* check for exactly one argument */ 368903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (wp[0] == NULL || wp[1] != NULL) 369003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf(Tsynerr); 369103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else if ((buf = do_realpath(wp[0])) == NULL) { 36925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = errno; 3693c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bi_errorf("%s: %s", wp[0], cstrerror(rv)); 36945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((unsigned int)rv > 255) 36955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 255; 36965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 36975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shprintf("%s\n", buf); 36985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(buf, ATEMP); 369903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 0; 37005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 37015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 37025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 37035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 370403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 370503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condraint 370603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrac_cat(const char **wp) 370703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{ 3708c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser int fd = STDIN_FILENO, rv, eno; 370903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ssize_t n, w; 371003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra const char *fn = "<stdin>"; 371103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra char *buf, *cp; 371203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define MKSH_CAT_BUFSIZ 4096 371303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 371403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* parse options: POSIX demands we support "-u" as no-op */ 371503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while ((rv = ksh_getopt(wp, &builtin_opt, "u")) != -1) { 371603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra switch (rv) { 371703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'u': 371803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* we already operate unbuffered */ 371903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 372003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra default: 372103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf(Tsynerr); 372203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (1); 372303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 372403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 372503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra wp += builtin_opt.optind; 372603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 0; 372703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 3728c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((buf = malloc_osfunc(MKSH_CAT_BUFSIZ)) == NULL) { 3729c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bi_errorf(Toomem, (unsigned long)MKSH_CAT_BUFSIZ); 3730c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return (1); 3731c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 3732c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 373303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra do { 373403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (*wp) { 373503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra fn = *wp++; 373603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (fn[0] == '-' && fn[1] == '\0') 373703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra fd = STDIN_FILENO; 373803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else if ((fd = open(fn, O_RDONLY)) < 0) { 3739c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser eno = errno; 3740c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bi_errorf("%s: %s", fn, cstrerror(eno)); 374103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 1; 374203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra continue; 374303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 374403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 374503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (/* CONSTCOND */ 1) { 374603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra n = blocking_read(fd, (cp = buf), MKSH_CAT_BUFSIZ); 3747c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser eno = errno; 3748c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* give the user a chance to ^C out */ 3749c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser intrcheck(); 375003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (n == -1) { 3751c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (eno == EINTR) { 375203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* interrupted, try again */ 375303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra continue; 375403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 375503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* an error occured during reading */ 3756c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bi_errorf("%s: %s", fn, cstrerror(eno)); 375703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 1; 375803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 375903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else if (n == 0) 376003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* end of file reached */ 376103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 376203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (n) { 376303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra w = write(STDOUT_FILENO, cp, n); 376403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (w == -1) { 376503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (errno == EINTR) 376603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* interrupted, try again */ 376703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra continue; 376803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* an error occured during writing */ 3769c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser eno = errno; 377003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", "<stdout>", 3771c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser cstrerror(eno)); 377203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 1; 377303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (fd != STDIN_FILENO) 377403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra close(fd); 377503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto out; 377603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 377703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra n -= w; 377803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra cp += w; 377903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 378003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 378103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (fd != STDIN_FILENO) 378203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra close(fd); 378303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } while (*wp); 378403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 378503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra out: 378603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra free_osfunc(buf); 378703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (rv); 378803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra} 378903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 379003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#if HAVE_SELECT 379103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condraint 379203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrac_sleep(const char **wp) 379303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{ 379403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra struct timeval tv; 379503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra int rv = 1; 379603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 379703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* skip argv[0] */ 379803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++wp; 379903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (wp[0] && !strcmp(wp[0], "--")) 380003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* skip "--" (options separator) */ 380103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++wp; 380203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 380303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!wp[0] || wp[1]) 380403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf(Tsynerr); 380503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else if (parse_usec(wp[0], &tv)) 3806c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bi_errorf("%s: %s '%s'", Tsynerr, cstrerror(errno), wp[0]); 380703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else { 380803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#ifndef MKSH_NOPROSPECTOFWORK 3809c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser sigset_t omask, bmask; 381003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 3811c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* block a number of signals from interrupting us, though */ 3812c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser (void)sigemptyset(&bmask); 3813c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser (void)sigaddset(&bmask, SIGPIPE); 3814c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser (void)sigaddset(&bmask, SIGCHLD); 3815c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef SIGWINCH 3816c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser (void)sigaddset(&bmask, SIGWINCH); 3817c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 3818c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef SIGINFO 3819c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser (void)sigaddset(&bmask, SIGINFO); 3820c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 3821c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef SIGUSR1 3822c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser (void)sigaddset(&bmask, SIGUSR1); 3823c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 3824c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef SIGUSR2 3825c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser (void)sigaddset(&bmask, SIGUSR2); 3826c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 3827c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser sigprocmask(SIG_BLOCK, &bmask, &omask); 382803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 3829c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (select(1, NULL, NULL, NULL, &tv) == 0 || errno == EINTR) 383003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 383103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * strictly speaking only for SIGALRM, but the 383203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * execution may be interrupted by other signals 383303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra */ 383403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 0; 383503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else 3836c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bi_errorf("%s: %s", Tselect, cstrerror(errno)); 383703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#ifndef MKSH_NOPROSPECTOFWORK 3838c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* this will re-schedule signal delivery */ 383903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra sigprocmask(SIG_SETMASK, &omask, NULL); 384003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 384103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 384203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (rv); 384303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra} 384403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 3845