~ubuntu-branches/ubuntu/trusty/bash/trusty-security

« back to all changes in this revision

Viewing changes to builtins/set.def

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2014-03-03 22:52:05 UTC
  • mfrom: (1.3.5) (2.2.6 experimental)
  • Revision ID: package-import@ubuntu.com-20140303225205-87ltrt5kspeq0g1b
Tags: 4.3-1ubuntu1
* Merge with Debian; remaining changes:
  - skel.bashrc:
    - Run lesspipe.
    - Enable ls aliases.
    - Set options in ll alias to -alF.
    - Define an alert alias.
    - Enabled colored grep aliases.
  - etc.bash.bashrc:
    - Add sudo hint.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
This file is set.def, from which is created set.c.
 
2
It implements the "set" and "unset" builtins in Bash.
 
3
 
 
4
Copyright (C) 1987-2012 Free Software Foundation, Inc.
 
5
 
 
6
This file is part of GNU Bash, the Bourne Again SHell.
 
7
 
 
8
Bash is free software: you can redistribute it and/or modify
 
9
it under the terms of the GNU General Public License as published by
 
10
the Free Software Foundation, either version 3 of the License, or
 
11
(at your option) any later version.
 
12
 
 
13
Bash is distributed in the hope that it will be useful,
 
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
GNU General Public License for more details.
 
17
 
 
18
You should have received a copy of the GNU General Public License
 
19
along with Bash.  If not, see <http://www.gnu.org/licenses/>.
 
20
 
 
21
$PRODUCES set.c
 
22
 
 
23
#include <config.h>
 
24
 
 
25
#if defined (HAVE_UNISTD_H)
 
26
#  ifdef _MINIX
 
27
#    include <sys/types.h>
 
28
#  endif
 
29
#  include <unistd.h>
 
30
#endif
 
31
 
 
32
#include <stdio.h>
 
33
 
 
34
#include "../bashansi.h"
 
35
#include "../bashintl.h"
 
36
 
 
37
#include "../shell.h"
 
38
#include "../flags.h"
 
39
#include "common.h"
 
40
#include "bashgetopt.h"
 
41
 
 
42
#if defined (READLINE)
 
43
#  include "../input.h"
 
44
#  include "../bashline.h"
 
45
#  include <readline/readline.h>
 
46
#endif
 
47
 
 
48
#if defined (HISTORY)
 
49
#  include "../bashhist.h"
 
50
#endif
 
51
 
 
52
extern int posixly_correct, ignoreeof, eof_encountered_limit;
 
53
#if defined (HISTORY)
 
54
extern int dont_save_function_defs;
 
55
#endif
 
56
#if defined (READLINE)
 
57
extern int no_line_editing;
 
58
#endif /* READLINE */
 
59
 
 
60
$BUILTIN set
 
61
$FUNCTION set_builtin
 
62
$SHORT_DOC set [-abefhkmnptuvxBCHP] [-o option-name] [--] [arg ...]
 
63
Set or unset values of shell options and positional parameters.
 
64
 
 
65
Change the value of shell attributes and positional parameters, or
 
66
display the names and values of shell variables.
 
67
 
 
68
Options:
 
69
  -a  Mark variables which are modified or created for export.
 
70
  -b  Notify of job termination immediately.
 
71
  -e  Exit immediately if a command exits with a non-zero status.
 
72
  -f  Disable file name generation (globbing).
 
73
  -h  Remember the location of commands as they are looked up.
 
74
  -k  All assignment arguments are placed in the environment for a
 
75
      command, not just those that precede the command name.
 
76
  -m  Job control is enabled.
 
77
  -n  Read commands but do not execute them.
 
78
  -o option-name
 
79
      Set the variable corresponding to option-name:
 
80
          allexport    same as -a
 
81
          braceexpand  same as -B
 
82
#if defined (READLINE)
 
83
          emacs        use an emacs-style line editing interface
 
84
#endif /* READLINE */
 
85
          errexit      same as -e
 
86
          errtrace     same as -E
 
87
          functrace    same as -T
 
88
          hashall      same as -h
 
89
#if defined (BANG_HISTORY)
 
90
          histexpand   same as -H
 
91
#endif /* BANG_HISTORY */
 
92
#if defined (HISTORY)
 
93
          history      enable command history
 
94
#endif
 
95
          ignoreeof    the shell will not exit upon reading EOF
 
96
          interactive-comments
 
97
                       allow comments to appear in interactive commands
 
98
          keyword      same as -k
 
99
#if defined (JOB_CONTROL)
 
100
          monitor      same as -m
 
101
#endif
 
102
          noclobber    same as -C
 
103
          noexec       same as -n
 
104
          noglob       same as -f
 
105
          nolog        currently accepted but ignored
 
106
#if defined (JOB_CONTROL)
 
107
          notify       same as -b
 
108
#endif
 
109
          nounset      same as -u
 
110
          onecmd       same as -t
 
111
          physical     same as -P
 
112
          pipefail     the return value of a pipeline is the status of
 
113
                       the last command to exit with a non-zero status,
 
114
                       or zero if no command exited with a non-zero status
 
115
          posix        change the behavior of bash where the default
 
116
                       operation differs from the Posix standard to
 
117
                       match the standard
 
118
          privileged   same as -p
 
119
          verbose      same as -v
 
120
#if defined (READLINE)
 
121
          vi           use a vi-style line editing interface
 
122
#endif /* READLINE */
 
123
          xtrace       same as -x
 
124
  -p  Turned on whenever the real and effective user ids do not match.
 
125
      Disables processing of the $ENV file and importing of shell
 
126
      functions.  Turning this option off causes the effective uid and
 
127
      gid to be set to the real uid and gid.
 
128
  -t  Exit after reading and executing one command.
 
129
  -u  Treat unset variables as an error when substituting.
 
130
  -v  Print shell input lines as they are read.
 
131
  -x  Print commands and their arguments as they are executed.
 
132
#if defined (BRACE_EXPANSION)
 
133
  -B  the shell will perform brace expansion
 
134
#endif /* BRACE_EXPANSION */
 
135
  -C  If set, disallow existing regular files to be overwritten
 
136
      by redirection of output.
 
137
  -E  If set, the ERR trap is inherited by shell functions.
 
138
#if defined (BANG_HISTORY)
 
139
  -H  Enable ! style history substitution.  This flag is on
 
140
      by default when the shell is interactive.
 
141
#endif /* BANG_HISTORY */
 
142
  -P  If set, do not resolve symbolic links when executing commands
 
143
      such as cd which change the current directory.
 
144
  -T  If set, the DEBUG trap is inherited by shell functions.
 
145
  --  Assign any remaining arguments to the positional parameters.
 
146
      If there are no remaining arguments, the positional parameters
 
147
      are unset.
 
148
  -   Assign any remaining arguments to the positional parameters.
 
149
      The -x and -v options are turned off.
 
150
 
 
151
Using + rather than - causes these flags to be turned off.  The
 
152
flags can also be used upon invocation of the shell.  The current
 
153
set of flags may be found in $-.  The remaining n ARGs are positional
 
154
parameters and are assigned, in order, to $1, $2, .. $n.  If no
 
155
ARGs are given, all shell variables are printed.
 
156
 
 
157
Exit Status:
 
158
Returns success unless an invalid option is given.
 
159
$END
 
160
 
 
161
typedef int setopt_set_func_t __P((int, char *));
 
162
typedef int setopt_get_func_t __P((char *));
 
163
 
 
164
static void print_minus_o_option __P((char *, int, int));
 
165
static void print_all_shell_variables __P((void));
 
166
 
 
167
static int set_ignoreeof __P((int, char *));
 
168
static int set_posix_mode __P((int, char *));
 
169
 
 
170
#if defined (READLINE)
 
171
static int set_edit_mode __P((int, char *));
 
172
static int get_edit_mode __P((char *));
 
173
#endif
 
174
 
 
175
#if defined (HISTORY)
 
176
static int bash_set_history __P((int, char *));
 
177
#endif
 
178
 
 
179
static const char * const on = "on";
 
180
static const char * const off = "off";
 
181
 
 
182
/* A struct used to match long options for set -o to the corresponding
 
183
   option letter or internal variable.  The functions can be called to
 
184
   dynamically generate values. */
 
185
const struct {
 
186
  char *name;
 
187
  int letter;
 
188
  int *variable;
 
189
  setopt_set_func_t *set_func;
 
190
  setopt_get_func_t *get_func;
 
191
} o_options[] = {
 
192
  { "allexport",  'a', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
 
193
#if defined (BRACE_EXPANSION)
 
194
  { "braceexpand",'B', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL  },
 
195
#endif
 
196
#if defined (READLINE)
 
197
  { "emacs",     '\0', (int *)NULL, set_edit_mode, get_edit_mode },
 
198
#endif
 
199
  { "errexit",    'e', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL  },
 
200
  { "errtrace",   'E', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL  },
 
201
  { "functrace",  'T', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL  },
 
202
  { "hashall",    'h', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL  },
 
203
#if defined (BANG_HISTORY)
 
204
  { "histexpand", 'H', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL  },
 
205
#endif /* BANG_HISTORY */
 
206
#if defined (HISTORY)
 
207
  { "history",   '\0', &enable_history_list, bash_set_history, (setopt_get_func_t *)NULL },
 
208
#endif
 
209
  { "ignoreeof", '\0', &ignoreeof, set_ignoreeof, (setopt_get_func_t *)NULL },
 
210
  { "interactive-comments", '\0', &interactive_comments, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
 
211
  { "keyword",    'k', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL  },
 
212
#if defined (JOB_CONTROL)
 
213
  { "monitor",    'm', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL  },
 
214
#endif
 
215
  { "noclobber",  'C', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL  },
 
216
  { "noexec",     'n', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL  },
 
217
  { "noglob",     'f', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL  },
 
218
#if defined (HISTORY)
 
219
  { "nolog",     '\0', &dont_save_function_defs, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
 
220
#endif
 
221
#if defined (JOB_CONTROL)
 
222
  { "notify",     'b', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL  },
 
223
#endif /* JOB_CONTROL */
 
224
  { "nounset",    'u', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL  },
 
225
  { "onecmd",     't', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
 
226
  { "physical",   'P', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL  },
 
227
  { "pipefail",  '\0', &pipefail_opt, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL  },
 
228
  { "posix",     '\0', &posixly_correct, set_posix_mode, (setopt_get_func_t *)NULL },
 
229
  { "privileged", 'p', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL  },
 
230
  { "verbose",    'v', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL  },
 
231
#if defined (READLINE)
 
232
  { "vi",        '\0', (int *)NULL, set_edit_mode, get_edit_mode },
 
233
#endif
 
234
  { "xtrace",     'x', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL  },
 
235
  {(char *)NULL, 0 , (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
 
236
};
 
237
 
 
238
#define N_O_OPTIONS     (sizeof (o_options) / sizeof (o_options[0]))
 
239
 
 
240
#define GET_BINARY_O_OPTION_VALUE(i, name) \
 
241
  ((o_options[i].get_func) ? (*o_options[i].get_func) (name) \
 
242
                           : (*o_options[i].variable))
 
243
 
 
244
#define SET_BINARY_O_OPTION_VALUE(i, onoff, name) \
 
245
  ((o_options[i].set_func) ? (*o_options[i].set_func) (onoff, name) \
 
246
                           : (*o_options[i].variable = (onoff == FLAG_ON)))
 
247
 
 
248
int
 
249
minus_o_option_value (name)
 
250
     char *name;
 
251
{
 
252
  register int  i;
 
253
  int *on_or_off;
 
254
 
 
255
  for (i = 0; o_options[i].name; i++)
 
256
    {
 
257
      if (STREQ (name, o_options[i].name))
 
258
        {
 
259
          if (o_options[i].letter)
 
260
            {
 
261
              on_or_off = find_flag (o_options[i].letter);
 
262
              return ((on_or_off == FLAG_UNKNOWN) ? -1 : *on_or_off);
 
263
            }
 
264
          else
 
265
            return (GET_BINARY_O_OPTION_VALUE (i, name));
 
266
        }
 
267
    }
 
268
 
 
269
  return (-1);
 
270
}
 
271
 
 
272
#define MINUS_O_FORMAT "%-15s\t%s\n"
 
273
 
 
274
static void
 
275
print_minus_o_option (name, value, pflag)
 
276
     char *name;
 
277
     int value, pflag;
 
278
{
 
279
  if (pflag == 0)
 
280
    printf (MINUS_O_FORMAT, name, value ? on : off);
 
281
  else
 
282
    printf ("set %co %s\n", value ? '-' : '+', name);
 
283
}
 
284
 
 
285
void
 
286
list_minus_o_opts (mode, reusable)
 
287
     int mode, reusable;
 
288
{
 
289
  register int  i;
 
290
  int *on_or_off, value;
 
291
 
 
292
  for (i = 0; o_options[i].name; i++)
 
293
    {
 
294
      if (o_options[i].letter)
 
295
        {
 
296
          value = 0;
 
297
          on_or_off = find_flag (o_options[i].letter);
 
298
          if (on_or_off == FLAG_UNKNOWN)
 
299
            on_or_off = &value;
 
300
          if (mode == -1 || mode == *on_or_off)
 
301
            print_minus_o_option (o_options[i].name, *on_or_off, reusable);
 
302
        }
 
303
      else
 
304
        {
 
305
          value = GET_BINARY_O_OPTION_VALUE (i, o_options[i].name);
 
306
          if (mode == -1 || mode == value)
 
307
            print_minus_o_option (o_options[i].name, value, reusable);
 
308
        }
 
309
    }
 
310
}
 
311
 
 
312
char **
 
313
get_minus_o_opts ()
 
314
{
 
315
  char **ret;
 
316
  int i;
 
317
 
 
318
  ret = strvec_create (N_O_OPTIONS + 1);
 
319
  for (i = 0; o_options[i].name; i++)
 
320
    ret[i] = o_options[i].name;
 
321
  ret[i] = (char *)NULL;
 
322
  return ret;
 
323
}
 
324
 
 
325
static int
 
326
set_ignoreeof (on_or_off, option_name)
 
327
     int on_or_off;
 
328
     char *option_name;
 
329
{
 
330
  ignoreeof = on_or_off == FLAG_ON;
 
331
  unbind_variable ("ignoreeof");
 
332
  if (ignoreeof)
 
333
    bind_variable ("IGNOREEOF", "10", 0); 
 
334
  else
 
335
    unbind_variable ("IGNOREEOF");
 
336
  sv_ignoreeof ("IGNOREEOF");
 
337
  return 0;
 
338
}
 
339
 
 
340
static int
 
341
set_posix_mode (on_or_off, option_name)
 
342
     int on_or_off;
 
343
     char *option_name;
 
344
{
 
345
  posixly_correct = on_or_off == FLAG_ON;
 
346
  if (posixly_correct == 0)
 
347
    unbind_variable ("POSIXLY_CORRECT");
 
348
  else
 
349
    bind_variable ("POSIXLY_CORRECT", "y", 0);
 
350
  sv_strict_posix ("POSIXLY_CORRECT");
 
351
  return (0);
 
352
}
 
353
 
 
354
#if defined (READLINE)
 
355
/* Magic.  This code `knows' how readline handles rl_editing_mode. */
 
356
static int
 
357
set_edit_mode (on_or_off, option_name)
 
358
     int on_or_off;
 
359
     char *option_name;
 
360
{
 
361
  int isemacs;
 
362
 
 
363
  if (on_or_off == FLAG_ON)
 
364
    {
 
365
      rl_variable_bind ("editing-mode", option_name);
 
366
 
 
367
      if (interactive)
 
368
        with_input_from_stdin ();
 
369
      no_line_editing = 0;
 
370
    }
 
371
  else
 
372
    {
 
373
      isemacs = rl_editing_mode == 1;
 
374
      if ((isemacs && *option_name == 'e') || (!isemacs && *option_name == 'v'))
 
375
        {
 
376
          if (interactive)
 
377
            with_input_from_stream (stdin, "stdin");
 
378
          no_line_editing = 1;
 
379
        }
 
380
    }
 
381
  return 1-no_line_editing;
 
382
}
 
383
 
 
384
static int
 
385
get_edit_mode (name)
 
386
     char *name;
 
387
{
 
388
  return (*name == 'e' ? no_line_editing == 0 && rl_editing_mode == 1
 
389
                       : no_line_editing == 0 && rl_editing_mode == 0);
 
390
}
 
391
#endif /* READLINE */
 
392
 
 
393
#if defined (HISTORY)
 
394
static int
 
395
bash_set_history (on_or_off, option_name)
 
396
     int on_or_off;
 
397
     char *option_name;
 
398
{
 
399
  if (on_or_off == FLAG_ON)
 
400
    {
 
401
      enable_history_list = 1;
 
402
      bash_history_enable ();
 
403
      if (history_lines_this_session == 0)
 
404
        load_history ();
 
405
    }
 
406
  else
 
407
    {
 
408
      enable_history_list = 0;
 
409
      bash_history_disable ();
 
410
    }
 
411
  return (1 - enable_history_list);
 
412
}
 
413
#endif
 
414
 
 
415
int
 
416
set_minus_o_option (on_or_off, option_name)
 
417
     int on_or_off;
 
418
     char *option_name;
 
419
{
 
420
  register int i;
 
421
 
 
422
  for (i = 0; o_options[i].name; i++)
 
423
    {
 
424
      if (STREQ (option_name, o_options[i].name))
 
425
        {
 
426
          if (o_options[i].letter == 0)
 
427
            {
 
428
              SET_BINARY_O_OPTION_VALUE (i, on_or_off, option_name);
 
429
              return (EXECUTION_SUCCESS);
 
430
            }
 
431
          else
 
432
            {
 
433
              if (change_flag (o_options[i].letter, on_or_off) == FLAG_ERROR)
 
434
                {
 
435
                  sh_invalidoptname (option_name);
 
436
                  return (EXECUTION_FAILURE);
 
437
                }
 
438
              else
 
439
                return (EXECUTION_SUCCESS);
 
440
            }
 
441
 
 
442
        }
 
443
    }
 
444
 
 
445
  sh_invalidoptname (option_name);
 
446
  return (EX_USAGE);
 
447
}
 
448
 
 
449
static void
 
450
print_all_shell_variables ()
 
451
{
 
452
  SHELL_VAR **vars;
 
453
 
 
454
  vars = all_shell_variables ();
 
455
  if (vars)
 
456
    {
 
457
      print_var_list (vars);
 
458
      free (vars);
 
459
    }
 
460
 
 
461
  /* POSIX.2 does not allow function names and definitions to be output when
 
462
     `set' is invoked without options (PASC Interp #202). */
 
463
  if (posixly_correct == 0)
 
464
    {
 
465
      vars = all_shell_functions ();
 
466
      if (vars)
 
467
        {
 
468
          print_func_list (vars);
 
469
          free (vars);
 
470
        }
 
471
    }
 
472
}
 
473
 
 
474
void
 
475
set_shellopts ()
 
476
{
 
477
  char *value;
 
478
  char tflag[N_O_OPTIONS];
 
479
  int vsize, i, vptr, *ip, exported;
 
480
  SHELL_VAR *v;
 
481
 
 
482
  for (vsize = i = 0; o_options[i].name; i++)
 
483
    {
 
484
      tflag[i] = 0;
 
485
      if (o_options[i].letter)
 
486
        {
 
487
          ip = find_flag (o_options[i].letter);
 
488
          if (ip && *ip)
 
489
            {
 
490
              vsize += strlen (o_options[i].name) + 1;
 
491
              tflag[i] = 1;
 
492
            }
 
493
        }
 
494
      else if (GET_BINARY_O_OPTION_VALUE (i, o_options[i].name))
 
495
        {
 
496
          vsize += strlen (o_options[i].name) + 1;
 
497
          tflag[i] = 1;
 
498
        }
 
499
    }
 
500
 
 
501
  value = (char *)xmalloc (vsize + 1);
 
502
 
 
503
  for (i = vptr = 0; o_options[i].name; i++)
 
504
    {
 
505
      if (tflag[i])
 
506
        {
 
507
          strcpy (value + vptr, o_options[i].name);
 
508
          vptr += strlen (o_options[i].name);
 
509
          value[vptr++] = ':';
 
510
        }
 
511
    }
 
512
 
 
513
  if (vptr)
 
514
    vptr--;                     /* cut off trailing colon */
 
515
  value[vptr] = '\0';
 
516
 
 
517
  v = find_variable ("SHELLOPTS");
 
518
 
 
519
  /* Turn off the read-only attribute so we can bind the new value, and
 
520
     note whether or not the variable was exported. */
 
521
  if (v)
 
522
    {
 
523
      VUNSETATTR (v, att_readonly);
 
524
      exported = exported_p (v);
 
525
    }
 
526
  else
 
527
    exported = 0;
 
528
 
 
529
  v = bind_variable ("SHELLOPTS", value, 0);
 
530
 
 
531
  /* Turn the read-only attribute back on, and turn off the export attribute
 
532
     if it was set implicitly by mark_modified_vars and SHELLOPTS was not
 
533
     exported before we bound the new value. */
 
534
  VSETATTR (v, att_readonly);
 
535
  if (mark_modified_vars && exported == 0 && exported_p (v))
 
536
    VUNSETATTR (v, att_exported);
 
537
 
 
538
  free (value);
 
539
}
 
540
 
 
541
void
 
542
parse_shellopts (value)
 
543
     char *value;
 
544
{
 
545
  char *vname;
 
546
  int vptr;
 
547
 
 
548
  vptr = 0;
 
549
  while (vname = extract_colon_unit (value, &vptr))
 
550
    {
 
551
      set_minus_o_option (FLAG_ON, vname);
 
552
      free (vname);
 
553
    }
 
554
}
 
555
 
 
556
void
 
557
initialize_shell_options (no_shellopts)
 
558
     int no_shellopts;
 
559
{
 
560
  char *temp;
 
561
  SHELL_VAR *var;
 
562
 
 
563
  if (no_shellopts == 0)
 
564
    {
 
565
      var = find_variable ("SHELLOPTS");
 
566
      /* set up any shell options we may have inherited. */
 
567
      if (var && imported_p (var))
 
568
        {
 
569
          temp = (array_p (var) || assoc_p (var)) ? (char *)NULL : savestring (value_cell (var));
 
570
          if (temp)
 
571
            {
 
572
              parse_shellopts (temp);
 
573
              free (temp);
 
574
            }
 
575
        }
 
576
    }
 
577
 
 
578
  /* Set up the $SHELLOPTS variable. */
 
579
  set_shellopts ();
 
580
}
 
581
 
 
582
/* Reset the values of the -o options that are not also shell flags.  This is
 
583
   called from execute_cmd.c:initialize_subshell() when setting up a subshell
 
584
   to run an executable shell script without a leading `#!'. */
 
585
void
 
586
reset_shell_options ()
 
587
{
 
588
#if defined (HISTORY)
 
589
  remember_on_history = enable_history_list = 1;
 
590
#endif
 
591
  ignoreeof = 0;
 
592
}
 
593
 
 
594
/* Set some flags from the word values in the input list.  If LIST is empty,
 
595
   then print out the values of the variables instead.  If LIST contains
 
596
   non-flags, then set $1 - $9 to the successive words of LIST. */
 
597
int
 
598
set_builtin (list)
 
599
     WORD_LIST *list;
 
600
{
 
601
  int on_or_off, flag_name, force_assignment, opts_changed, rv, r;
 
602
  register char *arg;
 
603
  char s[3];
 
604
 
 
605
  if (list == 0)
 
606
    {
 
607
      print_all_shell_variables ();
 
608
      return (sh_chkwrite (EXECUTION_SUCCESS));
 
609
    }
 
610
 
 
611
  /* Check validity of flag arguments. */
 
612
  rv = EXECUTION_SUCCESS;
 
613
  reset_internal_getopt ();
 
614
  while ((flag_name = internal_getopt (list, optflags)) != -1)
 
615
    {
 
616
      switch (flag_name)
 
617
        {
 
618
          case '?':
 
619
            builtin_usage ();
 
620
            return (list_optopt == '?' ? EXECUTION_SUCCESS : EX_USAGE);
 
621
          default:
 
622
            break;
 
623
        }
 
624
    }
 
625
    
 
626
  /* Do the set command.  While the list consists of words starting with
 
627
     '-' or '+' treat them as flags, otherwise, start assigning them to
 
628
     $1 ... $n. */
 
629
  for (force_assignment = opts_changed = 0; list; )
 
630
    {
 
631
      arg = list->word->word;
 
632
 
 
633
      /* If the argument is `--' or `-' then signal the end of the list
 
634
         and remember the remaining arguments. */
 
635
      if (arg[0] == '-' && (!arg[1] || (arg[1] == '-' && !arg[2])))
 
636
        {
 
637
          list = list->next;
 
638
 
 
639
          /* `set --' unsets the positional parameters. */
 
640
          if (arg[1] == '-')
 
641
            force_assignment = 1;
 
642
 
 
643
          /* Until told differently, the old shell behaviour of
 
644
             `set - [arg ...]' being equivalent to `set +xv [arg ...]'
 
645
             stands.  Posix.2 says the behaviour is marked as obsolescent. */
 
646
          else
 
647
            {
 
648
              change_flag ('x', '+');
 
649
              change_flag ('v', '+');
 
650
              opts_changed = 1;
 
651
            }
 
652
 
 
653
          break;
 
654
        }
 
655
 
 
656
      if ((on_or_off = *arg) && (on_or_off == '-' || on_or_off == '+'))
 
657
        {
 
658
          while (flag_name = *++arg)
 
659
            {
 
660
              if (flag_name == '?')
 
661
                {
 
662
                  builtin_usage ();
 
663
                  return (EXECUTION_SUCCESS);
 
664
                }
 
665
              else if (flag_name == 'o') /* -+o option-name */
 
666
                {
 
667
                  char *option_name;
 
668
                  WORD_LIST *opt;
 
669
 
 
670
                  opt = list->next;
 
671
 
 
672
                  if (opt == 0)
 
673
                    {
 
674
                      list_minus_o_opts (-1, (on_or_off == '+'));
 
675
                      rv = sh_chkwrite (rv);
 
676
                      continue;
 
677
                    }
 
678
 
 
679
                  option_name = opt->word->word;
 
680
 
 
681
                  if (option_name == 0 || *option_name == '\0' ||
 
682
                      *option_name == '-' || *option_name == '+')
 
683
                    {
 
684
                      list_minus_o_opts (-1, (on_or_off == '+'));
 
685
                      continue;
 
686
                    }
 
687
                  list = list->next; /* Skip over option name. */
 
688
 
 
689
                  opts_changed = 1;
 
690
                  if ((r = set_minus_o_option (on_or_off, option_name)) != EXECUTION_SUCCESS)
 
691
                    {
 
692
                      set_shellopts ();
 
693
                      return (r);
 
694
                    }
 
695
                }
 
696
              else if (change_flag (flag_name, on_or_off) == FLAG_ERROR)
 
697
                {
 
698
                  s[0] = on_or_off;
 
699
                  s[1] = flag_name;
 
700
                  s[2] = '\0';
 
701
                  sh_invalidopt (s);
 
702
                  builtin_usage ();
 
703
                  set_shellopts ();
 
704
                  return (EXECUTION_FAILURE);
 
705
                }
 
706
              opts_changed = 1;
 
707
            }
 
708
        }
 
709
      else
 
710
        {
 
711
          break;
 
712
        }
 
713
      list = list->next;
 
714
    }
 
715
 
 
716
  /* Assigning $1 ... $n */
 
717
  if (list || force_assignment)
 
718
    remember_args (list, 1);
 
719
  /* Set up new value of $SHELLOPTS */
 
720
  if (opts_changed)
 
721
    set_shellopts ();
 
722
  return (rv);
 
723
}
 
724
 
 
725
$BUILTIN unset
 
726
$FUNCTION unset_builtin
 
727
$SHORT_DOC unset [-f] [-v] [-n] [name ...]
 
728
Unset values and attributes of shell variables and functions.
 
729
 
 
730
For each NAME, remove the corresponding variable or function.
 
731
 
 
732
Options:
 
733
  -f    treat each NAME as a shell function
 
734
  -v    treat each NAME as a shell variable
 
735
  -n    treat each NAME as a name reference and unset the variable itself
 
736
        rather than the variable it references
 
737
 
 
738
Without options, unset first tries to unset a variable, and if that fails,
 
739
tries to unset a function.
 
740
 
 
741
Some variables cannot be unset; also see `readonly'.
 
742
 
 
743
Exit Status:
 
744
Returns success unless an invalid option is given or a NAME is read-only.
 
745
$END
 
746
 
 
747
#define NEXT_VARIABLE() any_failed++; list = list->next; continue;
 
748
 
 
749
int
 
750
unset_builtin (list)
 
751
  WORD_LIST *list;
 
752
{
 
753
  int unset_function, unset_variable, unset_array, opt, nameref, any_failed;
 
754
  char *name;
 
755
 
 
756
  unset_function = unset_variable = unset_array = nameref = any_failed = 0;
 
757
 
 
758
  reset_internal_getopt ();
 
759
  while ((opt = internal_getopt (list, "fnv")) != -1)
 
760
    {
 
761
      switch (opt)
 
762
        {
 
763
        case 'f':
 
764
          unset_function = 1;
 
765
          break;
 
766
        case 'v':
 
767
          unset_variable = 1;
 
768
          break;
 
769
        case 'n':
 
770
          nameref = 1;
 
771
          break;
 
772
        default:
 
773
          builtin_usage ();
 
774
          return (EX_USAGE);
 
775
        }
 
776
    }
 
777
 
 
778
  list = loptend;
 
779
 
 
780
  if (unset_function && unset_variable)
 
781
    {
 
782
      builtin_error (_("cannot simultaneously unset a function and a variable"));
 
783
      return (EXECUTION_FAILURE);
 
784
    }
 
785
  else if (unset_function && nameref)
 
786
    nameref = 0;
 
787
 
 
788
  while (list)
 
789
    {
 
790
      SHELL_VAR *var;
 
791
      int tem;
 
792
#if defined (ARRAY_VARS)
 
793
      char *t;
 
794
#endif
 
795
 
 
796
      name = list->word->word;
 
797
 
 
798
#if defined (ARRAY_VARS)
 
799
      unset_array = 0;
 
800
      if (!unset_function && valid_array_reference (name))
 
801
        {
 
802
          t = strchr (name, '[');
 
803
          *t++ = '\0';
 
804
          unset_array++;
 
805
        }
 
806
#endif
 
807
      /* Get error checking out of the way first.  The low-level functions
 
808
         just perform the unset, relying on the caller to verify. */
 
809
 
 
810
      /* Bash allows functions with names which are not valid identifiers
 
811
         to be created when not in posix mode, so check only when in posix
 
812
         mode when unsetting a function. */
 
813
      if (((unset_function && posixly_correct) || !unset_function) && legal_identifier (name) == 0)
 
814
        {
 
815
          sh_invalidid (name);
 
816
          NEXT_VARIABLE ();
 
817
        }
 
818
 
 
819
      /* Only search for functions here if -f supplied. */
 
820
      var = unset_function ? find_function (name)
 
821
                           : (nameref ? find_variable_last_nameref (name) : find_variable (name));
 
822
 
 
823
      /* Some variables (but not functions yet) cannot be unset, period. */
 
824
      if (var && unset_function == 0 && non_unsettable_p (var))
 
825
        {
 
826
          builtin_error (_("%s: cannot unset"), name);
 
827
          NEXT_VARIABLE ();
 
828
        }
 
829
 
 
830
      /* Posix.2 says try variables first, then functions.  If we would
 
831
         find a function after unsuccessfully searching for a variable,
 
832
         note that we're acting on a function now as if -f were
 
833
         supplied.  The readonly check below takes care of it. */
 
834
      if (var == 0 && unset_variable == 0 && unset_function == 0)
 
835
        {
 
836
          if (var = find_function (name))
 
837
            unset_function = 1;
 
838
        }
 
839
 
 
840
      /* Posix.2 says that unsetting readonly variables is an error. */
 
841
      if (var && readonly_p (var))
 
842
        {
 
843
          builtin_error (_("%s: cannot unset: readonly %s"),
 
844
                         var->name, unset_function ? "function" : "variable");
 
845
          NEXT_VARIABLE ();
 
846
        }
 
847
 
 
848
      /* Unless the -f option is supplied, the name refers to a variable. */
 
849
#if defined (ARRAY_VARS)
 
850
      if (var && unset_array)
 
851
        {
 
852
          if (array_p (var) == 0 && assoc_p (var) == 0)
 
853
            {
 
854
              builtin_error (_("%s: not an array variable"), var->name);
 
855
              NEXT_VARIABLE ();
 
856
            }
 
857
          else
 
858
            {
 
859
              tem = unbind_array_element (var, t);
 
860
              if (tem == -1)
 
861
                any_failed++;
 
862
            }
 
863
        }
 
864
      else
 
865
#endif /* ARRAY_VARS */
 
866
      tem = unset_function ? unbind_func (name) : (nameref ? unbind_nameref (name) : unbind_variable (name));
 
867
 
 
868
      /* This is what Posix.2 says:  ``If neither -f nor -v
 
869
         is specified, the name refers to a variable; if a variable by
 
870
         that name does not exist, a function by that name, if any,
 
871
         shall be unset.'' */
 
872
      if (tem == -1 && unset_function == 0 && unset_variable == 0)
 
873
        tem = unbind_func (name);
 
874
 
 
875
      /* SUSv3, POSIX.1-2001 say:  ``Unsetting a variable or function that
 
876
         was not previously set shall not be considered an error.'' */
 
877
 
 
878
      if (unset_function == 0)
 
879
        stupidly_hack_special_variables (name);
 
880
 
 
881
      list = list->next;
 
882
    }
 
883
 
 
884
  return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
 
885
}