1 /***********************************************************************
3 * This software is part of the ast package *
4 * Copyright (c) 1982-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
13 * Information and Software Systems Research *
17 * David Korn <dgk@research.att.com> *
19 ***********************************************************************/
21 * bash specific extensions
22 * originally provided by Karsten Fleischer
32 # define BASH_MAJOR "1"
33 # define BASH_MINOR "0"
34 # define BASH_PATCH "0"
35 # define BASH_BUILD "0"
36 # define BASH_RELEASE "experimental"
38 #define BASH_VERSION BASH_MAJOR "." BASH_MINOR "." BASH_PATCH "(" BASH_BUILD ")-" BASH_RELEASE
41 extern const char bash_pre_rc
[];
43 static char *login_files
[4];
45 const char sh_bash1
[] =
46 "[B?Enable brace group expansion. This option is only availabe in bash "
47 "compatibility mode. In ksh mode, brace group expansion is always on.]"
48 "[P?Do not follow symbolic links, use physical directory structure "
49 "instead. Only available in bash compatibility mode.]";
50 const char sh_bash2
[] =
51 "[O]:?[shopt_option?\ashopt_option\a is one of the shell options accepted by "
52 "the \bshopt\b builtin. If \ashopt_option\a is present, \b-O\b sets "
53 "the value of that option; \b+O\b unsets it. If \ashopt_option\a is "
54 "not supplied, the names and values of the shell options accepted by "
55 "\bshopt\b are printed on the standard output. If the invocation "
56 "option is \b+O\b, the output is displayed in a format that may be "
57 "reused as input. Only available if invoked as \bbash\b.]"
58 "[01:init-file|rcfile]:[file?Execute commands from \afile\a instead of the "
59 "standard personal initialization file ~/.bashrc if the shell is "
60 "interactive. Only available if invoked as \bbash\b.]"
61 "[02:editing?For option compatibility with \bbash\b only. Ignored.]"
62 "[03:profile?Read either the system-wide startup file or any of the "
63 "personal initialization files. On by default for interactive "
64 "shells. Only available if invoked as \bbash\b.]"
65 "[04:posix?If invoked as \bbash\b, turn on POSIX compatibility. \bBash\b in "
66 "POSIX mode is not the same as \bksh\b.]"
67 "[05:version?Print version number and exit.]";
69 const char sh_optshopt
[] =
70 "+[-1c?\n@(#)$Id: shopt (AT&T Research) 2003-02-13 $\n]"
71 "[-author?Karsten Fleischer <K.Fleischer@omnium.de>]"
73 "[+NAME?shopt - set/unset variables controlling optional shell behavior]"
74 "[+DESCRIPTION?\bshopt\b sets or unsets variables controlling optional shell "
75 "behavior. With no options, or with the \b-p\b option, a list of all "
76 "settable options is displayed, with an indication of whether or not "
78 "[p?Causes output to be displayed in a form that may be reused as input.]"
79 "[s?Set each \aoptname\a.]"
80 "[u?Unset each \aoptname\a.]"
81 "[q?Suppress output (quiet mode). The return status indicates whether the "
82 "\aoptname\a is set or unset. If multiple \aoptname\a arguments are "
83 "given with \b-q\b, the return status is zero if all \aoptname\as are "
84 "enabled; non-zero otherwise.]"
85 "[o?Restricts the values of \aoptname\a to be those defined for the \b-o\b "
86 "option to the set builtin.]"
87 "[+?If either \b-s\b or \b-u\b is used with no \aoptname\a arguments, the "
88 "display is limited to those options which are set or unset.]"
89 "[+?\bshopt\b supports all bash options. Some settings do not have any effect "
90 "or are are always on and cannot be changed.]"
91 "[+?The value of \aoptname\a must be one of the following:]{"
92 "[+cdable_vars?If set, arguments to the \bcd\b command are "
93 "assumed to be names of variables whose values are to "
94 "be used if the usual \bcd\b proceeding fails.]"
95 "[+cdspell?Currently ignored.]"
96 "[+checkhash?Always on.]"
97 "[+checkwinsize?Currently ignored.]"
98 "[+cmdhist?Always on.]"
99 "[+dotglob?If set, include filenames beginning with a \b.\b "
100 "in the results of pathname expansion.]"
101 "[+execfail?Always on.]"
102 "[+expand_aliases?Always on.]"
103 "[+extglob?Enable extended pattern matching features.]"
104 "[+histappend?Always on.]"
105 "[+histreedit?If set and an edit mode is selected, the user "
106 "is given the opportunity to re-edit a failed history "
108 "[+histverify?If set and an edit mode is selected, the result "
109 "of a history substitution will not be executed "
110 "immediately but be placed in the edit buffer for "
111 "further modifications.]"
112 "[+hostcomplete?Currently ignored.]"
113 "[+huponexit?Currently ignored.]"
114 "[+interactive_comments?Always on.]"
115 "[+lithist?Always on.]"
116 "[+login_shell?This option is set if the shell is started as "
117 "a login shell. The value cannot be changed.]"
118 "[+mailwarn?Currently ignored.]"
119 "[+no_empty_cmd_completion?Always on.]"
120 "[+nocaseglob?Match filenames in a case-insensitive fashion "
121 "when performing filename expansion.]"
122 "[+nullglob?Allows filename patterns which match no files to "
123 "expand to a null string, rather than themselves.]"
124 "[+progcomp?Currently ignored.]"
125 "[+promptvars?Currently ignored.]"
126 "[+restricted_shell?This option is set if the shell is started "
127 "as a restricted shell. The value cannot be changed. "
128 "It is not reset during execution of startup files, "
129 "allowing the startup files to determine whether the "
130 "shell is restricted.]"
131 "[+shift_verbose?Currently ignored.]"
132 "[+sourcepath?If set, the \b.\b builtin uses the value of PATH "
133 "to find the directory containing the file supplied "
135 "[+xpg_echo?If set, the \becho\b and \bprint\b builtins "
136 "expand backslash-escape sequences.]"
142 "[+?The return status when listing options is zero if all \aoptnames\a "
143 "are enabled, non-zero otherwise. When setting or unsetting options, "
144 "the return status is zero unless an \aoptname\a is not a valid shell "
148 "[+SEE ALSO?\bset\b(1)]"
151 /* GLOBIGNORE discipline. Turn on SH_DOTGLOB on set, turn off on unset. */
153 static void put_globignore(register Namval_t
* np
, const char *val
, int flags
, Namfun_t
*fp
)
156 sh_onoption(SH_DOTGLOB
);
158 sh_offoption(SH_DOTGLOB
);
160 nv_putv(np
,val
,flags
,fp
);
163 const Namdisc_t SH_GLOBIGNORE_disc
= { sizeof(Namfun_t
), put_globignore
};
165 /* FUNCNAME discipline */
172 static void put_funcname(register Namval_t
* np
,const char *val
,int flags
,Namfun_t
*fp
)
174 /* bash silently returns with an error when FUNCNAME is set,
175 unsetting FUNCNAME is allowed */
176 if(val
&& !(flags
&NV_RDONLY
))
179 nv_putv(np
,val
,flags
,fp
);
182 const Namdisc_t SH_FUNCNAME_disc
= { sizeof(struct funcname
), put_funcname
};
190 int b_shopt(int argc
,register char *argv
[],void *extra
)
192 Shell_t
*shp
= (Shell_t
*)extra
;
194 Shopt_t newflags
=shp
->options
, opt
;
195 int verbose
=PRINT_SHOPT
|PRINT_ALL
|PRINT_NO_HEADER
|PRINT_VERBOSE
;
196 int setflag
=0, quietflag
=0, oflag
=0;
197 memset(&opt
,0,sizeof(opt
));
199 on_option(&newflags
,SH_VIRAW
);
201 while((n
= optget(argv
,sh_optshopt
)))
206 verbose
&=~PRINT_VERBOSE
;
210 setflag
|=n
=='s'?SET_SET
:SET_UNSET
;
211 if(setflag
==(SET_SET
|SET_UNSET
))
213 errormsg(SH_DICT
,ERROR_ERROR
,"cannot set and unset options simultaneously");
222 verbose
&=~PRINT_SHOPT
;
225 errormsg(SH_DICT
,2, "%s", opt_info
.arg
);
228 errormsg(SH_DICT
,ERROR_usage(0), "%s", opt_info
.arg
);
232 if(error_info
.errors
)
233 errormsg(SH_DICT
,ERROR_usage(2),"%s",optusage(NIL(char*)));
234 argc
-= opt_info
.index
;
237 /* no args, -s => mask=current options, -u mask=~(current options)
238 else mask=all bits */
241 else if(setflag
&SET_UNSET
)
243 opt
.v
[n
]=~newflags
.v
[n
];
245 memset(&opt
,0xff,sizeof(opt
));
251 n
=sh_lookopt(argv
[opt_info
.index
],&f
);
253 && (is_option(&opt
,SH_INTERACTIVE
)
254 || is_option(&opt
,SH_RESTRICTED
)
255 || is_option(&opt
,SH_RESTRICTED2
)
256 || is_option(&opt
,SH_BASH
)
257 || is_option(&opt
,SH_LOGIN_SHELL
)))
258 ||(oflag
&&(n
&SH_BASHOPT
)))
260 errormsg(SH_DICT
,ERROR_ERROR
, e_option
, argv
[opt_info
.index
]);
265 on_option(&opt
,n
&0xff);
267 off_option(&opt
,n
&0xff);
271 if(setflag
&(SET_SET
|SET_UNSET
))
275 if(sh_isoption(SH_INTERACTIVE
))
276 off_option(&opt
,SH_NOEXEC
);
277 if(is_option(&opt
,SH_VI
)||is_option(&opt
,SH_EMACS
)||is_option(&opt
,SH_GMACS
))
279 off_option(&newflags
,SH_VI
);
280 off_option(&newflags
,SH_EMACS
);
281 off_option(&newflags
,SH_GMACS
);
284 newflags
.v
[n
] |= opt
.v
[n
];
286 else if(setflag
&SET_UNSET
)
288 newflags
.v
[n
] &= ~opt
.v
[n
];
289 sh_applyopts(shp
,newflags
);
290 shp
->options
= newflags
;
291 if(is_option(&newflags
,SH_XTRACE
))
294 else if(!(setflag
&SET_NOARGS
)) /* no -s,-u but args, ret=0 if opt&mask==mask */
297 ret
+=((newflags
.v
[n
]&opt
.v
[n
])!=opt
.v
[n
]);
299 if(!quietflag
&&!(setflag
&(SET_SET
|SET_UNSET
)))
300 sh_printopts(newflags
,verbose
,&opt
);
304 /* mode = 0: init, called two times
305 before parsing shell args with SH_PREINIT state turned on
306 second time after sh_init() is through and with SH_PREINIT state turned off
311 void bash_init(int mode
)
316 int n
=0,xtrace
,verbose
;
321 /* termination code */
322 if(sh_isoption(SH_LOGIN_SHELL
) && !sh_isoption(SH_POSIX
))
323 sh_source(shp
, NiL
, sh_mactry(shp
,(char*)e_bash_logout
));
327 if(sh_isstate(SH_PREINIT
))
328 { /* pre-init stage */
329 if(sh_isoption(SH_RESTRICTED
))
330 sh_onoption(SH_RESTRICTED2
);
331 sh_onoption(SH_HISTORY2
);
332 sh_onoption(SH_INTERACTIVE_COMM
);
333 sh_onoption(SH_SOURCEPATH
);
334 sh_onoption(SH_HISTAPPEND
);
335 sh_onoption(SH_CMDHIST
);
336 sh_onoption(SH_LITHIST
);
337 sh_onoption(SH_NOEMPTYCMDCOMPL
);
339 sh_onoption(SH_LOGIN_SHELL
);
340 if(strcmp(astconf("CONFORMANCE",0,0),"standard")==0)
341 sh_onoption(SH_POSIX
);
342 if(strcmp(astconf("UNIVERSE",0,0),"att")==0)
343 sh_onoption(SH_XPG_ECHO
);
345 sh_offoption(SH_XPG_ECHO
);
346 if(strcmp(astconf("PATH_RESOLVE",0,0),"physical")==0)
347 sh_onoption(SH_PHYSICAL
);
349 sh_offoption(SH_PHYSICAL
);
352 sh_addbuiltin("shopt", b_shopt
, &sh
);
354 /* set up some variables needed for --version
355 * needs to go here because --version option is parsed before the init script.
357 if(np
=nv_open("HOSTTYPE",shp
->var_tree
,0))
358 nv_putval(np
, BASH_HOSTTYPE
, NV_NOFREE
);
359 if(np
=nv_open("MACHTYPE",shp
->var_tree
,0))
360 nv_putval(np
, BASH_MACHTYPE
, NV_NOFREE
);
361 if(np
=nv_open("BASH_VERSION",shp
->var_tree
,0))
362 nv_putval(np
, BASH_VERSION
, NV_NOFREE
);
363 if(np
=nv_open("BASH_VERSINFO",shp
->var_tree
,0))
366 argv
[0] = BASH_MAJOR
;
367 argv
[1] = BASH_MINOR
;
368 argv
[2] = BASH_PATCH
;
369 argv
[3] = BASH_BUILD
;
370 argv
[4] = BASH_RELEASE
;
371 argv
[5] = BASH_MACHTYPE
;
373 nv_setvec(np
, 0, 6, argv
);
374 nv_onattr(np
,NV_RDONLY
);
379 /* rest of init stage */
381 /* restrict BASH_ENV */
382 if(np
=nv_open("BASH_ENV",shp
->var_tree
,0))
384 const Namdisc_t
*dp
= nv_discfun(NV_DCRESTRICT
);
385 Namfun_t
*fp
= calloc(dp
->dsize
,1);
390 /* open GLOBIGNORE node */
391 if(np
=nv_open("GLOBIGNORE",shp
->var_tree
,0))
393 const Namdisc_t
*dp
= &SH_GLOBIGNORE_disc
;
394 Namfun_t
*fp
= calloc(dp
->dsize
,1);
399 /* set startup files */
401 if(sh_isoption(SH_LOGIN_SHELL
))
403 if(!sh_isoption(SH_POSIX
))
405 login_files
[n
++] = (char*)e_bash_profile
;
406 login_files
[n
++] = (char*)e_bash_login
;
408 login_files
[n
++] = (char*)e_profile
;
410 shp
->login_files
= login_files
;
412 xtrace
= sh_isoption(SH_XTRACE
);
413 sh_offoption(SH_XTRACE
);
414 verbose
= sh_isoption(SH_VERBOSE
);
415 sh_offoption(SH_VERBOSE
);
416 if(np
= nv_open("SHELLOPTS", shp
->var_tree
, NV_NOADD
))
417 nv_offattr(np
,NV_RDONLY
);
418 iop
= sfopen(NULL
, bash_pre_rc
, "s");
421 sh_offoption(SH_XTRACE
);
423 sh_offoption(SH_VERBOSE
);