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. */
20 #include <sys/types.h>
21 #include "../posixstat.h"
22 #if defined (HAVE_VFPRINTF)
26 #if defined (HAVE_STRING_H)
28 #else /* !HAVE_STRING_H */
30 #endif /* !HAVE_STRING_H */
33 #include "../unwind_prot.h"
34 #include "../maxpath.h"
36 #include "../builtins.h"
38 #include "../execute_cmd.h"
41 #include <tilde/tilde.h>
44 # include "../bashhist.h"
47 extern int no_symbolic_links, interactive, interactive_shell;
48 extern int indirection_level, startup_state;
49 extern int last_command_exit_value;
50 extern int hashing_disabled;
51 extern int variable_context;
52 extern char *this_command_name, *shell_name;
53 extern COMMAND *global_command;
54 extern HASH_TABLE *hashed_filenames;
56 /* Read a numeric arg for this_command_name, the name of the shell builtin
57 that wants it. LIST is the word list that the arg is to come from. */
59 get_numeric_arg (list)
69 arg = list->word->word;
73 /* Skip optional leading white space. */
74 while (whitespace (*arg))
80 /* We allow leading `-' or `+'. */
81 if (*arg == '-' || *arg == '+')
92 for (count = 0; digit (*arg); arg++)
93 count = (count * 10) + digit_value (*arg);
95 /* Skip trailing whitespace, if any. */
96 while (whitespace (*arg))
100 count = count * sign;
104 builtin_error ("bad non-numeric arg `%s'", list->word->word);
105 throw_to_top_level ();
107 no_args (list->next);
112 /* This is a lot like report_error (), but it is for shell builtins
113 instead of shell control structures, and it won't ever exit the
115 #if defined (HAVE_VFPRINTF)
117 builtin_error (va_alist)
123 if (this_command_name && *this_command_name)
124 fprintf (stderr, "%s: ", this_command_name);
127 format = va_arg (args, char *);
128 vfprintf (stderr, format, args);
130 fprintf (stderr, "\n");
132 #else /* !HAVE_VFPRINTF */
134 builtin_error (format, arg1, arg2, arg3, arg4, arg5)
135 char *format, *arg1, *arg2, *arg3, *arg4, *arg5;
137 if (this_command_name && *this_command_name)
138 fprintf (stderr, "%s: ", this_command_name);
140 fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5);
141 fprintf (stderr, "\n");
144 #endif /* !HAVE_VFPRINTF */
146 /* Remember LIST in $0 ... $9, and REST_OF_ARGS. If DESTRUCTIVE is
147 non-zero, then discard whatever the existing arguments are, else
148 only discard the ones that are to be replaced. */
150 remember_args (list, destructive)
156 for (i = 1; i < 10; i++)
158 if (destructive && dollar_vars[i])
160 free (dollar_vars[i]);
161 dollar_vars[i] = (char *)NULL;
166 if (!destructive && dollar_vars[i])
167 free (dollar_vars[i]);
169 dollar_vars[i] = savestring (list->word->word);
174 /* If arguments remain, assign them to REST_OF_ARGS.
175 Note that copy_word_list (NULL) returns NULL, and
176 that dispose_words (NULL) does nothing. */
177 if (destructive || list)
179 dispose_words (rest_of_args);
180 rest_of_args = copy_word_list (list);
184 set_dollar_vars_changed ();
187 /* Return if LIST is NULL else barf and jump to top_level. */
194 builtin_error ("extra arguments");
195 longjmp (top_level, DISCARD);
199 /* Return the octal number parsed from STRING, or -1 to indicate
200 that the string contained a bad number. */
208 while (*string && *string >= '0' && *string < '8')
211 result = (result * 8) + *string++ - '0';
214 if (!digits || result > 0777 || *string)
220 /* Temporary static. */
221 static char *dotted_filename = (char *)NULL;
223 /* Return the full pathname that FILENAME hashes to. If FILENAME
224 is hashed, but data->check_dot is non-zero, check ./FILENAME
225 and return that if it is executable. */
227 find_hashed_filename (filename)
230 register BUCKET_CONTENTS *item;
232 if (hashing_disabled)
233 return ((char *)NULL);
235 item = find_hash_item (filename, hashed_filenames);
239 /* If this filename is hashed, but `.' comes before it in the path,
240 then see if `./filename' is an executable. */
241 if (pathdata(item)->check_dot)
244 free (dotted_filename);
246 dotted_filename = (char *)xmalloc (3 + strlen (filename));
247 strcpy (dotted_filename, "./");
248 strcat (dotted_filename, filename);
250 if (executable_file (dotted_filename))
251 return (dotted_filename);
253 /* Watch out. If this file was hashed to "./filename", and
254 "./filename" is not executable, then return NULL. */
256 /* Since we already know "./filename" is not executable, what
257 we're really interested in is whether or not the `path'
258 portion of the hashed filename is equivalent to the current
259 directory, but only if it starts with a `.'. (This catches
260 ./. and so on.) same_file () is in execute_cmd.c; it tests
261 general Unix file equivalence -- same device and inode. */
263 char *path = pathdata (item)->path;
270 tail = (char *) strrchr (path, '/');
276 (".", path, (struct stat *)NULL, (struct stat *)NULL);
280 return ((char *)NULL);
284 return (pathdata (item)->path);
287 return ((char *)NULL);
290 /* Remove FILENAME from the table of hashed commands. */
292 remove_hashed_filename (filename)
295 register BUCKET_CONTENTS *item;
297 if (hashing_disabled)
300 item = remove_hash_item (filename, hashed_filenames);
305 free (pathdata(item)->path);
314 /* **************************************************************** */
316 /* Pushing and Popping a Context */
318 /* **************************************************************** */
320 static WORD_LIST **dollar_arg_stack = (WORD_LIST **)NULL;
321 static int dollar_arg_stack_slots = 0;
322 static int dollar_arg_stack_index = 0;
335 kill_all_local_variables ();
339 /* Save the existing positional parameters on a stack. */
343 if (dollar_arg_stack_index + 2 > dollar_arg_stack_slots)
345 dollar_arg_stack = (WORD_LIST **)
346 xrealloc (dollar_arg_stack, (dollar_arg_stack_slots += 10)
347 * sizeof (WORD_LIST **));
349 dollar_arg_stack[dollar_arg_stack_index] = list_rest_of_args ();
350 dollar_arg_stack[++dollar_arg_stack_index] = (WORD_LIST *)NULL;
353 /* Restore the positional parameters from our stack. */
357 if (!dollar_arg_stack || !dollar_arg_stack_index)
360 remember_args (dollar_arg_stack[--dollar_arg_stack_index], 1);
361 dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
362 dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
366 dispose_saved_dollar_vars ()
368 if (!dollar_arg_stack || !dollar_arg_stack_index)
371 dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
372 dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
375 static int changed_dollar_vars = 0;
377 /* Have the dollar variables been reset to new values since we last
379 dollar_vars_changed ()
381 return (changed_dollar_vars);
385 set_dollar_vars_unchanged ()
387 changed_dollar_vars = 0;
391 set_dollar_vars_changed ()
393 changed_dollar_vars = 1;
396 /* Function called when one of the builtin commands detects a bad
402 builtin_error ("unknown option: %s", s);
405 /* Return a consed string which is the current working directory.
406 FOR_WHOM is the name of the caller for error printing. */
407 char *the_current_working_directory = (char *)NULL;
410 get_working_directory (for_whom)
413 if (no_symbolic_links)
415 if (the_current_working_directory)
416 free (the_current_working_directory);
418 the_current_working_directory = (char *)NULL;
421 if (!the_current_working_directory)
425 the_current_working_directory = xmalloc (MAXPATHLEN);
426 directory = getwd (the_current_working_directory);
429 if (for_whom && *for_whom)
430 fprintf (stderr, "%s: ", for_whom);
432 fprintf (stderr, "%s: ", get_name_for_error ());
434 fprintf (stderr, "could not get current directory: %s\n",
435 the_current_working_directory);
437 free (the_current_working_directory);
438 the_current_working_directory = (char *)NULL;
443 return (savestring (the_current_working_directory));
446 /* Make NAME our internal idea of the current working directory. */
448 set_working_directory (name)
451 if (the_current_working_directory)
452 free (the_current_working_directory);
454 the_current_working_directory = savestring (name);
457 #if defined (JOB_CONTROL)
458 /* Return the job spec found in LIST. */
467 return (current_job);
469 word = list->word->word;
472 return (current_job);
477 if (digit (*word) && (sscanf (word, "%d", &job) == 1))
485 return (current_job);
488 return (previous_job);
490 case '?': /* Substring search requested. */
498 register int i, wl = strlen (word);
499 for (i = 0; i < job_slots; i++)
503 register PROCESS *p = jobs[i]->pipe;
506 if ((substring && strindex (p->command, word)) ||
507 (strncmp (p->command, word, wl) == 0))
510 builtin_error ("ambigious job spec: %s", word);
518 while (p != jobs[i]->pipe);
525 #endif /* JOB_CONTROL */
527 int parse_and_execute_level = 0;
529 /* How to force parse_and_execute () to clean up after itself. */
531 parse_and_execute_cleanup ()
533 run_unwind_frame ("parse_and_execute_top");
536 /* Parse and execute the commands in STRING. Returns whatever
537 execute_command () returns. This frees STRING. INTERACT is
538 the new value for `interactive' while the commands are being
539 executed. A value of -1 means don't change it. */
541 parse_and_execute (string, from_file, interact)
546 int last_result = EXECUTION_SUCCESS;
547 int code = 0, jump_to_top_level = 0;
548 char *orig_string = string;
550 /* Unwind protect this invocation of parse_and_execute (). */
551 begin_unwind_frame ("parse_and_execute_top");
552 unwind_protect_int (parse_and_execute_level);
553 unwind_protect_jmp_buf (top_level);
554 unwind_protect_int (indirection_level);
555 if (interact != -1 && interactive != interact)
556 unwind_protect_int (interactive);
558 #if defined (HISTORY)
559 if (interactive_shell)
561 unwind_protect_int (remember_on_history);
562 # if defined (BANG_HISTORY)
563 unwind_protect_int (history_expansion_inhibited);
564 # endif /* BANG_HISTORY */
568 add_unwind_protect (pop_stream, (char *)NULL);
570 add_unwind_protect (xfree, orig_string);
573 parse_and_execute_level++;
577 interactive = interact;
579 #if defined (HISTORY)
580 /* We don't remember text read by the shell this way on
581 the history list, and we don't use !$ in shell scripts. */
582 remember_on_history = 0;
583 # if defined (BANG_HISTORY)
584 history_expansion_inhibited = 1;
585 # endif /* BANG_HISTORY */
588 with_input_from_string (string, from_file);
592 while (*(bash_input.location.string))
596 last_result = EXECUTION_FAILURE;
600 /* Provide a location for functions which `longjmp (top_level)' to
601 jump to. This prevents errors in substitution from restarting
602 the reader loop directly, for example. */
603 code = setjmp (top_level);
607 jump_to_top_level = 0;
612 run_unwind_frame ("pe_dispose");
613 /* Remember to call longjmp (top_level) after the old
614 value for it is restored. */
615 jump_to_top_level = 1;
619 dispose_command (command);
620 run_unwind_frame ("pe_dispose");
621 last_command_exit_value = 1;
625 programming_error ("bad jump to top_level: %d", code);
630 if (parse_command () == 0)
632 if ((command = global_command) != (COMMAND *)NULL)
634 struct fd_bitmap *bitmap;
636 bitmap = new_fd_bitmap (FD_BITMAP_SIZE);
637 begin_unwind_frame ("pe_dispose");
638 add_unwind_protect (dispose_fd_bitmap, bitmap);
640 global_command = (COMMAND *)NULL;
642 #if defined (ONESHOT)
643 if (startup_state == 2 && *bash_input.location.string == '\0' &&
644 command->type == cm_simple && !command->redirects &&
645 !command->value.Simple->redirects)
647 command->flags |= CMD_NO_FORK;
648 command->value.Simple->flags |= CMD_NO_FORK;
652 last_result = execute_command_internal
653 (command, 0, NO_PIPE, NO_PIPE, bitmap);
655 dispose_command (command);
656 run_unwind_frame ("pe_dispose");
661 last_result = EXECUTION_FAILURE;
663 /* Since we are shell compatible, syntax errors in a script
664 abort the execution of the script. Right? */
672 run_unwind_frame ("parse_and_execute_top");
674 if (interrupt_state && parse_and_execute_level == 0)
676 /* An interrupt during non-interactive execution in an
677 interactive shell (e.g. via $PROMPT_COMMAND) should
678 not cause the shell to exit. */
679 interactive = interactive_shell;
680 throw_to_top_level ();
683 if (jump_to_top_level)
684 longjmp (top_level, code);
686 return (last_result);
689 /* Return the address of the builtin named NAME.
690 DISABLED_OKAY means find it even if the builtin is disabled. */
692 builtin_address_internal (name, disabled_okay)
698 hi = num_shell_builtins - 1;
705 j = shell_builtins[mid].name[0] - name[0];
708 j = strcmp (shell_builtins[mid].name, name);
712 /* It must have a function pointer. It must be enabled, or we
713 must have explicitly allowed disabled functions to be found. */
714 if (shell_builtins[mid].function &&
715 ((shell_builtins[mid].flags & BUILTIN_ENABLED) || disabled_okay))
716 return (shell_builtins[mid].function);
718 return ((Function *)NULL);
725 return ((Function *)NULL);
728 /* Perform a binary search and return the address of the builtin function
729 whose name is NAME. If the function couldn't be found, or the builtin
730 is disabled or has no function associated with it, return NULL. */
732 find_shell_builtin (name)
735 return (builtin_address_internal (name, 0));
738 /* Return the address of builtin with NAME, irregardless of its state of
741 builtin_address (name)
744 return (builtin_address_internal (name, 1));
748 shell_builtin_compare (sbp1, sbp2)
749 struct builtin *sbp1, *sbp2;
753 if ((result = sbp1->name[0] - sbp2->name[0]) == 0)
754 result = strcmp (sbp1->name, sbp2->name);
759 /* Sort the table of shell builtins so that the binary search will work
760 in find_shell_builtin. */
762 initialize_shell_builtins ()
764 qsort (shell_builtins, num_shell_builtins, sizeof (struct builtin),
765 shell_builtin_compare);
768 /* Return a new string which is the quoted version of STRING. This is used
769 by alias and trap. */
771 single_quote (string)
774 register int i, j, c;
777 result = (char *)xmalloc (3 + (3 * strlen (string)));
781 for (i = 0, j = 1; string && (c = string[i]); i++)
787 result[j++] = '\\'; /* insert escaped single quote */
789 result[j++] = '\''; /* start new quoted string */
800 double_quote (string)
803 register int i, j, c;
806 result = (char *)xmalloc (3 + (3 * strlen (string)));
810 for (i = 0, j = 1; string && (c = string[i]); i++)