1996-12-23 17:02:34 +00:00
|
|
|
This file is shopt.def, from which is created shopt.c.
|
|
|
|
It implements the Bash `shopt' builtin.
|
|
|
|
|
|
|
|
Copyright (C) 1994 Free Software Foundation, Inc.
|
|
|
|
|
|
|
|
This file is part of GNU Bash, the Bourne Again SHell.
|
|
|
|
|
|
|
|
Bash is free software; you can redistribute it and/or modify it under
|
|
|
|
the terms of the GNU General Public License as published by the Free
|
|
|
|
Software Foundation; either version 1, or (at your option) any later
|
|
|
|
version.
|
|
|
|
|
|
|
|
Bash is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
|
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
|
|
for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License along
|
|
|
|
with Bash; see the file COPYING. If not, write to the Free Software
|
|
|
|
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
|
|
|
|
$PRODUCES shopt.c
|
|
|
|
|
|
|
|
$BUILTIN shopt
|
|
|
|
$DOCNAME shopt_builtin
|
|
|
|
$FUNCTION shopt_builtin
|
|
|
|
$SHORT_DOC shopt [-pqsu] [-o long-option] optname [optname...]
|
|
|
|
Toggle the values of variables controlling optional behavior.
|
|
|
|
The -s flag means to enable (set) each OPTNAME; the -u flag
|
|
|
|
unsets each OPTNAME. The -q flag suppresses output; the exit
|
|
|
|
status indicates whether each OPTNAME is set or unset. The -o
|
|
|
|
option restricts the OPTNAMEs to those defined for use with
|
|
|
|
`set -o'. With no options, or with the -p option, a list of all
|
|
|
|
settable options is displayed, with an indication of whether or
|
|
|
|
not each is set.
|
|
|
|
$END
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
#if defined (HAVE_UNISTD_H)
|
1998-04-17 19:52:44 +00:00
|
|
|
# ifdef _MINIX
|
|
|
|
# include <sys/types.h>
|
|
|
|
# endif
|
1996-12-23 17:02:34 +00:00
|
|
|
# include <unistd.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
#include "../shell.h"
|
|
|
|
#include "../flags.h"
|
|
|
|
#include "common.h"
|
|
|
|
#include "bashgetopt.h"
|
|
|
|
|
|
|
|
#define UNSETOPT 0
|
|
|
|
#define SETOPT 1
|
|
|
|
|
|
|
|
#define OPTFMT "%-15s\t%s\n"
|
|
|
|
|
|
|
|
extern int allow_null_glob_expansion, glob_dot_filenames;
|
|
|
|
extern int cdable_vars, mail_warning, source_uses_path;
|
|
|
|
extern int no_exit_on_failed_exec, print_shift_error;
|
|
|
|
extern int check_hashed_filenames, promptvars, interactive_comments;
|
|
|
|
extern int cdspelling, expand_aliases;
|
|
|
|
extern int check_window_size;
|
1998-04-17 19:52:44 +00:00
|
|
|
extern int glob_ignore_case;
|
|
|
|
extern int hup_on_exit;
|
|
|
|
|
|
|
|
#if defined (EXTENDED_GLOB)
|
|
|
|
extern int extended_glob;
|
|
|
|
#endif
|
1996-12-23 17:02:34 +00:00
|
|
|
|
|
|
|
#if defined (HISTORY)
|
1997-06-05 14:59:13 +00:00
|
|
|
extern int literal_history, command_oriented_history;
|
1996-12-23 17:02:34 +00:00
|
|
|
extern int force_append_history;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined (READLINE)
|
1997-06-05 14:59:13 +00:00
|
|
|
extern int hist_verify, history_reediting, perform_hostname_completion;
|
1996-12-23 17:02:34 +00:00
|
|
|
extern void enable_hostname_completion ();
|
|
|
|
#endif
|
|
|
|
|
1997-06-05 14:59:13 +00:00
|
|
|
extern void set_shellopts ();
|
|
|
|
|
1996-12-23 17:02:34 +00:00
|
|
|
static int set_interactive_comments ();
|
|
|
|
|
|
|
|
static struct {
|
|
|
|
char *name;
|
|
|
|
int *value;
|
|
|
|
Function *set_func;
|
|
|
|
} shopt_vars[] = {
|
|
|
|
{ "cdable_vars", &cdable_vars, (Function *)NULL },
|
|
|
|
{ "cdspell", &cdspelling, (Function *)NULL },
|
|
|
|
{ "checkhash", &check_hashed_filenames, (Function *)NULL },
|
|
|
|
{ "checkwinsize", &check_window_size, (Function *)NULL },
|
|
|
|
#if defined (HISTORY)
|
|
|
|
{ "cmdhist", &command_oriented_history, (Function *)NULL },
|
|
|
|
#endif
|
|
|
|
{ "dotglob", &glob_dot_filenames, (Function *)NULL },
|
|
|
|
{ "execfail", &no_exit_on_failed_exec, (Function *)NULL },
|
|
|
|
{ "expand_aliases", &expand_aliases, (Function *)NULL },
|
1998-04-17 19:52:44 +00:00
|
|
|
#if defined (EXTENDED_GLOB)
|
|
|
|
{ "extglob", &extended_glob, (Function *)NULL },
|
|
|
|
#endif
|
1996-12-23 17:02:34 +00:00
|
|
|
#if defined (READLINE)
|
|
|
|
{ "histreedit", &history_reediting, (Function *)NULL },
|
|
|
|
#endif
|
|
|
|
#if defined (HISTORY)
|
|
|
|
{ "histappend", &force_append_history, (Function *)NULL },
|
|
|
|
#endif
|
|
|
|
#if defined (READLINE)
|
1997-06-05 14:59:13 +00:00
|
|
|
{ "histverify", &hist_verify, (Function *)NULL },
|
1996-12-23 17:02:34 +00:00
|
|
|
{ "hostcomplete", &perform_hostname_completion, (Function *)enable_hostname_completion },
|
|
|
|
#endif
|
1998-04-17 19:52:44 +00:00
|
|
|
{ "huponexit", &hup_on_exit, (Function *)NULL },
|
1996-12-23 17:02:34 +00:00
|
|
|
{ "interactive_comments", &interactive_comments, set_interactive_comments },
|
|
|
|
#if defined (HISTORY)
|
|
|
|
{ "lithist", &literal_history, (Function *)NULL },
|
|
|
|
#endif
|
|
|
|
{ "mailwarn", &mail_warning, (Function *)NULL },
|
1998-04-17 19:52:44 +00:00
|
|
|
{ "nocaseglob", &glob_ignore_case, (Function *)NULL },
|
1996-12-23 17:02:34 +00:00
|
|
|
{ "nullglob", &allow_null_glob_expansion, (Function *)NULL },
|
|
|
|
{ "promptvars", &promptvars, (Function *)NULL },
|
|
|
|
{ "shift_verbose", &print_shift_error, (Function *)NULL },
|
|
|
|
{ "sourcepath", &source_uses_path, (Function *)NULL },
|
|
|
|
{ (char *)0, (int *)0, (Function *)NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static char *on = "on";
|
|
|
|
static char *off = "off";
|
|
|
|
|
|
|
|
static int list_shopt_o_options ();
|
|
|
|
static int list_some_o_options (), list_some_shopts ();
|
|
|
|
static int toggle_shopts (), list_shopts (), set_shopt_o_options ();
|
|
|
|
|
|
|
|
#define SFLAG 0x01
|
|
|
|
#define UFLAG 0x02
|
|
|
|
#define QFLAG 0x04
|
|
|
|
#define OFLAG 0x08
|
|
|
|
#define PFLAG 0x10
|
|
|
|
|
|
|
|
int
|
|
|
|
shopt_builtin (list)
|
|
|
|
WORD_LIST *list;
|
|
|
|
{
|
|
|
|
int opt, flags, rval;
|
|
|
|
|
|
|
|
flags = 0;
|
|
|
|
reset_internal_getopt ();
|
|
|
|
while ((opt = internal_getopt (list, "psuoq")) != -1)
|
|
|
|
{
|
|
|
|
switch (opt)
|
|
|
|
{
|
|
|
|
case 's':
|
|
|
|
flags |= SFLAG;
|
|
|
|
break;
|
|
|
|
case 'u':
|
|
|
|
flags |= UFLAG;
|
|
|
|
break;
|
|
|
|
case 'q':
|
|
|
|
flags |= QFLAG;
|
|
|
|
break;
|
|
|
|
case 'o':
|
|
|
|
flags |= OFLAG;
|
|
|
|
break;
|
|
|
|
case 'p':
|
|
|
|
flags |= PFLAG;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
builtin_usage ();
|
|
|
|
return (EX_USAGE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
list = loptend;
|
|
|
|
|
|
|
|
if ((flags & (SFLAG|UFLAG)) == (SFLAG|UFLAG))
|
|
|
|
{
|
|
|
|
builtin_error ("cannot set and unset shell options simultaneously");
|
|
|
|
return (EXECUTION_FAILURE);
|
|
|
|
}
|
|
|
|
|
|
|
|
rval = EXECUTION_SUCCESS;
|
|
|
|
if ((flags & OFLAG) && ((flags & (SFLAG|UFLAG)) == 0)) /* shopt -o */
|
1998-04-17 19:52:44 +00:00
|
|
|
rval = list_shopt_o_options (list, flags);
|
1996-12-23 17:02:34 +00:00
|
|
|
else if (list && (flags & OFLAG)) /* shopt -so args */
|
|
|
|
rval = set_shopt_o_options ((flags & SFLAG) ? FLAG_ON : FLAG_OFF, list, flags & QFLAG);
|
|
|
|
else if (flags & OFLAG) /* shopt -so */
|
1998-04-17 19:52:44 +00:00
|
|
|
rval = list_some_o_options ((flags & SFLAG) ? 1 : 0, flags);
|
1996-12-23 17:02:34 +00:00
|
|
|
else if (list && (flags & (SFLAG|UFLAG))) /* shopt -su args */
|
|
|
|
rval = toggle_shopts ((flags & SFLAG) ? SETOPT : UNSETOPT, list, flags & QFLAG);
|
|
|
|
else if ((flags & (SFLAG|UFLAG)) == 0) /* shopt [args] */
|
1998-04-17 19:52:44 +00:00
|
|
|
rval = list_shopts (list, flags);
|
1996-12-23 17:02:34 +00:00
|
|
|
else /* shopt -su */
|
1998-04-17 19:52:44 +00:00
|
|
|
rval = list_some_shopts ((flags & SFLAG) ? SETOPT : UNSETOPT, flags);
|
1996-12-23 17:02:34 +00:00
|
|
|
return (rval);
|
|
|
|
}
|
|
|
|
|
1997-06-05 14:59:13 +00:00
|
|
|
/* Reset the options managed by `shopt' to the values they would have at
|
|
|
|
shell startup. */
|
|
|
|
void
|
|
|
|
reset_shopt_options ()
|
|
|
|
{
|
|
|
|
allow_null_glob_expansion = glob_dot_filenames = 0;
|
|
|
|
cdable_vars = mail_warning = 0;
|
|
|
|
no_exit_on_failed_exec = print_shift_error = 0;
|
|
|
|
check_hashed_filenames = cdspelling = expand_aliases = check_window_size = 0;
|
|
|
|
|
|
|
|
source_uses_path = promptvars = 1;
|
|
|
|
|
1998-04-17 19:52:44 +00:00
|
|
|
#if defined (EXTENDED_GLOB)
|
|
|
|
extended_glob = 0;
|
|
|
|
#endif
|
|
|
|
|
1997-06-05 14:59:13 +00:00
|
|
|
#if defined (HISTORY)
|
|
|
|
literal_history = force_append_history = 0;
|
|
|
|
command_oriented_history = 1;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined (READLINE)
|
|
|
|
hist_verify = history_reediting = 0;
|
|
|
|
perform_hostname_completion = 1;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
1996-12-23 17:02:34 +00:00
|
|
|
static int
|
|
|
|
find_shopt (name)
|
|
|
|
char *name;
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; shopt_vars[i].name; i++)
|
|
|
|
if (STREQ (name, shopt_vars[i].name))
|
|
|
|
return i;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define SHOPT_ERROR(str) builtin_error ("%s: unknown shell option name", str)
|
|
|
|
|
|
|
|
static int
|
|
|
|
toggle_shopts (mode, list, quiet)
|
|
|
|
int mode;
|
|
|
|
WORD_LIST *list;
|
|
|
|
int quiet;
|
|
|
|
{
|
|
|
|
WORD_LIST *l;
|
|
|
|
int ind, rval;
|
|
|
|
|
|
|
|
for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
|
|
|
|
{
|
|
|
|
ind = find_shopt (l->word->word);
|
|
|
|
if (ind < 0)
|
|
|
|
{
|
|
|
|
SHOPT_ERROR (l->word->word);
|
|
|
|
rval = EXECUTION_FAILURE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*shopt_vars[ind].value = mode; /* 1 for set, 0 for unset */
|
|
|
|
if (shopt_vars[ind].set_func)
|
|
|
|
(*shopt_vars[ind].set_func) (mode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return (rval);
|
|
|
|
}
|
|
|
|
|
1998-04-17 19:52:44 +00:00
|
|
|
static int
|
|
|
|
print_shopt (name, val, flags)
|
|
|
|
char *name;
|
|
|
|
int val, flags;
|
|
|
|
{
|
|
|
|
if (flags & PFLAG)
|
|
|
|
printf ("shopt %s %s\n", val ? "-s" : "-u", name);
|
|
|
|
else
|
|
|
|
printf (OPTFMT, name, val ? on : off);
|
|
|
|
}
|
|
|
|
|
1996-12-23 17:02:34 +00:00
|
|
|
/* List the values of all or any of the `shopt' options. Returns 0 if
|
|
|
|
all were listed or all variables queried were on; 1 otherwise. */
|
|
|
|
static int
|
1998-04-17 19:52:44 +00:00
|
|
|
list_shopts (list, flags)
|
1996-12-23 17:02:34 +00:00
|
|
|
WORD_LIST *list;
|
1998-04-17 19:52:44 +00:00
|
|
|
int flags;
|
1996-12-23 17:02:34 +00:00
|
|
|
{
|
|
|
|
WORD_LIST *l;
|
|
|
|
int i, val, rval;
|
|
|
|
|
|
|
|
if (list == 0)
|
|
|
|
{
|
|
|
|
for (i = 0; shopt_vars[i].name; i++)
|
|
|
|
{
|
|
|
|
val = *shopt_vars[i].value;
|
1998-04-17 19:52:44 +00:00
|
|
|
if ((flags & QFLAG) == 0)
|
|
|
|
print_shopt (shopt_vars[i].name, val, flags);
|
1996-12-23 17:02:34 +00:00
|
|
|
}
|
|
|
|
return (EXECUTION_SUCCESS);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
|
|
|
|
{
|
|
|
|
i = find_shopt (l->word->word);
|
|
|
|
if (i < 0)
|
|
|
|
{
|
|
|
|
SHOPT_ERROR (l->word->word);
|
|
|
|
rval = EXECUTION_FAILURE;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
val = *shopt_vars[i].value;
|
|
|
|
if (val == 0)
|
|
|
|
rval = EXECUTION_FAILURE;
|
1998-04-17 19:52:44 +00:00
|
|
|
if ((flags & QFLAG) == 0)
|
|
|
|
print_shopt (l->word->word, val, flags);
|
1996-12-23 17:02:34 +00:00
|
|
|
}
|
|
|
|
return (rval);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
1998-04-17 19:52:44 +00:00
|
|
|
list_some_shopts (mode, flags)
|
|
|
|
int mode, flags;
|
1996-12-23 17:02:34 +00:00
|
|
|
{
|
|
|
|
int val, i;
|
|
|
|
|
|
|
|
for (i = 0; shopt_vars[i].name; i++)
|
|
|
|
{
|
|
|
|
val = *shopt_vars[i].value;
|
1998-04-17 19:52:44 +00:00
|
|
|
if (((flags & QFLAG) == 0) && mode == val)
|
|
|
|
print_shopt (shopt_vars[i].name, val, flags);
|
1996-12-23 17:02:34 +00:00
|
|
|
}
|
|
|
|
return (EXECUTION_SUCCESS);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
1998-04-17 19:52:44 +00:00
|
|
|
list_shopt_o_options (list, flags)
|
1996-12-23 17:02:34 +00:00
|
|
|
WORD_LIST *list;
|
1998-04-17 19:52:44 +00:00
|
|
|
int flags;
|
1996-12-23 17:02:34 +00:00
|
|
|
{
|
|
|
|
WORD_LIST *l;
|
|
|
|
int val, rval;
|
|
|
|
|
|
|
|
if (list == 0)
|
|
|
|
{
|
1998-04-17 19:52:44 +00:00
|
|
|
if ((flags & QFLAG) == 0)
|
|
|
|
list_minus_o_opts (-1, (flags & PFLAG));
|
1996-12-23 17:02:34 +00:00
|
|
|
return (EXECUTION_SUCCESS);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
|
|
|
|
{
|
|
|
|
val = minus_o_option_value (l->word->word);
|
|
|
|
if (val == -1)
|
|
|
|
{
|
|
|
|
builtin_error ("%s: unknown option name", l->word->word);
|
|
|
|
rval = EXECUTION_FAILURE;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (val == 0)
|
|
|
|
rval = EXECUTION_FAILURE;
|
1998-04-17 19:52:44 +00:00
|
|
|
if ((flags & QFLAG) == 0)
|
|
|
|
{
|
|
|
|
if (flags & PFLAG)
|
|
|
|
printf ("set %co %s\n", val ? '-' : '+', l->word->word);
|
|
|
|
else
|
|
|
|
printf (OPTFMT, l->word->word, val ? on : off);
|
|
|
|
}
|
1996-12-23 17:02:34 +00:00
|
|
|
}
|
|
|
|
return (rval);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
1998-04-17 19:52:44 +00:00
|
|
|
list_some_o_options (mode, flags)
|
|
|
|
int mode, flags;
|
1996-12-23 17:02:34 +00:00
|
|
|
{
|
1998-04-17 19:52:44 +00:00
|
|
|
if ((flags & QFLAG) == 0)
|
|
|
|
list_minus_o_opts (mode, (flags & PFLAG));
|
1996-12-23 17:02:34 +00:00
|
|
|
return (EXECUTION_SUCCESS);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
set_shopt_o_options (mode, list, quiet)
|
|
|
|
int mode;
|
|
|
|
WORD_LIST *list;
|
|
|
|
int quiet;
|
|
|
|
{
|
|
|
|
WORD_LIST *l;
|
|
|
|
int rval;
|
|
|
|
|
|
|
|
for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
|
|
|
|
{
|
|
|
|
if (set_minus_o_option (mode, l->word->word) == EXECUTION_FAILURE)
|
|
|
|
rval = EXECUTION_FAILURE;
|
|
|
|
}
|
|
|
|
set_shellopts ();
|
|
|
|
return rval;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If we set or unset interactive_comments with shopt, make sure the
|
|
|
|
change is reflected in $SHELLOPTS. */
|
|
|
|
static int
|
|
|
|
set_interactive_comments (mode)
|
|
|
|
int mode;
|
|
|
|
{
|
|
|
|
set_shellopts ();
|
|
|
|
return (0);
|
|
|
|
}
|