source: vendor/bash/3.1-p17/builtins/common.c

Last change on this file was 3231, checked in by bird, 18 years ago

eol style.

  • Property svn:eol-style set to native
File size: 17.9 KB
Line 
1/* Copyright (C) 1987-2005 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 2, 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, 59 Temple Place, Suite 330, Boston, MA 02111 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 <chartypes.h>
30#include "../bashtypes.h"
31#include "posixstat.h"
32#include <signal.h>
33
34#include <errno.h>
35
36#if defined (PREFER_STDARG)
37# include <stdarg.h>
38#else
39# include <varargs.h>
40#endif
41
42#include "../bashansi.h"
43#include "../bashintl.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)
63extern int errno;
64#endif /* !errno */
65
66extern int indirection_level, subshell_environment;
67extern int line_number;
68extern int last_command_exit_value;
69extern int running_trap;
70extern int posixly_correct;
71extern char *this_command_name, *shell_name;
72extern char *bash_getcwd_errstr;
73
74/* Used by some builtins and the mainline code. */
75sh_builtin_func_t *last_shell_builtin = (sh_builtin_func_t *)NULL;
76sh_builtin_func_t *this_shell_builtin = (sh_builtin_func_t *)NULL;
77
78/* **************************************************************** */
79/* */
80/* Error reporting, usage, and option processing */
81/* */
82/* **************************************************************** */
83
84/* This is a lot like report_error (), but it is for shell builtins
85 instead of shell control structures, and it won't ever exit the
86 shell. */
87void
88#if defined (PREFER_STDARG)
89builtin_error (const char *format, ...)
90#else
91builtin_error (format, va_alist)
92 const char *format;
93 va_dcl
94#endif
95{
96 va_list args;
97 char *name;
98
99 name = get_name_for_error ();
100 fprintf (stderr, "%s: ", name);
101
102 if (interactive_shell == 0)
103 fprintf (stderr, "line %d: ", executing_line_number ());
104
105 if (this_command_name && *this_command_name)
106 fprintf (stderr, "%s: ", this_command_name);
107
108 SH_VA_START (args, format);
109
110 vfprintf (stderr, format, args);
111 va_end (args);
112 fprintf (stderr, "\n");
113}
114
115/* Print a usage summary for the currently-executing builtin command. */
116void
117builtin_usage ()
118{
119 if (this_command_name && *this_command_name)
120 fprintf (stderr, "%s: usage: ", this_command_name);
121 fprintf (stderr, "%s\n", current_builtin->short_doc);
122 fflush (stderr);
123}
124
125/* Return if LIST is NULL else barf and jump to top_level. Used by some
126 builtins that do not accept arguments. */
127void
128no_args (list)
129 WORD_LIST *list;
130{
131 if (list)
132 {
133 builtin_error (_("too many arguments"));
134 jump_to_top_level (DISCARD);
135 }
136}
137
138/* Check that no options were given to the currently-executing builtin,
139 and return 0 if there were options. */
140int
141no_options (list)
142 WORD_LIST *list;
143{
144 reset_internal_getopt ();
145 if (internal_getopt (list, "") != -1)
146 {
147 builtin_usage ();
148 return (1);
149 }
150 return (0);
151}
152
153void
154sh_needarg (s)
155 char *s;
156{
157 builtin_error (_("%s: option requires an argument"), s);
158}
159
160void
161sh_neednumarg (s)
162 char *s;
163{
164 builtin_error (_("%s: numeric argument required"), s);
165}
166
167void
168sh_notfound (s)
169 char *s;
170{
171 builtin_error (_("%s: not found"), s);
172}
173
174/* Function called when one of the builtin commands detects an invalid
175 option. */
176void
177sh_invalidopt (s)
178 char *s;
179{
180 builtin_error (_("%s: invalid option"), s);
181}
182
183void
184sh_invalidoptname (s)
185 char *s;
186{
187 builtin_error (_("%s: invalid option name"), s);
188}
189
190void
191sh_invalidid (s)
192 char *s;
193{
194 builtin_error (_("`%s': not a valid identifier"), s);
195}
196
197void
198sh_invalidnum (s)
199 char *s;
200{
201 builtin_error (_("%s: invalid number"), s);
202}
203
204void
205sh_invalidsig (s)
206 char *s;
207{
208 builtin_error (_("%s: invalid signal specification"), s);
209}
210
211void
212sh_badpid (s)
213 char *s;
214{
215 builtin_error (_("`%s': not a pid or valid job spec"), s);
216}
217
218void
219sh_readonly (s)
220 const char *s;
221{
222 builtin_error (_("%s: readonly variable"), s);
223}
224
225void
226sh_erange (s, desc)
227 char *s, *desc;
228{
229 if (s)
230 builtin_error (_("%s: %s out of range"), s, desc ? desc : _("argument"));
231 else
232 builtin_error (_("%s out of range"), desc ? desc : _("argument"));
233}
234
235#if defined (JOB_CONTROL)
236void
237sh_badjob (s)
238 char *s;
239{
240 builtin_error (_("%s: no such job"), s);
241}
242
243void
244sh_nojobs (s)
245 char *s;
246{
247 if (s)
248 builtin_error (_("%s: no job control"), s);
249 else
250 builtin_error (_("no job control"));
251}
252#endif
253
254#if defined (RESTRICTED_SHELL)
255void
256sh_restricted (s)
257 char *s;
258{
259 if (s)
260 builtin_error (_("%s: restricted"), s);
261 else
262 builtin_error (_("restricted"));
263}
264#endif
265
266void
267sh_notbuiltin (s)
268 char *s;
269{
270 builtin_error (_("%s: not a shell builtin"), s);
271}
272
273void
274sh_wrerror ()
275{
276 builtin_error (_("write error: %s"), strerror (errno));
277}
278
279/* **************************************************************** */
280/* */
281/* Shell positional parameter manipulation */
282/* */
283/* **************************************************************** */
284
285/* Convert a WORD_LIST into a C-style argv. Return the number of elements
286 in the list in *IP, if IP is non-null. A convenience function for
287 loadable builtins; also used by `test'. */
288char **
289make_builtin_argv (list, ip)
290 WORD_LIST *list;
291 int *ip;
292{
293 char **argv;
294
295 argv = strvec_from_word_list (list, 0, 1, ip);
296 argv[0] = this_command_name;
297 return argv;
298}
299
300/* Remember LIST in $0 ... $9, and REST_OF_ARGS. If DESTRUCTIVE is
301 non-zero, then discard whatever the existing arguments are, else
302 only discard the ones that are to be replaced. */
303void
304remember_args (list, destructive)
305 WORD_LIST *list;
306 int destructive;
307{
308 register int i;
309
310 for (i = 1; i < 10; i++)
311 {
312 if ((destructive || list) && dollar_vars[i])
313 {
314 free (dollar_vars[i]);
315 dollar_vars[i] = (char *)NULL;
316 }
317
318 if (list)
319 {
320 dollar_vars[i] = savestring (list->word->word);
321 list = list->next;
322 }
323 }
324
325 /* If arguments remain, assign them to REST_OF_ARGS.
326 Note that copy_word_list (NULL) returns NULL, and
327 that dispose_words (NULL) does nothing. */
328 if (destructive || list)
329 {
330 dispose_words (rest_of_args);
331 rest_of_args = copy_word_list (list);
332 }
333
334 if (destructive)
335 set_dollar_vars_changed ();
336}
337
338static int changed_dollar_vars;
339
340/* Have the dollar variables been reset to new values since we last
341 checked? */
342int
343dollar_vars_changed ()
344{
345 return (changed_dollar_vars);
346}
347
348void
349set_dollar_vars_unchanged ()
350{
351 changed_dollar_vars = 0;
352}
353
354void
355set_dollar_vars_changed ()
356{
357 if (variable_context)
358 changed_dollar_vars |= ARGS_FUNC;
359 else if (this_shell_builtin == set_builtin)
360 changed_dollar_vars |= ARGS_SETBLTIN;
361 else
362 changed_dollar_vars |= ARGS_INVOC;
363}
364
365/* **************************************************************** */
366/* */
367/* Validating numeric input and arguments */
368/* */
369/* **************************************************************** */
370
371/* Read a numeric arg for this_command_name, the name of the shell builtin
372 that wants it. LIST is the word list that the arg is to come from.
373 Accept only the numeric argument; report an error if other arguments
374 follow. If FATAL is true, call throw_to_top_level, which exits the
375 shell; if not, call jump_to_top_level (DISCARD), which aborts the
376 current command. */
377intmax_t
378get_numeric_arg (list, fatal)
379 WORD_LIST *list;
380 int fatal;
381{
382 intmax_t count = 1;
383
384 if (list && list->word && ISOPTION (list->word->word, '-'))
385 list = list->next;
386
387 if (list)
388 {
389 register char *arg;
390
391 arg = list->word->word;
392 if (arg == 0 || (legal_number (arg, &count) == 0))
393 {
394 sh_neednumarg (list->word->word);
395 if (fatal)
396 throw_to_top_level ();
397 else
398 jump_to_top_level (DISCARD);
399 }
400 no_args (list->next);
401 }
402
403 return (count);
404}
405
406/* Get an eight-bit status value from LIST */
407int
408get_exitstat (list)
409 WORD_LIST *list;
410{
411 int status;
412 intmax_t sval;
413 char *arg;
414
415 if (list && list->word && ISOPTION (list->word->word, '-'))
416 list = list->next;
417
418 if (list == 0)
419 return (last_command_exit_value);
420
421 arg = list->word->word;
422 if (arg == 0 || legal_number (arg, &sval) == 0)
423 {
424 sh_neednumarg (list->word->word ? list->word->word : "`'");
425 return 255;
426 }
427 no_args (list->next);
428
429 status = sval & 255;
430 return status;
431}
432
433/* Return the octal number parsed from STRING, or -1 to indicate
434 that the string contained a bad number. */
435int
436read_octal (string)
437 char *string;
438{
439 int result, digits;
440
441 result = digits = 0;
442 while (*string && ISOCTAL (*string))
443 {
444 digits++;
445 result = (result * 8) + (*string++ - '0');
446 if (result > 0777)
447 return -1;
448 }
449
450 if (digits == 0 || *string)
451 result = -1;
452
453 return (result);
454}
455
456/* **************************************************************** */
457/* */
458/* Manipulating the current working directory */
459/* */
460/* **************************************************************** */
461
462/* Return a consed string which is the current working directory.
463 FOR_WHOM is the name of the caller for error printing. */
464char *the_current_working_directory = (char *)NULL;
465
466char *
467get_working_directory (for_whom)
468 char *for_whom;
469{
470 char *directory;
471 size_t dsize;
472
473 if (no_symbolic_links)
474 {
475 FREE (the_current_working_directory);
476 the_current_working_directory = (char *)NULL;
477 }
478
479 if (the_current_working_directory == 0)
480 {
481 the_current_working_directory = getcwd (0, 0);
482 if (the_current_working_directory == 0)
483 {
484 fprintf (stderr, _("%s: error retrieving current directory: %s: %s\n"),
485 (for_whom && *for_whom) ? for_whom : get_name_for_error (),
486 _(bash_getcwd_errstr), strerror (errno));
487 return (char *)NULL;
488 }
489 }
490
491 return (savestring (the_current_working_directory));
492}
493
494/* Make NAME our internal idea of the current working directory. */
495void
496set_working_directory (name)
497 char *name;
498{
499 FREE (the_current_working_directory);
500 the_current_working_directory = savestring (name);
501}
502
503/* **************************************************************** */
504/* */
505/* Job control support functions */
506/* */
507/* **************************************************************** */
508
509#if defined (JOB_CONTROL)
510int
511get_job_by_name (name, flags)
512 const char *name;
513 int flags;
514{
515 register int i, wl, cl, match, job;
516 register PROCESS *p;
517 register JOB *j;
518
519 job = NO_JOB;
520 wl = strlen (name);
521 for (i = js.j_jobslots - 1; i >= 0; i--)
522 {
523 j = get_job_by_jid (i);
524 if (j == 0 || ((flags & JM_STOPPED) && J_JOBSTATE(j) != JSTOPPED))
525 continue;
526
527 p = j->pipe;
528 do
529 {
530 if (flags & JM_EXACT)
531 {
532 cl = strlen (p->command);
533 match = STREQN (p->command, name, cl);
534 }
535 else if (flags & JM_SUBSTRING)
536 match = strindex (p->command, name) != (char *)0;
537 else
538 match = STREQN (p->command, name, wl);
539
540 if (match == 0)
541 {
542 p = p->next;
543 continue;
544 }
545 else if (flags & JM_FIRSTMATCH)
546 return i; /* return first match */
547 else if (job != NO_JOB)
548 {
549 if (this_shell_builtin)
550 builtin_error (_("%s: ambiguous job spec"), name);
551 else
552 report_error (_("%s: ambiguous job spec"), name);
553 return (DUP_JOB);
554 }
555 else
556 job = i;
557 }
558 while (p != j->pipe);
559 }
560
561 return (job);
562}
563
564/* Return the job spec found in LIST. */
565int
566get_job_spec (list)
567 WORD_LIST *list;
568{
569 register char *word;
570 int job, jflags;
571
572 if (list == 0)
573 return (js.j_current);
574
575 word = list->word->word;
576
577 if (*word == '\0')
578 return (NO_JOB);
579
580 if (*word == '%')
581 word++;
582
583 if (DIGIT (*word) && all_digits (word))
584 {
585 job = atoi (word);
586 return (job > js.j_jobslots ? NO_JOB : job - 1);
587 }
588
589 jflags = 0;
590 switch (*word)
591 {
592 case 0:
593 case '%':
594 case '+':
595 return (js.j_current);
596
597 case '-':
598 return (js.j_previous);
599
600 case '?': /* Substring search requested. */
601 jflags |= JM_SUBSTRING;
602 word++;
603 /* FALLTHROUGH */
604
605 default:
606 return get_job_by_name (word, jflags);
607 }
608}
609#endif /* JOB_CONTROL */
610
611/*
612 * NOTE: `kill' calls this function with forcecols == 0
613 */
614int
615display_signal_list (list, forcecols)
616 WORD_LIST *list;
617 int forcecols;
618{
619 register int i, column;
620 char *name;
621 int result, signum, dflags;
622 intmax_t lsignum;
623
624 result = EXECUTION_SUCCESS;
625 if (!list)
626 {
627 for (i = 1, column = 0; i < NSIG; i++)
628 {
629 name = signal_name (i);
630 if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7))
631 continue;
632
633 if (posixly_correct && !forcecols)
634 {
635 /* This is for the kill builtin. POSIX.2 says the signal names
636 are displayed without the `SIG' prefix. */
637 if (STREQN (name, "SIG", 3))
638 name += 3;
639 printf ("%s%s", name, (i == NSIG - 1) ? "" : " ");
640 }
641 else
642 {
643 printf ("%2d) %s", i, name);
644
645 if (++column < 4)
646 printf ("\t");
647 else
648 {
649 printf ("\n");
650 column = 0;
651 }
652 }
653 }
654
655 if ((posixly_correct && !forcecols) || column != 0)
656 printf ("\n");
657 return result;
658 }
659
660 /* List individual signal names or numbers. */
661 while (list)
662 {
663 if (legal_number (list->word->word, &lsignum))
664 {
665 /* This is specified by Posix.2 so that exit statuses can be
666 mapped into signal numbers. */
667 if (lsignum > 128)
668 lsignum -= 128;
669 if (lsignum < 0 || lsignum >= NSIG)
670 {
671 sh_invalidsig (list->word->word);
672 result = EXECUTION_FAILURE;
673 list = list->next;
674 continue;
675 }
676
677 signum = lsignum;
678 name = signal_name (signum);
679 if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7))
680 {
681 list = list->next;
682 continue;
683 }
684#if defined (JOB_CONTROL)
685 /* POSIX.2 says that `kill -l signum' prints the signal name without
686 the `SIG' prefix. */
687 printf ("%s\n", (this_shell_builtin == kill_builtin) ? name + 3 : name);
688#else
689 printf ("%s\n", name);
690#endif
691 }
692 else
693 {
694 dflags = DSIG_NOCASE;
695 if (posixly_correct == 0 || this_shell_builtin != kill_builtin)
696 dflags |= DSIG_SIGPREFIX;
697 signum = decode_signal (list->word->word, dflags);
698 if (signum == NO_SIG)
699 {
700 sh_invalidsig (list->word->word);
701 result = EXECUTION_FAILURE;
702 list = list->next;
703 continue;
704 }
705 printf ("%d\n", signum);
706 }
707 list = list->next;
708 }
709 return (result);
710}
711
712/* **************************************************************** */
713/* */
714/* Finding builtin commands and their functions */
715/* */
716/* **************************************************************** */
717
718/* Perform a binary search and return the address of the builtin function
719 whose name is NAME. If the function couldn't be found, or the builtin
720 is disabled or has no function associated with it, return NULL.
721 Return the address of the builtin.
722 DISABLED_OKAY means find it even if the builtin is disabled. */
723struct builtin *
724builtin_address_internal (name, disabled_okay)
725 char *name;
726 int disabled_okay;
727{
728 int hi, lo, mid, j;
729
730 hi = num_shell_builtins - 1;
731 lo = 0;
732
733 while (lo <= hi)
734 {
735 mid = (lo + hi) / 2;
736
737 j = shell_builtins[mid].name[0] - name[0];
738
739 if (j == 0)
740 j = strcmp (shell_builtins[mid].name, name);
741
742 if (j == 0)
743 {
744 /* It must have a function pointer. It must be enabled, or we
745 must have explicitly allowed disabled functions to be found,
746 and it must not have been deleted. */
747 if (shell_builtins[mid].function &&
748 ((shell_builtins[mid].flags & BUILTIN_DELETED) == 0) &&
749 ((shell_builtins[mid].flags & BUILTIN_ENABLED) || disabled_okay))
750 return (&shell_builtins[mid]);
751 else
752 return ((struct builtin *)NULL);
753 }
754 if (j > 0)
755 hi = mid - 1;
756 else
757 lo = mid + 1;
758 }
759 return ((struct builtin *)NULL);
760}
761
762/* Return the pointer to the function implementing builtin command NAME. */
763sh_builtin_func_t *
764find_shell_builtin (name)
765 char *name;
766{
767 current_builtin = builtin_address_internal (name, 0);
768 return (current_builtin ? current_builtin->function : (sh_builtin_func_t *)NULL);
769}
770
771/* Return the address of builtin with NAME, whether it is enabled or not. */
772sh_builtin_func_t *
773builtin_address (name)
774 char *name;
775{
776 current_builtin = builtin_address_internal (name, 1);
777 return (current_builtin ? current_builtin->function : (sh_builtin_func_t *)NULL);
778}
779
780/* Return the function implementing the builtin NAME, but only if it is a
781 POSIX.2 special builtin. */
782sh_builtin_func_t *
783find_special_builtin (name)
784 char *name;
785{
786 current_builtin = builtin_address_internal (name, 0);
787 return ((current_builtin && (current_builtin->flags & SPECIAL_BUILTIN)) ?
788 current_builtin->function :
789 (sh_builtin_func_t *)NULL);
790}
791
792static int
793shell_builtin_compare (sbp1, sbp2)
794 struct builtin *sbp1, *sbp2;
795{
796 int result;
797
798 if ((result = sbp1->name[0] - sbp2->name[0]) == 0)
799 result = strcmp (sbp1->name, sbp2->name);
800
801 return (result);
802}
803
804/* Sort the table of shell builtins so that the binary search will work
805 in find_shell_builtin. */
806void
807initialize_shell_builtins ()
808{
809 qsort (shell_builtins, num_shell_builtins, sizeof (struct builtin),
810 (QSFUNC *)shell_builtin_compare);
811}
Note: See TracBrowser for help on using the repository browser.