1*4887Schin /*********************************************************************** 2*4887Schin * * 3*4887Schin * This software is part of the ast package * 4*4887Schin * Copyright (c) 1982-2007 AT&T Knowledge Ventures * 5*4887Schin * and is licensed under the * 6*4887Schin * Common Public License, Version 1.0 * 7*4887Schin * by AT&T Knowledge Ventures * 8*4887Schin * * 9*4887Schin * A copy of the License is available at * 10*4887Schin * http://www.opensource.org/licenses/cpl1.0.txt * 11*4887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 12*4887Schin * * 13*4887Schin * Information and Software Systems Research * 14*4887Schin * AT&T Research * 15*4887Schin * Florham Park NJ * 16*4887Schin * * 17*4887Schin * David Korn <dgk@research.att.com> * 18*4887Schin * * 19*4887Schin ***********************************************************************/ 20*4887Schin #pragma prototyped 21*4887Schin /* 22*4887Schin * David Korn 23*4887Schin * AT&T Labs 24*4887Schin * 25*4887Schin * Shell interface private definitions 26*4887Schin * 27*4887Schin */ 28*4887Schin 29*4887Schin #include <ast.h> 30*4887Schin #include <sfio.h> 31*4887Schin #include <error.h> 32*4887Schin #include "FEATURE/options" 33*4887Schin #include <cdt.h> 34*4887Schin #include <history.h> 35*4887Schin #include "fault.h" 36*4887Schin #include "argnod.h" 37*4887Schin 38*4887Schin #ifndef pointerof 39*4887Schin #define pointerof(x) ((void*)((char*)0+(x))) 40*4887Schin #endif 41*4887Schin 42*4887Schin #define env_change() (++ast.env_serial) 43*4887Schin #if SHOPT_ENV 44*4887Schin # include <env.h> 45*4887Schin #else 46*4887Schin # define Env_t void 47*4887Schin # define sh_envput(e,p) env_change() 48*4887Schin # define env_delete(e,p) env_change() 49*4887Schin #endif 50*4887Schin 51*4887Schin /* 52*4887Schin * note that the first few fields have to be the same as for 53*4887Schin * Shscoped_t in <shell.h> 54*4887Schin */ 55*4887Schin struct sh_scoped 56*4887Schin { 57*4887Schin struct sh_scoped *prevst; /* pointer to previous state */ 58*4887Schin int dolc; 59*4887Schin char **dolv; 60*4887Schin char *cmdname; 61*4887Schin char *filename; 62*4887Schin int lineno; 63*4887Schin Dt_t *save_tree; /* var_tree for calling function */ 64*4887Schin struct sh_scoped *self; /* pointer to copy of this scope*/ 65*4887Schin Dt_t *var_local; /* local level variables for name() */ 66*4887Schin struct slnod *staklist; /* link list of function stacks */ 67*4887Schin int states; 68*4887Schin int breakcnt; 69*4887Schin int execbrk; 70*4887Schin int loopcnt; 71*4887Schin int firstline; 72*4887Schin int32_t optindex; 73*4887Schin int32_t optnum; 74*4887Schin int32_t tmout; /* value for TMOUT */ 75*4887Schin short optchar; 76*4887Schin short opterror; 77*4887Schin int ioset; 78*4887Schin unsigned short trapmax; 79*4887Schin char *trap[SH_DEBUGTRAP+1]; 80*4887Schin char **trapcom; 81*4887Schin char **otrapcom; 82*4887Schin void *timetrap; 83*4887Schin }; 84*4887Schin 85*4887Schin struct limits 86*4887Schin { 87*4887Schin long arg_max; /* max arg+env exec() size */ 88*4887Schin int open_max; /* maximum number of file descriptors */ 89*4887Schin int clk_tck; /* number of ticks per second */ 90*4887Schin int child_max; /* maxumum number of children */ 91*4887Schin int ngroups_max; /* maximum number of process groups */ 92*4887Schin unsigned char posix_version; /* posix version number */ 93*4887Schin unsigned char posix_jobcontrol;/* non-zero for job control systems */ 94*4887Schin unsigned char fs3d; /* non-zero for 3-d file system */ 95*4887Schin }; 96*4887Schin 97*4887Schin #define _SH_PRIVATE \ 98*4887Schin struct sh_scoped st; /* scoped information */ \ 99*4887Schin struct limits lim; /* run time limits */ \ 100*4887Schin Sfio_t *heredocs; /* current here-doc temp file */ \ 101*4887Schin Sfio_t *funlog; /* for logging function definitions */ \ 102*4887Schin int **fdptrs; /* pointer to file numbers */ \ 103*4887Schin int savexit; \ 104*4887Schin char *lastarg; \ 105*4887Schin char *lastpath; /* last alsolute path found */ \ 106*4887Schin int path_err; /* last error on path search */ \ 107*4887Schin Dt_t *track_tree; /* for tracked aliases*/ \ 108*4887Schin Namval_t *bltin_nodes; /* pointer to built-in variables */ \ 109*4887Schin Dt_t *var_base; /* global level variables */ \ 110*4887Schin Namval_t *namespace; /* current active namespace*/ \ 111*4887Schin Namval_t *last_table; /* last table used in last nv_open */ \ 112*4887Schin Sfio_t *outpool; /* ouput stream pool */ \ 113*4887Schin long timeout; /* read timeout */ \ 114*4887Schin short curenv; /* current subshell number */ \ 115*4887Schin short jobenv; /* subshell number for jobs */ \ 116*4887Schin int nextprompt; /* next prompt is PS<nextprompt> */ \ 117*4887Schin Namval_t *bltin_cmds; /* pointer to built-in commands */ \ 118*4887Schin Namval_t *posix_fun; /* points to last name() function */ \ 119*4887Schin int infd; /* input file descriptor */ \ 120*4887Schin char *outbuff; /* pointer to output buffer */ \ 121*4887Schin char *errbuff; /* pointer to stderr buffer */ \ 122*4887Schin char *prompt; /* pointer to prompt string */ \ 123*4887Schin char *shname; /* shell name */ \ 124*4887Schin char *shpath; /* path name of shell */ \ 125*4887Schin char *user; /* name of real user for pfsh */ \ 126*4887Schin char *comdiv; /* points to sh -c argument */ \ 127*4887Schin char *prefix; /* prefix for compound assignment */ \ 128*4887Schin sigjmp_buf *jmplist; /* longjmp return stack */ \ 129*4887Schin char **sigmsg; /* points to signal messages */ \ 130*4887Schin int oldexit; \ 131*4887Schin uid_t userid,euserid; /* real and effective user id */ \ 132*4887Schin gid_t groupid,egroupid;/* real and effective group id */ \ 133*4887Schin pid_t pid; /* process id of shell */ \ 134*4887Schin pid_t bckpid; /* background process id */ \ 135*4887Schin pid_t cpid; \ 136*4887Schin int32_t ppid; /* parent process id of shell */ \ 137*4887Schin int topfd; \ 138*4887Schin int sigmax; /* maximum number of signals */ \ 139*4887Schin int savesig; \ 140*4887Schin unsigned char *sigflag; /* pointer to signal states */ \ 141*4887Schin char intrap; \ 142*4887Schin char login_sh; \ 143*4887Schin char lastbase; \ 144*4887Schin char forked; \ 145*4887Schin char binscript; \ 146*4887Schin char deftype; \ 147*4887Schin char used_pos; /* used postional parameter */\ 148*4887Schin unsigned char lastsig; /* last signal received */ \ 149*4887Schin char *readscript; /* set before reading a script */ \ 150*4887Schin int *inpipe; /* input pipe pointer */ \ 151*4887Schin int *outpipe; /* output pipe pointer */ \ 152*4887Schin int cpipe[2]; \ 153*4887Schin int coutpipe; \ 154*4887Schin int inuse_bits; \ 155*4887Schin struct argnod *envlist; \ 156*4887Schin struct dolnod *arglist; \ 157*4887Schin int fn_depth; \ 158*4887Schin int dot_depth; \ 159*4887Schin int hist_depth; \ 160*4887Schin int xargmin; \ 161*4887Schin int xargmax; \ 162*4887Schin int xargexit; \ 163*4887Schin mode_t mask; \ 164*4887Schin long nforks; \ 165*4887Schin Env_t *env; \ 166*4887Schin void *init_context; \ 167*4887Schin void *mac_context; \ 168*4887Schin void *lex_context; \ 169*4887Schin void *arg_context; \ 170*4887Schin void *ed_context; \ 171*4887Schin void *job_context; \ 172*4887Schin void *pathlist; \ 173*4887Schin void *defpathlist; \ 174*4887Schin void *cdpathlist; \ 175*4887Schin char **argaddr; \ 176*4887Schin void *optlist; \ 177*4887Schin int optcount ; \ 178*4887Schin struct sh_scoped global; \ 179*4887Schin struct checkpt checkbase; \ 180*4887Schin Shinit_f userinit; \ 181*4887Schin Shbltin_f bltinfun; \ 182*4887Schin Shwait_f waitevent; \ 183*4887Schin char *cur_line; \ 184*4887Schin char *rcfile; \ 185*4887Schin char **login_files; \ 186*4887Schin short offsets[10]; \ 187*4887Schin Sfio_t **sftable; \ 188*4887Schin unsigned char *fdstatus; \ 189*4887Schin const char *pwd; \ 190*4887Schin History_t *hist_ptr; \ 191*4887Schin char universe; \ 192*4887Schin void *jmpbuffer; \ 193*4887Schin void *mktype; \ 194*4887Schin Sfio_t *strbuf; \ 195*4887Schin Dt_t *last_root; \ 196*4887Schin char ifstable[256]; \ 197*4887Schin Shopt_t offoptions; 198*4887Schin 199*4887Schin #include <shell.h> 200*4887Schin 201*4887Schin 202*4887Schin /* error exits from various parts of shell */ 203*4887Schin #define NIL(type) ((type)0) 204*4887Schin 205*4887Schin #define new_of(type,x) ((type*)malloc((unsigned)sizeof(type)+(x))) 206*4887Schin 207*4887Schin #define exitset() (sh.savexit=sh.exitval) 208*4887Schin 209*4887Schin #ifndef SH_DICT 210*4887Schin #define SH_DICT (void*)e_dict 211*4887Schin #endif 212*4887Schin 213*4887Schin #ifndef SH_CMDLIB_DIR 214*4887Schin #define SH_CMDLIB_DIR "/opt/ast/bin" 215*4887Schin #endif 216*4887Schin 217*4887Schin /* states */ 218*4887Schin /* low numbered states are same as options */ 219*4887Schin #define SH_NOFORK 0 /* set when fork not necessary, not a state */ 220*4887Schin #define SH_COMPLETE 0 /* set for command completion */ 221*4887Schin #define SH_FORKED 7 /* set when process has been forked */ 222*4887Schin #define SH_PROFILE 8 /* set when processing profiles */ 223*4887Schin #define SH_NOALIAS 9 /* do not expand non-exported aliases */ 224*4887Schin #define SH_NOTRACK 10 /* set to disable sftrack() function */ 225*4887Schin #define SH_STOPOK 11 /* set for stopable builtins */ 226*4887Schin #define SH_GRACE 12 /* set for timeout grace period */ 227*4887Schin #define SH_TIMING 13 /* set while timing pipelines */ 228*4887Schin #define SH_DEFPATH 14 /* set when using default path */ 229*4887Schin #define SH_INIT 15 /* set when initializing the shell */ 230*4887Schin #define SH_TTYWAIT 16 /* waiting for keyboard input */ 231*4887Schin #define SH_FCOMPLETE 17 /* set for filename completion */ 232*4887Schin #define SH_PREINIT 18 /* set with SH_INIT before parsing options */ 233*4887Schin 234*4887Schin #define SH_BASH 41 235*4887Schin #define SH_BRACEEXPAND 42 236*4887Schin #define SH_POSIX 46 237*4887Schin #define SH_MULTILINE 47 238*4887Schin 239*4887Schin #define SH_NOPROFILE 78 240*4887Schin #define SH_NOUSRPROFILE 79 241*4887Schin #define SH_LOGIN_SHELL 67 242*4887Schin #define SH_COMMANDLINE 0x100 243*4887Schin #define SH_BASHEXTRA 0x200 244*4887Schin #define SH_BASHOPT 0x400 245*4887Schin 246*4887Schin #define SH_ID "ksh" /* ksh id */ 247*4887Schin #define SH_STD "sh" /* standard sh id */ 248*4887Schin 249*4887Schin /* defines for sh_type() */ 250*4887Schin 251*4887Schin #define SH_TYPE_SH 001 252*4887Schin #define SH_TYPE_KSH 002 253*4887Schin #define SH_TYPE_BASH 004 254*4887Schin #define SH_TYPE_LOGIN 010 255*4887Schin #define SH_TYPE_PROFILE 020 256*4887Schin #define SH_TYPE_RESTRICTED 040 257*4887Schin 258*4887Schin #if SHOPT_BASH 259*4887Schin # ifndef SHOPT_HISTEXPAND 260*4887Schin # define SHOPT_HISTEXPAND 1 261*4887Schin # endif 262*4887Schin /* 263*4887Schin * define for all the bash options 264*4887Schin */ 265*4887Schin # define SH_CDABLE_VARS 51 266*4887Schin # define SH_CDSPELL 52 267*4887Schin # define SH_CHECKHASH 53 268*4887Schin # define SH_CHECKWINSIZE 54 269*4887Schin # define SH_CMDHIST 55 270*4887Schin # define SH_DOTGLOB 56 271*4887Schin # define SH_EXECFAIL 57 272*4887Schin # define SH_EXPAND_ALIASES 58 273*4887Schin # define SH_EXTGLOB 59 274*4887Schin # define SH_HOSTCOMPLETE 63 275*4887Schin # define SH_HUPONEXIT 64 276*4887Schin # define SH_INTERACTIVE_COMM 65 277*4887Schin # define SH_LITHIST 66 278*4887Schin # define SH_MAILWARN 68 279*4887Schin # define SH_NOEMPTYCMDCOMPL 69 280*4887Schin # define SH_NOCASEGLOB 70 281*4887Schin # define SH_NULLGLOB 71 282*4887Schin # define SH_PHYSICAL 45 283*4887Schin # define SH_PROGCOMP 72 284*4887Schin # define SH_PROMPTVARS 73 285*4887Schin # define SH_RESTRICTED2 74 286*4887Schin # define SH_SHIFT_VERBOSE 75 287*4887Schin # define SH_SOURCEPATH 76 288*4887Schin # define SH_XPG_ECHO 77 289*4887Schin #endif 290*4887Schin 291*4887Schin #if SHOPT_HISTEXPAND 292*4887Schin # define SH_HISTAPPEND 60 293*4887Schin # define SH_HISTEXPAND 43 294*4887Schin # define SH_HISTORY2 44 295*4887Schin # define SH_HISTREEDIT 61 296*4887Schin # define SH_HISTVERIFY 62 297*4887Schin #endif 298*4887Schin 299*4887Schin #ifndef PIPE_BUF 300*4887Schin # define PIPE_BUF 512 301*4887Schin #endif 302*4887Schin 303*4887Schin #define MATCH_MAX 64 304*4887Schin 305*4887Schin extern int sh_addlib(void*); 306*4887Schin extern void *sh_argopen(Shell_t*); 307*4887Schin extern Namval_t *sh_assignok(Namval_t*,int); 308*4887Schin extern char *sh_checkid(char*,char*); 309*4887Schin extern int sh_debug(const char*,const char*,const char*,char *const[],int); 310*4887Schin extern int sh_echolist(Sfio_t*, int, char**); 311*4887Schin extern struct argnod *sh_endword(int); 312*4887Schin extern char **sh_envgen(void); 313*4887Schin #if SHOPT_ENV 314*4887Schin extern void sh_envput(Env_t*, Namval_t*); 315*4887Schin #endif 316*4887Schin extern void sh_envnolocal(Namval_t*,void*); 317*4887Schin extern Sfdouble_t sh_arith(const char*); 318*4887Schin extern void *sh_arithcomp(char*); 319*4887Schin extern pid_t sh_fork(int,int*); 320*4887Schin extern pid_t _sh_fork(pid_t, int ,int*); 321*4887Schin extern char *sh_mactrim(char*,int); 322*4887Schin extern int sh_macexpand(struct argnod*,struct argnod**,int); 323*4887Schin extern void sh_machere(Sfio_t*, Sfio_t*, char*); 324*4887Schin extern void *sh_macopen(Shell_t*); 325*4887Schin extern char *sh_macpat(struct argnod*,int); 326*4887Schin extern char *sh_mactry(char*); 327*4887Schin extern void sh_printopts(Shopt_t,int,Shopt_t*); 328*4887Schin extern int sh_readline(Shell_t*,char**,int,int,long); 329*4887Schin extern Sfio_t *sh_sfeval(char*[]); 330*4887Schin extern void sh_setmatch(const char*,int,int,int[]); 331*4887Schin extern Dt_t *sh_subaliastree(int); 332*4887Schin extern Dt_t *sh_subfuntree(int); 333*4887Schin extern int sh_subsavefd(int); 334*4887Schin extern void sh_subtmpfile(void); 335*4887Schin extern char *sh_substitute(const char*,const char*,char*); 336*4887Schin extern const char *_sh_translate(const char*); 337*4887Schin extern int sh_trace(char*[],int); 338*4887Schin extern void sh_trim(char*); 339*4887Schin extern int sh_type(const char*); 340*4887Schin extern void sh_utol(const char*, char*); 341*4887Schin extern int sh_whence(char**,int); 342*4887Schin 343*4887Schin #ifndef ERROR_dictionary 344*4887Schin # define ERROR_dictionary(s) (s) 345*4887Schin #endif 346*4887Schin #define sh_translate(s) _sh_translate(ERROR_dictionary(s)) 347*4887Schin 348*4887Schin #define WBITS (sizeof(long)*8) 349*4887Schin #define WMASK (0xff) 350*4887Schin 351*4887Schin #define is_option(s,x) ((s)->v[((x)&WMASK)/WBITS] & (1L << ((x) % WBITS))) 352*4887Schin #define on_option(s,x) ((s)->v[((x)&WMASK)/WBITS] |= (1L << ((x) % WBITS))) 353*4887Schin #define off_option(s,x) ((s)->v[((x)&WMASK)/WBITS] &= ~(1L << ((x) % WBITS))) 354*4887Schin #define sh_isoption(x) is_option(&sh.options,x) 355*4887Schin #define sh_onoption(x) on_option(&sh.options,x) 356*4887Schin #define sh_offoption(x) off_option(&sh.options,x) 357*4887Schin 358*4887Schin 359*4887Schin #define sh_state(x) ( 1<<(x)) 360*4887Schin #define sh_isstate(x) (sh.st.states&sh_state(x)) 361*4887Schin #define sh_onstate(x) (sh.st.states |= sh_state(x)) 362*4887Schin #define sh_offstate(x) (sh.st.states &= ~sh_state(x)) 363*4887Schin #define sh_getstate() (sh.st.states) 364*4887Schin #define sh_setstate(x) (sh.st.states = (x)) 365*4887Schin 366*4887Schin #define sh_sigcheck() do{if(sh.trapnote&SH_SIGSET)sh_exit(SH_EXITSIG);} while(0) 367*4887Schin 368*4887Schin extern int32_t sh_mailchk; 369*4887Schin extern const char e_dict[]; 370*4887Schin 371*4887Schin /* sh_printopts() mode flags -- set --[no]option by default */ 372*4887Schin 373*4887Schin #define PRINT_VERBOSE 0x01 /* option on|off list */ 374*4887Schin #define PRINT_ALL 0x02 /* list unset iptions too */ 375*4887Schin #define PRINT_NO_HEADER 0x04 /* omit listing header */ 376*4887Schin #define PRINT_SHOPT 0x08 /* shopt -s|-u */ 377*4887Schin #define PRINT_TABLE 0x10 /* table of all options */ 378