1 /* Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
3 This file is part of GNU Bash, the Bourne Again SHell.
5 Bash is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free
7 Software Foundation; either version 1, or (at your option) any later
10 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
11 WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 You should have received a copy of the GNU General Public License along
16 with Bash; see the file COPYING. If not, write to the Free Software
17 Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
21 #if defined (HAVE_UNISTD_H)
23 # include <sys/types.h>
29 #include "../bashtypes.h"
30 #include "../posixstat.h"
35 #if defined (PREFER_STDARG)
38 # if defined (PREFER_VARARGS)
43 #include "../bashansi.h"
46 #include "../maxpath.h"
49 #include "../builtins.h"
51 #include "../execute_cmd.h"
53 #include "bashgetopt.h"
56 #include <tilde/tilde.h>
59 # include "../bashhist.h"
66 extern int no_symbolic_links
, interactive
, interactive_shell
;
67 extern int indirection_level
, startup_state
, subshell_environment
;
68 extern int line_number
;
69 extern int last_command_exit_value
;
70 extern int running_trap
;
71 extern int variable_context
;
72 extern int posixly_correct
;
73 extern char *this_command_name
, *shell_name
;
74 extern COMMAND
*global_command
;
75 extern char *bash_getcwd_errstr
;
77 /* Used by some builtins and the mainline code. */
78 Function
*last_shell_builtin
= (Function
*)NULL
;
79 Function
*this_shell_builtin
= (Function
*)NULL
;
81 /* **************************************************************** */
83 /* Error reporting, usage, and option processing */
85 /* **************************************************************** */
87 /* This is a lot like report_error (), but it is for shell builtins
88 instead of shell control structures, and it won't ever exit the
90 #if defined (USE_VARARGS)
92 #if defined (PREFER_STDARG)
93 builtin_error (const char *format
, ...)
95 builtin_error (format
, va_alist
)
103 name
= get_name_for_error ();
104 fprintf (stderr
, "%s: ", name
);
106 if (this_command_name
&& *this_command_name
)
107 fprintf (stderr
, "%s: ", this_command_name
);
109 #if defined (PREFER_STDARG)
110 va_start (args
, format
);
115 vfprintf (stderr
, format
, args
);
117 fprintf (stderr
, "\n");
119 #else /* !USE_VARARGS */
121 builtin_error (format
, arg1
, arg2
, arg3
, arg4
, arg5
)
122 char *format
, *arg1
, *arg2
, *arg3
, *arg4
, *arg5
;
124 if (this_command_name
&& *this_command_name
)
125 fprintf (stderr
, "%s: ", this_command_name
);
127 fprintf (stderr
, format
, arg1
, arg2
, arg3
, arg4
, arg5
);
128 fprintf (stderr
, "\n");
131 #endif /* !USE_VARARGS */
133 /* Print a usage summary for the currently-executing builtin command. */
137 if (this_command_name
&& *this_command_name
)
138 fprintf (stderr
, "%s: usage: ", this_command_name
);
139 fprintf (stderr
, "%s\n", current_builtin
->short_doc
);
143 /* Return if LIST is NULL else barf and jump to top_level. Used by some
144 builtins that do not accept arguments. */
151 builtin_error ("too many arguments");
152 jump_to_top_level (DISCARD
);
156 /* Function called when one of the builtin commands detects a bad
162 builtin_error ("unknown option: %s", s
);
165 /* Check that no options were given to the currently-executing builtin,
166 and return 0 if there were options. */
171 reset_internal_getopt ();
172 if (internal_getopt (list
, "") != -1)
180 /* **************************************************************** */
182 /* Shell positional parameter manipulation */
184 /* **************************************************************** */
186 /* Convert a WORD_LIST into a C-style argv. Return the number of elements
187 in the list in *IP, if IP is non-null. A convenience function for
188 loadable builtins; also used by `test'. */
190 make_builtin_argv (list
, ip
)
196 argv
= word_list_to_argv (list
, 0, 1, ip
);
197 argv
[0] = this_command_name
;
201 /* Remember LIST in $0 ... $9, and REST_OF_ARGS. If DESTRUCTIVE is
202 non-zero, then discard whatever the existing arguments are, else
203 only discard the ones that are to be replaced. */
205 remember_args (list
, destructive
)
211 for (i
= 1; i
< 10; i
++)
213 if ((destructive
|| list
) && dollar_vars
[i
])
215 free (dollar_vars
[i
]);
216 dollar_vars
[i
] = (char *)NULL
;
221 dollar_vars
[i
] = savestring (list
->word
->word
);
226 /* If arguments remain, assign them to REST_OF_ARGS.
227 Note that copy_word_list (NULL) returns NULL, and
228 that dispose_words (NULL) does nothing. */
229 if (destructive
|| list
)
231 dispose_words (rest_of_args
);
232 rest_of_args
= copy_word_list (list
);
236 set_dollar_vars_changed ();
239 /* **************************************************************** */
241 /* Pushing and Popping variable contexts */
243 /* **************************************************************** */
245 static WORD_LIST
**dollar_arg_stack
= (WORD_LIST
**)NULL
;
246 static int dollar_arg_stack_slots
;
247 static int dollar_arg_stack_index
;
260 kill_all_local_variables ();
264 /* Save the existing positional parameters on a stack. */
268 if (dollar_arg_stack_index
+ 2 > dollar_arg_stack_slots
)
270 dollar_arg_stack
= (WORD_LIST
**)
271 xrealloc (dollar_arg_stack
, (dollar_arg_stack_slots
+= 10)
272 * sizeof (WORD_LIST
**));
274 dollar_arg_stack
[dollar_arg_stack_index
++] = list_rest_of_args ();
275 dollar_arg_stack
[dollar_arg_stack_index
] = (WORD_LIST
*)NULL
;
278 /* Restore the positional parameters from our stack. */
282 if (!dollar_arg_stack
|| dollar_arg_stack_index
== 0)
285 remember_args (dollar_arg_stack
[--dollar_arg_stack_index
], 1);
286 dispose_words (dollar_arg_stack
[dollar_arg_stack_index
]);
287 dollar_arg_stack
[dollar_arg_stack_index
] = (WORD_LIST
*)NULL
;
291 dispose_saved_dollar_vars ()
293 if (!dollar_arg_stack
|| dollar_arg_stack_index
== 0)
296 dispose_words (dollar_arg_stack
[dollar_arg_stack_index
]);
297 dollar_arg_stack
[dollar_arg_stack_index
] = (WORD_LIST
*)NULL
;
300 static int changed_dollar_vars
;
302 /* Have the dollar variables been reset to new values since we last
305 dollar_vars_changed ()
307 return (changed_dollar_vars
);
311 set_dollar_vars_unchanged ()
313 changed_dollar_vars
= 0;
317 set_dollar_vars_changed ()
319 changed_dollar_vars
= 1;
322 /* **************************************************************** */
324 /* Validating numeric input and arguments */
326 /* **************************************************************** */
328 /* Read a numeric arg for this_command_name, the name of the shell builtin
329 that wants it. LIST is the word list that the arg is to come from.
330 Accept only the numeric argument; report an error if other arguments
331 follow. If FATAL is true, call throw_to_top_level, which exits the
332 shell; if not, call jump_to_top_level (DISCARD), which aborts the
335 get_numeric_arg (list
, fatal
)
345 arg
= list
->word
->word
;
346 if (!arg
|| (legal_number (arg
, &count
) == 0))
348 builtin_error ("bad non-numeric arg `%s'", list
->word
->word
);
350 throw_to_top_level ();
352 jump_to_top_level (DISCARD
);
354 no_args (list
->next
);
359 /* Return the octal number parsed from STRING, or -1 to indicate
360 that the string contained a bad number. */
368 while (*string
&& *string
>= '0' && *string
< '8')
371 result
= (result
* 8) + *string
++ - '0';
374 if (!digits
|| result
> 0777 || *string
)
380 /* **************************************************************** */
382 /* Manipulating the current working directory */
384 /* **************************************************************** */
386 /* Return a consed string which is the current working directory.
387 FOR_WHOM is the name of the caller for error printing. */
388 char *the_current_working_directory
= (char *)NULL
;
391 get_working_directory (for_whom
)
396 if (no_symbolic_links
)
398 if (the_current_working_directory
)
399 free (the_current_working_directory
);
401 the_current_working_directory
= (char *)NULL
;
404 if (the_current_working_directory
== 0)
406 the_current_working_directory
= xmalloc (PATH_MAX
);
407 the_current_working_directory
[0] = '\0';
408 directory
= getcwd (the_current_working_directory
, PATH_MAX
);
411 fprintf (stderr
, "%s: could not get current directory: %s: %s\n",
412 (for_whom
&& *for_whom
) ? for_whom
: get_name_for_error (),
413 the_current_working_directory
[0]
414 ? the_current_working_directory
415 : bash_getcwd_errstr
,
418 free (the_current_working_directory
);
419 the_current_working_directory
= (char *)NULL
;
424 return (savestring (the_current_working_directory
));
427 /* Make NAME our internal idea of the current working directory. */
429 set_working_directory (name
)
432 FREE (the_current_working_directory
);
433 the_current_working_directory
= savestring (name
);
436 /* **************************************************************** */
438 /* Job control support functions */
440 /* **************************************************************** */
442 #if defined (JOB_CONTROL)
443 /* Return the job spec found in LIST. */
452 return (current_job
);
454 word
= list
->word
->word
;
457 return (current_job
);
462 if (digit (*word
) && all_digits (word
))
474 return (current_job
);
477 return (previous_job
);
479 case '?': /* Substring search requested. */
490 for (i
= 0; i
< job_slots
; i
++)
498 if ((substring
&& strindex (p
->command
, word
)) ||
499 (STREQN (p
->command
, word
, wl
)))
502 builtin_error ("ambigious job spec: %s", word
);
510 while (p
!= jobs
[i
]->pipe
);
517 #endif /* JOB_CONTROL */
520 display_signal_list (list
, forcecols
)
524 register int i
, column
;
529 result
= EXECUTION_SUCCESS
;
532 for (i
= 1, column
= 0; i
< NSIG
; i
++)
534 name
= signal_name (i
);
535 if (STREQN (name
, "SIGJUNK", 7) || STREQN (name
, "Unknown", 7))
538 if (posixly_correct
&& !forcecols
)
539 printf ("%s%s", name
, (i
== NSIG
- 1) ? "" : " ");
542 printf ("%2d) %s", i
, name
);
554 if ((posixly_correct
&& !forcecols
) || column
!= 0)
559 /* List individual signal names or numbers. */
562 if (legal_number (list
->word
->word
, &signum
))
564 /* This is specified by Posix.2 so that exit statuses can be
565 mapped into signal numbers. */
568 if (signum
< 0 || signum
>= NSIG
)
570 builtin_error ("bad signal number: %s", list
->word
->word
);
571 result
= EXECUTION_FAILURE
;
576 name
= signal_name (signum
);
577 if (STREQN (name
, "SIGJUNK", 7) || STREQN (name
, "Unknown", 7))
582 #if defined (JOB_CONTROL)
583 /* POSIX.2 says that `kill -l signum' prints the signal name without
585 printf ("%s\n", (this_shell_builtin
== kill_builtin
) ? name
+ 3 : name
);
587 printf ("%s\n", name
);
592 signum
= decode_signal (list
->word
->word
);
593 if (signum
== NO_SIG
)
595 builtin_error ("%s: not a signal specification", list
->word
->word
);
596 result
= EXECUTION_FAILURE
;
600 printf ("%ld\n", signum
);
607 /* **************************************************************** */
609 /* Finding builtin commands and their functions */
611 /* **************************************************************** */
613 /* Perform a binary search and return the address of the builtin function
614 whose name is NAME. If the function couldn't be found, or the builtin
615 is disabled or has no function associated with it, return NULL.
616 Return the address of the builtin.
617 DISABLED_OKAY means find it even if the builtin is disabled. */
619 builtin_address_internal (name
, disabled_okay
)
625 hi
= num_shell_builtins
- 1;
632 j
= shell_builtins
[mid
].name
[0] - name
[0];
635 j
= strcmp (shell_builtins
[mid
].name
, name
);
639 /* It must have a function pointer. It must be enabled, or we
640 must have explicitly allowed disabled functions to be found,
641 and it must not have been deleted. */
642 if (shell_builtins
[mid
].function
&&
643 ((shell_builtins
[mid
].flags
& BUILTIN_DELETED
) == 0) &&
644 ((shell_builtins
[mid
].flags
& BUILTIN_ENABLED
) || disabled_okay
))
645 return (&shell_builtins
[mid
]);
647 return ((struct builtin
*)NULL
);
654 return ((struct builtin
*)NULL
);
657 /* Return the pointer to the function implementing builtin command NAME. */
659 find_shell_builtin (name
)
662 current_builtin
= builtin_address_internal (name
, 0);
663 return (current_builtin
? current_builtin
->function
: (Function
*)NULL
);
666 /* Return the address of builtin with NAME, whether it is enabled or not. */
668 builtin_address (name
)
671 current_builtin
= builtin_address_internal (name
, 1);
672 return (current_builtin
? current_builtin
->function
: (Function
*)NULL
);
675 /* Return the function implementing the builtin NAME, but only if it is a
676 POSIX.2 special builtin. */
678 find_special_builtin (name
)
681 current_builtin
= builtin_address_internal (name
, 0);
682 return ((current_builtin
&& (current_builtin
->flags
& SPECIAL_BUILTIN
)) ?
683 current_builtin
->function
:
688 shell_builtin_compare (sbp1
, sbp2
)
689 struct builtin
*sbp1
, *sbp2
;
693 if ((result
= sbp1
->name
[0] - sbp2
->name
[0]) == 0)
694 result
= strcmp (sbp1
->name
, sbp2
->name
);
699 /* Sort the table of shell builtins so that the binary search will work
700 in find_shell_builtin. */
702 initialize_shell_builtins ()
705 qsort (shell_builtins
, num_shell_builtins
, sizeof (struct builtin
),
706 (int (*)(const void *, const void *))shell_builtin_compare
);
708 qsort (shell_builtins
, num_shell_builtins
, sizeof (struct builtin
),
709 shell_builtin_compare
);
713 /* **************************************************************** */
715 /* Functions for quoting strings to be re-read as input */
717 /* **************************************************************** */
719 /* Return a new string which is the single-quoted version of STRING.
720 Used by alias and trap, among others. */
722 single_quote (string
)
726 char *result
, *r
, *s
;
728 result
= (char *)xmalloc (3 + (4 * strlen (string
)));
732 for (s
= string
; s
&& (c
= *s
); s
++)
738 *r
++ = '\\'; /* insert escaped single quote */
740 *r
++ = '\''; /* start new quoted string */
750 /* Quote STRING using double quotes. Return a new string. */
752 double_quote (string
)
756 char *result
, *r
, *s
;
758 result
= (char *)xmalloc (3 + (2 * strlen (string
)));
762 for (s
= string
; s
&& (c
= *s
); s
++)
783 /* Quote special characters in STRING using backslashes. Return a new
786 backslash_quote (string
)
790 char *result
, *r
, *s
;
792 result
= xmalloc (2 * strlen (string
) + 1);
794 for (r
= result
, s
= string
; s
&& (c
= *s
); s
++)
798 case ' ': case '\t': case '\n': /* IFS white space */
799 case '\'': case '"': case '\\': /* quoting chars */
800 case '|': case '&': case ';': /* shell metacharacters */
801 case '(': case ')': case '<': case '>':
802 case '!': case '{': case '}': /* reserved words */
803 case '*': case '[': case '?': case ']': /* globbing chars */
805 case '$': case '`': /* expansion chars */
810 case '~': /* tilde expansion */
811 if (s
== string
|| s
[-1] == '=' || s
[-1] == ':')
816 case '#': /* comment char */
831 contains_shell_metas (string
)
836 for (s
= string
; s
&& *s
; s
++)
840 case ' ': case '\t': case '\n': /* IFS white space */
841 case '\'': case '"': case '\\': /* quoting chars */
842 case '|': case '&': case ';': /* shell metacharacters */
843 case '(': case ')': case '<': case '>':
844 case '!': case '{': case '}': /* reserved words */
845 case '*': case '[': case '?': case ']': /* globbing chars */
847 case '$': case '`': /* expansion chars */
849 case '~': /* tilde expansion */
850 if (s
== string
|| s
[-1] == '=' || s
[-1] == ':')
853 if (s
== string
) /* comment char */