1 /* general.c -- Stuff that is used by all files. */
3 /* Copyright (C) 1987-2020 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
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 Bash is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Bash. If not, see <http://www.gnu.org/licenses/>.
23 #include "bashtypes.h"
24 #if defined (HAVE_SYS_PARAM_H)
25 # include <sys/param.h>
27 #include "posixstat.h"
29 #if defined (HAVE_UNISTD_H)
36 #include "chartypes.h"
49 #include "builtins/common.h"
51 #if defined (HAVE_MBSTR_H) && defined (HAVE_MBSCHR)
52 # include <mbstr.h> /* mbschr */
55 #include <tilde/tilde.h>
62 # include <sys/cygwin.h>
65 static char *bash_special_tilde_expansions
PARAMS((char *));
66 static int unquoted_tilde_word
PARAMS((const char *));
67 static void initialize_group_array
PARAMS((void));
69 /* A standard error message to use when getcwd() returns NULL. */
70 const char * const bash_getcwd_errstr
= N_("getcwd: cannot access parent directories");
72 /* Do whatever is necessary to initialize `Posix mode'. This currently
73 modifies the following variables which are controlled via shopt:
81 and the following variables which cannot be user-modified:
85 If we add to the first list, we need to change the table and functions
92 &interactive_comments
,
100 static char *saved_posix_vars
= 0;
103 posix_initialize (on
)
106 /* Things that should be turned on when posix mode is enabled. */
109 interactive_comments
= source_uses_path
= expand_aliases
= 1;
111 source_searches_cwd
= 0;
112 print_shift_error
= 1;
115 /* Things that should be turned on when posix mode is disabled. */
116 else if (saved_posix_vars
) /* on == 0, restore saved settings */
118 set_posix_options (saved_posix_vars
);
119 free (saved_posix_vars
);
120 saved_posix_vars
= 0;
122 else /* on == 0, restore a default set of settings */
124 source_searches_cwd
= 1;
125 expand_aliases
= interactive_shell
;
126 print_shift_error
= 0;
133 return ((sizeof (posix_vars
) / sizeof (posix_vars
[0])) - 1);
137 get_posix_options (bitmap
)
143 bitmap
= (char *)xmalloc (num_posix_options ()); /* no trailing NULL */
144 for (i
= 0; posix_vars
[i
].posix_mode_var
; i
++)
145 bitmap
[i
] = *(posix_vars
[i
].posix_mode_var
);
149 #undef save_posix_options
151 save_posix_options ()
153 saved_posix_vars
= get_posix_options (saved_posix_vars
);
157 set_posix_options (bitmap
)
162 for (i
= 0; posix_vars
[i
].posix_mode_var
; i
++)
163 *(posix_vars
[i
].posix_mode_var
) = bitmap
[i
];
166 /* **************************************************************** */
168 /* Functions to convert to and from and display non-standard types */
170 /* **************************************************************** */
172 #if defined (RLIMTYPE)
174 string_to_rlimtype (s
)
182 while (s
&& *s
&& whitespace (*s
))
184 if (s
&& (*s
== '-' || *s
== '+'))
189 for ( ; s
&& *s
&& DIGIT (*s
); s
++)
190 ret
= (ret
* 10) + TODIGIT (*s
);
191 return (neg
? -ret
: ret
);
195 print_rlimtype (n
, addnl
)
199 char s
[INT_STRLEN_BOUND (RLIMTYPE
) + 1], *p
;
208 while ((n
/= 10) != 0);
216 while ((n
/= 10) != 0);
219 printf ("%s%s", p
, addnl
? "\n" : "");
221 #endif /* RLIMTYPE */
223 /* **************************************************************** */
225 /* Input Validation Functions */
227 /* **************************************************************** */
229 /* Return non-zero if all of the characters in STRING are digits. */
234 register const char *s
;
236 for (s
= string
; *s
; s
++)
243 /* Return non-zero if the characters pointed to by STRING constitute a
244 valid number. Stuff the converted number into RESULT if RESULT is
247 legal_number (string
, result
)
261 value
= strtoimax (string
, &ep
, 10);
262 if (errno
|| ep
== string
)
263 return 0; /* errno is set on overflow or underflow */
265 /* Skip any trailing whitespace, since strtoimax does not. */
266 while (whitespace (*ep
))
269 /* If *string is not '\0' but *ep is '\0' on return, the entire string
271 if (*string
&& *ep
== '\0')
275 /* The SunOS4 implementation of strtol() will happily ignore
276 overflow conditions, so this cannot do overflow correctly
284 /* Return 1 if this token is a legal shell `identifier'; that is, it consists
285 solely of letters, digits, and underscores, and does not begin with a
288 legal_identifier (name
)
291 register const char *s
;
294 if (!name
|| !(c
= *name
) || (legal_variable_starter (c
) == 0))
297 for (s
= name
+ 1; (c
= *s
) != 0; s
++)
299 if (legal_variable_char (c
) == 0)
305 /* Return 1 if NAME is a valid value that can be assigned to a nameref
306 variable. FLAGS can be 2, in which case the name is going to be used
307 to create a variable. Other values are currently unused, but could
308 be used to allow values to be stored and indirectly referenced, but
309 not used in assignments. */
311 valid_nameref_value (name
, flags
)
315 if (name
== 0 || *name
== 0)
318 /* valid identifier */
319 #if defined (ARRAY_VARS)
320 if (legal_identifier (name
) || (flags
!= 2 && valid_array_reference (name
, 0)))
322 if (legal_identifier (name
))
330 check_selfref (name
, value
, flags
)
337 if (STREQ (name
, value
))
340 #if defined (ARRAY_VARS)
341 if (valid_array_reference (value
, 0))
343 t
= array_variable_name (value
, 0, (char **)NULL
, (int *)NULL
);
344 if (t
&& STREQ (name
, t
))
353 return 0; /* not a self reference */
356 /* Make sure that WORD is a valid shell identifier, i.e.
357 does not contain a dollar sign, nor is quoted in any way.
358 If CHECK_WORD is non-zero,
359 the word is checked to ensure that it consists of only letters,
360 digits, and underscores, and does not consist of all digits. */
362 check_identifier (word
, check_word
)
366 if (word
->flags
& (W_HASDOLLAR
|W_QUOTED
)) /* XXX - HASDOLLAR? */
368 internal_error (_("`%s': not a valid identifier"), word
->word
);
371 else if (check_word
&& (all_digits (word
->word
) || legal_identifier (word
->word
) == 0))
373 internal_error (_("`%s': not a valid identifier"), word
->word
);
380 /* Return 1 if STRING is a function name that the shell will import from
381 the environment. Currently we reject attempts to import shell functions
382 containing slashes, beginning with newlines or containing blanks. In
383 Posix mode, we require that STRING be a valid shell identifier. Not
386 importable_function_name (string
, len
)
390 if (absolute_program (string
)) /* don't allow slash */
392 if (*string
== '\n') /* can't start with a newline */
394 if (shellblank (*string
) || shellblank(string
[len
-1]))
396 return (posixly_correct
? legal_identifier (string
) : 1);
400 exportable_function_name (string
)
403 if (absolute_program (string
))
405 if (mbschr (string
, '=') != 0)
410 /* Return 1 if STRING comprises a valid alias name. The shell accepts
411 essentially all characters except those which must be quoted to the
412 parser (which disqualifies them from alias expansion anyway) and `/'. */
414 legal_alias_name (string
, flags
)
418 register const char *s
;
420 for (s
= string
; *s
; s
++)
421 if (shellbreak (*s
) || shellxquote (*s
) || shellexp (*s
) || (*s
== '/'))
426 /* Returns non-zero if STRING is an assignment statement. The returned value
427 is the index of the `=' sign. If FLAGS&1 we are expecting a compound assignment
428 and require an array subscript before the `=' to denote an assignment
431 assignment (string
, flags
)
435 register unsigned char c
;
436 register int newi
, indx
;
438 c
= string
[indx
= 0];
440 #if defined (ARRAY_VARS)
441 /* If parser_state includes PST_COMPASSIGN, FLAGS will include 1, so we are
442 parsing the contents of a compound assignment. If parser_state includes
443 PST_REPARSE, we are in the middle of an assignment statement and breaking
444 the words between the parens into words and assignment statements, but
445 we don't need to check for that right now. Within a compound assignment,
446 the subscript is required to make the word an assignment statement. If
447 we don't have a subscript, even if the word is a valid assignment
448 statement otherwise, we don't want to treat it as one. */
449 if ((flags
& 1) && c
!= '[') /* ] */
451 else if ((flags
& 1) == 0 && legal_variable_starter (c
) == 0)
453 if (legal_variable_starter (c
) == 0)
457 while (c
= string
[indx
])
459 /* The following is safe. Note that '=' at the start of a word
460 is not an assignment statement. */
464 #if defined (ARRAY_VARS)
467 newi
= skipsubscript (string
, indx
, (flags
& 2) ? 1 : 0);
468 /* XXX - why not check for blank subscripts here, if we do in
469 valid_array_reference? */
470 if (string
[newi
++] != ']')
472 if (string
[newi
] == '+' && string
[newi
+1] == '=')
474 return ((string
[newi
] == '=') ? newi
: 0);
476 #endif /* ARRAY_VARS */
479 if (c
== '+' && string
[indx
+1] == '=')
482 /* Variable names in assignment statements may contain only letters,
484 if (legal_variable_char (c
) == 0)
500 for (i
= 0; line
[i
]; i
++)
501 if (isblank ((unsigned char)line
[i
]) == 0)
503 return (line
[i
] == '\0');
506 /* **************************************************************** */
508 /* Functions to manage files and file descriptors */
510 /* **************************************************************** */
512 /* A function to unset no-delay mode on a file descriptor. Used in shell.c
513 to unset it on the fd passed as stdin. Should be called on stdin if
514 readline gets an EAGAIN or EWOULDBLOCK when trying to read input. */
516 #if !defined (O_NDELAY)
517 # if defined (FNDELAY)
518 # define O_NDELAY FNDELAY
520 #endif /* O_NDELAY */
522 /* Make sure no-delay mode is not set on file descriptor FD. */
524 sh_unset_nodelay_mode (fd
)
529 if ((flags
= fcntl (fd
, F_GETFL
, 0)) < 0)
534 /* This is defined to O_NDELAY in filecntl.h if O_NONBLOCK is not present
535 and O_NDELAY is defined. */
537 bflags
|= O_NONBLOCK
;
547 return (fcntl (fd
, F_SETFL
, flags
));
553 /* Just a wrapper for the define in include/filecntl.h */
558 return (SET_CLOSE_ON_EXEC (fd
));
561 /* Return 1 if file descriptor FD is valid; 0 otherwise. */
566 return (fcntl (fd
, F_GETFD
, 0) >= 0);
574 return ((lseek (fd
, 0L, SEEK_CUR
) < 0) && (errno
== ESPIPE
));
577 /* There is a bug in the NeXT 2.1 rlogind that causes opens
578 of /dev/tty to fail. */
580 #if defined (__BEOS__)
581 /* On BeOS, opening in non-blocking mode exposes a bug in BeOS, so turn it
582 into a no-op. This should probably go away in the future. */
584 # define O_NONBLOCK 0
585 #endif /* __BEOS__ */
593 tty_fd
= open ("/dev/tty", O_RDWR
|O_NONBLOCK
);
597 tty
= (char *)ttyname (fileno (stdin
));
600 tty_fd
= open (tty
, O_RDWR
|O_NONBLOCK
);
606 /* Return 1 if PATH1 and PATH2 are the same file. This is kind of
607 expensive. If non-NULL STP1 and STP2 point to stat structures
608 corresponding to PATH1 and PATH2, respectively. */
610 same_file (path1
, path2
, stp1
, stp2
)
611 const char *path1
, *path2
;
612 struct stat
*stp1
, *stp2
;
614 struct stat st1
, st2
;
618 if (stat (path1
, &st1
) != 0)
625 if (stat (path2
, &st2
) != 0)
630 return ((stp1
->st_dev
== stp2
->st_dev
) && (stp1
->st_ino
== stp2
->st_ino
));
633 /* Move FD to a number close to the maximum number of file descriptors
634 allowed in the shell process, to avoid the user stepping on it with
635 redirection and causing us extra work. If CHECK_NEW is non-zero,
636 we check whether or not the file descriptors are in use before
637 duplicating FD onto them. MAXFD says where to start checking the
638 file descriptors. If it's less than 20, we get the maximum value
639 available from getdtablesize(2). */
641 move_to_high_fd (fd
, check_new
, maxfd
)
642 int fd
, check_new
, maxfd
;
644 int script_fd
, nfds
, ignore
;
648 nfds
= getdtablesize ();
651 if (nfds
> HIGH_FD_MAX
)
652 nfds
= HIGH_FD_MAX
; /* reasonable maximum */
657 for (nfds
--; check_new
&& nfds
> 3; nfds
--)
658 if (fcntl (nfds
, F_GETFD
, &ignore
) == -1)
661 if (nfds
> 3 && fd
!= nfds
&& (script_fd
= dup2 (fd
, nfds
)) != -1)
663 if (check_new
== 0 || fd
!= fileno (stderr
)) /* don't close stderr */
668 /* OK, we didn't find one less than our artificial maximum; return the
669 original file descriptor. */
673 /* Return non-zero if the characters from SAMPLE are not all valid
674 characters to be found in the first line of a shell script. We
675 check up to the first newline, or SAMPLE_LEN, whichever comes first.
676 All of the characters must be printable or whitespace. */
679 check_binary_file (sample
, sample_len
)
686 for (i
= 0; i
< sample_len
; i
++)
698 /* **************************************************************** */
700 /* Functions to manipulate pipes */
702 /* **************************************************************** */
710 if ((r
= pipe (pv
)) < 0)
713 pv
[0] = move_to_high_fd (pv
[0], 1, 64);
714 pv
[1] = move_to_high_fd (pv
[1], 1, 64);
733 /* **************************************************************** */
735 /* Functions to inspect pathnames */
737 /* **************************************************************** */
745 return (stat (fn
, &sb
) == 0);
754 return ((stat (fn
, &sb
) == 0) && S_ISDIR (sb
.st_mode
));
761 return (file_isdir (fn
) && sh_eaccess (fn
, W_OK
) == 0);
764 /* Return 1 if STRING is "." or "..", optionally followed by a directory
767 path_dot_or_dotdot (string
)
770 if (string
== 0 || *string
== '\0' || *string
!= '.')
773 /* string[0] == '.' */
774 if (PATHSEP(string
[1]) || (string
[1] == '.' && PATHSEP(string
[2])))
780 /* Return 1 if STRING contains an absolute pathname, else 0. Used by `cd'
781 to decide whether or not to look up a directory name in $CDPATH. */
783 absolute_pathname (string
)
786 if (string
== 0 || *string
== '\0')
792 if (string
[0] == '.' && PATHSEP(string
[1])) /* . and ./ */
795 if (string
[0] == '.' && string
[1] == '.' && PATHSEP(string
[2])) /* .. and ../ */
801 /* Return 1 if STRING is an absolute program name; it is absolute if it
802 contains any slashes. This is used to decide whether or not to look
805 absolute_program (string
)
808 return ((char *)mbschr (string
, '/') != (char *)NULL
);
811 /* **************************************************************** */
813 /* Functions to manipulate pathnames */
815 /* **************************************************************** */
817 /* Turn STRING (a pathname) into an absolute pathname, assuming that
818 DOT_PATH contains the symbolic location of `.'. This always
819 returns a new string, even if STRING was an absolute pathname to
822 make_absolute (string
, dot_path
)
823 const char *string
, *dot_path
;
827 if (dot_path
== 0 || ABSPATH(string
))
830 char pathbuf
[PATH_MAX
+ 1];
832 /* WAS cygwin_conv_to_full_posix_path (string, pathbuf); */
833 cygwin_conv_path (CCP_WIN_A_TO_POSIX
, string
, pathbuf
, PATH_MAX
);
834 result
= savestring (pathbuf
);
837 result
= savestring (string
);
840 result
= sh_makepath (dot_path
, string
, 0);
845 /* Return the `basename' of the pathname in STRING (the stuff after the
846 last '/'). If STRING is `/', just return it. */
848 base_pathname (string
)
854 if (absolute_pathname (string
) == 0)
858 if (string
[0] == '/' && string
[1] == 0)
861 p
= (char *)strrchr (string
, '/');
862 return (p
? ++p
: string
);
865 /* Return the full pathname of FILE. Easy. Filenames that begin
866 with a '/' are returned as themselves. Other filenames have
867 the current working directory prepended. A new string is
868 returned in either case. */
875 file
= (*file
== '~') ? bash_tilde_expand (file
, 0) : savestring (file
);
880 ret
= sh_makepath ((char *)NULL
, file
, (MP_DOCWD
|MP_RMDOT
));
886 /* A slightly related function. Get the prettiest name of this
887 directory possible. */
888 static char tdir
[PATH_MAX
];
890 /* Return a pretty pathname. If the first part of the pathname is
891 the same as $HOME, then replace that with `~'. */
893 polite_directory_format (name
)
899 home
= get_string_value ("HOME");
900 l
= home
? strlen (home
) : 0;
901 if (l
> 1 && strncmp (home
, name
, l
) == 0 && (!name
[l
] || name
[l
] == '/'))
903 strncpy (tdir
+ 1, name
+ l
, sizeof(tdir
) - 2);
905 tdir
[sizeof(tdir
) - 1] = '\0';
912 /* Trim NAME. If NAME begins with `~/', skip over tilde prefix. Trim to
913 keep any tilde prefix and PROMPT_DIRTRIM trailing directory components
914 and replace the intervening characters with `...' */
916 trim_pathname (name
, maxlen
)
922 char *nbeg
, *nend
, *ntail
, *v
;
924 if (name
== 0 || (nlen
= strlen (name
)) == 0)
928 v
= get_string_value ("PROMPT_DIRTRIM");
929 if (v
== 0 || *v
== 0)
931 if (legal_number (v
, &nskip
) == 0 || nskip
<= 0)
934 /* Skip over tilde prefix */
937 for (nbeg
= name
; *nbeg
; nbeg
++)
946 for (ndirs
= 0, ntail
= nbeg
; *ntail
; ntail
++)
952 for (ntail
= (*nend
== '/') ? nend
: nend
- 1; ntail
> nbeg
; ntail
--)
962 /* Now we want to return name[0..nbeg]+"..."+ntail, modifying name in place */
972 memmove (nbeg
, ntail
, nlen
);
978 /* Return a printable representation of FN without special characters. The
979 caller is responsible for freeing memory if this returns something other
980 than its argument. If FLAGS is non-zero, we are printing for portable
981 re-input and should single-quote filenames appropriately. */
983 printable_filename (fn
, flags
)
989 if (ansic_shouldquote (fn
))
990 newf
= ansic_quote (fn
, 0, NULL
);
991 else if (flags
&& sh_contains_shell_metas (fn
))
992 newf
= sh_single_quote (fn
);
999 /* Given a string containing units of information separated by colons,
1000 return the next one pointed to by (P_INDEX), or NULL if there are no more.
1001 Advance (P_INDEX) to the character after the colon. */
1003 extract_colon_unit (string
, p_index
)
1013 len
= strlen (string
);
1014 if (*p_index
>= len
)
1015 return ((char *)NULL
);
1019 /* Each call to this routine leaves the index pointing at a colon if
1020 there is more to the path. If I is > 0, then increment past the
1021 `:'. If I is 0, then the path has a leading colon. Trailing colons
1022 are handled OK by the `else' part of the if statement; an empty
1023 string is returned in that case. */
1024 if (i
&& string
[i
] == ':')
1027 for (start
= i
; string
[i
] && string
[i
] != ':'; i
++)
1036 /* Return "" in the case of a trailing `:'. */
1037 value
= (char *)xmalloc (1);
1041 value
= substring (string
, start
, i
);
1046 /* **************************************************************** */
1048 /* Tilde Initialization and Expansion */
1050 /* **************************************************************** */
1052 #if defined (PUSHD_AND_POPD)
1053 extern char *get_dirstack_from_string
PARAMS((char *));
1056 static char **bash_tilde_prefixes
;
1057 static char **bash_tilde_prefixes2
;
1058 static char **bash_tilde_suffixes
;
1059 static char **bash_tilde_suffixes2
;
1061 /* If tilde_expand hasn't been able to expand the text, perhaps it
1062 is a special shell expansion. This function is installed as the
1063 tilde_expansion_preexpansion_hook. It knows how to expand ~- and ~+.
1064 If PUSHD_AND_POPD is defined, ~[+-]N expands to directories from the
1067 bash_special_tilde_expansions (text
)
1072 result
= (char *)NULL
;
1074 if (text
[0] == '+' && text
[1] == '\0')
1075 result
= get_string_value ("PWD");
1076 else if (text
[0] == '-' && text
[1] == '\0')
1077 result
= get_string_value ("OLDPWD");
1078 #if defined (PUSHD_AND_POPD)
1079 else if (DIGIT (*text
) || ((*text
== '+' || *text
== '-') && DIGIT (text
[1])))
1080 result
= get_dirstack_from_string (text
);
1083 return (result
? savestring (result
) : (char *)NULL
);
1086 /* Initialize the tilde expander. In Bash, we handle `~-' and `~+', as
1087 well as handling special tilde prefixes; `:~" and `=~' are indications
1088 that we should do tilde expansion. */
1092 static int times_called
= 0;
1094 /* Tell the tilde expander that we want a crack first. */
1095 tilde_expansion_preexpansion_hook
= bash_special_tilde_expansions
;
1097 /* Tell the tilde expander about special strings which start a tilde
1098 expansion, and the special strings that end one. Only do this once.
1099 tilde_initialize () is called from within bashline_reinitialize (). */
1100 if (times_called
++ == 0)
1102 bash_tilde_prefixes
= strvec_create (3);
1103 bash_tilde_prefixes
[0] = "=~";
1104 bash_tilde_prefixes
[1] = ":~";
1105 bash_tilde_prefixes
[2] = (char *)NULL
;
1107 bash_tilde_prefixes2
= strvec_create (2);
1108 bash_tilde_prefixes2
[0] = ":~";
1109 bash_tilde_prefixes2
[1] = (char *)NULL
;
1111 tilde_additional_prefixes
= bash_tilde_prefixes
;
1113 bash_tilde_suffixes
= strvec_create (3);
1114 bash_tilde_suffixes
[0] = ":";
1115 bash_tilde_suffixes
[1] = "=~"; /* XXX - ?? */
1116 bash_tilde_suffixes
[2] = (char *)NULL
;
1118 tilde_additional_suffixes
= bash_tilde_suffixes
;
1120 bash_tilde_suffixes2
= strvec_create (2);
1121 bash_tilde_suffixes2
[0] = ":";
1122 bash_tilde_suffixes2
[1] = (char *)NULL
;
1126 /* POSIX.2, 3.6.1: A tilde-prefix consists of an unquoted tilde character
1127 at the beginning of the word, followed by all of the characters preceding
1128 the first unquoted slash in the word, or all the characters in the word
1129 if there is no slash...If none of the characters in the tilde-prefix are
1130 quoted, the characters in the tilde-prefix following the tilde shell be
1131 treated as a possible login name. */
1133 #define TILDE_END(c) ((c) == '\0' || (c) == '/' || (c) == ':')
1136 unquoted_tilde_word (s
)
1141 for (r
= s
; TILDE_END(*r
) == 0; r
++)
1154 /* Find the end of the tilde-prefix starting at S, and return the tilde
1155 prefix in newly-allocated memory. Return the length of the string in
1156 *LENP. FLAGS tells whether or not we're in an assignment context --
1157 if so, `:' delimits the end of the tilde prefix as well. */
1159 bash_tilde_find_word (s
, flags
, lenp
)
1167 for (r
= s
; *r
&& *r
!= '/'; r
++)
1169 /* Short-circuit immediately if we see a quote character. Even though
1170 POSIX says that `the first unquoted slash' (or `:') terminates the
1171 tilde-prefix, in practice, any quoted portion of the tilde prefix
1172 will cause it to not be expanded. */
1173 if (*r
== '\\' || *r
== '\'' || *r
== '"')
1175 ret
= savestring (s
);
1180 else if (flags
&& *r
== ':')
1184 ret
= xmalloc (l
+ 1);
1185 strncpy (ret
, s
, l
);
1192 /* Tilde-expand S by running it through the tilde expansion library.
1193 ASSIGN_P is 1 if this is a variable assignment, so the alternate
1194 tilde prefixes should be enabled (`=~' and `:~', see above). If
1195 ASSIGN_P is 2, we are expanding the rhs of an assignment statement,
1196 so `=~' is not valid. */
1198 bash_tilde_expand (s
, assign_p
)
1205 tilde_additional_prefixes
= assign_p
== 0 ? (char **)0
1206 : (assign_p
== 2 ? bash_tilde_prefixes2
: bash_tilde_prefixes
);
1208 tilde_additional_suffixes
= bash_tilde_suffixes2
;
1210 r
= (*s
== '~') ? unquoted_tilde_word (s
) : 1;
1211 ret
= r
? tilde_expand (s
) : savestring (s
);
1218 /* **************************************************************** */
1220 /* Functions to manipulate and search the group list */
1222 /* **************************************************************** */
1224 static int ngroups
, maxgroups
;
1226 /* The set of groups that this user is a member of. */
1227 static GETGROUPS_T
*group_array
= (GETGROUPS_T
*)NULL
;
1229 #if !defined (NOGROUP)
1230 # define NOGROUP (gid_t) -1
1234 initialize_group_array ()
1239 maxgroups
= getmaxgroups ();
1242 group_array
= (GETGROUPS_T
*)xrealloc (group_array
, maxgroups
* sizeof (GETGROUPS_T
));
1244 #if defined (HAVE_GETGROUPS)
1245 ngroups
= getgroups (maxgroups
, group_array
);
1248 /* If getgroups returns nothing, or the OS does not support getgroups(),
1249 make sure the groups array includes at least the current gid. */
1252 group_array
[0] = current_user
.gid
;
1256 /* If the primary group is not in the groups array, add it as group_array[0]
1257 and shuffle everything else up 1, if there's room. */
1258 for (i
= 0; i
< ngroups
; i
++)
1259 if (current_user
.gid
== (gid_t
)group_array
[i
])
1261 if (i
== ngroups
&& ngroups
< maxgroups
)
1263 for (i
= ngroups
; i
> 0; i
--)
1264 group_array
[i
] = group_array
[i
- 1];
1265 group_array
[0] = current_user
.gid
;
1269 /* If the primary group is not group_array[0], swap group_array[0] and
1270 whatever the current group is. The vast majority of systems should
1271 not need this; a notable exception is Linux. */
1272 if (group_array
[0] != current_user
.gid
)
1274 for (i
= 0; i
< ngroups
; i
++)
1275 if (group_array
[i
] == current_user
.gid
)
1279 group_array
[i
] = group_array
[0];
1280 group_array
[0] = current_user
.gid
;
1285 /* Return non-zero if GID is one that we have in our groups list. */
1287 #if defined (__STDC__) || defined ( _MINIX)
1288 group_member (gid_t gid
)
1292 #endif /* !__STDC__ && !_MINIX */
1294 #if defined (HAVE_GETGROUPS)
1298 /* Short-circuit if possible, maybe saving a call to getgroups(). */
1299 if (gid
== current_user
.gid
|| gid
== current_user
.egid
)
1302 #if defined (HAVE_GETGROUPS)
1304 initialize_group_array ();
1306 /* In case of error, the user loses. */
1310 /* Search through the list looking for GID. */
1311 for (i
= 0; i
< ngroups
; i
++)
1312 if (gid
== (gid_t
)group_array
[i
])
1320 get_group_list (ngp
)
1323 static char **group_vector
= (char **)NULL
;
1330 return group_vector
;
1334 initialize_group_array ();
1340 return (char **)NULL
;
1343 group_vector
= strvec_create (ngroups
);
1344 for (i
= 0; i
< ngroups
; i
++)
1345 group_vector
[i
] = itos (group_array
[i
]);
1349 return group_vector
;
1353 get_group_array (ngp
)
1357 static int *group_iarray
= (int *)NULL
;
1363 return (group_iarray
);
1367 initialize_group_array ();
1376 group_iarray
= (int *)xmalloc (ngroups
* sizeof (int));
1377 for (i
= 0; i
< ngroups
; i
++)
1378 group_iarray
[i
] = (int)group_array
[i
];
1382 return group_iarray
;
1385 /* **************************************************************** */
1387 /* Miscellaneous functions */
1389 /* **************************************************************** */
1391 /* Return a value for PATH that is guaranteed to find all of the standard
1392 utilities. This uses Posix.2 configuration variables, if present. It
1393 uses a value defined in config.h as a last resort. */
1395 conf_standard_path ()
1397 #if defined (_CS_PATH) && defined (HAVE_CONFSTR)
1401 len
= (size_t)confstr (_CS_PATH
, (char *)NULL
, (size_t)0);
1404 p
= (char *)xmalloc (len
+ 2);
1406 confstr (_CS_PATH
, p
, len
);
1410 return (savestring (STANDARD_UTILS_PATH
));
1411 #else /* !_CS_PATH || !HAVE_CONFSTR */
1412 # if defined (CS_PATH)
1413 return (savestring (CS_PATH
));
1415 return (savestring (STANDARD_UTILS_PATH
));
1416 # endif /* !CS_PATH */
1417 #endif /* !_CS_PATH || !HAVE_CONFSTR */
1427 v
= get_string_value ("COLUMNS");
1435 if (check_window_size
)
1436 get_new_window_size (0, (int *)0, &c
);
1438 return (c
> 0 ? c
: 80);