Imported from ../bash-2.05.tar.gz.
[platform/upstream/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 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 "../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 #ifdef __STDC__
67 typedef int QSFUNC (const void *, const void *);
68 #else
69 typedef int QSFUNC ();
70 #endif 
71
72 extern int no_symbolic_links, interactive, interactive_shell;
73 extern int indirection_level, startup_state, subshell_environment;
74 extern int line_number;
75 extern int last_command_exit_value;
76 extern int running_trap;
77 extern int variable_context;
78 extern int posixly_correct;
79 extern char *this_command_name, *shell_name;
80 extern COMMAND *global_command;
81 extern char *bash_getcwd_errstr;
82
83 /* Used by some builtins and the mainline code. */
84 Function *last_shell_builtin = (Function *)NULL;
85 Function *this_shell_builtin = (Function *)NULL;
86
87 /* **************************************************************** */
88 /*                                                                  */
89 /*           Error reporting, usage, and option processing          */
90 /*                                                                  */
91 /* **************************************************************** */
92
93 /* This is a lot like report_error (), but it is for shell builtins
94    instead of shell control structures, and it won't ever exit the
95    shell. */
96 #if defined (USE_VARARGS)
97 void
98 #if defined (PREFER_STDARG)
99 builtin_error (const char *format, ...)
100 #else
101 builtin_error (format, va_alist)
102      const char *format;
103      va_dcl
104 #endif
105 {
106   va_list args;
107   char *name;
108
109   name = get_name_for_error ();
110   fprintf (stderr, "%s: ", name);
111
112   if (this_command_name && *this_command_name)
113     fprintf (stderr, "%s: ", this_command_name);
114
115 #if defined (PREFER_STDARG)
116   va_start (args, format);
117 #else
118   va_start (args);
119 #endif
120
121   vfprintf (stderr, format, args);
122   va_end (args);
123   fprintf (stderr, "\n");
124 }
125 #else /* !USE_VARARGS */
126 void
127 builtin_error (format, arg1, arg2, arg3, arg4, arg5)
128      char *format, *arg1, *arg2, *arg3, *arg4, *arg5;
129 {
130   if (this_command_name && *this_command_name)
131     fprintf (stderr, "%s: ", this_command_name);
132
133   fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5);
134   fprintf (stderr, "\n");
135   fflush (stderr);
136 }
137 #endif /* !USE_VARARGS */
138
139 /* Print a usage summary for the currently-executing builtin command. */
140 void
141 builtin_usage ()
142 {
143   if (this_command_name && *this_command_name)
144     fprintf (stderr, "%s: usage: ", this_command_name);
145   fprintf (stderr, "%s\n", current_builtin->short_doc);
146   fflush (stderr);
147 }
148
149 /* Return if LIST is NULL else barf and jump to top_level.  Used by some
150    builtins that do not accept arguments. */
151 void
152 no_args (list)
153      WORD_LIST *list;
154 {
155   if (list)
156     {
157       builtin_error ("too many arguments");
158       jump_to_top_level (DISCARD);
159     }
160 }
161
162 /* Function called when one of the builtin commands detects a bad
163    option. */
164 void
165 bad_option (s)
166      char *s;
167 {
168   builtin_error ("unknown option: %s", s);
169 }
170
171 /* Check that no options were given to the currently-executing builtin,
172    and return 0 if there were options. */
173 int
174 no_options (list)
175      WORD_LIST *list;
176 {
177   reset_internal_getopt ();
178   if (internal_getopt (list, "") != -1)
179     {
180       builtin_usage ();
181       return (1);
182     }
183   return (0);
184 }
185
186 /* **************************************************************** */
187 /*                                                                  */
188 /*           Shell positional parameter manipulation                */
189 /*                                                                  */
190 /* **************************************************************** */
191
192 /* Convert a WORD_LIST into a C-style argv.  Return the number of elements
193    in the list in *IP, if IP is non-null.  A convenience function for
194    loadable builtins; also used by `test'. */
195 char **
196 make_builtin_argv (list, ip)
197      WORD_LIST *list;
198      int *ip;
199 {
200   char **argv;
201
202   argv = word_list_to_argv (list, 0, 1, ip);
203   argv[0] = this_command_name;
204   return argv;
205 }
206
207 /* Remember LIST in $0 ... $9, and REST_OF_ARGS.  If DESTRUCTIVE is
208    non-zero, then discard whatever the existing arguments are, else
209    only discard the ones that are to be replaced. */
210 void
211 remember_args (list, destructive)
212      WORD_LIST *list;
213      int destructive;
214 {
215   register int i;
216
217   for (i = 1; i < 10; i++)
218     {
219       if ((destructive || list) && dollar_vars[i])
220         {
221           free (dollar_vars[i]);
222           dollar_vars[i] = (char *)NULL;
223         }
224
225       if (list)
226         {
227           dollar_vars[i] = savestring (list->word->word);
228           list = list->next;
229         }
230     }
231
232   /* If arguments remain, assign them to REST_OF_ARGS.
233      Note that copy_word_list (NULL) returns NULL, and
234      that dispose_words (NULL) does nothing. */
235   if (destructive || list)
236     {
237       dispose_words (rest_of_args);
238       rest_of_args = copy_word_list (list);
239     }
240
241   if (destructive)
242     set_dollar_vars_changed ();
243 }
244
245 /* **************************************************************** */
246 /*                                                                  */
247 /*               Pushing and Popping variable contexts              */
248 /*                                                                  */
249 /* **************************************************************** */
250
251 static WORD_LIST **dollar_arg_stack = (WORD_LIST **)NULL;
252 static int dollar_arg_stack_slots;
253 static int dollar_arg_stack_index;
254
255 void
256 push_context ()
257 {
258   push_dollar_vars ();
259   variable_context++;
260 }
261
262 void
263 pop_context ()
264 {
265   pop_dollar_vars ();
266   kill_all_local_variables ();
267   variable_context--;
268 }
269
270 /* Save the existing positional parameters on a stack. */
271 void
272 push_dollar_vars ()
273 {
274   if (dollar_arg_stack_index + 2 > dollar_arg_stack_slots)
275     {
276       dollar_arg_stack = (WORD_LIST **)
277         xrealloc (dollar_arg_stack, (dollar_arg_stack_slots += 10)
278                   * sizeof (WORD_LIST **));
279     }
280   dollar_arg_stack[dollar_arg_stack_index++] = list_rest_of_args ();
281   dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
282 }
283
284 /* Restore the positional parameters from our stack. */
285 void
286 pop_dollar_vars ()
287 {
288   if (!dollar_arg_stack || dollar_arg_stack_index == 0)
289     return;
290
291   remember_args (dollar_arg_stack[--dollar_arg_stack_index], 1);
292   dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
293   dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
294 }
295
296 void
297 dispose_saved_dollar_vars ()
298 {
299   if (!dollar_arg_stack || dollar_arg_stack_index == 0)
300     return;
301
302   dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
303   dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
304 }
305
306 static int changed_dollar_vars;
307
308 /* Have the dollar variables been reset to new values since we last
309    checked? */
310 int
311 dollar_vars_changed ()
312 {
313   return (changed_dollar_vars);
314 }
315
316 void
317 set_dollar_vars_unchanged ()
318 {
319   changed_dollar_vars = 0;
320 }
321
322 void
323 set_dollar_vars_changed ()
324 {
325   changed_dollar_vars = 1;
326 }
327
328 /* **************************************************************** */
329 /*                                                                  */
330 /*              Validating numeric input and arguments              */
331 /*                                                                  */
332 /* **************************************************************** */
333
334 /* Read a numeric arg for this_command_name, the name of the shell builtin
335    that wants it.  LIST is the word list that the arg is to come from.
336    Accept only the numeric argument; report an error if other arguments
337    follow.  If FATAL is true, call throw_to_top_level, which exits the
338    shell; if not, call jump_to_top_level (DISCARD), which aborts the
339    current command. */
340 int
341 get_numeric_arg (list, fatal)
342      WORD_LIST *list;
343      int fatal;
344 {
345   long count = 1;
346
347   if (list)
348     {
349       register char *arg;
350
351       arg = list->word->word;
352       if (!arg || (legal_number (arg, &count) == 0))
353         {
354           builtin_error ("bad non-numeric arg `%s'", list->word->word);
355           if (fatal)
356             throw_to_top_level ();
357           else
358             jump_to_top_level (DISCARD);
359         }
360       no_args (list->next);
361     }
362   return (count);
363 }
364
365 /* Return the octal number parsed from STRING, or -1 to indicate
366    that the string contained a bad number. */
367 int
368 read_octal (string)
369      char *string;
370 {
371   int result, digits;
372
373   result = digits = 0;
374   while (*string && ISOCTAL (*string))
375     {
376       digits++;
377       result = (result * 8) + (*string++ - '0');
378     }
379
380   if (!digits || result > 0777 || *string)
381     result = -1;
382
383   return (result);
384 }
385
386 /* **************************************************************** */
387 /*                                                                  */
388 /*           Manipulating the current working directory             */
389 /*                                                                  */
390 /* **************************************************************** */
391
392 /* Return a consed string which is the current working directory.
393    FOR_WHOM is the name of the caller for error printing.  */
394 char *the_current_working_directory = (char *)NULL;
395
396 char *
397 get_working_directory (for_whom)
398      char *for_whom;
399 {
400   char *directory;
401
402   if (no_symbolic_links)
403     {
404       if (the_current_working_directory)
405         free (the_current_working_directory);
406
407       the_current_working_directory = (char *)NULL;
408     }
409
410   if (the_current_working_directory == 0)
411     {
412       the_current_working_directory = xmalloc (PATH_MAX);
413       the_current_working_directory[0] = '\0';
414       directory = getcwd (the_current_working_directory, PATH_MAX);
415       if (directory == 0)
416         {
417           fprintf (stderr, "%s: could not get current directory: %s: %s\n",
418                    (for_whom && *for_whom) ? for_whom : get_name_for_error (),
419                    bash_getcwd_errstr, strerror (errno));
420
421           free (the_current_working_directory);
422           the_current_working_directory = (char *)NULL;
423           return (char *)NULL;
424         }
425     }
426
427   return (savestring (the_current_working_directory));
428 }
429
430 /* Make NAME our internal idea of the current working directory. */
431 void
432 set_working_directory (name)
433      char *name;
434 {
435   FREE (the_current_working_directory);
436   the_current_working_directory = savestring (name);
437 }
438
439 /* **************************************************************** */
440 /*                                                                  */
441 /*              Job control support functions                       */
442 /*                                                                  */
443 /* **************************************************************** */
444
445 #if defined (JOB_CONTROL)
446 /* Return the job spec found in LIST. */
447 int
448 get_job_spec (list)
449      WORD_LIST *list;
450 {
451   register char *word;
452   int job, substring;
453
454   if (list == 0)
455     return (current_job);
456
457   word = list->word->word;
458
459   if (*word == '\0')
460     return (current_job);
461
462   if (*word == '%')
463     word++;
464
465   if (digit (*word) && all_digits (word))
466     {
467       job = atoi (word);
468       return (job >= job_slots ? NO_JOB : job - 1);
469     }
470
471   substring = 0;
472   switch (*word)
473     {
474     case 0:
475     case '%':
476     case '+':
477       return (current_job);
478
479     case '-':
480       return (previous_job);
481
482     case '?':                   /* Substring search requested. */
483       substring++;
484       word++;
485       /* FALLTHROUGH */
486
487     default:
488       {
489         register int i, wl;
490
491         job = NO_JOB;
492         wl = strlen (word);
493         for (i = 0; i < job_slots; i++)
494           {
495             if (jobs[i])
496               {
497                 register PROCESS *p;
498                 p = jobs[i]->pipe;
499                 do
500                   {
501                     if ((substring && strindex (p->command, word)) ||
502                         (STREQN (p->command, word, wl)))
503                       if (job != NO_JOB)
504                         {
505                           builtin_error ("ambigious job spec: %s", word);
506                           return (DUP_JOB);
507                         }
508                       else
509                         job = i;
510
511                     p = p->next;
512                   }
513                 while (p != jobs[i]->pipe);
514               }
515           }
516         return (job);
517       }
518     }
519 }
520 #endif /* JOB_CONTROL */
521
522 int
523 display_signal_list (list, forcecols)
524      WORD_LIST *list;
525      int forcecols;
526 {
527   register int i, column;
528   char *name;
529   int result;
530   long signum;
531
532   result = EXECUTION_SUCCESS;
533   if (!list)
534     {
535       for (i = 1, column = 0; i < NSIG; i++)
536         {
537           name = signal_name (i);
538           if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7))
539             continue;
540
541           if (posixly_correct && !forcecols)
542             printf ("%s%s", name, (i == NSIG - 1) ? "" : " ");
543           else
544             {
545               printf ("%2d) %s", i, name);
546
547               if (++column < 4)
548                 printf ("\t");
549               else
550                 {
551                   printf ("\n");
552                   column = 0;
553                 }
554             }
555         }
556
557       if ((posixly_correct && !forcecols) || column != 0)
558         printf ("\n");
559       return result;
560     }
561
562   /* List individual signal names or numbers. */
563   while (list)
564     {
565       if (legal_number (list->word->word, &signum))
566         {
567           /* This is specified by Posix.2 so that exit statuses can be
568              mapped into signal numbers. */
569           if (signum > 128)
570             signum -= 128;
571           if (signum < 0 || signum >= NSIG)
572             {
573               builtin_error ("bad signal number: %s", list->word->word);
574               result = EXECUTION_FAILURE;
575               list = list->next;
576               continue;
577             }
578
579           name = signal_name (signum);
580           if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7))
581             {
582               list = list->next;
583               continue;
584             }
585 #if defined (JOB_CONTROL)
586           /* POSIX.2 says that `kill -l signum' prints the signal name without
587              the `SIG' prefix. */
588           printf ("%s\n", (this_shell_builtin == kill_builtin) ? name + 3 : name);
589 #else
590           printf ("%s\n", name);
591 #endif
592         }
593       else
594         {
595           signum = decode_signal (list->word->word);
596           if (signum == NO_SIG)
597             {
598               builtin_error ("%s: not a signal specification", list->word->word);
599               result = EXECUTION_FAILURE;
600               list = list->next;
601               continue;
602             }
603           printf ("%ld\n", signum);
604         }
605       list = list->next;
606     }
607   return (result);
608 }
609
610 /* **************************************************************** */
611 /*                                                                  */
612 /*          Finding builtin commands and their functions            */
613 /*                                                                  */
614 /* **************************************************************** */
615
616 /* Perform a binary search and return the address of the builtin function
617    whose name is NAME.  If the function couldn't be found, or the builtin
618    is disabled or has no function associated with it, return NULL.
619    Return the address of the builtin.
620    DISABLED_OKAY means find it even if the builtin is disabled. */
621 struct builtin *
622 builtin_address_internal (name, disabled_okay)
623      char *name;
624      int disabled_okay;
625 {
626   int hi, lo, mid, j;
627
628   hi = num_shell_builtins - 1;
629   lo = 0;
630
631   while (lo <= hi)
632     {
633       mid = (lo + hi) / 2;
634
635       j = shell_builtins[mid].name[0] - name[0];
636
637       if (j == 0)
638         j = strcmp (shell_builtins[mid].name, name);
639
640       if (j == 0)
641         {
642           /* It must have a function pointer.  It must be enabled, or we
643              must have explicitly allowed disabled functions to be found,
644              and it must not have been deleted. */
645           if (shell_builtins[mid].function &&
646               ((shell_builtins[mid].flags & BUILTIN_DELETED) == 0) &&
647               ((shell_builtins[mid].flags & BUILTIN_ENABLED) || disabled_okay))
648             return (&shell_builtins[mid]);
649           else
650             return ((struct builtin *)NULL);
651         }
652       if (j > 0)
653         hi = mid - 1;
654       else
655         lo = mid + 1;
656     }
657   return ((struct builtin *)NULL);
658 }
659
660 /* Return the pointer to the function implementing builtin command NAME. */
661 Function *
662 find_shell_builtin (name)
663      char *name;
664 {
665   current_builtin = builtin_address_internal (name, 0);
666   return (current_builtin ? current_builtin->function : (Function *)NULL);
667 }
668
669 /* Return the address of builtin with NAME, whether it is enabled or not. */
670 Function *
671 builtin_address (name)
672      char *name;
673 {
674   current_builtin = builtin_address_internal (name, 1);
675   return (current_builtin ? current_builtin->function : (Function *)NULL);
676 }
677
678 /* Return the function implementing the builtin NAME, but only if it is a
679    POSIX.2 special builtin. */
680 Function *
681 find_special_builtin (name)
682      char *name;
683 {
684   current_builtin = builtin_address_internal (name, 0);
685   return ((current_builtin && (current_builtin->flags & SPECIAL_BUILTIN)) ?
686                         current_builtin->function :
687                         (Function *)NULL);
688 }
689   
690 static int
691 shell_builtin_compare (sbp1, sbp2)
692      struct builtin *sbp1, *sbp2;
693 {
694   int result;
695
696   if ((result = sbp1->name[0] - sbp2->name[0]) == 0)
697     result = strcmp (sbp1->name, sbp2->name);
698
699   return (result);
700 }
701
702 /* Sort the table of shell builtins so that the binary search will work
703    in find_shell_builtin. */
704 void
705 initialize_shell_builtins ()
706 {
707   qsort (shell_builtins, num_shell_builtins, sizeof (struct builtin),
708     (QSFUNC *)shell_builtin_compare);
709 }