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, 803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * 2010, 2011 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 4103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.197 2011/09/07 15:24:15 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 6303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#if defined(ANDROID) 6403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic int c_android_lsmod(const char **); 655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic int 6803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrac_true(const char **wp MKSH_A_UNUSED) 6903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{ 7003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (0); 7103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra} 725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic int 7403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrac_false(const char **wp MKSH_A_UNUSED) 7503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{ 7603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (1); 7703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra} 7803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 7903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* 8003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * A leading = means assignments before command are kept; 815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * a leading * means a POSIX special builtin; 825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * a leading + means a POSIX regular builtin 835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (* and + should not be combined). 845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruconst struct builtin mkshbuiltins[] = { 865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"*=.", c_dot}, 8703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra {"*=:", c_true}, 885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"[", c_test}, 895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"*=break", c_brkcont}, 9003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra {Tgbuiltin, c_builtin}, 915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"*=continue", c_brkcont}, 925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"*=eval", c_eval}, 935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"*=exec", c_exec}, 945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"*=exit", c_exitreturn}, 9503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra {"+false", c_false}, 965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"*=return", c_exitreturn}, 9703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra {Tsgset, c_set}, 985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"*=shift", c_shift}, 995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"=times", c_times}, 1005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"*=trap", c_trap}, 1015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"+=wait", c_wait}, 1025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"+read", c_read}, 1035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"test", c_test}, 10403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra {"+true", c_true}, 1055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"ulimit", c_ulimit}, 1065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"+umask", c_umask}, 1075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"*=unset", c_unset}, 10803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* no =: AT&T manual wrong */ 10903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra {Tpalias, c_alias}, 1105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"+cd", c_cd}, 11103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* dash compatibility hack */ 11203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra {"chdir", c_cd}, 1135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"+command", c_command}, 1145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"echo", c_print}, 1155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"*=export", c_typeset}, 1165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"+fc", c_fc}, 1175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"+getopts", c_getopts}, 11803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra {"=global", c_typeset}, 1195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"+jobs", c_jobs}, 1205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"+kill", c_kill}, 1215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"let", c_let}, 1225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"print", c_print}, 1235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef MKSH_PRINTF_BUILTIN 1245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"printf", c_printf}, 1255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 1265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"pwd", c_pwd}, 1275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"*=readonly", c_typeset}, 12803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra {T_typeset, c_typeset}, 12903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra {Tpunalias, c_unalias}, 1305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"whence", c_whence}, 1315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_UNEMPLOYED 1325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"+bg", c_fgbg}, 1335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"+fg", c_fgbg}, 1345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 1355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"bind", c_bind}, 13603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra {"cat", c_cat}, 1375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if HAVE_MKNOD 1385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"mknod", c_mknod}, 1395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 1405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"realpath", c_realpath}, 1415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"rename", c_rename}, 14203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#if HAVE_SELECT 14303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra {"sleep", c_sleep}, 14403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 14503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#ifdef __MirBSD__ 14603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* alias to "true" for historical reasons */ 14703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra {"domainname", c_true}, 14803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 14903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#if defined(ANDROID) 15003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra {"lsmod", c_android_lsmod}, 15103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 1525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {NULL, (int (*)(const char **))NULL} 1535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}; 1545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustruct kill_info { 1565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int num_width; 1575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int name_width; 1585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}; 1595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic const struct t_op { 1615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char op_text[4]; 1625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Test_op op_num; 1635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} u_ops[] = { 1645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-a", TO_FILAXST }, 1655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-b", TO_FILBDEV }, 1665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-c", TO_FILCDEV }, 1675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-d", TO_FILID }, 1685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-e", TO_FILEXST }, 1695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-f", TO_FILREG }, 1705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-G", TO_FILGID }, 1715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-g", TO_FILSETG }, 1725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-h", TO_FILSYM }, 1735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-H", TO_FILCDF }, 1745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-k", TO_FILSTCK }, 1755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-L", TO_FILSYM }, 1765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-n", TO_STNZE }, 1775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-O", TO_FILUID }, 1785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-o", TO_OPTION }, 1795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-p", TO_FILFIFO }, 1805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-r", TO_FILRD }, 1815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-s", TO_FILGZ }, 1825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-S", TO_FILSOCK }, 1835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-t", TO_FILTT }, 1845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-u", TO_FILSETU }, 1855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-w", TO_FILWR }, 1865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-x", TO_FILEX }, 1875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-z", TO_STZER }, 1885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"", TO_NONOP } 1895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}; 1905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic const struct t_op b_ops[] = { 1915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"=", TO_STEQL }, 1925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"==", TO_STEQL }, 1935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"!=", TO_STNEQ }, 1945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"<", TO_STLT }, 1955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {">", TO_STGT }, 1965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-eq", TO_INTEQ }, 1975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-ne", TO_INTNE }, 1985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-gt", TO_INTGT }, 1995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-ge", TO_INTGE }, 2005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-lt", TO_INTLT }, 2015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-le", TO_INTLE }, 2025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-ef", TO_FILEQ }, 2035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-nt", TO_FILNT }, 2045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"-ot", TO_FILOT }, 2055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru {"", TO_NONOP } 2065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}; 2075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int test_oexpr(Test_env *, bool); 2095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int test_aexpr(Test_env *, bool); 2105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int test_nexpr(Test_env *, bool); 2115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int test_primary(Test_env *, bool); 2125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic Test_op ptest_isa(Test_env *, Test_meta); 2135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic const char *ptest_getopnd(Test_env *, Test_op, bool); 2145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void ptest_error(Test_env *, int, const char *); 21503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic char *kill_fmt_entry(char *, size_t, int, const void *); 2165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void p_time(struct shf *, bool, long, int, int, 2175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *, const char *) 21803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra MKSH_A_NONNULL((__nonnull__ (6, 7))); 2195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 2215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_pwd(const char **wp) 2225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 2235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int optc; 22403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bool physical = tobool(Flag(FPHYSICAL)); 2255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *p, *allocd = NULL; 2265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt(wp, &builtin_opt, "LP")) != -1) 2285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 2295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'L': 2305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru physical = false; 2315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 2325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'P': 2335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru physical = true; 2345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 2355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 2365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 2375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 2395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (wp[0]) { 2415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("too many arguments"); 2425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 2435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p = current_wd[0] ? (physical ? allocd = do_realpath(current_wd) : 2455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru current_wd) : NULL; 24603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* LINTED use of access */ 2475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (p && access(p, R_OK) < 0) 2485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p = NULL; 24903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!p && !(p = allocd = ksh_get_wd())) { 25003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", "can't determine current directory", 25103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra strerror(errno)); 2525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 2535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shprintf("%s\n", p); 2555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(allocd, ATEMP); 2565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 2575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 2585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic const char *s_ptr; 2605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int s_get(void); 2615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void s_put(int); 2625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 2645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_print(const char **wp) 2655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 2665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define PO_NL BIT(0) /* print newline */ 2675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define PO_EXPAND BIT(1) /* expand backslash sequences */ 2685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define PO_PMINUSMINUS BIT(2) /* print a -- argument */ 2695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define PO_HIST BIT(3) /* print to history instead of stdout */ 2705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define PO_COPROC BIT(4) /* printing to coprocess: block SIGPIPE */ 2715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int fd = 1, c; 2725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int flags = PO_EXPAND|PO_NL; 2735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *s, *emsg; 2745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XString xs; 2755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *xp; 2765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (wp[0][0] == 'e') { 2785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* echo builtin */ 2795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp++; 28003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (Flag(FPOSIX) || Flag(FSH) || Flag(FAS_BUILTIN)) { 2815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Debian Policy 10.4 compliant "echo" builtin */ 2825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*wp && !strcmp(*wp, "-n")) { 2835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* we recognise "-n" only as the first arg */ 2845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flags = 0; 2855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp++; 2865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 2875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* otherwise, we print everything as-is */ 2885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flags = PO_NL; 2895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 2905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int nflags = flags; 2915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /** 2935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * a compromise between sysV and BSD echo commands: 2945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * escape sequences are enabled by default, and -n, 2955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * -e and -E are recognised if they appear in argu- 2965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * ments with no illegal options (ie, echo -nq will 2975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * print -nq). 2985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Different from sysV echo since options are reco- 2995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * gnised, different from BSD echo since escape se- 3005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * quences are enabled by default. 3015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 3025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((s = *wp) && *s == '-' && s[1]) { 3045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (*++s) 3055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*s == 'n') 3065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nflags &= ~PO_NL; 3075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (*s == 'e') 3085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nflags |= PO_EXPAND; 3095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (*s == 'E') 3105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nflags &= ~PO_EXPAND; 3115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 3125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 3135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * bad option: don't use 3145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * nflags, print argument 3155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 3165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*s) 3195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp++; 3215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flags = nflags; 3225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 3255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int optc; 3265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *opts = "Rnprsu,"; 3275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt(wp, &builtin_opt, opts)) != -1) 3295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 33003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'R': 33103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* fake BSD echo command */ 3325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flags |= PO_PMINUSMINUS; 3335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flags &= ~PO_EXPAND; 3345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru opts = "ne"; 3355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'e': 3375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flags |= PO_EXPAND; 3385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'n': 3405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flags &= ~PO_NL; 3415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'p': 3435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((fd = coproc_getfd(W_OK, &emsg)) < 0) { 34403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", "-p", emsg); 3455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 3465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'r': 3495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flags &= ~PO_EXPAND; 3505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 's': 3525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flags |= PO_HIST; 3535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'u': 3555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!*(s = builtin_opt.optarg)) 3565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fd = 0; 3575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if ((fd = check_fd(s, W_OK, &emsg)) < 0) { 35803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s: %s", "-u", s, emsg); 3595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 3605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 3635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 3645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(builtin_opt.info & GI_MINUSMINUS)) { 3675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* treat a lone - like -- */ 3685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (wp[builtin_opt.optind] && 3695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ksh_isdash(wp[builtin_opt.optind])) 3705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru builtin_opt.optind++; 3715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (flags & PO_PMINUSMINUS) 3725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru builtin_opt.optind--; 3735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 3745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xinit(xs, xp, 128, ATEMP); 3775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (*wp != NULL) { 3795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = *wp; 3805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((c = *s++) != '\0') { 3815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xcheck(xs, xp); 3825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((flags & PO_EXPAND) && c == '\\') { 3835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s_ptr = s; 3845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = unbksl(false, s_get, s_put); 3855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = s_ptr; 3865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == -1) { 3875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* rejected by generic function */ 3885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch ((c = *s++)) { 3895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'c': 3905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flags &= ~PO_NL; 3915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* AT&T brain damage */ 3925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 3935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '\0': 3945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s--; 3955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = '\\'; 3965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 3985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xput(xs, xp, '\\'); 3995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if ((unsigned int)c > 0xFF) { 4015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* generic function returned Unicode */ 4025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char ts[4]; 4035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 40403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ts[utf_wctomb(ts, c - 0x100)] = 0; 4055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (c = 0; ts[c]; ++c) 4065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xput(xs, xp, ts[c]); 4075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 4085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xput(xs, xp, c); 4115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*++wp != NULL) 4135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xput(xs, xp, ' '); 4145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (flags & PO_NL) 4165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xput(xs, xp, '\n'); 4175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (flags & PO_HIST) { 4195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xput(xs, xp, '\0'); 4205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru histsave(&source->line, Xstring(xs, xp), true, false); 4215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xfree(xs, xp); 4225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 4235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int len = Xlength(xs, xp); 4245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int opipe = 0; 4255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 42603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 42703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Ensure we aren't killed by a SIGPIPE while writing to 4285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * a coprocess. AT&T ksh doesn't seem to do this (seems 4295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * to just check that the co-process is alive which is 4305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * not enough). 4315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 4325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (coproc.write >= 0 && coproc.write == fd) { 4335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flags |= PO_COPROC; 4345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru opipe = block_pipe(); 4355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (s = Xstring(xs, xp); len > 0; ) { 4375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c = write(fd, s, len)) < 0) { 4385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (flags & PO_COPROC) 4395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru restore_pipe(opipe); 4405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (errno == EINTR) { 4415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* allow user to ^C out */ 4425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru intrcheck(); 4435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (flags & PO_COPROC) 4445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru opipe = block_pipe(); 4455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 4465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 4485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s += c; 4505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru len -= c; 4515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (flags & PO_COPROC) 4535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru restore_pipe(opipe); 4545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 4575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 4585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 4605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querus_get(void) 4615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 4625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (*s_ptr++); 4635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 4645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 4665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querus_put(int c MKSH_A_UNUSED) 4675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 4685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru --s_ptr; 4695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 4705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 4725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_whence(const char **wp) 4735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 4745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *tp; 4755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *id; 4765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool pflag = false, vflag = false, Vflag = false; 4775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv = 0, optc, fcflags; 4785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool iam_whence = wp[0][0] == 'w'; 4795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *opts = iam_whence ? "pv" : "pvV"; 4805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt(wp, &builtin_opt, opts)) != -1) 4825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 4835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'p': 4845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru pflag = true; 4855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 4865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'v': 4875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vflag = true; 4885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 4895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'V': 4905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Vflag = true; 4915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 4925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 4935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 4945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 4965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fcflags = FC_BI | FC_PATH | FC_FUNC; 4985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!iam_whence) { 4995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Note that -p on its own is deal with in comexec() */ 5005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (pflag) 5015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fcflags |= FC_DEFPATH; 50203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 50303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Convert command options to whence options - note that 5045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * command -pV uses a different path search than whence -v 5055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * or whence -pv. This should be considered a feature. 5065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 5075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vflag = Vflag; 5085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (pflag) 5105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fcflags &= ~(FC_BI | FC_FUNC); 5115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((vflag || rv == 0) && (id = *wp++) != NULL) { 5135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru uint32_t h = 0; 5145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp = NULL; 5165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((iam_whence || vflag) && !pflag) 5175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp = ktsearch(&keywords, id, h = hash(id)); 5185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!tp && !pflag) { 5195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp = ktsearch(&aliases, id, h ? h : hash(id)); 5205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tp && !(tp->flag & ISSET)) 5215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp = NULL; 5225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!tp) 5245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp = findcom(id, fcflags); 5255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vflag || (tp->type != CALIAS && tp->type != CEXEC && 5265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp->type != CTALIAS)) 5275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts(id, shl_stdout); 52803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (vflag) 52903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra switch (tp->type) { 53003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case CKEYWD: 53103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case CALIAS: 53203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case CFUNC: 53303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case CSHELL: 53403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shf_puts(" is a", shl_stdout); 53503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 53603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 53703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 5385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (tp->type) { 5395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case CKEYWD: 5405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vflag) 54103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shf_puts(" reserved word", shl_stdout); 5425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case CALIAS: 5445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vflag) 54503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shprintf("n %s%s for ", 54603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra (tp->flag & EXPORT) ? "exported " : null, 54703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Talias); 5485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!iam_whence && !vflag) 54903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shprintf("%s %s=", Talias, id); 5505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru print_value_quoted(tp->val.s); 5515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case CFUNC: 5535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vflag) { 5545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tp->flag & EXPORT) 5555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts("n exported", shl_stdout); 5565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tp->flag & TRACE) 5575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts(" traced", shl_stdout); 5585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(tp->flag & ISSET)) { 5595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts(" undefined", shl_stdout); 5605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tp->u.fpath) 5615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shprintf(" (autoload from %s)", 5625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp->u.fpath); 5635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 56403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shf_puts(T_function, shl_stdout); 5655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case CSHELL: 5685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vflag) 56903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shprintf("%s %s %s", 57003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra (tp->flag & SPEC_BI) ? " special" : null, 57103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra "shell", Tbuiltin); 5725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case CTALIAS: 5745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case CEXEC: 5755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tp->flag & ISSET) { 5765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vflag) { 5775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts(" is ", shl_stdout); 5785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tp->type == CTALIAS) 57903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shprintf("a tracked %s%s for ", 5805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (tp->flag & EXPORT) ? 58103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra "exported " : null, 58203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Talias); 5835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts(tp->val.s, shl_stdout); 5855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 5865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vflag) 58703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shprintf(" %s\n", "not found"); 5885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 1; 5895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 5925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shprintf("%s is *GOK*", id); 5935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vflag || !rv) 5965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_putc('\n', shl_stdout); 5975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 5995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 6005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Deal with command -vV - command -p dealt with in comexec() */ 6025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 6035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_command(const char **wp) 6045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 60503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 60603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Let c_whence do the work. Note that c_command() must be 6075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * a distinct function from c_whence() (tested in comexec()). 6085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 6095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (c_whence(wp)); 6105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 6115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 61203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* typeset, global, export, and readonly */ 6135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 6145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_typeset(const char **wp) 6155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 6165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct block *l; 6175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *vp, **p; 61803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra uint32_t fset = 0, fclr = 0, flag; 6195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int thing = 0, field, base, optc; 6205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *opts; 6215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *fieldstr, *basestr; 6225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool localv = false, func = false, pflag = false, istset = true; 6235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (**wp) { 62503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 62603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* export */ 62703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'e': 6285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fset |= EXPORT; 6295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru istset = false; 6305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 63103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 63203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* readonly */ 63303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'r': 6345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fset |= RDONLY; 6355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru istset = false; 6365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 63703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 63803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* set */ 63903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 's': 6405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* called with 'typeset -' */ 6415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 64203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 64303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* typeset */ 64403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 't': 6455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru localv = true; 6465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 6475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* see comment below regarding possible opions */ 6505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru opts = istset ? "L#R#UZ#afi#lnprtux" : "p"; 6515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fieldstr = basestr = NULL; 6535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru builtin_opt.flags |= GF_PLUSOPT; 65403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 65503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * AT&T ksh seems to have 0-9 as options which are multiplied 6565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * to get a number that is used with -L, -R, -Z or -i (eg, -1R2 6575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * sets right justify in a field of 12). This allows options 6585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * to be grouped in an order (eg, -Lu12), but disallows -i8 -L3 and 6595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * does not allow the number to be specified as a separate argument 6605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Here, the number must follow the RLZi option, but is optional 6615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (see the # kludge in ksh_getopt()). 6625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 6635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt(wp, &builtin_opt, opts)) != -1) { 6645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flag = 0; 6655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 6665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'L': 6675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flag = LJUST; 6685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fieldstr = builtin_opt.optarg; 6695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 6705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'R': 6715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flag = RJUST; 6725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fieldstr = builtin_opt.optarg; 6735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 6745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'U': 67503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 67603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * AT&T ksh uses u, but this conflicts with 6775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * upper/lower case. If this option is changed, 6785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * need to change the -U below as well 6795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 6805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flag = INT_U; 6815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 6825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'Z': 6835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flag = ZEROFIL; 6845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fieldstr = builtin_opt.optarg; 6855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 6865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'a': 6875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 6885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * this is supposed to set (-a) or unset (+a) the 6895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * indexed array attribute; it does nothing on an 6905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * existing regular string or indexed array though 6915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 6925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 6935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'f': 6945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru func = true; 6955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 6965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'i': 6975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flag = INTEGER; 6985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru basestr = builtin_opt.optarg; 6995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'l': 7015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flag = LCASEV; 7025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'n': 70403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra set_refflag = (builtin_opt.info & GI_PLUS) ? 70503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra SRF_DISABLE : SRF_ENABLE; 7065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 70703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* export, readonly: POSIX -p flag */ 7085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'p': 7095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* typeset: show values as well */ 7105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru pflag = true; 7115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (istset) 7125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 7135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'r': 7155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flag = RDONLY; 7165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 't': 7185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flag = TRACE; 7195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'u': 72103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* upper case / autoload */ 72203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra flag = UCASEV_AL; 7235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'x': 7255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flag = EXPORT; 7265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 7285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 7295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (builtin_opt.info & GI_PLUS) { 7315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fclr |= flag; 7325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fset &= ~flag; 7335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru thing = '+'; 7345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 7355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fset |= flag; 7365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fclr &= ~flag; 7375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru thing = '-'; 7385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru field = 0; 7425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (fieldstr && !bi_getn(fieldstr, &field)) 7435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 7445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru base = 0; 7455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (basestr && !bi_getn(basestr, &base)) 7465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 7475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(builtin_opt.info & GI_MINUSMINUS) && wp[builtin_opt.optind] && 7495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (wp[builtin_opt.optind][0] == '-' || 7505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp[builtin_opt.optind][0] == '+') && 7515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp[builtin_opt.optind][1] == '\0') { 7525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru thing = wp[builtin_opt.optind][0]; 7535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru builtin_opt.optind++; 7545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 75603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (func && (((fset|fclr) & ~(TRACE|UCASEV_AL|EXPORT)) || 75703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra set_refflag != SRF_NOP)) { 7585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("only -t, -u and -x options may be used with -f"); 75903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra set_refflag = SRF_NOP; 7605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 7615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (wp[builtin_opt.optind]) { 76303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 76403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Take care of exclusions. 7655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * At this point, flags in fset are cleared in fclr and vice 7665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * versa. This property should be preserved. 7675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 76803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (fset & LCASEV) 76903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* LCASEV has priority over UCASEV_AL */ 7705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fset &= ~UCASEV_AL; 77103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (fset & LJUST) 77203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* LJUST has priority over RJUST */ 7735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fset &= ~RJUST; 77403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((fset & (ZEROFIL|LJUST)) == ZEROFIL) { 77503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -Z implies -ZR */ 7765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fset |= RJUST; 7775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fclr &= ~RJUST; 7785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 77903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 78003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Setting these attributes clears the others, unless they 7815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * are also set in this command 7825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 7835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((fset & (LJUST | RJUST | ZEROFIL | UCASEV_AL | LCASEV | 78403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra INTEGER | INT_U | INT_L)) || set_refflag != SRF_NOP) 7855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fclr |= ~fset & (LJUST | RJUST | ZEROFIL | UCASEV_AL | 7865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru LCASEV | INTEGER | INT_U | INT_L); 7875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* set variables and attributes */ 7905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (wp[builtin_opt.optind]) { 7915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int i, rv = 0; 7925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *f; 7935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (localv && !func) 7955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fset |= LOCAL; 7965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (i = builtin_opt.optind; wp[i]; i++) { 7975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (func) { 7985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru f = findfunc(wp[i], hash(wp[i]), 79903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra tobool(fset & UCASEV_AL)); 8005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!f) { 8015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* AT&T ksh does ++rv: bogus */ 8025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 1; 8035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 8045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (fset | fclr) { 8065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru f->flag |= fset; 8075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru f->flag &= ~fclr; 80803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else { 80903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra fpFUNCTf(shl_stdout, 0, 81003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra tobool(f->flag & FKSH), 81103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra wp[i], f->val.t); 81203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shf_putc('\n', shl_stdout); 81303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 8145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (!typeset(wp[i], fset, fclr, field, base)) { 81503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", wp[i], "not identifier"); 81603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra set_refflag = SRF_NOP; 8175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 8185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 82003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra set_refflag = SRF_NOP; 8215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 8225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* list variables and attributes */ 82503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 82603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* no difference at this point.. */ 82703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra flag = fset | fclr; 8285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (func) { 8295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (l = e->loc; l; l = l->next) { 8305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (p = ktsort(&l->funs); (vp = *p++); ) { 8315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (flag && (vp->flag & flag) == 0) 8325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 8335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (thing == '-') 83403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra fpFUNCTf(shl_stdout, 0, 83503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra tobool(vp->flag & FKSH), 8365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->name, vp->val.t); 8375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 83803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shf_puts(vp->name, shl_stdout); 83903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shf_putc('\n', shl_stdout); 8405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 8435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (l = e->loc; l; l = l->next) { 8445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (p = ktsort(&l->vars); (vp = *p++); ) { 8455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *tvp; 8465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool any_set = false; 8475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 8485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * See if the parameter is set (for arrays, if any 8495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * element is set). 8505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 8515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (tvp = vp; tvp; tvp = tvp->u.array) 8525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tvp->flag & ISSET) { 8535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru any_set = true; 8545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 8555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 8585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Check attributes - note that all array elements 8595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * have (should have?) the same attributes, so checking 8605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * the first is sufficient. 8615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 8625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Report an unset param only if the user has 8635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * explicitly given it some attribute (like export); 8645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * otherwise, after "echo $FOO", we would report FOO... 8655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 8665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!any_set && !(vp->flag & USERATTRIB)) 8675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 8685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (flag && (vp->flag & flag) == 0) 8695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 8705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; vp; vp = vp->u.array) { 87103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 87203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Ignore array elements that aren't 8735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * set unless there are no set elements, 87403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * in which case the first is reported on 87503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra */ 8765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vp->flag&ARRAY) && any_set && 8775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru !(vp->flag & ISSET)) 8785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 8795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* no arguments */ 8805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (thing == 0 && flag == 0) { 88103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 88203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * AT&T ksh prints things 8835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * like export, integer, 8845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * leftadj, zerofill, etc., 8855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * but POSIX says must 8865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * be suitable for re-entry... 8875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 8885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts("typeset ", shl_stdout); 8895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (((vp->flag&(ARRAY|ASSOC))==ASSOC)) 89003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shprintf("%s ", "-n"); 8915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vp->flag&INTEGER)) 89203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shprintf("%s ", "-i"); 8935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vp->flag&EXPORT)) 89403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shprintf("%s ", "-x"); 8955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vp->flag&RDONLY)) 89603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shprintf("%s ", "-r"); 8975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vp->flag&TRACE)) 89803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shprintf("%s ", "-t"); 8995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vp->flag&LJUST)) 9005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shprintf("-L%d ", vp->u2.field); 9015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vp->flag&RJUST)) 9025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shprintf("-R%d ", vp->u2.field); 9035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vp->flag&ZEROFIL)) 90403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shprintf("%s ", "-Z"); 9055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vp->flag&LCASEV)) 90603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shprintf("%s ", "-l"); 9075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vp->flag&UCASEV_AL)) 90803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shprintf("%s ", "-u"); 9095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vp->flag&INT_U)) 91003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shprintf("%s ", "-U"); 9115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts(vp->name, shl_stdout); 9125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (pflag) { 9135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *s = str_val(vp); 9145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_putc('=', shl_stdout); 91603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 91703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * AT&T ksh can't have 91803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * justified integers... 91903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra */ 9205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vp->flag & 9215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (INTEGER|LJUST|RJUST)) == 9225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru INTEGER) 9235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts(s, shl_stdout); 9245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 9255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru print_value_quoted(s); 9265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_putc('\n', shl_stdout); 9285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vp->flag & ARRAY) 9295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 9305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 9315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (pflag) 9325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts(istset ? 9335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "typeset " : 9345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (flag & EXPORT) ? 9355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "export " : 9365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "readonly ", 9375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shl_stdout); 9385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vp->flag&ARRAY) && any_set) 9395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shprintf("%s[%lu]", 9405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->name, 9415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru arrayindex(vp)); 9425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 9435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts(vp->name, shl_stdout); 9445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (thing == '-' && (vp->flag&ISSET)) { 9455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *s = str_val(vp); 9465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_putc('=', shl_stdout); 94803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 94903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * AT&T ksh can't have 95003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * justified integers... 95103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra */ 9525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vp->flag & 9535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (INTEGER|LJUST|RJUST)) == 9545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru INTEGER) 9555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts(s, shl_stdout); 9565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 9575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru print_value_quoted(s); 9585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_putc('\n', shl_stdout); 9605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 96103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 96203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Only report first 'element' of an array with 9635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * no set elements. 9645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 9655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!any_set) 9665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 9675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 9725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 9735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 9755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_alias(const char **wp) 9765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 9775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct table *t = &aliases; 9785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv = 0, prefix = 0; 9795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool rflag = false, tflag, Uflag = false, pflag = false; 98003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra uint32_t xflag = 0; 9815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int optc; 9825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru builtin_opt.flags |= GF_PLUSOPT; 9845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt(wp, &builtin_opt, "dprtUx")) != -1) { 9855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru prefix = builtin_opt.info & GI_PLUS ? '+' : '-'; 9865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 9875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'd': 9885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef MKSH_NOPWNAM 9895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = NULL; /* fix "alias -dt" */ 9905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#else 9915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = &homedirs; 9925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 9935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 9945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'p': 9955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru pflag = true; 9965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 9975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'r': 9985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rflag = true; 9995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 10005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 't': 10015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = &taliases; 10025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 10035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'U': 10045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 10055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * kludge for tracked alias initialization 10065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (don't do a path search, just make an entry) 10075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 10085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Uflag = true; 10095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 10105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'x': 10115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru xflag = EXPORT; 10125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 10135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 10145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 10155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef MKSH_NOPWNAM 10185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (t == NULL) 10195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 10205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 10215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 10225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(builtin_opt.info & GI_MINUSMINUS) && *wp && 10245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (wp[0][0] == '-' || wp[0][0] == '+') && wp[0][1] == '\0') { 10255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru prefix = wp[0][0]; 10265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp++; 10275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tflag = t == &taliases; 10305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* "hash -r" means reset all the tracked aliases.. */ 10325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (rflag) { 10335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru static const char *args[] = { 103403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Tunalias, "-ta", NULL 10355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru }; 10365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!tflag || *wp) { 103803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shprintf("%s: -r flag can only be used with -t" 103903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra " and without arguments\n", Talias); 10405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 10415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ksh_getopt_reset(&builtin_opt, GF_ERROR); 10435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (c_unalias(args)); 10445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*wp == NULL) { 10475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *ap, **p; 10485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (p = ktsort(t); (ap = *p++) != NULL; ) 10505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((ap->flag & (ISSET|xflag)) == (ISSET|xflag)) { 10515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (pflag) 105203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shprintf("%s ", Talias); 10535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts(ap->name, shl_stdout); 10545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (prefix != '+') { 10555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_putc('=', shl_stdout); 10565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru print_value_quoted(ap->val.s); 10575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_putc('\n', shl_stdout); 10595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; *wp != NULL; wp++) { 10635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *alias = *wp, *val, *newval; 10645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *xalias = NULL; 10655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *ap; 10665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru uint32_t h; 10675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((val = cstrchr(alias, '='))) { 10695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strndupx(xalias, alias, val++ - alias, ATEMP); 10705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru alias = xalias; 10715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru h = hash(alias); 10735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (val == NULL && !tflag && !xflag) { 10745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap = ktsearch(t, alias, h); 10755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ap != NULL && (ap->flag&ISSET)) { 10765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (pflag) 107703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shprintf("%s ", Talias); 10785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts(ap->name, shl_stdout); 10795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (prefix != '+') { 10805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_putc('=', shl_stdout); 10815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru print_value_quoted(ap->val.s); 10825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_putc('\n', shl_stdout); 10845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 108503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shprintf("%s %s %s\n", alias, Talias, 108603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra "not found"); 10875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 1; 10885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 10905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap = ktenter(t, alias, h); 10925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap->type = tflag ? CTALIAS : CALIAS; 10935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Are we setting the value or just some flags? */ 10945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((val && !tflag) || (!val && tflag && !Uflag)) { 10955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ap->flag&ALLOC) { 10965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap->flag &= ~(ALLOC|ISSET); 10975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(ap->val.s, APERM); 10985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* ignore values for -t (AT&T ksh does this) */ 110003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra newval = tflag ? 110103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra search_path(alias, path, X_OK, NULL) : 110203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra val; 11035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (newval) { 11045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strdupx(ap->val.s, newval, APERM); 11055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap->flag |= ALLOC|ISSET; 11065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 11075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap->flag &= ~ISSET; 11085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap->flag |= DEFINED; 11105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (prefix == '+') 11115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap->flag &= ~xflag; 11125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 11135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap->flag |= xflag; 11145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(xalias, ATEMP); 11155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 11185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 11195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 11215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_unalias(const char **wp) 11225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 11235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct table *t = &aliases; 11245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *ap; 11255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int optc, rv = 0; 11265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool all = false; 11275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt(wp, &builtin_opt, "adt")) != -1) 11295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 11305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'a': 11315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru all = true; 11325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 11335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'd': 11345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef MKSH_NOPWNAM 113503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* fix "unalias -dt" */ 113603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra t = NULL; 11375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#else 11385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = &homedirs; 11395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 11405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 11415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 't': 11425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = &taliases; 11435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 11445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 11455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 11465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef MKSH_NOPWNAM 11485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (t == NULL) 11495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 11505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 11515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 11525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; *wp != NULL; wp++) { 11545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap = ktsearch(t, *wp, hash(*wp)); 11555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ap == NULL) { 115603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* POSIX */ 115703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 1; 11585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 11595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ap->flag&ALLOC) { 11615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap->flag &= ~(ALLOC|ISSET); 11625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(ap->val.s, APERM); 11635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap->flag &= ~(DEFINED|ISSET|EXPORT); 11655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (all) { 11685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tstate ts; 11695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (ktwalk(&ts, t); (ap = ktnext(&ts)); ) { 11715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ap->flag&ALLOC) { 11725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap->flag &= ~(ALLOC|ISSET); 11735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(ap->val.s, APERM); 11745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ap->flag &= ~(DEFINED|ISSET|EXPORT); 11765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 11805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 11815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 11835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_let(const char **wp) 11845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 11855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv = 1; 11865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mksh_ari_t val; 11875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 118803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (wp[1] == NULL) 118903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* AT&T ksh does this */ 11905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("no arguments"); 11915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 11925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (wp++; *wp; wp++) 11935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!evaluate(*wp, &val, KSH_RETURN_ERROR, true)) { 119403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* distinguish error from zero result */ 119503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 2; 11965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 11975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 11985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = val == 0; 11995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 12005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 12015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 12035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_jobs(const char **wp) 12045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 12055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int optc, flag = 0, nflag = 0, rv = 0; 12065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt(wp, &builtin_opt, "lpnz")) != -1) 12085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 12095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'l': 12105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flag = 1; 12115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'p': 12135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru flag = 2; 12145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'n': 12165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nflag = 1; 12175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 121803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'z': 121903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* debugging: print zombies */ 12205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nflag = -1; 12215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 12235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 12245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 12255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 12265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!*wp) { 12275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (j_jobs(NULL, flag, nflag)) 12285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 1; 12295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 12305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; *wp; wp++) 12315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (j_jobs(*wp, flag, nflag)) 12325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 1; 12335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 12345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 12355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 12365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_UNEMPLOYED 12385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 12395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_fgbg(const char **wp) 12405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 12415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool bg = strcmp(*wp, "bg") == 0; 12425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv = 0; 12435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!Flag(FMONITOR)) { 12455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("job control not enabled"); 12465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 12475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 12485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_getopt(wp, &builtin_opt, null) == '?') 12495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 12505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 12515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*wp) 12525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; *wp; wp++) 12535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = j_resume(*wp, bg); 12545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 12555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = j_resume("%%", bg); 12565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (bg ? 0 : rv); 12575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 12585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 12595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* format a single kill item */ 12615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic char * 126203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrakill_fmt_entry(char *buf, size_t buflen, int i, const void *arg) 12635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 12645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const struct kill_info *ki = (const struct kill_info *)arg; 12655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru i++; 12675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_snprintf(buf, buflen, "%*d %*s %s", 12685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ki->num_width, i, 12695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ki->name_width, sigtraps[i].name, 12705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sigtraps[i].mess); 12715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (buf); 12725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 12735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 12755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_kill(const char **wp) 12765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 12775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Trap *t = NULL; 12785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *p; 12795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool lflag = false; 12805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int i, n, rv, sig; 12815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* assume old style options if -digits or -UPPERCASE */ 12835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((p = wp[1]) && *p == '-' && (ksh_isdigit(p[1]) || 12845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ksh_isupper(p[1]))) { 12855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(t = gettrap(p + 1, true))) { 12865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("bad signal '%s'", p + 1); 12875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 12885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 12895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru i = (wp[2] && strcmp(wp[2], "--") == 0) ? 3 : 2; 12905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 12915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int optc; 12925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt(wp, &builtin_opt, "ls:")) != -1) 12945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 12955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'l': 12965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru lflag = true; 12975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 's': 12995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(t = gettrap(builtin_opt.optarg, true))) { 13005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("bad signal '%s'", 13015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru builtin_opt.optarg); 13025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 13035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 13055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 13065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 13075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru i = builtin_opt.optind; 13095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((lflag && t) || (!wp[i] && !lflag)) { 13115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_SMALL 13125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts("usage:\tkill [-s signame | -signum | -signame]" 13135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru " { job | pid | pgrp } ...\n" 13145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "\tkill -l [exit_status ...]\n", shl_out); 13155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 13165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorfz(); 13175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 13185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (lflag) { 13215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (wp[i]) { 13225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; wp[i]; i++) { 13235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!bi_getn(wp[i], &n)) 13245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 13255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (n > 128 && n < 128 + NSIG) 13265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru n -= 128; 13275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (n > 0 && n < NSIG) 13285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shprintf("%s\n", sigtraps[n].name); 13295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 13305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shprintf("%d\n", n); 13315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 133303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ssize_t w, mess_cols, mess_octs; 133403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra int j; 13355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct kill_info ki; 13365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (j = NSIG, ki.num_width = 1; j >= 10; j /= 10) 13385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ki.num_width++; 13395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ki.name_width = mess_cols = mess_octs = 0; 13405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (j = 0; j < NSIG; j++) { 13415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru w = strlen(sigtraps[j].name); 13425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (w > ki.name_width) 13435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ki.name_width = w; 13445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru w = strlen(sigtraps[j].mess); 13455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (w > mess_octs) 13465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mess_octs = w; 13475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru w = utf_mbswidth(sigtraps[j].mess); 13485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (w > mess_cols) 13495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mess_cols = w; 13505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru print_columns(shl_stdout, NSIG - 1, 13535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru kill_fmt_entry, (void *)&ki, 13545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ki.num_width + 1 + ki.name_width + 1 + mess_octs, 13555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ki.num_width + 1 + ki.name_width + 1 + mess_cols, 13565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru true); 13575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 13595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 0; 13615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sig = t ? t->signal : SIGTERM; 13625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; (p = wp[i]); i++) { 13635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*p == '%') { 13645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (j_kill(p, sig)) 13655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 1; 13665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (!getn(p, &n)) { 136703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", p, 136803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra "arguments must be jobs or process IDs"); 13695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 1; 13705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 13715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (mksh_kill(n, sig) < 0) { 13725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("%s: %s", p, strerror(errno)); 13735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 1; 13745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 13785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 13795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 13815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querugetopts_reset(int val) 13825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 13835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (val >= 1) { 13845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ksh_getopt_reset(&user_opt, GF_NONAME | GF_PLUSOPT); 13855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru user_opt.optind = user_opt.uoptind = val; 13865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 13885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 13905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_getopts(const char **wp) 13915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 13925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int argc, optc, rv; 13935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *opts, *var; 13945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char buf[3]; 13955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *vq, *voptarg; 13965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_getopt(wp, &builtin_opt, null) == '?') 13985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 13995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 14005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru opts = *wp++; 14025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!opts) { 140303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("missing %s argument", "options"); 14045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 14055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru var = *wp++; 14085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!var) { 140903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("missing %s argument", "name"); 14105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 14115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!*var || *skip_varname(var, true)) { 141303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", var, "is not an identifier"); 14145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 14155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (e->loc->next == NULL) { 141803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra internal_warningf("%s: %s", "c_getopts", "no argv"); 14195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 14205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Which arguments are we parsing... */ 14225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*wp == NULL) 14235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp = e->loc->next->argv; 14245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 14255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *--wp = e->loc->next->argv[0]; 14265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Check that our saved state won't cause a core dump... */ 14285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (argc = 0; wp[argc]; argc++) 14295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 14305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (user_opt.optind > argc || 14315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (user_opt.p != 0 && 14325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru user_opt.p > strlen(wp[user_opt.optind - 1]))) { 14335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("arguments changed since last call"); 14345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 14355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru user_opt.optarg = NULL; 14385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru optc = ksh_getopt(wp, &user_opt, opts); 14395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (optc >= 0 && optc != '?' && (user_opt.info & GI_PLUS)) { 14415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru buf[0] = '+'; 14425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru buf[1] = optc; 14435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru buf[2] = '\0'; 14445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 144503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 144603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * POSIX says var is set to ? at end-of-options, AT&T ksh 14475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * sets it to null - we go with POSIX... 14485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 14495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru buf[0] = optc < 0 ? '?' : optc; 14505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru buf[1] = '\0'; 14515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* AT&T ksh93 in fact does change OPTIND for unknown options too */ 14545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru user_opt.uoptind = user_opt.optind; 14555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru voptarg = global("OPTARG"); 145703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* AT&T ksh clears ro and int */ 145803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra voptarg->flag &= ~RDONLY; 14595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Paranoia: ensure no bizarre results. */ 14605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (voptarg->flag & INTEGER) 14615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru typeset("OPTARG", 0, INTEGER, 0, 0); 14625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (user_opt.optarg == NULL) 14635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unset(voptarg, 1); 14645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 14655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* This can't fail (have cleared readonly/integer) */ 14665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setstr(voptarg, user_opt.optarg, KSH_RETURN_ERROR); 14675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 0; 14695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vq = global(var); 14715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Error message already printed (integer, readonly) */ 14725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!setstr(vq, buf, KSH_RETURN_ERROR)) 147303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 2; 14745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (Flag(FEXPORT)) 14755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru typeset(var, EXPORT, 0, 0, 0); 14765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (optc < 0 ? 1 : rv); 14785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 14795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 14815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_bind(const char **wp) 14825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 14835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int optc, rv = 0; 14845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_SMALL 14855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool macro = false; 14865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 14875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool list = false; 14885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *cp; 14895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *up; 14905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt(wp, &builtin_opt, 14925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_SMALL 14935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "lm" 14945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#else 14955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "l" 14965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 14975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru )) != -1) 14985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 14995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'l': 15005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru list = true; 15015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 15025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_SMALL 15035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'm': 15045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru macro = true; 15055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 15065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 15075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 15085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 15095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 15115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 151203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (*wp == NULL) 151303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* list all */ 15145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = x_bind(NULL, NULL, 15155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_SMALL 15165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru false, 15175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 15185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru list); 15195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; *wp != NULL; wp++) { 15215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((cp = cstrchr(*wp, '=')) == NULL) 15225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru up = NULL; 15235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else { 15245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strdupx(up, *wp, ATEMP); 15255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru up[cp++ - *wp] = '\0'; 15265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (x_bind(up ? up : *wp, cp, 15285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_SMALL 15295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru macro, 15305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 15315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru false)) 15325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 1; 15335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(up, ATEMP); 15345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 15375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 15385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 15405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_shift(const char **wp) 15415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 15425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct block *l = e->loc; 15435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int n; 15445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mksh_ari_t val; 15455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *arg; 15465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_getopt(wp, &builtin_opt, null) == '?') 15485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 15495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru arg = wp[builtin_opt.optind]; 15505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (arg) { 15525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru evaluate(arg, &val, KSH_UNWIND_ERROR, false); 15535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru n = val; 15545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 15555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru n = 1; 15565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (n < 0) { 155703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", arg, "bad number"); 15585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 15595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (l->argc < n) { 15615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("nothing to shift"); 15625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 15635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru l->argv[n] = l->argv[0]; 15655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru l->argv += n; 15665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru l->argc -= n; 15675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 15685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 15695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 15715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_umask(const char **wp) 15725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 15735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int i, optc; 15745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *cp; 15755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool symbolic = false; 15765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mode_t old_umask; 15775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt(wp, &builtin_opt, "S")) != -1) 15795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 15805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'S': 15815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru symbolic = true; 15825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 15835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 15845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 15855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru cp = wp[builtin_opt.optind]; 15875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (cp == NULL) { 15885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru old_umask = umask((mode_t)0); 15895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru umask(old_umask); 15905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (symbolic) { 15915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char buf[18], *p; 15925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int j; 15935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru old_umask = ~old_umask; 15955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p = buf; 15965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (i = 0; i < 3; i++) { 15975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *p++ = "ugo"[i]; 15985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *p++ = '='; 15995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (j = 0; j < 3; j++) 16005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (old_umask & (1 << (8 - (3*i + j)))) 16015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *p++ = "rwx"[j]; 16025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *p++ = ','; 16035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 16045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p[-1] = '\0'; 16055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shprintf("%s\n", buf); 16065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 16075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shprintf("%#3.3o\n", (unsigned int)old_umask); 16085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 16095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mode_t new_umask; 16105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_isdigit(*cp)) { 16125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (new_umask = 0; *cp >= '0' && *cp <= '7'; cp++) 16135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru new_umask = new_umask * 8 + (*cp - '0'); 16145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*cp) { 16155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("bad number"); 16165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 16175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 16185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 16195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* symbolic format */ 16205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int positions, new_val; 16215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char op; 16225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru old_umask = umask((mode_t)0); 162403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* in case of error */ 162503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra umask(old_umask); 16265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru old_umask = ~old_umask; 16275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru new_umask = old_umask; 16285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru positions = 0; 16295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (*cp) { 16305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (*cp && vstrchr("augo", *cp)) 16315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (*cp++) { 16325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'a': 16335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru positions |= 0111; 16345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'u': 16365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru positions |= 0100; 16375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'g': 16395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru positions |= 0010; 16405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'o': 16425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru positions |= 0001; 16435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 16455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!positions) 164603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* default is a */ 164703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra positions = 0111; 16485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!vstrchr("=+-", op = *cp)) 16495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru cp++; 16515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru new_val = 0; 16525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (*cp && vstrchr("rwxugoXs", *cp)) 16535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (*cp++) { 16545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'r': new_val |= 04; break; 16555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'w': new_val |= 02; break; 16565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'x': new_val |= 01; break; 16575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'u': 16585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru new_val |= old_umask >> 6; 16595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'g': 16615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru new_val |= old_umask >> 3; 16625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'o': 16645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru new_val |= old_umask >> 0; 16655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'X': 16675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (old_umask & 0111) 16685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru new_val |= 01; 16695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 's': 16715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* ignored */ 16725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 16745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru new_val = (new_val & 07) * positions; 16755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (op) { 16765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '-': 16775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru new_umask &= ~new_val; 16785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '=': 16805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru new_umask = new_val | 16815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (new_umask & ~(positions * 07)); 16825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '+': 16845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru new_umask |= new_val; 16855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 16865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*cp == ',') { 16875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru positions = 0; 16885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru cp++; 16895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (!vstrchr("=+-", *cp)) 16905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 16925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*cp) { 16935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("bad mask"); 16945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 16955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 16965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru new_umask = ~new_umask; 16975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 16985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru umask(new_umask); 16995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 17015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 17025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 17045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_dot(const char **wp) 17055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 17065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *file, *cp, **argv; 17075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int argc, i, errcode; 17085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_getopt(wp, &builtin_opt, null) == '?') 17105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 17115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((cp = wp[builtin_opt.optind]) == NULL) { 17135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("missing argument"); 17145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 17155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 171603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((file = search_path(cp, path, R_OK, &errcode)) == NULL) { 171703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", cp, strerror(errcode)); 17185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 17195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Set positional parameters? */ 17225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (wp[builtin_opt.optind + 1]) { 17235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru argv = wp + builtin_opt.optind; 172403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* preserve $0 */ 172503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra argv[0] = e->loc->argv[0]; 17265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (argc = 0; argv[argc + 1]; argc++) 17275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 17285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 17295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru argc = 0; 17305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru argv = NULL; 17315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((i = include(file, argc, argv, 0)) < 0) { 17335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* should not happen */ 17345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("%s: %s", cp, strerror(errno)); 17355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 17365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (i); 17385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 17395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 17415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_wait(const char **wp) 17425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 17435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv = 0, sig; 17445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_getopt(wp, &builtin_opt, null) == '?') 17465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 17475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 17485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*wp == NULL) { 17495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (waitfor(NULL, &sig) >= 0) 17505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 17515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = sig; 17525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 17535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; *wp; wp++) 17545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = waitfor(*wp, &sig); 17555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (rv < 0) 175603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* magic exit code: bad job-id */ 175703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = sig ? sig : 127; 17585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 17605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 17615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 17635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_read(const char **wp) 17645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 176503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define is_ifsws(c) (ctype((c), C_IFS) && ctype((c), C_IFSWS)) 17665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru static char REPLY[] = "REPLY"; 176703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra int c, fd = 0, rv = 0, lastparm = 0; 176803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bool savehist = false, intoarray = false, aschars = false; 176903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bool rawmode = false, expanding = false; 177003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra enum { LINES, BYTES, UPTO, READALL } readmode = LINES; 177103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra char delim = '\n'; 177203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra size_t bytesleft = 128, bytesread; 177303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra struct tbl *vp /* FU gcc */ = NULL, *vq; 177403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra char *cp, *allocd = NULL, *xp; 177503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra const char *ccp; 177603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra XString xs; 177703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ptrdiff_t xsave = 0; 177803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra struct termios tios; 177903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bool restore_tios = false; 178003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#if HAVE_SELECT 178103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bool hastimeout = false; 178203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra struct timeval tv, tvlim; 178303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define c_read_opts "Aad:N:n:prst:u," 178403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#else 178503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define c_read_opts "Aad:N:n:prsu," 178603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 17875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 178803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while ((c = ksh_getopt(wp, &builtin_opt, c_read_opts)) != -1) 178903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra switch (c) { 179003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'a': 179103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra aschars = true; 179203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* FALLTHROUGH */ 179303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'A': 179403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra intoarray = true; 179503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 179603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'd': 179703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra delim = builtin_opt.optarg[0]; 179803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 179903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'N': 180003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'n': 180103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra readmode = c == 'N' ? BYTES : UPTO; 180203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!bi_getn(builtin_opt.optarg, &c)) 180303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (2); 180403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (c == -1) { 180503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra readmode = READALL; 180603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bytesleft = 1024; 180703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else 180803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bytesleft = (unsigned int)c; 180903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 181003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'p': 181103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((fd = coproc_getfd(R_OK, &ccp)) < 0) { 181203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", "-p", ccp); 181303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (2); 18145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 181503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 181603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'r': 181703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rawmode = true; 181803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 181903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 's': 182003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra savehist = true; 182103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 182203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#if HAVE_SELECT 182303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 't': 182403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (parse_usec(builtin_opt.optarg, &tv)) { 182503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s '%s'", Tsynerr, strerror(errno), 182603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra builtin_opt.optarg); 182703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (2); 182803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 182903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra hastimeout = true; 183003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 183103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 183203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'u': 183303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!builtin_opt.optarg[0]) 183403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra fd = 0; 183503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else if ((fd = check_fd(builtin_opt.optarg, R_OK, &ccp)) < 0) { 183603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s: %s", "-u", builtin_opt.optarg, ccp); 183703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (2); 183803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 183903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 184003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case '?': 184103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (2); 184203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 18435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 18445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*wp == NULL) 18455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *--wp = REPLY; 18465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 184703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (intoarray && wp[1] != NULL) { 184803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("too many arguments"); 184903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (2); 185003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 18515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 185203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((ccp = cstrchr(*wp, '?')) != NULL) { 185303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra strdupx(allocd, *wp, ATEMP); 185403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra allocd[ccp - *wp] = '\0'; 185503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra *wp = allocd; 18565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (isatty(fd)) { 185703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 185803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * AT&T ksh says it prints prompt on fd if it's open 18595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * for writing and is a tty, but it doesn't do it 18605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (it also doesn't check the interactive flag, 186103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * as is indicated in the Korn Shell book). 18625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 186303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shf_puts(ccp + 1, shl_out); 186403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra shf_flush(shl_out); 18655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 18665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 18675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 186803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xinit(xs, xp, bytesleft, ATEMP); 18695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 187003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (readmode == LINES) 187103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bytesleft = 1; 187203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else if (isatty(fd)) { 187303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra x_mkraw(fd, &tios, true); 187403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra restore_tios = true; 187503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 18765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 187703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#if HAVE_SELECT 187803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (hastimeout) { 187903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra gettimeofday(&tvlim, NULL); 188003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra timeradd(&tvlim, &tv, &tvlim); 188103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 188203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 188303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 188403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c_read_readloop: 188503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#if HAVE_SELECT 188603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (hastimeout) { 188703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra fd_set fdset; 188803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 188903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra FD_ZERO(&fdset); 189003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra FD_SET(fd, &fdset); 189103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra gettimeofday(&tv, NULL); 189203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra timersub(&tvlim, &tv, &tv); 189303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (tv.tv_sec < 0) { 189403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* timeout expired globally */ 189503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 1; 189603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_out; 189703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 189803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 189903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra switch (select(fd + 1, &fdset, NULL, NULL, &tv)) { 190003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 1: 190103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 190203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 0: 190303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* timeout expired for this call */ 190403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 1; 190503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_out; 190603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra default: 190703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", Tselect, strerror(errno)); 190803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 2; 190903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_out; 191003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 191103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 191203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 191303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 191403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bytesread = blocking_read(fd, xp, bytesleft); 191503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (bytesread == (size_t)-1) { 191603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* interrupted */ 191703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (errno == EINTR && fatal_trap_check()) { 191803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 191903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Was the offending signal one that would 192003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * normally kill a process? If so, pretend 192103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * the read was killed. 192203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra */ 192303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 2; 192403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_out; 192503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 192603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* just ignore the signal */ 192703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_readloop; 192803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 192903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 193003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra switch (readmode) { 193103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case READALL: 193203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (bytesread == 0) { 193303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* end of file reached */ 193403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 1; 193503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_readdone; 193603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 193703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xp += bytesread; 193803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra XcheckN(xs, xp, bytesleft); 193903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 194003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 194103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case UPTO: 194203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (bytesread == 0) 194303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* end of file reached */ 194403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 1; 194503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xp += bytesread; 194603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_readdone; 194703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 194803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case BYTES: 194903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (bytesread == 0) { 195003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* end of file reached */ 195103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 1; 195203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xp = Xstring(xs, xp); 195303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_readdone; 195403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 195503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xp += bytesread; 195603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((bytesleft -= bytesread) == 0) 195703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_readdone; 195803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 195903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case LINES: 196003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (bytesread == 0) { 196103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* end of file reached */ 196203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 1; 196303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_readdone; 196403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 196503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((c = *xp) == '\0' && !aschars && delim != '\0') { 196603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* skip any read NULs unless delimiter */ 196703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 196803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 196903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (expanding) { 197003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra expanding = false; 197103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (c == delim) { 197203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (Flag(FTALKING_I) && isatty(fd)) { 197303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 197403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * set prompt in case this is 197503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * called from .profile or $ENV 197603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra */ 197703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra set_prompt(PS2, NULL); 197803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra pprompt(prompt, 0); 19795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 198003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* drop the backslash */ 198103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra --xp; 198203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* and the delimiter */ 19835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 19845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 198503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else if (c == delim) { 198603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_readdone; 198703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else if (!rawmode && c == '\\') { 198803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra expanding = true; 198903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 199003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xcheck(xs, xp); 199103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++xp; 199203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 199303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 199403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_readloop; 199503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 199603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c_read_readdone: 199703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bytesread = Xlength(xs, xp); 199803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xput(xs, xp, '\0'); 199903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 200003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /*- 200103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * state: we finished reading the input and NUL terminated it 200203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Xstring(xs, xp) -> xp-1 = input string without trailing delim 200303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * rv = 1 if EOF, 0 otherwise (errors handled already) 200403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra */ 200503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 200603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (rv == 1) { 200703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* clean up coprocess if needed, on EOF */ 200803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra coproc_read_close(fd); 200903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (readmode == READALL) 201003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* EOF is no error here */ 201103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 0; 201203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 201303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 201403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (savehist) 201503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra histsave(&source->line, Xstring(xs, xp), true, false); 201603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 201703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ccp = cp = Xclose(xs, xp); 201803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra expanding = false; 201903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra XinitN(xs, 128, ATEMP); 202003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (intoarray) { 20215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp = global(*wp); 20225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vp->flag & RDONLY) { 202303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c_read_splitro: 202403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", *wp, "is read only"); 202503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c_read_spliterr: 202603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 2; 202703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra afree(cp, ATEMP); 202803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_out; 202903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 203003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* exporting an array is currently pointless */ 203103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra unset(vp, 1); 203203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* counter for array index */ 203303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c = 0; 203403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 203503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!aschars) { 203603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* skip initial IFS whitespace */ 203703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (bytesread && is_ifsws(*ccp)) { 203803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++ccp; 203903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra --bytesread; 204003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 204103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* trim trailing IFS whitespace */ 204203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (bytesread && is_ifsws(ccp[bytesread - 1])) { 204303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra --bytesread; 204403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 204503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 204603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c_read_splitloop: 204703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xp = Xstring(xs, xp); 204803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* generate next word */ 204903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!bytesread) { 205003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* no more input */ 205103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (intoarray) 205203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_splitdone; 205303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* zero out next parameters */ 205403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_gotword; 205503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 205603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (aschars) { 205703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xput(xs, xp, '1'); 205803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xput(xs, xp, '#'); 205903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bytesleft = utf_ptradj(ccp); 206003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (bytesleft && bytesread) { 206103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra *xp++ = *ccp++; 206203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra --bytesleft; 206303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra --bytesread; 206403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 206503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (xp[-1] == '\0') { 206603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xp[-1] = '0'; 206703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xp[-3] = '2'; 206803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 206903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_gotword; 207003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 207103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 207203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!intoarray && wp[1] == NULL) 207303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra lastparm = 1; 207403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 207503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c_read_splitlast: 207603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* copy until IFS character */ 207703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (bytesread) { 207803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra char ch; 207903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 208003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ch = *ccp; 208103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (expanding) { 208203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra expanding = false; 208303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_splitcopy; 208403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else if (ctype(ch, C_IFS)) { 208503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 208603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else if (!rawmode && ch == '\\') { 208703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra expanding = true; 208803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else { 208903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c_read_splitcopy: 209003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xcheck(xs, xp); 209103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xput(xs, xp, ch); 20925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 209303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++ccp; 209403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra --bytesread; 209503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 209603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xsave = Xsavepos(xs, xp); 209703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* copy word delimiter: IFSWS+IFS,IFSWS */ 209803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (bytesread) { 209903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra char ch; 210003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 210103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ch = *ccp; 210203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!ctype(ch, C_IFS)) 210303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 210403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xcheck(xs, xp); 210503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xput(xs, xp, ch); 210603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++ccp; 210703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra --bytesread; 210803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!ctype(ch, C_IFSWS)) 210903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 211003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 211103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (bytesread && is_ifsws(*ccp)) { 211203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xcheck(xs, xp); 211303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xput(xs, xp, *ccp); 211403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++ccp; 211503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra --bytesread; 211603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 211703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* if no more parameters, rinse and repeat */ 211803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (lastparm && bytesread) { 211903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++lastparm; 212003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_splitlast; 212103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 212203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* get rid of the delimiter unless we pack the rest */ 212303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (lastparm < 2) 212403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xp = Xrestpos(xs, xp, xsave); 212503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c_read_gotword: 212603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xput(xs, xp, '\0'); 212703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (intoarray) { 212803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vq = arraysearch(vp, c++); 212903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else { 213003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vq = global(*wp); 213103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* must be checked before exporting */ 213203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (vq->flag & RDONLY) 213303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_splitro; 21345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (Flag(FEXPORT)) 21355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru typeset(*wp, EXPORT, 0, 0, 0); 21365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 213703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!setstr(vq, Xstring(xs, xp), KSH_RETURN_ERROR)) 213803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_spliterr; 213903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (aschars) { 214003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra setint_v(vq, vq, false); 214103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* protect from UTFMODE changes */ 214203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vq->type = 0; 21435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 214403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (intoarray || *++wp != NULL) 214503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto c_read_splitloop; 214603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 214703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c_read_splitdone: 214803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* free up */ 214903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra afree(cp, ATEMP); 21505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 215103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c_read_out: 215203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra afree(allocd, ATEMP); 215303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xfree(xs, xp); 215403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (restore_tios) 215503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra tcsetattr(fd, TCSADRAIN, &tios); 215603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (rv); 215703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#undef is_ifsws 21585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 21595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 21605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 21615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_eval(const char **wp) 21625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 21635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct source *s, *saves = source; 21645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unsigned char savef; 21655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv; 21665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 21675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_getopt(wp, &builtin_opt, null) == '?') 21685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 21695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = pushs(SWORDS, ATEMP); 21705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->u.strv = wp + builtin_opt.optind; 21715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 21725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /*- 21735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * The following code handles the case where the command is 21745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * empty due to failed command substitution, for example by 21755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * eval "$(false)" 21765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * This has historically returned 1 by AT&T ksh88. In this 21775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * case, shell() will not set or change exstat because the 21785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * compiled tree is empty, so it will use the value we pass 21795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * from subst_exstat, which is cleared in execute(), so it 21805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * should have been 0 if there were no substitutions. 21815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 21825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * POSIX however says we don't do this, even though it is 21835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * traditionally done. AT&T ksh93 agrees with POSIX, so we 21845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * do. The following is an excerpt from SUSv4 [1003.2-2008]: 21855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 21865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 2.9.1: Simple Commands 21875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * ... If there is a command name, execution shall 21885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * continue as described in 2.9.1.1 [Command Search 21895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * and Execution]. If there is no command name, but 21905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * the command contained a command substitution, the 21915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * command shall complete with the exit status of the 21925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * last command substitution performed. 21935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 2.9.1.1: Command Search and Execution 21945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (1) a. If the command name matches the name of a 21955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * special built-in utility, that special built-in 21965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * utility shall be invoked. 21975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 2.14.5: eval 21985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * If there are no arguments, or only null arguments, 21995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * eval shall return a zero exit status; ... 22005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 22015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* exstat = subst_exstat; */ /* AT&T ksh88 */ 22025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru exstat = 0; /* SUSv4 */ 22035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 22045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru savef = Flag(FERREXIT); 22055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Flag(FERREXIT) = 0; 22065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = shell(s, false); 22075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Flag(FERREXIT) = savef; 22085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source = saves; 22095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(s, ATEMP); 22105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 22115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 22125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 22135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 22145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_trap(const char **wp) 22155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 22165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int i; 22175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *s; 22185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Trap *p; 22195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 22205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_getopt(wp, &builtin_opt, null) == '?') 22215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 22225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 22235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 22245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*wp == NULL) { 22255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (p = sigtraps, i = NSIG+1; --i >= 0; p++) 22265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (p->trap != NULL) { 22275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts("trap -- ", shl_stdout); 22285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru print_value_quoted(p->trap); 22295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shprintf(" %s\n", p->name); 22305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 22315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 22325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 22335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 22345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 22355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Use case sensitive lookup for first arg so the 22365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * command 'exit' isn't confused with the pseudo-signal 22375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 'EXIT'. 22385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 223903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* get command */ 224003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra s = (gettrap(*wp, false) == NULL) ? *wp++ : NULL; 22415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s != NULL && s[0] == '-' && s[1] == '\0') 22425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = NULL; 22435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 22445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* set/clear traps */ 224503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra i = 0; 224603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (*wp != NULL) 224703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((p = gettrap(*wp++, true)) == NULL) { 224803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra warningf(true, "%s: %s '%s'", builtin_argv0, 224903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra "bad signal", wp[-1]); 225003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++i; 225103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else 225203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra settrap(p, s); 225303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (i); 22545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 22555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 22565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 22575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_exitreturn(const char **wp) 22585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 22595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int n, how = LEXIT; 22605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *arg; 22615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 22625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_getopt(wp, &builtin_opt, null) == '?') 22635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 22645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru arg = wp[builtin_opt.optind]; 22655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 22665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (arg) { 22675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!getn(arg, &n)) { 22685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru exstat = 1; 226903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra warningf(true, "%s: %s", arg, "bad number"); 22705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 22715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru exstat = n; 227203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else if (trap_exstat != -1) 227303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra exstat = trap_exstat; 227403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (wp[0][0] == 'r') { 227503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* return */ 22765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct env *ep; 22775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 227803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 227903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * need to tell if this is exit or return so trap exit will 22805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * work right (POSIX) 22815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 22825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (ep = e; ep; ep = ep->oenv) 22835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (STOP_RETURN(ep->type)) { 22845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru how = LRETURN; 22855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 22865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 22875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 22885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 22895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (how == LEXIT && !really_exit && j_stopped_running()) { 22905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru really_exit = 1; 22915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru how = LSHELL; 22925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 22935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 229403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* get rid of any i/o redirections */ 229503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra quitenv(NULL); 22965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unwind(how); 22975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* NOTREACHED */ 22985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 22995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 23005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 23015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_brkcont(const char **wp) 23025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 23035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int n, quit; 23045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct env *ep, *last_ep = NULL; 23055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *arg; 23065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 23075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_getopt(wp, &builtin_opt, null) == '?') 23085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 23095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru arg = wp[builtin_opt.optind]; 23105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 23115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!arg) 23125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru n = 1; 23135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (!bi_getn(arg, &n)) 23145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 23155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru quit = n; 23165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (quit <= 0) { 23175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* AT&T ksh does this for non-interactive shells only - weird */ 231803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", arg, "bad value"); 23195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 23205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 23215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 23225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Stop at E_NONE, E_PARSE, E_FUNC, or E_INCL */ 23235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (ep = e; ep && !STOP_BRKCONT(ep->type); ep = ep->oenv) 23245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ep->type == E_LOOP) { 23255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (--quit == 0) 23265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 23275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ep->flags |= EF_BRKCONT_PASS; 23285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru last_ep = ep; 23295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 23305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 23315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (quit) { 233203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 233303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * AT&T ksh doesn't print a message - just does what it 23345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * can. We print a message 'cause it helps in debugging 23355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * scripts, but don't generate an error (ie, keep going). 23365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 23375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (n == quit) { 233803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra warningf(true, "%s: %s %s", wp[0], "can't", wp[0]); 23395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 23405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 234103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 234203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * POSIX says if n is too big, the last enclosing loop 23435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * shall be used. Doesn't say to print an error but we 23445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * do anyway 'cause the user messed up. 23455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 23465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (last_ep) 23475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru last_ep->flags &= ~EF_BRKCONT_PASS; 23485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru warningf(true, "%s: can only %s %d level(s)", 23495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp[0], wp[0], n - quit); 23505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 23515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 23525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unwind(*wp[0] == 'b' ? LBREAK : LCONTIN); 23535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* NOTREACHED */ 23545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 23555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 23565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 23575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_set(const char **wp) 23585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 23595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int argi; 23605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool setargs; 23615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct block *l = e->loc; 23625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char **owp; 23635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 23645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (wp[1] == NULL) { 236503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra static const char *args[] = { Tset, "-", NULL }; 23665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (c_typeset(args)); 23675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 23685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 23695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru argi = parse_args(wp, OF_SET, &setargs); 23705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (argi < 0) 23715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 23725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* set $# and $* */ 23735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (setargs) { 23745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += argi - 1; 23755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru owp = wp; 237603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* save $0 */ 237703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra wp[0] = l->argv[0]; 23785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (*++wp != NULL) 23795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strdupx(*wp, *wp, &l->area); 23805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru l->argc = wp - owp - 1; 238103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra l->argv = alloc2(l->argc + 2, sizeof(char *), &l->area); 23825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (wp = l->argv; (*wp++ = *owp++) != NULL; ) 23835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 23845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 23855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /*- 23865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * POSIX says set exit status is 0, but old scripts that use 23875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * getopt(1) use the construct 23885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * set -- $(getopt ab:c "$@") 23895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * which assumes the exit value set will be that of the $() 23905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (subst_exstat is cleared in execute() so that it will be 0 23915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * if there are no command substitutions). 23925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Switched ksh (!posix !sh) to POSIX in mksh R39b. 23935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 23945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (Flag(FSH) ? subst_exstat : 0); 23955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 23965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 23975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 23985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_unset(const char **wp) 23995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 24005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *id; 240103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra int optc, rv = 0; 24025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool unset_var = true; 24035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 24045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt(wp, &builtin_opt, "fv")) != -1) 24055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 24065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'f': 24075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unset_var = false; 24085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 24095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'v': 24105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unset_var = true; 24115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 24125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 241303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /*XXX not reached due to GF_ERROR */ 241403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (2); 24155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 24165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 24175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; (id = *wp) != NULL; wp++) 241803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (unset_var) { 241903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* unset variable */ 24205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *vp; 24215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *cp = NULL; 24225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru size_t n; 24235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 24245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru n = strlen(id); 24255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (n > 3 && id[n-3] == '[' && id[n-2] == '*' && 24265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru id[n-1] == ']') { 24275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strndupx(cp, id, n - 3, ATEMP); 24285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru id = cp; 24295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru optc = 3; 24305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 24315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru optc = vstrchr(id, '[') ? 0 : 1; 24325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 24335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp = global(id); 24345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(cp, ATEMP); 24355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 24365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vp->flag&RDONLY)) { 243703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra warningf(true, "%s: %s", vp->name, 243803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra "is read only"); 243903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 1; 244003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else 244103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra unset(vp, optc); 244203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else 244303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* unset function */ 24445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru define(id, NULL); 244503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (rv); 24465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 24475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 24485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 24495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querup_time(struct shf *shf, bool posix, long tv_sec, int tv_usec, int width, 24505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *prefix, const char *suffix) 24515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 24525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tv_usec /= 10000; 24535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (posix) 24545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_fprintf(shf, "%s%*ld.%02d%s", prefix, width, 24555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tv_sec, tv_usec, suffix); 24565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 24575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_fprintf(shf, "%s%*ldm%d.%02ds%s", prefix, width, 24585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tv_sec / 60, (int)(tv_sec % 60), tv_usec, suffix); 24595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 24605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 24615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 24625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_times(const char **wp MKSH_A_UNUSED) 24635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 24645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct rusage usage; 24655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 24665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru getrusage(RUSAGE_SELF, &usage); 24675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p_time(shl_stdout, false, usage.ru_utime.tv_sec, 24685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru usage.ru_utime.tv_usec, 0, null, " "); 24695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p_time(shl_stdout, false, usage.ru_stime.tv_sec, 24705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru usage.ru_stime.tv_usec, 0, null, "\n"); 24715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 24725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru getrusage(RUSAGE_CHILDREN, &usage); 24735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p_time(shl_stdout, false, usage.ru_utime.tv_sec, 24745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru usage.ru_utime.tv_usec, 0, null, " "); 24755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p_time(shl_stdout, false, usage.ru_stime.tv_sec, 24765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru usage.ru_stime.tv_usec, 0, null, "\n"); 24775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 24785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 24795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 24805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 24815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 24825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * time pipeline (really a statement, not a built-in command) 24835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 24845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 24855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutimex(struct op *t, int f, volatile int *xerrok) 24865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 24875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define TF_NOARGS BIT(0) 24885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define TF_NOREAL BIT(1) /* don't report real time */ 24895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define TF_POSIX BIT(2) /* report in POSIX format */ 24905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv = 0, tf = 0; 24915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct rusage ru0, ru1, cru0, cru1; 24925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct timeval usrtime, systime, tv0, tv1; 24935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 24945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru gettimeofday(&tv0, NULL); 24955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru getrusage(RUSAGE_SELF, &ru0); 24965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru getrusage(RUSAGE_CHILDREN, &cru0); 24975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (t->left) { 24985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 24995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Two ways of getting cpu usage of a command: just use t0 25005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * and t1 (which will get cpu usage from other jobs that 25015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * finish while we are executing t->left), or get the 25025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * cpu usage of t->left. AT&T ksh does the former, while 25035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * pdksh tries to do the later (the j_usrtime hack doesn't 25045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * really work as it only counts the last job). 25055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 25065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru timerclear(&j_usrtime); 25075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru timerclear(&j_systime); 25085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = execute(t->left, f | XTIME, xerrok); 25095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (t->left->type == TCOM) 25105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tf |= t->left->str[0]; 25115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru gettimeofday(&tv1, NULL); 25125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru getrusage(RUSAGE_SELF, &ru1); 25135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru getrusage(RUSAGE_CHILDREN, &cru1); 25145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 25155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tf = TF_NOARGS; 25165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 251703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (tf & TF_NOARGS) { 251803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* ksh93 - report shell times (shell+kids) */ 25195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tf |= TF_NOREAL; 25205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru timeradd(&ru0.ru_utime, &cru0.ru_utime, &usrtime); 25215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru timeradd(&ru0.ru_stime, &cru0.ru_stime, &systime); 25225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 25235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru timersub(&ru1.ru_utime, &ru0.ru_utime, &usrtime); 25245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru timeradd(&usrtime, &j_usrtime, &usrtime); 25255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru timersub(&ru1.ru_stime, &ru0.ru_stime, &systime); 25265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru timeradd(&systime, &j_systime, &systime); 25275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 25285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 25295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(tf & TF_NOREAL)) { 25305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru timersub(&tv1, &tv0, &tv1); 25315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tf & TF_POSIX) 25325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p_time(shl_out, true, tv1.tv_sec, tv1.tv_usec, 25335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5, "real ", "\n"); 25345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 25355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p_time(shl_out, false, tv1.tv_sec, tv1.tv_usec, 25365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5, null, " real "); 25375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 25385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tf & TF_POSIX) 25395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p_time(shl_out, true, usrtime.tv_sec, usrtime.tv_usec, 25405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5, "user ", "\n"); 25415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 25425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p_time(shl_out, false, usrtime.tv_sec, usrtime.tv_usec, 25435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5, null, " user "); 25445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tf & TF_POSIX) 25455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p_time(shl_out, true, systime.tv_sec, systime.tv_usec, 25465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5, "sys ", "\n"); 25475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 25485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p_time(shl_out, false, systime.tv_sec, systime.tv_usec, 25495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5, null, " system\n"); 25505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_flush(shl_out); 25515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 25525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 25535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 25545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 25555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 25565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutimex_hook(struct op *t, char **volatile *app) 25575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 25585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char **wp = *app; 25595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int optc, i, j; 25605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Getopt opt; 25615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 25625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ksh_getopt_reset(&opt, 0); 256303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* start at the start */ 256403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra opt.optind = 0; 25655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt((const char **)wp, &opt, ":p")) != -1) 25665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 25675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'p': 25685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->str[0] |= TF_POSIX; 25695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 25705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 257103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra errorf("time: -%s %s", opt.optarg, 257203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra "unknown option"); 25735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case ':': 257403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra errorf("time: -%s %s", opt.optarg, 257503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra "requires an argument"); 25765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 25775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Copy command words down over options. */ 25785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (opt.optind != 0) { 25795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (i = 0; i < opt.optind; i++) 25805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(wp[i], ATEMP); 25815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (i = 0, j = opt.optind; (wp[i] = wp[j]); i++, j++) 25825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 25835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 25845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!wp[0]) 25855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->str[0] |= TF_NOARGS; 25865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *app = wp; 25875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 25885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 25895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* exec with no args - args case is taken care of in comexec() */ 25905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 25915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_exec(const char **wp MKSH_A_UNUSED) 25925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 25935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int i; 25945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 25955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* make sure redirects stay in place */ 25965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (e->savefd != NULL) { 25975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (i = 0; i < NUFILE; i++) { 25985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (e->savefd[i] > 0) 25995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru close(e->savefd[i]); 26005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 26015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * keep all file descriptors > 2 private for ksh, 26025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * but not for POSIX or legacy/kludge sh 26035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 26045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!Flag(FPOSIX) && !Flag(FSH) && i > 2 && 26055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru e->savefd[i]) 26065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fcntl(i, F_SETFD, FD_CLOEXEC); 26075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 26085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru e->savefd = NULL; 26095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 26105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 26115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 26125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 26135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if HAVE_MKNOD 26145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 26155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_mknod(const char **wp) 26165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 26175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int argc, optc, rv = 0; 26185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool ismkfifo = false; 26195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char **argv; 26205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru void *set = NULL; 26215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mode_t mode = 0, oldmode = 0; 26225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 26235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt(wp, &builtin_opt, "m:")) != -1) { 26245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 26255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'm': 26265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru set = setmode(builtin_opt.optarg); 26275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (set == NULL) { 26285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("invalid file mode"); 26295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 26305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 26315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mode = getmode(set, (mode_t)(DEFFILEMODE)); 263203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra free_ossetmode(set); 26335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 26345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 26355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto c_mknod_usage; 26365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 26375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 26385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru argv = &wp[builtin_opt.optind]; 26395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (argv[0] == NULL) 26405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto c_mknod_usage; 26415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (argc = 0; argv[argc]; argc++) 26425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 26435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (argc == 2 && argv[1][0] == 'p') 26445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ismkfifo = true; 26455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (argc != 4 || (argv[1][0] != 'b' && argv[1][0] != 'c')) 26465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto c_mknod_usage; 26475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 26485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (set != NULL) 26495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru oldmode = umask((mode_t)0); 26505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 26515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mode = DEFFILEMODE; 26525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 26535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mode |= (argv[1][0] == 'b') ? S_IFBLK : 26545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (argv[1][0] == 'c') ? S_IFCHR : 0; 26555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 26565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!ismkfifo) { 26575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unsigned long majnum, minnum; 26585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru dev_t dv; 26595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *c; 26605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 26615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru majnum = strtoul(argv[2], &c, 0); 26625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c == argv[2]) || (*c != '\0')) { 266303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("non-numeric %s %s '%s'", "device", "major", argv[2]); 26645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto c_mknod_err; 26655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 26665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru minnum = strtoul(argv[3], &c, 0); 26675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c == argv[3]) || (*c != '\0')) { 266803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("non-numeric %s %s '%s'", "device", "minor", argv[3]); 26695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto c_mknod_err; 26705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 26715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru dv = makedev(majnum, minnum); 26725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((unsigned long)(major(dv)) != majnum) { 267303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s %s too large: %lu", "device", "major", majnum); 26745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto c_mknod_err; 26755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 26765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((unsigned long)(minor(dv)) != minnum) { 267703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s %s too large: %lu", "device", "minor", minnum); 26785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto c_mknod_err; 26795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 26805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (mknod(argv[0], mode, dv)) 26815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto c_mknod_failed; 26825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (mkfifo(argv[0], mode)) { 26835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c_mknod_failed: 268403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", argv[0], strerror(errno)); 26855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c_mknod_err: 26865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 1; 26875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 26885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 26895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (set) 26905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru umask(oldmode); 26915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 26925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c_mknod_usage: 269303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", "usage", "mknod [-m mode] name b|c major minor"); 269403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", "usage", "mknod [-m mode] name p"); 26955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 26965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 26975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 26985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 269903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/*- 270003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra test(1) accepts the following grammar: 27015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru oexpr ::= aexpr | aexpr "-o" oexpr ; 27025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru aexpr ::= nexpr | nexpr "-a" aexpr ; 27035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nexpr ::= primary | "!" nexpr ; 27045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru primary ::= unary-operator operand 27055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru | operand binary-operator operand 27065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru | operand 27075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru | "(" oexpr ")" 27085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 27095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 27105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unary-operator ::= "-a"|"-r"|"-w"|"-x"|"-e"|"-f"|"-d"|"-c"|"-b"|"-p"| 27115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "-u"|"-g"|"-k"|"-s"|"-t"|"-z"|"-n"|"-o"|"-O"|"-G"| 27125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "-L"|"-h"|"-S"|"-H"; 27135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 27145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru binary-operator ::= "="|"=="|"!="|"-eq"|"-ne"|"-ge"|"-gt"|"-le"|"-lt"| 27155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "-nt"|"-ot"|"-ef"| 27165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "<"|">" # rules used for [[ .. ]] expressions 27175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 27185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru operand ::= <any thing> 27195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru*/ 27205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 272103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* POSIX says > 1 for errors */ 272203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define T_ERR_EXIT 2 27235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 27245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 27255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_test(const char **wp) 27265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 27275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int argc, res; 27285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Test_env te; 27295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 27305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te.flags = 0; 27315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te.isa = ptest_isa; 27325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te.getopnd = ptest_getopnd; 27335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te.eval = test_eval; 27345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te.error = ptest_error; 27355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 27365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (argc = 0; wp[argc]; argc++) 27375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 27385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 27395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (strcmp(wp[0], "[") == 0) { 27405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (strcmp(wp[--argc], "]") != 0) { 27415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("missing ]"); 27425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (T_ERR_EXIT); 27435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 27445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 27455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 27465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te.pos.wp = wp + 1; 27475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te.wp_end = wp + argc; 27485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 27495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 27505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Handle the special cases from POSIX.2, section 4.62.4. 27515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Implementation of all the rules isn't necessary since 27525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * our parser does the right thing for the omitted steps. 27535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 27545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (argc <= 5) { 275503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra const char **owp = wp, **owpend = te.wp_end; 27565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int invert = 0; 27575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Test_op op; 27585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *opnd1, *opnd2; 27595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 276003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (argc >= 2 && ((*te.isa)(&te, TM_OPAREN))) { 276103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra te.pos.wp = te.wp_end - 1; 276203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((*te.isa)(&te, TM_CPAREN)) { 276303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra argc -= 2; 276403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra te.wp_end--; 276503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra te.pos.wp = owp + 2; 276603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else { 276703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra te.pos.wp = owp + 1; 276803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra te.wp_end = owpend; 276903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 277003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 277103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 27725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (--argc >= 0) { 27735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((*te.isa)(&te, TM_END)) 27745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (!0); 27755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (argc == 3) { 27765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru opnd1 = (*te.getopnd)(&te, TO_NONOP, 1); 27775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((op = (*te.isa)(&te, TM_BINOP))) { 27785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru opnd2 = (*te.getopnd)(&te, op, 1); 27795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru res = (*te.eval)(&te, op, opnd1, 27805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru opnd2, 1); 27815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (te.flags & TEF_ERROR) 27825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (T_ERR_EXIT); 27835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (invert & 1) 27845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru res = !res; 27855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (!res); 27865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 27875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* back up to opnd1 */ 27885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te.pos.wp--; 27895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 27905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (argc == 1) { 27915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru opnd1 = (*te.getopnd)(&te, TO_NONOP, 1); 27925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru res = (*te.eval)(&te, TO_STNZE, opnd1, 27935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru NULL, 1); 27945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (invert & 1) 27955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru res = !res; 27965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (!res); 27975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 27985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((*te.isa)(&te, TM_NOT)) { 27995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru invert++; 28005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 28015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 28025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 28035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te.pos.wp = owp + 1; 280403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra te.wp_end = owpend; 28055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 28065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 28075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (test_parse(&te)); 28085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 28095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 28105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 28115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Generic test routines. 28125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 28135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 28145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste QueruTest_op 28155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutest_isop(Test_meta meta, const char *s) 28165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 28175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char sc1; 28185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const struct t_op *tbl; 28195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 28205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tbl = meta == TM_UNOP ? u_ops : b_ops; 28215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*s) { 28225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sc1 = s[1]; 28235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; tbl->op_text[0]; tbl++) 28245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (sc1 == tbl->op_text[1] && !strcmp(s, tbl->op_text)) 28255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (tbl->op_num); 28265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 28275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (TO_NONOP); 28285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 28295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 28305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 28315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutest_eval(Test_env *te, Test_op op, const char *opnd1, const char *opnd2, 28325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool do_eval) 28335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 28345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int i, s; 28355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru size_t k; 28365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct stat b1, b2; 28375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mksh_ari_t v1, v2; 28385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 28395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!do_eval) 28405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 28415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 284203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra switch (op) { 284303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 28445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 28455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Unary Operators 28465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 284703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 284803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -n */ 284903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_STNZE: 28505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (*opnd1 != '\0'); 285103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 285203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -z */ 285303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_STZER: 28545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (*opnd1 == '\0'); 285503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 285603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -o */ 285703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_OPTION: 28585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((i = *opnd1) == '!' || i == '?') 28595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru opnd1++; 28605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((k = option(opnd1)) == (size_t)-1) 28615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 28625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (i == '?' ? 1 : i == '!' ? !Flag(k) : Flag(k)); 286303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 286403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -r */ 286503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILRD: 286603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* LINTED use of access */ 286703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (access(opnd1, R_OK) == 0); 286803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 286903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -w */ 287003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILWR: 287103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* LINTED use of access */ 287203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (access(opnd1, W_OK) == 0); 287303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 287403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -x */ 287503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILEX: 287603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (ksh_access(opnd1, X_OK) == 0); 287703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 287803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -a */ 287903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILAXST: 288003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -e */ 288103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILEXST: 28825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd1, &b1) == 0); 288303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 288403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -r */ 288503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILREG: 28865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd1, &b1) == 0 && S_ISREG(b1.st_mode)); 288703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 288803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -d */ 288903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILID: 28905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd1, &b1) == 0 && S_ISDIR(b1.st_mode)); 289103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 289203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -c */ 289303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILCDEV: 28945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd1, &b1) == 0 && S_ISCHR(b1.st_mode)); 289503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 289603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -b */ 289703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILBDEV: 28985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd1, &b1) == 0 && S_ISBLK(b1.st_mode)); 289903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 290003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -p */ 290103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILFIFO: 29025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd1, &b1) == 0 && S_ISFIFO(b1.st_mode)); 290303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 290403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -h or -L */ 290503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILSYM: 29065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (lstat(opnd1, &b1) == 0 && S_ISLNK(b1.st_mode)); 290703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 290803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -S */ 290903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILSOCK: 29105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd1, &b1) == 0 && S_ISSOCK(b1.st_mode)); 291103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 291203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -H => HP context dependent files (directories) */ 291303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILCDF: 291403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#ifdef S_ISCDF 291503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra { 291603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra char *nv; 291703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 291803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 291903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Append a + to filename and check to see if result is 292003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * a setuid directory. CDF stuff in general is hookey, 292103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * since it breaks for, e.g., the following sequence: 292203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * echo hi >foo+; mkdir foo; echo bye >foo/default; 292303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * chmod u+s foo (foo+ refers to the file with hi in it, 292403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * there is no way to get at the file with bye in it; 292503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * please correct me if I'm wrong about this). 292603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra */ 292703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 292803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra nv = shf_smprintf("%s+", opnd1); 292903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra i = (stat(nv, &b1) == 0 && S_ISCDF(b1.st_mode)); 293003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra afree(nv, ATEMP); 293103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (i); 293203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 293303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#else 29345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 293503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 293603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 293703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -u */ 293803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILSETU: 29395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd1, &b1) == 0 && 29405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (b1.st_mode & S_ISUID) == S_ISUID); 294103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 294203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -g */ 294303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILSETG: 29445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd1, &b1) == 0 && 29455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (b1.st_mode & S_ISGID) == S_ISGID); 294603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 294703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -k */ 294803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILSTCK: 29495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef S_ISVTX 29505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd1, &b1) == 0 && 29515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (b1.st_mode & S_ISVTX) == S_ISVTX); 29525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#else 29535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 29545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 295503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 295603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -s */ 295703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILGZ: 29585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd1, &b1) == 0 && b1.st_size > 0L); 295903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 296003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -t */ 296103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILTT: 29625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (opnd1 && !bi_getn(opnd1, &i)) { 29635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te->flags |= TEF_ERROR; 29645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru i = 0; 29655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 29665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru i = isatty(opnd1 ? i : 0); 29675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (i); 296803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 296903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -O */ 297003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILUID: 29715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd1, &b1) == 0 && b1.st_uid == ksheuid); 297203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 297303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -G */ 297403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILGID: 29755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd1, &b1) == 0 && b1.st_gid == getegid()); 297603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 29775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 29785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Binary Operators 29795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 298003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 298103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* = */ 298203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_STEQL: 29835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (te->flags & TEF_DBRACKET) 29845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (gmatchx(opnd1, opnd2, false)); 29855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (strcmp(opnd1, opnd2) == 0); 298603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 298703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* != */ 298803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_STNEQ: 29895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (te->flags & TEF_DBRACKET) 29905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (!gmatchx(opnd1, opnd2, false)); 29915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (strcmp(opnd1, opnd2) != 0); 299203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 299303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* < */ 299403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_STLT: 29955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (strcmp(opnd1, opnd2) < 0); 299603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 299703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* > */ 299803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_STGT: 29995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (strcmp(opnd1, opnd2) > 0); 300003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 300103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -eq */ 300203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_INTEQ: 300303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -ne */ 300403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_INTNE: 300503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -ge */ 300603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_INTGE: 300703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -gt */ 300803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_INTGT: 300903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -le */ 301003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_INTLE: 301103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -lt */ 301203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_INTLT: 30135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!evaluate(opnd1, &v1, KSH_RETURN_ERROR, false) || 30145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru !evaluate(opnd2, &v2, KSH_RETURN_ERROR, false)) { 30155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* error already printed.. */ 30165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te->flags |= TEF_ERROR; 30175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 30185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 301903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra switch (op) { 30205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case TO_INTEQ: 30215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (v1 == v2); 30225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case TO_INTNE: 30235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (v1 != v2); 30245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case TO_INTGE: 30255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (v1 >= v2); 30265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case TO_INTGT: 30275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (v1 > v2); 30285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case TO_INTLE: 30295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (v1 <= v2); 30305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case TO_INTLT: 30315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (v1 < v2); 303203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra default: 303303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* NOTREACHED */ 303403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 30355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 303603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* NOTREACHED */ 303703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 303803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -nt */ 303903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILNT: 304003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 304103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * ksh88/ksh93 succeed if file2 can't be stated 30425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (subtly different from 'does not exist'). 30435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 30445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd1, &b1) == 0 && 30455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (((s = stat(opnd2, &b2)) == 0 && 30465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru b1.st_mtime > b2.st_mtime) || s < 0)); 304703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 304803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -ot */ 304903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILOT: 305003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 305103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * ksh88/ksh93 succeed if file1 can't be stated 30525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (subtly different from 'does not exist'). 30535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 30545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat(opnd2, &b2) == 0 && 30555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (((s = stat(opnd1, &b1)) == 0 && 30565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru b1.st_mtime < b2.st_mtime) || s < 0)); 305703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 305803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* -ef */ 305903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_FILEQ: 30605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (stat (opnd1, &b1) == 0 && stat (opnd2, &b2) == 0 && 30615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru b1.st_dev == b2.st_dev && b1.st_ino == b2.st_ino); 306203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 306303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* all other cases */ 306403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_NONOP: 306503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case TO_NONNULL: 306603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* throw the error */ 306703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 30685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 30695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (*te->error)(te, 0, "internal error: unknown op"); 30705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 30715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 30725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 30735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 30745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutest_parse(Test_env *te) 30755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 30765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv; 30775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 30785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = test_oexpr(te, 1); 30795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 30805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(te->flags & TEF_ERROR) && !(*te->isa)(te, TM_END)) 30815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (*te->error)(te, 0, "unexpected operator/operand"); 30825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 30835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return ((te->flags & TEF_ERROR) ? T_ERR_EXIT : !rv); 30845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 30855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 30865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 30875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutest_oexpr(Test_env *te, bool do_eval) 30885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 30895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv; 30905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 30915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((rv = test_aexpr(te, do_eval))) 30925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru do_eval = false; 30935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(te->flags & TEF_ERROR) && (*te->isa)(te, TM_OR)) 30945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (test_oexpr(te, do_eval) || rv); 30955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 30965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 30975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 30985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 30995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutest_aexpr(Test_env *te, bool do_eval) 31005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 31015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv; 31025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 31035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(rv = test_nexpr(te, do_eval))) 31045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru do_eval = false; 31055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(te->flags & TEF_ERROR) && (*te->isa)(te, TM_AND)) 31065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (test_aexpr(te, do_eval) && rv); 31075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 31085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 31095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 31105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 31115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutest_nexpr(Test_env *te, bool do_eval) 31125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 31135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(te->flags & TEF_ERROR) && (*te->isa)(te, TM_NOT)) 31145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (!test_nexpr(te, do_eval)); 31155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (test_primary(te, do_eval)); 31165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 31175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 31185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 31195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutest_primary(Test_env *te, bool do_eval) 31205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 31215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *opnd1, *opnd2; 31225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv; 31235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Test_op op; 31245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 31255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (te->flags & TEF_ERROR) 31265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 31275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((*te->isa)(te, TM_OPAREN)) { 31285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = test_oexpr(te, do_eval); 31295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (te->flags & TEF_ERROR) 31305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 31315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(*te->isa)(te, TM_CPAREN)) { 313203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra (*te->error)(te, 0, "missing )"); 31335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 31345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 31355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 31365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 31375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 31385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Binary should have precedence over unary in this case 31395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * so that something like test \( -f = -f \) is accepted 31405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 31415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((te->flags & TEF_DBRACKET) || (&te->pos.wp[1] < te->wp_end && 31425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru !test_isop(TM_BINOP, te->pos.wp[1]))) { 31435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((op = (*te->isa)(te, TM_UNOP))) { 31445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* unary expression */ 31455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru opnd1 = (*te->getopnd)(te, op, do_eval); 31465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!opnd1) { 31475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (*te->error)(te, -1, "missing argument"); 31485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 31495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 31505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 31515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return ((*te->eval)(te, op, opnd1, NULL, do_eval)); 31525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 31535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 31545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru opnd1 = (*te->getopnd)(te, TO_NONOP, do_eval); 31555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!opnd1) { 31565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (*te->error)(te, 0, "expression expected"); 31575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 31585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 31595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((op = (*te->isa)(te, TM_BINOP))) { 31605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* binary expression */ 31615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru opnd2 = (*te->getopnd)(te, op, do_eval); 31625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!opnd2) { 31635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (*te->error)(te, -1, "missing second argument"); 31645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 31655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 31665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 31675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return ((*te->eval)(te, op, opnd1, opnd2, do_eval)); 31685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 31695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return ((*te->eval)(te, TO_STNZE, opnd1, NULL, do_eval)); 31705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 31715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 31725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 31735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Plain test (test and [ .. ]) specific routines. 31745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 31755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 31765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 31775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Test if the current token is a whatever. Accepts the current token if 31785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * it is. Returns 0 if it is not, non-zero if it is (in the case of 31795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * TM_UNOP and TM_BINOP, the returned value is a Test_op). 31805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 31815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic Test_op 31825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruptest_isa(Test_env *te, Test_meta meta) 31835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 31845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Order important - indexed by Test_meta values */ 31855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru static const char *const tokens[] = { 31865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "-o", "-a", "!", "(", ")" 31875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru }; 31885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Test_op rv; 31895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 31905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (te->pos.wp >= te->wp_end) 31915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (meta == TM_END ? TO_NONNULL : TO_NONOP); 31925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 31935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (meta == TM_UNOP || meta == TM_BINOP) 31945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = test_isop(meta, *te->pos.wp); 31955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (meta == TM_END) 31965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = TO_NONOP; 31975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 31985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = !strcmp(*te->pos.wp, tokens[(int)meta]) ? 31995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru TO_NONNULL : TO_NONOP; 32005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Accept the token? */ 32025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (rv != TO_NONOP) 32035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te->pos.wp++; 32045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 32065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 32075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic const char * 32095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruptest_getopnd(Test_env *te, Test_op op, bool do_eval MKSH_A_UNUSED) 32105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 32115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (te->pos.wp >= te->wp_end) 32125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (op == TO_FILTT ? "1" : NULL); 32135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (*te->pos.wp++); 32145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 32155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 32175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruptest_error(Test_env *te, int ofs, const char *msg) 32185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 32195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *op; 32205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te->flags |= TEF_ERROR; 32225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((op = te->pos.wp + ofs >= te->wp_end ? NULL : te->pos.wp[ofs])) 32235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("%s: %s", op, msg); 32245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 32255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("%s", msg); 32265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 32275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_NO_LIMITS 32295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define SOFT 0x1 32305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define HARD 0x2 32315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustruct limits { 32335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *name; 32345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int resource; /* resource to get/set */ 32355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int factor; /* multiply by to get rlim_{cur,max} values */ 32365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char option; 32375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}; 32385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void print_ulimit(const struct limits *, int); 32405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int set_ulimit(const struct limits *, const char *, int); 32415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Magic to divine the 'm' and 'v' limits */ 32435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_AS 32455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if !defined(RLIMIT_VMEM) || (RLIMIT_VMEM == RLIMIT_AS) || \ 32465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru !defined(RLIMIT_RSS) || (RLIMIT_VMEM == RLIMIT_RSS) 32475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define ULIMIT_V_IS_AS 32485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#elif defined(RLIMIT_VMEM) 32495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if !defined(RLIMIT_RSS) || (RLIMIT_RSS == RLIMIT_AS) 32505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define ULIMIT_V_IS_AS 32515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#else 32525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define ULIMIT_V_IS_VMEM 32535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 32545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 32555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 32565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_RSS 32585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef ULIMIT_V_IS_VMEM 32595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define ULIMIT_M_IS_RSS 32605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#elif defined(RLIMIT_VMEM) && (RLIMIT_VMEM == RLIMIT_RSS) 32615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define ULIMIT_M_IS_VMEM 32625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#else 32635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define ULIMIT_M_IS_RSS 32645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 32655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if defined(ULIMIT_M_IS_RSS) && defined(RLIMIT_AS) && (RLIMIT_RSS == RLIMIT_AS) 32665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#undef ULIMIT_M_IS_RSS 32675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 32685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 32695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if !defined(RLIMIT_AS) && !defined(ULIMIT_M_IS_VMEM) && defined(RLIMIT_VMEM) 32715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define ULIMIT_V_IS_VMEM 32725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 32735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if !defined(ULIMIT_V_IS_VMEM) && defined(RLIMIT_VMEM) && \ 32755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (!defined(RLIMIT_RSS) || (defined(RLIMIT_AS) && (RLIMIT_RSS == RLIMIT_AS))) 32765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define ULIMIT_M_IS_VMEM 32775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 32785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if defined(ULIMIT_M_IS_VMEM) && defined(RLIMIT_AS) && \ 32805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (RLIMIT_VMEM == RLIMIT_AS) 32815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#undef ULIMIT_M_IS_VMEM 32825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 32835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 32855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 32865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_ulimit(const char **wp) 32875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 32885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru static const struct limits limits[] = { 32895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* do not use options -H, -S or -a or change the order */ 32905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_CPU 32915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "time(cpu-seconds)", RLIMIT_CPU, 1, 't' }, 32925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 32935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_FSIZE 32945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "file(blocks)", RLIMIT_FSIZE, 512, 'f' }, 32955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 32965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_CORE 32975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "coredump(blocks)", RLIMIT_CORE, 512, 'c' }, 32985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 32995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_DATA 33005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "data(KiB)", RLIMIT_DATA, 1024, 'd' }, 33015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_STACK 33035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "stack(KiB)", RLIMIT_STACK, 1024, 's' }, 33045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_MEMLOCK 33065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "lockedmem(KiB)", RLIMIT_MEMLOCK, 1024, 'l' }, 33075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_NOFILE 33095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "nofiles(descriptors)", RLIMIT_NOFILE, 1, 'n' }, 33105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_NPROC 33125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "processes", RLIMIT_NPROC, 1, 'p' }, 33135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_SWAP 33155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "swap(KiB)", RLIMIT_SWAP, 1024, 'w' }, 33165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_LOCKS 33185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "flocks", RLIMIT_LOCKS, -1, 'L' }, 33195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_TIME 33215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "humantime(seconds)", RLIMIT_TIME, 1, 'T' }, 33225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_NOVMON 33245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "vnodemonitors", RLIMIT_NOVMON, 1, 'V' }, 33255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_SIGPENDING 33275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "sigpending", RLIMIT_SIGPENDING, 1, 'i' }, 33285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_MSGQUEUE 33305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "msgqueue(bytes)", RLIMIT_MSGQUEUE, 1, 'q' }, 33315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_AIO_MEM 33335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "AIOlockedmem(KiB)", RLIMIT_AIO_MEM, 1024, 'M' }, 33345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_AIO_OPS 33365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "AIOoperations", RLIMIT_AIO_OPS, 1, 'O' }, 33375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_TCACHE 33395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "cachedthreads", RLIMIT_TCACHE, 1, 'C' }, 33405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_SBSIZE 33425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "sockbufsiz(KiB)", RLIMIT_SBSIZE, 1024, 'B' }, 33435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_PTHREAD 33455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "threadsperprocess", RLIMIT_PTHREAD, 1, 'P' }, 33465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_NICE 33485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "maxnice", RLIMIT_NICE, 1, 'e' }, 33495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef RLIMIT_RTPRIO 33515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "maxrtprio", RLIMIT_RTPRIO, 1, 'r' }, 33525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if defined(ULIMIT_M_IS_RSS) 33545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "resident-set(KiB)", RLIMIT_RSS, 1024, 'm' }, 33555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#elif defined(ULIMIT_M_IS_VMEM) 33565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "memory(KiB)", RLIMIT_VMEM, 1024, 'm' }, 33575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if defined(ULIMIT_V_IS_VMEM) 33595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "virtual-memory(KiB)", RLIMIT_VMEM, 1024, 'v' }, 33605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#elif defined(ULIMIT_V_IS_AS) 33615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "address-space(KiB)", RLIMIT_AS, 1024, 'v' }, 33625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 33635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { NULL, 0, 0, 0 } 33645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru }; 33655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru static char opts[3 + NELEM(limits)]; 33665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int how = SOFT | HARD, optc, what = 'f'; 33675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool all = false; 33685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const struct limits *l; 33695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 33705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!opts[0]) { 33715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* build options string on first call - yuck */ 33725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *p = opts; 33735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 33745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *p++ = 'H'; *p++ = 'S'; *p++ = 'a'; 33755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (l = limits; l->name; l++) 33765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *p++ = l->option; 33775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *p = '\0'; 33785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 33795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 33805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt(wp, &builtin_opt, opts)) != -1) 33815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 33825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'H': 33835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru how = HARD; 33845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 33855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'S': 33865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru how = SOFT; 33875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 33885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'a': 33895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru all = true; 33905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 33915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 339203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", "usage", 339303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra "ulimit [-acdfHLlmnpSsTtvw] [value]"); 33945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 33955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 33965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru what = optc; 33975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 33985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 33995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (l = limits; l->name && l->option != what; l++) 34005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 34015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!l->name) { 34025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru internal_warningf("ulimit: %c", what); 34035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 34045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 34055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 34065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (wp[builtin_opt.optind]) { 34075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (all || wp[builtin_opt.optind + 1]) { 34085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("too many arguments"); 34095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 34105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 34115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (set_ulimit(l, wp[builtin_opt.optind], how)); 34125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 34135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!all) 34145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru print_ulimit(l, how); 34155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else for (l = limits; l->name; l++) { 34165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shprintf("%-20s ", l->name); 34175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru print_ulimit(l, how); 34185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 34195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 34205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 34215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 34225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 34235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruset_ulimit(const struct limits *l, const char *v, int how) 34245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 34255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rlim_t val = (rlim_t)0; 34265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct rlimit limit; 34275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 34285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (strcmp(v, "unlimited") == 0) 34295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru val = (rlim_t)RLIM_INFINITY; 34305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else { 34315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mksh_ari_t rval; 34325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 34335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!evaluate(v, &rval, KSH_RETURN_ERROR, false)) 34345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 34355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 34365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Avoid problems caused by typos that evaluate misses due 34375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * to evaluating unset parameters to 0... 34385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * If this causes problems, will have to add parameter to 34395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * evaluate() to control if unset params are 0 or an error. 34405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 34415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!rval && !ksh_isdigit(v[0])) { 34425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("invalid %s limit: %s", l->name, v); 34435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 34445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 34455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru val = (rlim_t)((rlim_t)rval * l->factor); 34465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 34475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 34485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (getrlimit(l->resource, &limit) < 0) { 344903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* some can't be read, e.g. Linux RLIMIT_LOCKS */ 34505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru limit.rlim_cur = RLIM_INFINITY; 34515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru limit.rlim_max = RLIM_INFINITY; 34525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 34535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (how & SOFT) 34545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru limit.rlim_cur = val; 34555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (how & HARD) 34565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru limit.rlim_max = val; 34575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!setrlimit(l->resource, &limit)) 34585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 34595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (errno == EPERM) 34605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("%s exceeds allowable %s limit", v, l->name); 34615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 34625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("bad %s limit: %s", l->name, strerror(errno)); 34635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 34645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 34655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 34665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 34675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruprint_ulimit(const struct limits *l, int how) 34685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 34695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rlim_t val = (rlim_t)0; 34705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct rlimit limit; 34715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 34725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (getrlimit(l->resource, &limit)) { 34735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts("unknown\n", shl_stdout); 34745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return; 34755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 34765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (how & SOFT) 34775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru val = limit.rlim_cur; 34785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (how & HARD) 34795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru val = limit.rlim_max; 34805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (val == (rlim_t)RLIM_INFINITY) 34815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts("unlimited\n", shl_stdout); 34825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 34835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shprintf("%ld\n", (long)(val / l->factor)); 34845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 34855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 34865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 34875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 34885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_rename(const char **wp) 34895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 34905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv = 1; 34915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 349203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* skip argv[0] */ 349303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++wp; 349403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (wp[0] && !strcmp(wp[0], "--")) 349503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* skip "--" (options separator) */ 349603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++wp; 349703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 349803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* check for exactly two arguments */ 349903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (wp[0] == NULL /* first argument */ || 350003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra wp[1] == NULL /* second argument */ || 350103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra wp[2] != NULL /* no further args please */) 350203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf(Tsynerr); 350303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else if ((rv = rename(wp[0], wp[1])) != 0) { 35045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = errno; 350503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", "failed", strerror(rv)); 35065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 35075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 35085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 35095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 35105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 35115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 35125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_realpath(const char **wp) 35135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 35145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rv = 1; 35155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *buf; 35165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 351703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* skip argv[0] */ 351803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++wp; 351903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (wp[0] && !strcmp(wp[0], "--")) 352003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* skip "--" (options separator) */ 352103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++wp; 35225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 352303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* check for exactly one argument */ 352403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (wp[0] == NULL || wp[1] != NULL) 352503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf(Tsynerr); 352603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else if ((buf = do_realpath(wp[0])) == NULL) { 35275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = errno; 352803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", wp[0], strerror(rv)); 35295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((unsigned int)rv > 255) 35305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 255; 35315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 35325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shprintf("%s\n", buf); 35335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(buf, ATEMP); 353403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 0; 35355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 35365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 35375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 35385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 353903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 354003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condraint 354103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrac_cat(const char **wp) 354203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{ 354303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra int fd = STDIN_FILENO, rv; 354403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ssize_t n, w; 354503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra const char *fn = "<stdin>"; 354603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra char *buf, *cp; 354703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define MKSH_CAT_BUFSIZ 4096 354803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 354903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((buf = malloc_osfunc(MKSH_CAT_BUFSIZ)) == NULL) { 355003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf(Toomem, (unsigned long)MKSH_CAT_BUFSIZ); 355103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (1); 355203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 355303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 355403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* parse options: POSIX demands we support "-u" as no-op */ 355503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while ((rv = ksh_getopt(wp, &builtin_opt, "u")) != -1) { 355603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra switch (rv) { 355703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 'u': 355803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* we already operate unbuffered */ 355903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 356003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra default: 356103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf(Tsynerr); 356203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (1); 356303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 356403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 356503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra wp += builtin_opt.optind; 356603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 0; 356703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 356803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra do { 356903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (*wp) { 357003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra fn = *wp++; 357103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (fn[0] == '-' && fn[1] == '\0') 357203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra fd = STDIN_FILENO; 357303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else if ((fd = open(fn, O_RDONLY)) < 0) { 357403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = errno; 357503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", fn, strerror(rv)); 357603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 1; 357703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra continue; 357803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 357903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 358003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (/* CONSTCOND */ 1) { 358103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra n = blocking_read(fd, (cp = buf), MKSH_CAT_BUFSIZ); 358203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (n == -1) { 358303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (errno == EINTR) { 358403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* give the user a chance to ^C out */ 358503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra intrcheck(); 358603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* interrupted, try again */ 358703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra continue; 358803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 358903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* an error occured during reading */ 359003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = errno; 359103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", fn, strerror(rv)); 359203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 1; 359303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 359403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else if (n == 0) 359503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* end of file reached */ 359603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 359703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (n) { 359803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra w = write(STDOUT_FILENO, cp, n); 359903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (w == -1) { 360003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (errno == EINTR) 360103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* interrupted, try again */ 360203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra continue; 360303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* an error occured during writing */ 360403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = errno; 360503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", "<stdout>", 360603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra strerror(rv)); 360703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 1; 360803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (fd != STDIN_FILENO) 360903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra close(fd); 361003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto out; 361103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 361203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra n -= w; 361303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra cp += w; 361403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 361503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 361603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (fd != STDIN_FILENO) 361703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra close(fd); 361803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } while (*wp); 361903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 362003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra out: 362103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra free_osfunc(buf); 362203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (rv); 362303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra} 362403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 362503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#if HAVE_SELECT 362603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condraint 362703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrac_sleep(const char **wp) 362803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{ 362903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra struct timeval tv; 363003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra int rv = 1; 363103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 363203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* skip argv[0] */ 363303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++wp; 363403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (wp[0] && !strcmp(wp[0], "--")) 363503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* skip "--" (options separator) */ 363603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++wp; 363703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 363803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!wp[0] || wp[1]) 363903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf(Tsynerr); 364003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else if (parse_usec(wp[0], &tv)) 364103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s '%s'", Tsynerr, strerror(errno), wp[0]); 364203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else { 364303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#ifndef MKSH_NOPROSPECTOFWORK 364403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra sigset_t omask; 364503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 364603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* block SIGCHLD from interrupting us, though */ 364703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra sigprocmask(SIG_BLOCK, &sm_sigchld, &omask); 364803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 364903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (select(0, NULL, NULL, NULL, &tv) == 0 || errno == EINTR) 365003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 365103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * strictly speaking only for SIGALRM, but the 365203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * execution may be interrupted by other signals 365303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra */ 365403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rv = 0; 365503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else 365603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bi_errorf("%s: %s", Tselect, strerror(errno)); 365703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#ifndef MKSH_NOPROSPECTOFWORK 365803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra sigprocmask(SIG_SETMASK, &omask, NULL); 365903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 366003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 366103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (rv); 366203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra} 366303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 366403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 366503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#if defined(ANDROID) 366603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic int 366703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrac_android_lsmod(const char **wp MKSH_A_UNUSED) 366803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{ 366903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra const char *cwp[3] = { "cat", "/proc/modules", NULL }; 367003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 367103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra builtin_argv0 = cwp[0]; 367203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (c_cat(cwp)); 367303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra} 367403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 3675