da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1982-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma prototyped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * UNIX shell
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * S. R. Bourne
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Rewritten by David Korn
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Labs
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "defs.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "path.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "builtins.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "terminal.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "edit.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "FEATURE/poll"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_KIA
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# include "shlex.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# include "io.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_KIA */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_PFSH
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define PFSHOPT "P"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define PFSHOPT
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_BASH
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# define BASHOPT "\374"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define BASHOPT
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_HISTEXPAND
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define HFLAG "H"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define HFLAG ""
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define SORT 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PRINT 2
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char *null;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* The following order is determined by sh_optset */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic const char optksh[] = PFSHOPT BASHOPT "DircabefhkmnpstuvxBCGEl" HFLAG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic const int flagval[] =
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_PFSH
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin SH_PFSH,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_BASH
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin SH_POSIX,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin SH_DICTIONARY, SH_INTERACTIVE, SH_RESTRICTED, SH_CFLAG,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin SH_ALLEXPORT, SH_NOTIFY, SH_ERREXIT, SH_NOGLOB, SH_TRACKALL,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin SH_KEYWORD, SH_MONITOR, SH_NOEXEC, SH_PRIVILEGED, SH_SFLAG, SH_TFLAG,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin SH_NOUNSET, SH_VERBOSE, SH_XTRACE, SH_BRACEEXPAND, SH_NOCLOBBER,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin SH_GLOBSTARS, SH_RC, SH_LOGIN_SHELL,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_HISTEXPAND
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin SH_HISTEXPAND,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin 0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define NUM_OPTS (sizeof(flagval)/sizeof(*flagval))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef struct _arg_
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *sh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct dolnod *argfor; /* linked list of blocks to be cleaned up */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct dolnod *dolh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char flagadr[NUM_OPTS+1];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_KIA
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *kiafile;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_KIA */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin} Arg_t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic int arg_expand(Shell_t*,struct argnod*,struct argnod**,int);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic void sh_argset(Arg_t*, char *[]);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* ======== option handling ======== */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid *sh_argopen(Shell_t *shp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin void *addr = newof(0,Arg_t,1,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Arg_t *ap = (Arg_t*)addr;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ap->sh = shp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(addr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int infof(Opt_t* op, Sfio_t* sp, const char* s, Optdisc_t* dp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_BASH
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin extern const char sh_bash1[], sh_bash2[];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(strcmp(s,"bash1")==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(SH_BASH))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(sp,sh_bash1,-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(strcmp(s,"bash2")==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(SH_BASH))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(sp,sh_bash2,-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(*s==':' && sh_isoption(SH_BASH))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(sp,s,-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*s!=':')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(sp,sh_set,-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This routine turns options on and off
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The options "PDicr" are illegal from set command.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The -o option is used to set option by name
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This routine returns the number of non-option arguments
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinint sh_argopts(int argc,register char *argv[], void *context)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *shp = (Shell_t*)context;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register int n,o;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Arg_t *ap = (Arg_t*)(shp->arg_context);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Lex_t *lp = (Lex_t*)(shp->lex_context);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shopt_t newflags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int setflag=0, action=0, trace=(int)sh_isoption(SH_XTRACE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t *np = NIL(Namval_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin const char *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int verbose,f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Optdisc_t disc;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin newflags=ap->sh->options;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memset(&disc, 0, sizeof(disc));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin disc.version = OPT_VERSION;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin disc.infof = infof;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin opt_info.disc = &disc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(argc>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setflag = 4;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argc = -argc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while((n = optget(argv,setflag?sh_optset:sh_optksh)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin o=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin f=*opt_info.option=='-' && (opt_info.num || opt_info.arg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'A':
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = nv_open(opt_info.arg,ap->sh->var_tree,NV_NOASSIGN|NV_ARRAY|NV_VARNAME);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(f)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_unset(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_BASH
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'O': /* shopt options, only in bash mode */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!sh_isoption(SH_BASH))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1), e_option, opt_info.name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'o': /* set options */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin byname:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!opt_info.arg||!*opt_info.arg||*opt_info.arg=='-')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin action = PRINT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* print style: -O => shopt options
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * bash => print unset options also, no heading
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin verbose = (f?PRINT_VERBOSE:PRINT_NO_HEADER)|
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (n=='O'?PRINT_SHOPT:0)|
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (sh_isoption(SH_BASH)?PRINT_ALL|PRINT_NO_HEADER:0)|
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ((opt_info.arg&&(!*opt_info.arg||*opt_info.arg=='-'))?(PRINT_TABLE|PRINT_NO_HEADER):0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin o = sh_lookopt(opt_info.arg,&f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(o<=0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin || (!sh_isoption(SH_BASH) && (o&SH_BASHEXTRA))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin || ((!sh_isoption(SH_BASH) || n=='o') && (o&SH_BASHOPT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin || (setflag && (o&SH_COMMANDLINE)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,2, e_option, opt_info.arg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.errors++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin o &= 0xff;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(SH_RESTRICTED) && !f && o==SH_RESTRICTED)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1), e_restricted, opt_info.arg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_BASH
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case -1: /* --rcfile */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ap->sh->rcfile = opt_info.arg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case -2: /* --noediting */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (!f)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin off_option(&newflags,SH_VI);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin off_option(&newflags,SH_EMACS);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin off_option(&newflags,SH_GMACS);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case -3: /* --profile */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin n = 'l';
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin goto skip;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case -4: /* --posix */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* mask lower 8 bits to find char in optksh string */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n&=0xff;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto skip;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case -5: /* --version */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputr(sfstdout, "ksh bash emulation, version ",-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = nv_open("BASH_VERSION",ap->sh->var_tree,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputr(sfstdout, nv_getval(np),-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = nv_open("MACHTYPE",ap->sh->var_tree,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(sfstdout, " (%s)\n", nv_getval(np));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_exit(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case -6: /* --default */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register const Shtable_t *tp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for(tp=shtab_options; o = tp->sh_number; tp++)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(o&SH_COMMANDLINE) && is_option(&newflags,o&0xff))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin off_option(&newflags,o&0xff);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin continue;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case -7:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin f = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin goto byname;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'D':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin on_option(&newflags,SH_NOEXEC);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto skip;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case 'T':
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (opt_info.num)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ap->sh->test |= opt_info.num;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ap->sh->test = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 's':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(setflag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin action = SORT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_KIA
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto skip;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'R':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(setflag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = ':';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->kiafile = opt_info.arg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 'n';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_KIA */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#if SHOPT_REGRESS
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz goto skip;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'I':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz continue;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#endif /* SHOPT_REGRESS */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin skip:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(cp=strchr(optksh,n))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin o = flagval[cp-optksh];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ':':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(opt_info.name[0]=='-'&&opt_info.name[1]=='-')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin opt_info.arg = argv[opt_info.index-1] + 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto byname;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,2, "%s", opt_info.arg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '?':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_usage(0), "%s", opt_info.arg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(f)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(o==SH_VI || o==SH_EMACS || o==SH_GMACS)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin off_option(&newflags,SH_VI);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin off_option(&newflags,SH_EMACS);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin off_option(&newflags,SH_GMACS);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin on_option(&newflags,o);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin off_option(&ap->sh->offoptions,o);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(o==SH_XTRACE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin trace = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin off_option(&newflags,o);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(setflag==0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin on_option(&ap->sh->offoptions,o);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(error_info.errors)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_usage(2),"%s",optusage(NIL(char*)));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for '-' or '+' argument */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((cp=argv[opt_info.index]) && cp[1]==0 && (*cp=='+' || *cp=='-') &&
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strcmp(argv[opt_info.index-1],"--"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin opt_info.index++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin off_option(&newflags,SH_XTRACE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin off_option(&newflags,SH_VERBOSE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin trace = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(trace)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_trace(argv,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argc -= opt_info.index;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv += opt_info.index;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(action==PRINT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_printopts(newflags,verbose,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(setflag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(action==SORT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(argc>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strsort(argv,argc,strcoll);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin strsort(ap->sh->st.dolv+1,ap->sh->st.dolc,strcoll);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_setvec(np,0,argc,argv);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_close(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(argc>0 || ((cp=argv[-1]) && strcmp(cp,"--")==0))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_argset(ap,argv-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(is_option(&newflags,SH_CFLAG))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(ap->sh->comdiv = *argv++))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,2,e_cneedsarg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_usage(2),optusage(NIL(char*)));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argc--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* handling SH_INTERACTIVE and SH_PRIVILEGED has been moved to
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * sh_applyopts(), so that the code can be reused from b_shopt(), too
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_applyopts(ap->sh,newflags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_KIA
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ap->kiafile)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!argv[0])
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin errormsg(SH_DICT,ERROR_usage(2),"-R requires scriptname");
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(lp->kiafile=sfopen(NIL(Sfio_t*),ap->kiafile,"w+")))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_system(3),e_create,ap->kiafile);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(lp->kiatmp=sftmp(2*SF_BUFSIZE)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_system(3),e_tmpcreate);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputr(lp->kiafile,";vdb;CIAO/ksh",'\n');
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->kiabegin = sftell(lp->kiafile);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->entity_tree = dtopen(&_Nvdisc,Dtbag);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->scriptname = strdup(sh_fmtq(argv[0]));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->script=kiaentity(lp,lp->scriptname,-1,'p',-1,0,0,'s',0,"");
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->fscript=kiaentity(lp,lp->scriptname,-1,'f',-1,0,0,'s',0,"");
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->unknown=kiaentity(lp,"<unknown>",-1,'p',-1,0,0,'0',0,"");
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin kiaentity(lp,"<unknown>",-1,'p',0,0,lp->unknown,'0',0,"");
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->current = lp->script;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->kiafile = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_KIA */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(argc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* apply new options */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinvoid sh_applyopts(Shell_t* shp,Shopt_t newflags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* cannot set -n for interactive shells since there is no way out */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(SH_INTERACTIVE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin off_option(&newflags,SH_NOEXEC);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(is_option(&newflags,SH_PRIVILEGED))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin on_option(&newflags,SH_NOUSRPROFILE);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(!sh_isstate(SH_INIT) && is_option(&newflags,SH_PRIVILEGED) != sh_isoption(SH_PRIVILEGED) || sh_isstate(SH_INIT) && is_option(&((Arg_t*)shp->arg_context)->sh->offoptions,SH_PRIVILEGED) && shp->userid!=shp->euserid)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(!is_option(&newflags,SH_PRIVILEGED))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin setuid(shp->userid);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin setgid(shp->groupid);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->euserid==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->euserid = shp->userid;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->egroupid = shp->groupid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if((shp->userid!=shp->euserid && setuid(shp->euserid)<0) ||
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin (shp->groupid!=shp->egroupid && setgid(shp->egroupid)<0) ||
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin (shp->userid==shp->euserid && shp->groupid==shp->egroupid))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin off_option(&newflags,SH_PRIVILEGED);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_BASH
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin on_option(&newflags,SH_CMDHIST);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin on_option(&newflags,SH_CHECKHASH);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin on_option(&newflags,SH_EXECFAIL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin on_option(&newflags,SH_EXPAND_ALIASES);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin on_option(&newflags,SH_HISTAPPEND);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin on_option(&newflags,SH_INTERACTIVE_COMM);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin on_option(&newflags,SH_LITHIST);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin on_option(&newflags,SH_NOEMPTYCMDCOMPL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!is_option(&newflags,SH_XPG_ECHO) && sh_isoption(SH_XPG_ECHO))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin astconf("UNIVERSE", 0, "ucb");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(is_option(&newflags,SH_XPG_ECHO) && !sh_isoption(SH_XPG_ECHO))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin astconf("UNIVERSE", 0, "att");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!is_option(&newflags,SH_PHYSICAL) && sh_isoption(SH_PHYSICAL))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin astconf("PATH_RESOLVE", 0, "metaphysical");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(is_option(&newflags,SH_PHYSICAL) && !sh_isoption(SH_PHYSICAL))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin astconf("PATH_RESOLVE", 0, "physical");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(is_option(&newflags,SH_HISTORY2) && !sh_isoption(SH_HISTORY2))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onstate(SH_HISTORY);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onoption(SH_HISTORY);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!is_option(&newflags,SH_HISTORY2) && sh_isoption(SH_HISTORY2))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offstate(SH_HISTORY);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offoption(SH_HISTORY);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->options = newflags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * returns the value of $-
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinchar *sh_argdolminus(void* context)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Arg_t *ap = (Arg_t*)context;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const char *cp=optksh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *flagp=ap->flagadr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(cp< &optksh[NUM_OPTS])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int n = flagval[cp-optksh];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(n))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *flagp++ = *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *flagp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(ap->flagadr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * set up positional parameters
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic void sh_argset(Arg_t *ap,char *argv[])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_argfree(ap->sh,ap->dolh,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->dolh = sh_argcreate(argv);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* link into chain */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->dolh->dolnxt = ap->argfor;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->argfor = ap->dolh;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ap->sh->st.dolc = ap->dolh->dolnum-1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ap->sh->st.dolv = ap->dolh->dolval;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * free the argument list if the use count is 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If count is greater than 1 decrement count and return same blk
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Free the argument list if the use count is 1 and return next blk
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Delete the blk from the argfor chain
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If flag is set, then the block dolh is not freed
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstruct dolnod *sh_argfree(Shell_t *shp, struct dolnod *blk,int flag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct dolnod* argr=blk;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct dolnod* argblk;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Arg_t *ap = (Arg_t*)shp->arg_context;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(argblk=argr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((--argblk->dolrefcnt)==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argr = argblk->dolnxt;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag && argblk==ap->dolh)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->dolh->dolrefcnt = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* delete from chain */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ap->argfor == argblk)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->argfor = argblk->dolnxt;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(argr=ap->argfor;argr;argr=argr->dolnxt)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(argr->dolnxt==argblk)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!argr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(NIL(struct dolnod*));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argr->dolnxt = argblk->dolnxt;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argr = argblk->dolnxt;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)argblk);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(argr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * grab space for arglist and copy args
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The strings are copied after the argment vector
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct dolnod *sh_argcreate(register char *argv[])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct dolnod *dp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char **pp=argv, *sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int size=0,n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* count args and number of bytes of arglist */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(sp= *pp++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size += strlen(sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = (pp - argv)-1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp=new_of(struct dolnod,n*sizeof(char*)+size+n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->dolrefcnt=1; /* use count */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->dolnum = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->dolnxt = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp = dp->dolval;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = (char*)dp + sizeof(struct dolnod) + n*sizeof(char*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(n--)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *pp++ = sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = strcopy(sp, *argv++) + 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *pp = NIL(char*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(dp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * used to set new arguments for functions
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstruct dolnod *sh_argnew(Shell_t *shp,char *argi[], struct dolnod **savargfor)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Arg_t *ap = (Arg_t*)shp->arg_context;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct dolnod *olddolh = ap->dolh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *savargfor = ap->argfor;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->dolh = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->argfor = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_argset(ap,argi);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(olddolh);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * reset arguments as they were before function
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinvoid sh_argreset(Shell_t *shp,struct dolnod *blk, struct dolnod *afor)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Arg_t *ap = (Arg_t*)shp->arg_context;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while(ap->argfor=sh_argfree(shp,ap->argfor,0));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->argfor = afor;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ap->dolh = blk)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.dolc = ap->dolh->dolnum-1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.dolv = ap->dolh->dolval;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * increase the use count so that an sh_argset will not make it go away
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstruct dolnod *sh_arguse(Shell_t* shp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct dolnod *dh;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Arg_t *ap = (Arg_t*)shp->arg_context;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(dh=ap->dolh)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dh->dolrefcnt++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(dh);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Print option settings on standard output
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if mode is inclusive or of PRINT_*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if <mask> is set, only options with this mask value are displayed
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid sh_printopts(Shopt_t oflags,register int mode, Shopt_t *mask)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const Shtable_t *tp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin const char *name;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int on;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int value;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(mode&PRINT_NO_HEADER))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(sfstdout,sh_translate(e_heading),'\n');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode&PRINT_TABLE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int w;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int r;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(tp=shtab_options; value=tp->sh_number; tp++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mask && !is_option(mask,value&0xff))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin name = tp->sh_name;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(name[0] == 'n' && name[1] == 'o' && name[2] != 't')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin name += 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c<(w=strlen(name)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = w;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c += 4;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((w = ed_window()) < (2*c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin w = 2*c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r = w / c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(tp=shtab_options; value=tp->sh_number; tp++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mask && !is_option(mask,value&0xff))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin on = !!is_option(&oflags,value);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value &= 0xff;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin name = tp->sh_name;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(name[0] == 'n' && name[1] == 'o' && name[2] != 't')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin name += 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin on = !on;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(++i>=r)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstdout, "%s%s\n", on ? "" : "no", name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstdout, "%s%-*s", on ? "" : "no", on ? c : (c-2), name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(i)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(sfstdout,'\n');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_RAWONLY
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin on_option(&oflags,SH_VIRAW);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(mode&(PRINT_ALL|PRINT_VERBOSE))) /* only print set options */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode&PRINT_SHOPT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfwrite(sfstdout,"shopt -s",3);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfwrite(sfstdout,"set --default",13);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(tp=shtab_options; value=tp->sh_number; tp++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mask && !is_option(mask,value&0xff))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(SH_BASH))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(mode&PRINT_SHOPT) != !(value&SH_BASHOPT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (value&(SH_BASHEXTRA|SH_BASHOPT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin on = !!is_option(&oflags,value);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin name = tp->sh_name;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(name[0] == 'n' && name[1] == 'o' && name[2] != 't')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin name += 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin on = !on;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode&PRINT_VERBOSE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(sfstdout,name,' ');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfnputc(sfstdout,' ',24-strlen(name));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(sfstdout,on ? sh_translate(e_on) : sh_translate(e_off),'\n');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(mode&PRINT_ALL) /* print unset options also */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode&PRINT_SHOPT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstdout, "shopt -%c %s\n",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin on?'s':'u',
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstdout, "set %co %s\n",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin on?'-':'+',
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(!(value&SH_COMMANDLINE) && is_option(&oflags,value&0xff))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstdout," %s%s%s",(mode&PRINT_SHOPT)?"":"--",on?"":"no",name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(mode&(PRINT_VERBOSE|PRINT_ALL)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(sfstdout,'\n');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * build an argument list
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinchar **sh_argbuild(Shell_t *shp,int *nargs, const struct comnod *comptr,int flag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct argnod *argp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct argnod *arghead=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->xargmin = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const struct comnod *ac = comptr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* see if the arguments have already been expanded */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!ac->comarg)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *nargs = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(&null);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(!(ac->comtyp&COMSCAN))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct dolnod *ap = (struct dolnod*)ac->comarg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *nargs = ap->dolnum;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(ap->dolval+ap->dolbot);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->lastpath = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *nargs = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ac)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ac->comnamp == SYSLET)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flag |= ARG_LET;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argp = ac->comarg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(argp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin n = arg_expand(shp,argp,&arghead,flag);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n>1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->xargmin==0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->xargmin = *nargs;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->xargmax = *nargs+n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *nargs += n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argp = argp->argnxt.ap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argp = arghead;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char **comargn;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int argn;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char **comargm;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argn = *nargs;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* allow room to prepend args */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argn += 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin comargn=(char**)stkalloc(shp->stk,(unsigned)(argn+1)*sizeof(char*));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin comargm = comargn += argn;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *comargn = NIL(char*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!argp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* reserve an extra null pointer */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *--comargn = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(comargn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(argp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct argnod *nextarg = argp->argchn.ap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argp->argchn.ap = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *--comargn = argp->argval;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(argp->argflag&ARG_RAW))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_trim(*comargn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(argp=nextarg) || (argp->argflag&ARG_MAKE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((argn=comargm-comargn)>1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strsort(comargn,argn,strcoll);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin comargm = comargn;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->last_table = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(comargn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _pipe_socketpair && !_socketpair_devfd
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define sh_pipe arg_pipe
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * create a real pipe (not a socket) and print message on failure
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int arg_pipe(register int pv[])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int fd[2];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pipe(fd)<0 || (pv[0]=fd[0])<0 || (pv[1]=fd[1])<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_system(1),e_pipe);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pv[0] = sh_iomovefd(pv[0]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pv[1] = sh_iomovefd(pv[1]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.fdstatus[pv[0]] = IONOSEEK|IOREAD;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.fdstatus[pv[1]] = IONOSEEK|IOWRITE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_subsavefd(pv[0]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_subsavefd(pv[1]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzstruct argnod *sh_argprocsub(Shell_t *shp,struct argnod *argp)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz{
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /* argument of the form <(cmd) or >(cmd) */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz register struct argnod *ap;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz int monitor, fd, pv[2];
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz int subshell = shp->subshell;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz ap = (struct argnod*)stkseek(shp->stk,ARGVAL);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz ap->argflag |= ARG_MAKE;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz ap->argflag &= ~ARG_RAW;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfwrite(shp->stk,e_devfdNN,8);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sh_pipe(pv);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fd = argp->argflag&ARG_RAW;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfputr(shp->stk,fmtbase((long)pv[fd],10,0),0);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz ap = (struct argnod*)stkfreeze(shp->stk,0);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz shp->inpipe = shp->outpipe = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(monitor = (sh_isstate(SH_MONITOR)!=0))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sh_offstate(SH_MONITOR);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz shp->subshell = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(fd)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz shp->inpipe = pv;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sh_exec((Shnode_t*)argp->argchn.ap,(int)sh_isstate(SH_ERREXIT));
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz shp->outpipe = pv;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sh_exec((Shnode_t*)argp->argchn.ap,(int)sh_isstate(SH_ERREXIT));
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz shp->subshell = subshell;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(monitor)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sh_onstate(SH_MONITOR);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz close(pv[1-fd]);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sh_iosave(shp,-pv[fd], shp->topfd, (char*)0);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return(ap);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz}
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* Argument expansion */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic int arg_expand(Shell_t *shp,register struct argnod *argp, struct argnod **argchain,int flag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int count = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argp->argflag &= ~ARG_MAKE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_DEVFD
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*argp->argval==0 && (argp->argflag&ARG_EXP))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz struct argnod *ap;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz ap = sh_argprocsub(shp,argp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->argchn.ap = *argchain;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *argchain = ap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin count++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_DEVFD */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(argp->argflag&ARG_RAW))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_OPTIMIZE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct argnod *ap;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_stats(STAT_ARGEXPAND);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag&ARG_OPTIMIZE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argp->argchn.ap=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ap=argp->argchn.ap)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_stats(STAT_ARGHITS);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin count = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->argchn.ap = *argchain;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->argflag |= ARG_RAW;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->argflag &= ~ARG_EXP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *argchain = ap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_OPTIMIZE */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin count = sh_macexpand(shp,argp,argchain,flag);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argp->argchn.ap = *argchain;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *argchain = argp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argp->argflag |= ARG_MAKE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin count++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(count);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin