]> git.ipfire.org Git - thirdparty/bash.git/blob - builtins/common.c
696901e08109abdee647826b99395f17c07d092f
[thirdparty/bash.git] / builtins / common.c
1 /* Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
2
3 This file is part of GNU Bash, the Bourne Again SHell.
4
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
8 version.
9
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
13 for more details.
14
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. */
18
19 #include <config.h>
20
21 #if defined (HAVE_UNISTD_H)
22 # ifdef _MINIX
23 # include <sys/types.h>
24 # endif
25 # include <unistd.h>
26 #endif
27
28 #include <stdio.h>
29 #include "../bashtypes.h"
30 #include "../posixstat.h"
31 #include <signal.h>
32
33 #include <errno.h>
34
35 #if defined (PREFER_STDARG)
36 # include <stdarg.h>
37 #else
38 # if defined (PREFER_VARARGS)
39 # include <varargs.h>
40 # endif
41 #endif
42
43 #include "../bashansi.h"
44
45 #include "../shell.h"
46 #include "../maxpath.h"
47 #include "../flags.h"
48 #include "../jobs.h"
49 #include "../builtins.h"
50 #include "../input.h"
51 #include "../execute_cmd.h"
52 #include "../trap.h"
53 #include "bashgetopt.h"
54 #include "common.h"
55 #include "builtext.h"
56 #include <tilde/tilde.h>
57
58 #if defined (HISTORY)
59 # include "../bashhist.h"
60 #endif
61
62 #if !defined (errno)
63 extern int errno;
64 #endif /* !errno */
65
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;
76
77 /* Used by some builtins and the mainline code. */
78 Function *last_shell_builtin = (Function *)NULL;
79 Function *this_shell_builtin = (Function *)NULL;
80
81 /* **************************************************************** */
82 /* */
83 /* Error reporting, usage, and option processing */
84 /* */
85 /* **************************************************************** */
86
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
89 shell. */
90 #if defined (USE_VARARGS)
91 void
92 #if defined (PREFER_STDARG)
93 builtin_error (const char *format, ...)
94 #else
95 builtin_error (format, va_alist)
96 const char *format;
97 va_dcl
98 #endif
99 {
100 va_list args;
101 char *name;
102
103 name = get_name_for_error ();
104 fprintf (stderr, "%s: ", name);
105
106 if (this_command_name && *this_command_name)
107 fprintf (stderr, "%s: ", this_command_name);
108
109 #if defined (PREFER_STDARG)
110 va_start (args, format);
111 #else
112 va_start (args);
113 #endif
114
115 vfprintf (stderr, format, args);
116 va_end (args);
117 fprintf (stderr, "\n");
118 }
119 #else /* !USE_VARARGS */
120 void
121 builtin_error (format, arg1, arg2, arg3, arg4, arg5)
122 char *format, *arg1, *arg2, *arg3, *arg4, *arg5;
123 {
124 if (this_command_name && *this_command_name)
125 fprintf (stderr, "%s: ", this_command_name);
126
127 fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5);
128 fprintf (stderr, "\n");
129 fflush (stderr);
130 }
131 #endif /* !USE_VARARGS */
132
133 /* Print a usage summary for the currently-executing builtin command. */
134 void
135 builtin_usage ()
136 {
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);
140 fflush (stderr);
141 }
142
143 /* Return if LIST is NULL else barf and jump to top_level. Used by some
144 builtins that do not accept arguments. */
145 void
146 no_args (list)
147 WORD_LIST *list;
148 {
149 if (list)
150 {
151 builtin_error ("too many arguments");
152 jump_to_top_level (DISCARD);
153 }
154 }
155
156 /* Function called when one of the builtin commands detects a bad
157 option. */
158 void
159 bad_option (s)
160 char *s;
161 {
162 builtin_error ("unknown option: %s", s);
163 }
164
165 /* Check that no options were given to the currently-executing builtin,
166 and return 0 if there were options. */
167 int
168 no_options (list)
169 WORD_LIST *list;
170 {
171 reset_internal_getopt ();
172 if (internal_getopt (list, "") != -1)
173 {
174 builtin_usage ();
175 return (1);
176 }
177 return (0);
178 }
179
180 /* **************************************************************** */
181 /* */
182 /* Shell positional parameter manipulation */
183 /* */
184 /* **************************************************************** */
185
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'. */
189 char **
190 make_builtin_argv (list, ip)
191 WORD_LIST *list;
192 int *ip;
193 {
194 char **argv;
195
196 argv = word_list_to_argv (list, 0, 1, ip);
197 argv[0] = this_command_name;
198 return argv;
199 }
200
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. */
204 void
205 remember_args (list, destructive)
206 WORD_LIST *list;
207 int destructive;
208 {
209 register int i;
210
211 for (i = 1; i < 10; i++)
212 {
213 if ((destructive || list) && dollar_vars[i])
214 {
215 free (dollar_vars[i]);
216 dollar_vars[i] = (char *)NULL;
217 }
218
219 if (list)
220 {
221 dollar_vars[i] = savestring (list->word->word);
222 list = list->next;
223 }
224 }
225
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)
230 {
231 dispose_words (rest_of_args);
232 rest_of_args = copy_word_list (list);
233 }
234
235 if (destructive)
236 set_dollar_vars_changed ();
237 }
238
239 /* **************************************************************** */
240 /* */
241 /* Pushing and Popping variable contexts */
242 /* */
243 /* **************************************************************** */
244
245 static WORD_LIST **dollar_arg_stack = (WORD_LIST **)NULL;
246 static int dollar_arg_stack_slots;
247 static int dollar_arg_stack_index;
248
249 void
250 push_context ()
251 {
252 push_dollar_vars ();
253 variable_context++;
254 }
255
256 void
257 pop_context ()
258 {
259 pop_dollar_vars ();
260 kill_all_local_variables ();
261 variable_context--;
262 }
263
264 /* Save the existing positional parameters on a stack. */
265 void
266 push_dollar_vars ()
267 {
268 if (dollar_arg_stack_index + 2 > dollar_arg_stack_slots)
269 {
270 dollar_arg_stack = (WORD_LIST **)
271 xrealloc (dollar_arg_stack, (dollar_arg_stack_slots += 10)
272 * sizeof (WORD_LIST **));
273 }
274 dollar_arg_stack[dollar_arg_stack_index++] = list_rest_of_args ();
275 dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
276 }
277
278 /* Restore the positional parameters from our stack. */
279 void
280 pop_dollar_vars ()
281 {
282 if (!dollar_arg_stack || dollar_arg_stack_index == 0)
283 return;
284
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;
288 }
289
290 void
291 dispose_saved_dollar_vars ()
292 {
293 if (!dollar_arg_stack || dollar_arg_stack_index == 0)
294 return;
295
296 dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
297 dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
298 }
299
300 static int changed_dollar_vars;
301
302 /* Have the dollar variables been reset to new values since we last
303 checked? */
304 int
305 dollar_vars_changed ()
306 {
307 return (changed_dollar_vars);
308 }
309
310 void
311 set_dollar_vars_unchanged ()
312 {
313 changed_dollar_vars = 0;
314 }
315
316 void
317 set_dollar_vars_changed ()
318 {
319 changed_dollar_vars = 1;
320 }
321
322 /* **************************************************************** */
323 /* */
324 /* Validating numeric input and arguments */
325 /* */
326 /* **************************************************************** */
327
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
333 current command. */
334 int
335 get_numeric_arg (list, fatal)
336 WORD_LIST *list;
337 int fatal;
338 {
339 long count = 1;
340
341 if (list)
342 {
343 register char *arg;
344
345 arg = list->word->word;
346 if (!arg || (legal_number (arg, &count) == 0))
347 {
348 builtin_error ("bad non-numeric arg `%s'", list->word->word);
349 if (fatal)
350 throw_to_top_level ();
351 else
352 jump_to_top_level (DISCARD);
353 }
354 no_args (list->next);
355 }
356 return (count);
357 }
358
359 /* Return the octal number parsed from STRING, or -1 to indicate
360 that the string contained a bad number. */
361 int
362 read_octal (string)
363 char *string;
364 {
365 int result, digits;
366
367 result = digits = 0;
368 while (*string && *string >= '0' && *string < '8')
369 {
370 digits++;
371 result = (result * 8) + *string++ - '0';
372 }
373
374 if (!digits || result > 0777 || *string)
375 result = -1;
376
377 return (result);
378 }
379
380 /* **************************************************************** */
381 /* */
382 /* Manipulating the current working directory */
383 /* */
384 /* **************************************************************** */
385
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;
389
390 char *
391 get_working_directory (for_whom)
392 char *for_whom;
393 {
394 char *directory;
395
396 if (no_symbolic_links)
397 {
398 if (the_current_working_directory)
399 free (the_current_working_directory);
400
401 the_current_working_directory = (char *)NULL;
402 }
403
404 if (the_current_working_directory == 0)
405 {
406 the_current_working_directory = xmalloc (PATH_MAX);
407 the_current_working_directory[0] = '\0';
408 directory = getcwd (the_current_working_directory, PATH_MAX);
409 if (directory == 0)
410 {
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,
416 strerror (errno));
417
418 free (the_current_working_directory);
419 the_current_working_directory = (char *)NULL;
420 return (char *)NULL;
421 }
422 }
423
424 return (savestring (the_current_working_directory));
425 }
426
427 /* Make NAME our internal idea of the current working directory. */
428 void
429 set_working_directory (name)
430 char *name;
431 {
432 FREE (the_current_working_directory);
433 the_current_working_directory = savestring (name);
434 }
435
436 /* **************************************************************** */
437 /* */
438 /* Job control support functions */
439 /* */
440 /* **************************************************************** */
441
442 #if defined (JOB_CONTROL)
443 /* Return the job spec found in LIST. */
444 int
445 get_job_spec (list)
446 WORD_LIST *list;
447 {
448 register char *word;
449 int job, substring;
450
451 if (list == 0)
452 return (current_job);
453
454 word = list->word->word;
455
456 if (*word == '\0')
457 return (current_job);
458
459 if (*word == '%')
460 word++;
461
462 if (digit (*word) && all_digits (word))
463 {
464 job = atoi (word);
465 return (job - 1);
466 }
467
468 substring = 0;
469 switch (*word)
470 {
471 case 0:
472 case '%':
473 case '+':
474 return (current_job);
475
476 case '-':
477 return (previous_job);
478
479 case '?': /* Substring search requested. */
480 substring++;
481 word++;
482 /* FALLTHROUGH */
483
484 default:
485 {
486 register int i, wl;
487
488 job = NO_JOB;
489 wl = strlen (word);
490 for (i = 0; i < job_slots; i++)
491 {
492 if (jobs[i])
493 {
494 register PROCESS *p;
495 p = jobs[i]->pipe;
496 do
497 {
498 if ((substring && strindex (p->command, word)) ||
499 (STREQN (p->command, word, wl)))
500 if (job != NO_JOB)
501 {
502 builtin_error ("ambigious job spec: %s", word);
503 return (DUP_JOB);
504 }
505 else
506 job = i;
507
508 p = p->next;
509 }
510 while (p != jobs[i]->pipe);
511 }
512 }
513 return (job);
514 }
515 }
516 }
517 #endif /* JOB_CONTROL */
518
519 int
520 display_signal_list (list, forcecols)
521 WORD_LIST *list;
522 int forcecols;
523 {
524 register int i, column;
525 char *name;
526 int result;
527 long signum;
528
529 result = EXECUTION_SUCCESS;
530 if (!list)
531 {
532 for (i = 1, column = 0; i < NSIG; i++)
533 {
534 name = signal_name (i);
535 if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7))
536 continue;
537
538 if (posixly_correct && !forcecols)
539 printf ("%s%s", name, (i == NSIG - 1) ? "" : " ");
540 else
541 {
542 printf ("%2d) %s", i, name);
543
544 if (++column < 4)
545 printf ("\t");
546 else
547 {
548 printf ("\n");
549 column = 0;
550 }
551 }
552 }
553
554 if ((posixly_correct && !forcecols) || column != 0)
555 printf ("\n");
556 return result;
557 }
558
559 /* List individual signal names or numbers. */
560 while (list)
561 {
562 if (legal_number (list->word->word, &signum))
563 {
564 /* This is specified by Posix.2 so that exit statuses can be
565 mapped into signal numbers. */
566 if (signum > 128)
567 signum -= 128;
568 if (signum < 0 || signum >= NSIG)
569 {
570 builtin_error ("bad signal number: %s", list->word->word);
571 result = EXECUTION_FAILURE;
572 list = list->next;
573 continue;
574 }
575
576 name = signal_name (signum);
577 if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7))
578 {
579 list = list->next;
580 continue;
581 }
582 #if defined (JOB_CONTROL)
583 /* POSIX.2 says that `kill -l signum' prints the signal name without
584 the `SIG' prefix. */
585 printf ("%s\n", (this_shell_builtin == kill_builtin) ? name + 3 : name);
586 #else
587 printf ("%s\n", name);
588 #endif
589 }
590 else
591 {
592 signum = decode_signal (list->word->word);
593 if (signum == NO_SIG)
594 {
595 builtin_error ("%s: not a signal specification", list->word->word);
596 result = EXECUTION_FAILURE;
597 list = list->next;
598 continue;
599 }
600 printf ("%ld\n", signum);
601 }
602 list = list->next;
603 }
604 return (result);
605 }
606
607 /* **************************************************************** */
608 /* */
609 /* Finding builtin commands and their functions */
610 /* */
611 /* **************************************************************** */
612
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. */
618 struct builtin *
619 builtin_address_internal (name, disabled_okay)
620 char *name;
621 int disabled_okay;
622 {
623 int hi, lo, mid, j;
624
625 hi = num_shell_builtins - 1;
626 lo = 0;
627
628 while (lo <= hi)
629 {
630 mid = (lo + hi) / 2;
631
632 j = shell_builtins[mid].name[0] - name[0];
633
634 if (j == 0)
635 j = strcmp (shell_builtins[mid].name, name);
636
637 if (j == 0)
638 {
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]);
646 else
647 return ((struct builtin *)NULL);
648 }
649 if (j > 0)
650 hi = mid - 1;
651 else
652 lo = mid + 1;
653 }
654 return ((struct builtin *)NULL);
655 }
656
657 /* Return the pointer to the function implementing builtin command NAME. */
658 Function *
659 find_shell_builtin (name)
660 char *name;
661 {
662 current_builtin = builtin_address_internal (name, 0);
663 return (current_builtin ? current_builtin->function : (Function *)NULL);
664 }
665
666 /* Return the address of builtin with NAME, whether it is enabled or not. */
667 Function *
668 builtin_address (name)
669 char *name;
670 {
671 current_builtin = builtin_address_internal (name, 1);
672 return (current_builtin ? current_builtin->function : (Function *)NULL);
673 }
674
675 /* Return the function implementing the builtin NAME, but only if it is a
676 POSIX.2 special builtin. */
677 Function *
678 find_special_builtin (name)
679 char *name;
680 {
681 current_builtin = builtin_address_internal (name, 0);
682 return ((current_builtin && (current_builtin->flags & SPECIAL_BUILTIN)) ?
683 current_builtin->function :
684 (Function *)NULL);
685 }
686
687 static int
688 shell_builtin_compare (sbp1, sbp2)
689 struct builtin *sbp1, *sbp2;
690 {
691 int result;
692
693 if ((result = sbp1->name[0] - sbp2->name[0]) == 0)
694 result = strcmp (sbp1->name, sbp2->name);
695
696 return (result);
697 }
698
699 /* Sort the table of shell builtins so that the binary search will work
700 in find_shell_builtin. */
701 void
702 initialize_shell_builtins ()
703 {
704 #ifdef _MINIX
705 qsort (shell_builtins, num_shell_builtins, sizeof (struct builtin),
706 (int (*)(const void *, const void *))shell_builtin_compare);
707 #else
708 qsort (shell_builtins, num_shell_builtins, sizeof (struct builtin),
709 shell_builtin_compare);
710 #endif
711 }
712
713 /* **************************************************************** */
714 /* */
715 /* Functions for quoting strings to be re-read as input */
716 /* */
717 /* **************************************************************** */
718
719 /* Return a new string which is the single-quoted version of STRING.
720 Used by alias and trap, among others. */
721 char *
722 single_quote (string)
723 char *string;
724 {
725 register int c;
726 char *result, *r, *s;
727
728 result = (char *)xmalloc (3 + (4 * strlen (string)));
729 r = result;
730 *r++ = '\'';
731
732 for (s = string; s && (c = *s); s++)
733 {
734 *r++ = c;
735
736 if (c == '\'')
737 {
738 *r++ = '\\'; /* insert escaped single quote */
739 *r++ = '\'';
740 *r++ = '\''; /* start new quoted string */
741 }
742 }
743
744 *r++ = '\'';
745 *r = '\0';
746
747 return (result);
748 }
749
750 /* Quote STRING using double quotes. Return a new string. */
751 char *
752 double_quote (string)
753 char *string;
754 {
755 register int c;
756 char *result, *r, *s;
757
758 result = (char *)xmalloc (3 + (2 * strlen (string)));
759 r = result;
760 *r++ = '"';
761
762 for (s = string; s && (c = *s); s++)
763 {
764 switch (c)
765 {
766 case '"':
767 case '$':
768 case '`':
769 case '\\':
770 *r++ = '\\';
771 default:
772 *r++ = c;
773 break;
774 }
775 }
776
777 *r++ = '"';
778 *r = '\0';
779
780 return (result);
781 }
782
783 /* Quote special characters in STRING using backslashes. Return a new
784 string. */
785 char *
786 backslash_quote (string)
787 char *string;
788 {
789 int c;
790 char *result, *r, *s;
791
792 result = xmalloc (2 * strlen (string) + 1);
793
794 for (r = result, s = string; s && (c = *s); s++)
795 {
796 switch (c)
797 {
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 */
804 case '^':
805 case '$': case '`': /* expansion chars */
806 *r++ = '\\';
807 *r++ = c;
808 break;
809 #if 0
810 case '~': /* tilde expansion */
811 if (s == string || s[-1] == '=' || s[-1] == ':')
812 *r++ = '\\';
813 *r++ = c;
814 break;
815 #endif
816 case '#': /* comment char */
817 if (s == string)
818 *r++ = '\\';
819 /* FALLTHROUGH */
820 default:
821 *r++ = c;
822 break;
823 }
824 }
825
826 *r = '\0';
827 return (result);
828 }
829
830 int
831 contains_shell_metas (string)
832 char *string;
833 {
834 char *s;
835
836 for (s = string; s && *s; s++)
837 {
838 switch (*s)
839 {
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 */
846 case '^':
847 case '$': case '`': /* expansion chars */
848 return (1);
849 case '~': /* tilde expansion */
850 if (s == string || s[-1] == '=' || s[-1] == ':')
851 return (1);
852 case '#':
853 if (s == string) /* comment char */
854 return (1);
855 /* FALLTHROUGH */
856 default:
857 break;
858 }
859 }
860
861 return (0);
862 }