1 /* general.c -- Stuff that is used by all files. */
3 /* Copyright (C) 1987-2002 Free Software Foundation, Inc.
5 This file is part of GNU Bash, the Bourne Again SHell.
7 Bash is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License along
18 with Bash; see the file COPYING. If not, write to the Free Software
19 Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
23 #include "bashtypes.h"
25 # include <sys/param.h>
27 #include "posixstat.h"
29 #if defined (HAVE_UNISTD_H)
36 #include "chartypes.h"
40 #include <tilde/tilde.h>
46 extern int expand_aliases;
47 extern int interrupt_immediately;
48 extern int interactive_comments;
49 extern int check_hashed_filenames;
50 extern int source_uses_path;
51 extern int source_searches_cwd;
53 static char *bash_special_tilde_expansions __P((char *));
54 static int unquoted_tilde_word __P((const char *));
55 static void initialize_group_array __P((void));
57 /* A standard error message to use when getcwd() returns NULL. */
58 char *bash_getcwd_errstr = "getcwd: cannot access parent directories";
60 /* Do whatever is necessary to initialize `Posix mode'. */
65 /* Things that should be turned on when posix mode is enabled. */
68 interactive_comments = source_uses_path = expand_aliases = 1;
71 /* Things that should be turned on when posix mode is disabled. */
74 source_searches_cwd = 1;
75 expand_aliases = interactive_shell;
79 /* **************************************************************** */
81 /* Functions to convert to and from and display non-standard types */
83 /* **************************************************************** */
85 #if defined (RLIMTYPE)
87 string_to_rlimtype (s)
95 while (s && *s && whitespace (*s))
97 if (*s == '-' || *s == '+')
102 for ( ; s && *s && DIGIT (*s); s++)
103 ret = (ret * 10) + TODIGIT (*s);
104 return (neg ? -ret : ret);
108 print_rlimtype (n, addnl)
112 char s[INT_STRLEN_BOUND (RLIMTYPE) + 1], *p;
121 while ((n /= 10) != 0);
129 while ((n /= 10) != 0);
132 printf ("%s%s", p, addnl ? "\n" : "");
134 #endif /* RLIMTYPE */
136 /* **************************************************************** */
138 /* Input Validation Functions */
140 /* **************************************************************** */
142 /* Return non-zero if all of the characters in STRING are digits. */
149 for (s = string; *s; s++)
156 /* Return non-zero if the characters pointed to by STRING constitute a
157 valid number. Stuff the converted number into RESULT if RESULT is
160 legal_number (string, result)
171 value = strtoimax (string, &ep, 10);
173 return 0; /* errno is set on overflow or underflow */
175 /* Skip any trailing whitespace, since strtoimax does not. */
176 while (whitespace (*ep))
179 /* If *string is not '\0' but *ep is '\0' on return, the entire string
181 if (string && *string && *ep == '\0')
185 /* The SunOS4 implementation of strtol() will happily ignore
186 overflow conditions, so this cannot do overflow correctly
194 /* Return 1 if this token is a legal shell `identifier'; that is, it consists
195 solely of letters, digits, and underscores, and does not begin with a
198 legal_identifier (name)
204 if (!name || !(c = *name) || (legal_variable_starter (c) == 0))
207 for (s = name + 1; (c = *s) != 0; s++)
209 if (legal_variable_char (c) == 0)
215 /* Make sure that WORD is a valid shell identifier, i.e.
216 does not contain a dollar sign, nor is quoted in any way. Nor
217 does it consist of all digits. If CHECK_WORD is non-zero,
218 the word is checked to ensure that it consists of only letters,
219 digits, and underscores. */
221 check_identifier (word, check_word)
225 if ((word->flags & (W_HASDOLLAR|W_QUOTED)) || all_digits (word->word))
227 internal_error ("`%s': not a valid identifier", word->word);
230 else if (check_word && legal_identifier (word->word) == 0)
232 internal_error ("`%s': not a valid identifier", word->word);
239 /* Returns non-zero if STRING is an assignment statement. The returned value
240 is the index of the `=' sign. */
245 register unsigned char c;
246 register int newi, indx;
248 c = string[indx = 0];
250 if (legal_variable_starter (c) == 0)
253 while (c = string[indx])
255 /* The following is safe. Note that '=' at the start of a word
256 is not an assignment statement. */
260 #if defined (ARRAY_VARS)
263 newi = skipsubscript (string, indx);
264 if (string[newi++] != ']')
266 return ((string[newi] == '=') ? newi : 0);
268 #endif /* ARRAY_VARS */
270 /* Variable names in assignment statements may contain only letters,
272 if (legal_variable_char (c) == 0)
280 /* **************************************************************** */
282 /* Functions to manage files and file descriptors */
284 /* **************************************************************** */
286 /* A function to unset no-delay mode on a file descriptor. Used in shell.c
287 to unset it on the fd passed as stdin. Should be called on stdin if
288 readline gets an EAGAIN or EWOULDBLOCK when trying to read input. */
290 #if !defined (O_NDELAY)
291 # if defined (FNDELAY)
292 # define O_NDELAY FNDELAY
294 #endif /* O_NDELAY */
296 /* Make sure no-delay mode is not set on file descriptor FD. */
298 sh_unset_nodelay_mode (fd)
303 if ((flags = fcntl (fd, F_GETFL, 0)) < 0)
308 /* This is defined to O_NDELAY in filecntl.h if O_NONBLOCK is not present
309 and O_NDELAY is defined. */
311 bflags |= O_NONBLOCK;
321 return (fcntl (fd, F_SETFL, flags));
327 /* Return 1 if file descriptor FD is valid; 0 otherwise. */
332 return (fcntl (fd, F_GETFD, 0) >= 0);
335 /* There is a bug in the NeXT 2.1 rlogind that causes opens
336 of /dev/tty to fail. */
338 #if defined (__BEOS__)
339 /* On BeOS, opening in non-blocking mode exposes a bug in BeOS, so turn it
340 into a no-op. This should probably go away in the future. */
342 # define O_NONBLOCK 0
343 #endif /* __BEOS__ */
351 tty_fd = open ("/dev/tty", O_RDWR|O_NONBLOCK);
355 tty = (char *)ttyname (fileno (stdin));
358 tty_fd = open (tty, O_RDWR|O_NONBLOCK);
363 /* Return 1 if PATH1 and PATH2 are the same file. This is kind of
364 expensive. If non-NULL STP1 and STP2 point to stat structures
365 corresponding to PATH1 and PATH2, respectively. */
367 same_file (path1, path2, stp1, stp2)
369 struct stat *stp1, *stp2;
371 struct stat st1, st2;
375 if (stat (path1, &st1) != 0)
382 if (stat (path2, &st2) != 0)
387 return ((stp1->st_dev == stp2->st_dev) && (stp1->st_ino == stp2->st_ino));
390 /* Move FD to a number close to the maximum number of file descriptors
391 allowed in the shell process, to avoid the user stepping on it with
392 redirection and causing us extra work. If CHECK_NEW is non-zero,
393 we check whether or not the file descriptors are in use before
394 duplicating FD onto them. MAXFD says where to start checking the
395 file descriptors. If it's less than 20, we get the maximum value
396 available from getdtablesize(2). */
398 move_to_high_fd (fd, check_new, maxfd)
399 int fd, check_new, maxfd;
401 int script_fd, nfds, ignore;
405 nfds = getdtablesize ();
408 if (nfds > HIGH_FD_MAX)
409 nfds = HIGH_FD_MAX; /* reasonable maximum */
414 for (nfds--; check_new && nfds > 3; nfds--)
415 if (fcntl (nfds, F_GETFD, &ignore) == -1)
418 if (nfds > 3 && fd != nfds && (script_fd = dup2 (fd, nfds)) != -1)
420 if (check_new == 0 || fd != fileno (stderr)) /* don't close stderr */
425 /* OK, we didn't find one less than our artificial maximum; return the
426 original file descriptor. */
430 /* Return non-zero if the characters from SAMPLE are not all valid
431 characters to be found in the first line of a shell script. We
432 check up to the first newline, or SAMPLE_LEN, whichever comes first.
433 All of the characters must be printable or whitespace. */
436 check_binary_file (sample, sample_len)
443 for (i = 0; i < sample_len; i++)
449 if (ISSPACE (c) == 0 && ISPRINT (c) == 0)
456 /* **************************************************************** */
458 /* Functions to manipulate pathnames */
460 /* **************************************************************** */
462 /* Turn STRING (a pathname) into an absolute pathname, assuming that
463 DOT_PATH contains the symbolic location of `.'. This always
464 returns a new string, even if STRING was an absolute pathname to
467 make_absolute (string, dot_path)
468 char *string, *dot_path;
472 if (dot_path == 0 || ABSPATH(string))
473 result = savestring (string);
475 result = sh_makepath (dot_path, string, 0);
480 /* Return 1 if STRING contains an absolute pathname, else 0. Used by `cd'
481 to decide whether or not to look up a directory name in $CDPATH. */
483 absolute_pathname (string)
486 if (string == 0 || *string == '\0')
492 if (string[0] == '.' && PATHSEP(string[1])) /* . and ./ */
495 if (string[0] == '.' && string[1] == '.' && PATHSEP(string[2])) /* .. and ../ */
501 /* Return 1 if STRING is an absolute program name; it is absolute if it
502 contains any slashes. This is used to decide whether or not to look
505 absolute_program (string)
508 return ((char *)xstrchr (string, '/') != (char *)NULL);
511 /* Return the `basename' of the pathname in STRING (the stuff after the
512 last '/'). If STRING is not a full pathname, simply return it. */
514 base_pathname (string)
519 if (absolute_pathname (string) == 0)
522 p = (char *)strrchr (string, '/');
523 return (p ? ++p : string);
526 /* Return the full pathname of FILE. Easy. Filenames that begin
527 with a '/' are returned as themselves. Other filenames have
528 the current working directory prepended. A new string is
529 returned in either case. */
536 file = (*file == '~') ? bash_tilde_expand (file, 0) : savestring (file);
541 ret = sh_makepath ((char *)NULL, file, (MP_DOCWD|MP_RMDOT));
547 /* A slightly related function. Get the prettiest name of this
548 directory possible. */
549 static char tdir[PATH_MAX];
551 /* Return a pretty pathname. If the first part of the pathname is
552 the same as $HOME, then replace that with `~'. */
554 polite_directory_format (name)
560 home = get_string_value ("HOME");
561 l = home ? strlen (home) : 0;
562 if (l > 1 && strncmp (home, name, l) == 0 && (!name[l] || name[l] == '/'))
564 strncpy (tdir + 1, name + l, sizeof(tdir) - 2);
566 tdir[sizeof(tdir) - 1] = '\0';
573 /* Given a string containing units of information separated by colons,
574 return the next one pointed to by (P_INDEX), or NULL if there are no more.
575 Advance (P_INDEX) to the character after the colon. */
577 extract_colon_unit (string, p_index)
587 len = strlen (string);
589 return ((char *)NULL);
593 /* Each call to this routine leaves the index pointing at a colon if
594 there is more to the path. If I is > 0, then increment past the
595 `:'. If I is 0, then the path has a leading colon. Trailing colons
596 are handled OK by the `else' part of the if statement; an empty
597 string is returned in that case. */
598 if (i && string[i] == ':')
601 for (start = i; string[i] && string[i] != ':'; i++)
610 /* Return "" in the case of a trailing `:'. */
611 value = (char *)xmalloc (1);
615 value = substring (string, start, i);
620 /* **************************************************************** */
622 /* Tilde Initialization and Expansion */
624 /* **************************************************************** */
626 #if defined (PUSHD_AND_POPD)
627 extern char *get_dirstack_from_string __P((char *));
630 static char **bash_tilde_prefixes;
631 static char **bash_tilde_suffixes;
633 /* If tilde_expand hasn't been able to expand the text, perhaps it
634 is a special shell expansion. This function is installed as the
635 tilde_expansion_preexpansion_hook. It knows how to expand ~- and ~+.
636 If PUSHD_AND_POPD is defined, ~[+-]N expands to directories from the
639 bash_special_tilde_expansions (text)
644 result = (char *)NULL;
646 if (text[0] == '+' && text[1] == '\0')
647 result = get_string_value ("PWD");
648 else if (text[0] == '-' && text[1] == '\0')
649 result = get_string_value ("OLDPWD");
650 #if defined (PUSHD_AND_POPD)
651 else if (DIGIT (*text) || ((*text == '+' || *text == '-') && DIGIT (text[1])))
652 result = get_dirstack_from_string (text);
655 return (result ? savestring (result) : (char *)NULL);
658 /* Initialize the tilde expander. In Bash, we handle `~-' and `~+', as
659 well as handling special tilde prefixes; `:~" and `=~' are indications
660 that we should do tilde expansion. */
664 static int times_called = 0;
666 /* Tell the tilde expander that we want a crack first. */
667 tilde_expansion_preexpansion_hook = bash_special_tilde_expansions;
669 /* Tell the tilde expander about special strings which start a tilde
670 expansion, and the special strings that end one. Only do this once.
671 tilde_initialize () is called from within bashline_reinitialize (). */
672 if (times_called++ == 0)
674 bash_tilde_prefixes = strvec_create (3);
675 bash_tilde_prefixes[0] = "=~";
676 bash_tilde_prefixes[1] = ":~";
677 bash_tilde_prefixes[2] = (char *)NULL;
679 tilde_additional_prefixes = bash_tilde_prefixes;
681 bash_tilde_suffixes = strvec_create (3);
682 bash_tilde_suffixes[0] = ":";
683 bash_tilde_suffixes[1] = "=~"; /* XXX - ?? */
684 bash_tilde_suffixes[2] = (char *)NULL;
686 tilde_additional_suffixes = bash_tilde_suffixes;
690 /* POSIX.2, 3.6.1: A tilde-prefix consists of an unquoted tilde character
691 at the beginning of the word, followed by all of the characters preceding
692 the first unquoted slash in the word, or all the characters in the word
693 if there is no slash...If none of the characters in the tilde-prefix are
694 quoted, the characters in the tilde-prefix following the tilde shell be
695 treated as a possible login name. */
697 #define TILDE_END(c) ((c) == '\0' || (c) == '/' || (c) == ':')
700 unquoted_tilde_word (s)
705 for (r = s; TILDE_END(*r) == 0; r++)
718 /* Tilde-expand S by running it through the tilde expansion library.
719 ASSIGN_P is 1 if this is a variable assignment, so the alternate
720 tilde prefixes should be enabled (`=~' and `:~', see above). */
722 bash_tilde_expand (s, assign_p)
729 old_immed = interrupt_immediately;
730 interrupt_immediately = 1;
731 tilde_additional_prefixes = assign_p ? bash_tilde_prefixes : (char **)0;
732 r = (*s == '~') ? unquoted_tilde_word (s) : 1;
733 ret = r ? tilde_expand (s) : savestring (s);
734 interrupt_immediately = old_immed;
738 /* **************************************************************** */
740 /* Functions to manipulate and search the group list */
742 /* **************************************************************** */
744 static int ngroups, maxgroups;
746 /* The set of groups that this user is a member of. */
747 static GETGROUPS_T *group_array = (GETGROUPS_T *)NULL;
749 #if !defined (NOGROUP)
750 # define NOGROUP (gid_t) -1
754 initialize_group_array ()
759 maxgroups = getmaxgroups ();
762 group_array = (GETGROUPS_T *)xrealloc (group_array, maxgroups * sizeof (GETGROUPS_T));
764 #if defined (HAVE_GETGROUPS)
765 ngroups = getgroups (maxgroups, group_array);
768 /* If getgroups returns nothing, or the OS does not support getgroups(),
769 make sure the groups array includes at least the current gid. */
772 group_array[0] = current_user.gid;
776 /* If the primary group is not in the groups array, add it as group_array[0]
777 and shuffle everything else up 1, if there's room. */
778 for (i = 0; i < ngroups; i++)
779 if (current_user.gid == (gid_t)group_array[i])
781 if (i == ngroups && ngroups < maxgroups)
783 for (i = ngroups; i > 0; i--)
784 group_array[i] = group_array[i - 1];
785 group_array[0] = current_user.gid;
789 /* If the primary group is not group_array[0], swap group_array[0] and
790 whatever the current group is. The vast majority of systems should
791 not need this; a notable exception is Linux. */
792 if (group_array[0] != current_user.gid)
794 for (i = 0; i < ngroups; i++)
795 if (group_array[i] == current_user.gid)
799 group_array[i] = group_array[0];
800 group_array[0] = current_user.gid;
805 /* Return non-zero if GID is one that we have in our groups list. */
807 #if defined (__STDC__) || defined ( _MINIX)
808 group_member (gid_t gid)
812 #endif /* !__STDC__ && !_MINIX */
814 #if defined (HAVE_GETGROUPS)
818 /* Short-circuit if possible, maybe saving a call to getgroups(). */
819 if (gid == current_user.gid || gid == current_user.egid)
822 #if defined (HAVE_GETGROUPS)
824 initialize_group_array ();
826 /* In case of error, the user loses. */
830 /* Search through the list looking for GID. */
831 for (i = 0; i < ngroups; i++)
832 if (gid == (gid_t)group_array[i])
843 static char **group_vector = (char **)NULL;
854 initialize_group_array ();
860 return (char **)NULL;
863 group_vector = strvec_create (ngroups);
864 for (i = 0; i < ngroups; i++)
865 group_vector[i] = itos (group_array[i]);
873 get_group_array (ngp)
877 static int *group_iarray = (int *)NULL;
883 return (group_iarray);
887 initialize_group_array ();
896 group_iarray = (int *)xmalloc (ngroups * sizeof (int));
897 for (i = 0; i < ngroups; i++)
898 group_iarray[i] = (int)group_array[i];