1 /* general.c -- Stuff that is used by all files. */
3 /* Copyright (C) 1987-2016 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"
48 #include "builtins/common.h"
50 #if defined (HAVE_MBSTR_H) && defined (HAVE_MBSCHR)
51 # include <mbstr.h> /* mbschr */
54 #include <tilde/tilde.h>
61 # include <sys/cygwin.h>
64 static char *bash_special_tilde_expansions
__P((char *));
65 static int unquoted_tilde_word
__P((const char *));
66 static void initialize_group_array
__P((void));
68 /* A standard error message to use when getcwd() returns NULL. */
69 const char * const bash_getcwd_errstr
= N_("getcwd: cannot access parent directories");
71 /* Do whatever is necessary to initialize `Posix mode'. This currently
72 modifies the following variables which are controlled via shopt:
79 and the following variables which cannot be user-modified:
83 If we add to the first list, we need to change the table and functions
90 &interactive_comments
,
102 /* Things that should be turned on when posix mode is enabled. */
105 interactive_comments
= source_uses_path
= expand_aliases
= 1;
107 source_searches_cwd
= 0;
108 print_shift_error
= 1;
112 /* Things that should be turned on when posix mode is disabled. */
115 source_searches_cwd
= 1;
116 expand_aliases
= interactive_shell
;
117 print_shift_error
= 0;
124 return ((sizeof (posix_vars
) / sizeof (posix_vars
[0])) - 1);
128 get_posix_options (bitmap
)
134 bitmap
= (char *)xmalloc (num_posix_options ()); /* no trailing NULL */
135 for (i
= 0; posix_vars
[i
].posix_mode_var
; i
++)
136 bitmap
[i
] = *(posix_vars
[i
].posix_mode_var
);
141 set_posix_options (bitmap
)
146 for (i
= 0; posix_vars
[i
].posix_mode_var
; i
++)
147 *(posix_vars
[i
].posix_mode_var
) = bitmap
[i
];
150 /* **************************************************************** */
152 /* Functions to convert to and from and display non-standard types */
154 /* **************************************************************** */
156 #if defined (RLIMTYPE)
158 string_to_rlimtype (s
)
166 while (s
&& *s
&& whitespace (*s
))
168 if (s
&& (*s
== '-' || *s
== '+'))
173 for ( ; s
&& *s
&& DIGIT (*s
); s
++)
174 ret
= (ret
* 10) + TODIGIT (*s
);
175 return (neg
? -ret
: ret
);
179 print_rlimtype (n
, addnl
)
183 char s
[INT_STRLEN_BOUND (RLIMTYPE
) + 1], *p
;
192 while ((n
/= 10) != 0);
200 while ((n
/= 10) != 0);
203 printf ("%s%s", p
, addnl
? "\n" : "");
205 #endif /* RLIMTYPE */
207 /* **************************************************************** */
209 /* Input Validation Functions */
211 /* **************************************************************** */
213 /* Return non-zero if all of the characters in STRING are digits. */
218 register const char *s
;
220 for (s
= string
; *s
; s
++)
227 /* Return non-zero if the characters pointed to by STRING constitute a
228 valid number. Stuff the converted number into RESULT if RESULT is
231 legal_number (string
, result
)
245 value
= strtoimax (string
, &ep
, 10);
246 if (errno
|| ep
== string
)
247 return 0; /* errno is set on overflow or underflow */
249 /* Skip any trailing whitespace, since strtoimax does not. */
250 while (whitespace (*ep
))
253 /* If *string is not '\0' but *ep is '\0' on return, the entire string
255 if (*string
&& *ep
== '\0')
259 /* The SunOS4 implementation of strtol() will happily ignore
260 overflow conditions, so this cannot do overflow correctly
268 /* Return 1 if this token is a legal shell `identifier'; that is, it consists
269 solely of letters, digits, and underscores, and does not begin with a
272 legal_identifier (name
)
275 register const char *s
;
278 if (!name
|| !(c
= *name
) || (legal_variable_starter (c
) == 0))
281 for (s
= name
+ 1; (c
= *s
) != 0; s
++)
283 if (legal_variable_char (c
) == 0)
289 /* Return 1 if NAME is a valid value that can be assigned to a nameref
290 variable. FLAGS can be 2, in which case the name is going to be used
291 to create a variable. Other values are currently unused, but could
292 be used to allow values to be stored and indirectly referenced, but
293 not used in assignments. */
295 valid_nameref_value (name
, flags
)
299 if (name
== 0 || *name
== 0)
302 /* valid identifier */
303 #if defined (ARRAY_VARS)
304 if (legal_identifier (name
) || (flags
!= 2 && valid_array_reference (name
, 0)))
306 if (legal_identifier (name
))
314 check_selfref (name
, value
, flags
)
321 if (STREQ (name
, value
))
324 #if defined (ARRAY_VARS)
325 if (valid_array_reference (value
, 0))
327 t
= array_variable_name (value
, 0, (char **)NULL
, (int *)NULL
);
328 if (t
&& STREQ (name
, t
))
337 return 0; /* not a self reference */
340 /* Make sure that WORD is a valid shell identifier, i.e.
341 does not contain a dollar sign, nor is quoted in any way. Nor
342 does it consist of all digits. If CHECK_WORD is non-zero,
343 the word is checked to ensure that it consists of only letters,
344 digits, and underscores. */
346 check_identifier (word
, check_word
)
350 if ((word
->flags
& (W_HASDOLLAR
|W_QUOTED
)) || all_digits (word
->word
))
352 internal_error (_("`%s': not a valid identifier"), word
->word
);
355 else if (check_word
&& legal_identifier (word
->word
) == 0)
357 internal_error (_("`%s': not a valid identifier"), word
->word
);
364 /* Return 1 if STRING is a function name that the shell will import from
365 the environment. Currently we reject attempts to import shell functions
366 containing slashes, beginning with newlines or containing blanks. In
367 Posix mode, we require that STRING be a valid shell identifier. Not
370 importable_function_name (string
, len
)
374 if (absolute_program (string
)) /* don't allow slash */
376 if (*string
== '\n') /* can't start with a newline */
378 if (shellblank (*string
) || shellblank(string
[len
-1]))
380 return (posixly_correct
? legal_identifier (string
) : 1);
384 exportable_function_name (string
)
387 if (absolute_program (string
))
389 if (mbschr (string
, '=') != 0)
394 /* Return 1 if STRING comprises a valid alias name. The shell accepts
395 essentially all characters except those which must be quoted to the
396 parser (which disqualifies them from alias expansion anyway) and `/'. */
398 legal_alias_name (string
, flags
)
402 register const char *s
;
404 for (s
= string
; *s
; s
++)
405 if (shellbreak (*s
) || shellxquote (*s
) || shellexp (*s
) || (*s
== '/'))
410 /* Returns non-zero if STRING is an assignment statement. The returned value
411 is the index of the `=' sign. If FLAGS&1 we are expecting a compound assignment
412 and don't want an array subscript before the `='. */
414 assignment (string
, flags
)
418 register unsigned char c
;
419 register int newi
, indx
;
421 c
= string
[indx
= 0];
423 #if defined (ARRAY_VARS)
424 if ((legal_variable_starter (c
) == 0) && ((flags
&1) == 0 || c
!= '[')) /* ] */
426 if (legal_variable_starter (c
) == 0)
430 while (c
= string
[indx
])
432 /* The following is safe. Note that '=' at the start of a word
433 is not an assignment statement. */
437 #if defined (ARRAY_VARS)
440 newi
= skipsubscript (string
, indx
, (flags
& 2) ? 1 : 0);
441 /* XXX - why not check for blank subscripts here, if we do in
442 valid_array_reference? */
443 if (string
[newi
++] != ']')
445 if (string
[newi
] == '+' && string
[newi
+1] == '=')
447 return ((string
[newi
] == '=') ? newi
: 0);
449 #endif /* ARRAY_VARS */
452 if (c
== '+' && string
[indx
+1] == '=')
455 /* Variable names in assignment statements may contain only letters,
457 if (legal_variable_char (c
) == 0)
473 for (i
= 0; line
[i
]; i
++)
474 if (isblank ((unsigned char)line
[i
]) == 0)
476 return (line
[i
] == '\0');
479 /* **************************************************************** */
481 /* Functions to manage files and file descriptors */
483 /* **************************************************************** */
485 /* A function to unset no-delay mode on a file descriptor. Used in shell.c
486 to unset it on the fd passed as stdin. Should be called on stdin if
487 readline gets an EAGAIN or EWOULDBLOCK when trying to read input. */
489 #if !defined (O_NDELAY)
490 # if defined (FNDELAY)
491 # define O_NDELAY FNDELAY
493 #endif /* O_NDELAY */
495 /* Make sure no-delay mode is not set on file descriptor FD. */
497 sh_unset_nodelay_mode (fd
)
502 if ((flags
= fcntl (fd
, F_GETFL
, 0)) < 0)
507 /* This is defined to O_NDELAY in filecntl.h if O_NONBLOCK is not present
508 and O_NDELAY is defined. */
510 bflags
|= O_NONBLOCK
;
520 return (fcntl (fd
, F_SETFL
, flags
));
526 /* Just a wrapper for the define in include/filecntl.h */
531 return (SET_CLOSE_ON_EXEC (fd
));
534 /* Return 1 if file descriptor FD is valid; 0 otherwise. */
539 return (fcntl (fd
, F_GETFD
, 0) >= 0);
547 return ((lseek (fd
, 0L, SEEK_CUR
) < 0) && (errno
== ESPIPE
));
550 /* There is a bug in the NeXT 2.1 rlogind that causes opens
551 of /dev/tty to fail. */
553 #if defined (__BEOS__)
554 /* On BeOS, opening in non-blocking mode exposes a bug in BeOS, so turn it
555 into a no-op. This should probably go away in the future. */
557 # define O_NONBLOCK 0
558 #endif /* __BEOS__ */
566 tty_fd
= open ("/dev/tty", O_RDWR
|O_NONBLOCK
);
570 tty
= (char *)ttyname (fileno (stdin
));
573 tty_fd
= open (tty
, O_RDWR
|O_NONBLOCK
);
579 /* Return 1 if PATH1 and PATH2 are the same file. This is kind of
580 expensive. If non-NULL STP1 and STP2 point to stat structures
581 corresponding to PATH1 and PATH2, respectively. */
583 same_file (path1
, path2
, stp1
, stp2
)
584 const char *path1
, *path2
;
585 struct stat
*stp1
, *stp2
;
587 struct stat st1
, st2
;
591 if (stat (path1
, &st1
) != 0)
598 if (stat (path2
, &st2
) != 0)
603 return ((stp1
->st_dev
== stp2
->st_dev
) && (stp1
->st_ino
== stp2
->st_ino
));
606 /* Move FD to a number close to the maximum number of file descriptors
607 allowed in the shell process, to avoid the user stepping on it with
608 redirection and causing us extra work. If CHECK_NEW is non-zero,
609 we check whether or not the file descriptors are in use before
610 duplicating FD onto them. MAXFD says where to start checking the
611 file descriptors. If it's less than 20, we get the maximum value
612 available from getdtablesize(2). */
614 move_to_high_fd (fd
, check_new
, maxfd
)
615 int fd
, check_new
, maxfd
;
617 int script_fd
, nfds
, ignore
;
621 nfds
= getdtablesize ();
624 if (nfds
> HIGH_FD_MAX
)
625 nfds
= HIGH_FD_MAX
; /* reasonable maximum */
630 for (nfds
--; check_new
&& nfds
> 3; nfds
--)
631 if (fcntl (nfds
, F_GETFD
, &ignore
) == -1)
634 if (nfds
> 3 && fd
!= nfds
&& (script_fd
= dup2 (fd
, nfds
)) != -1)
636 if (check_new
== 0 || fd
!= fileno (stderr
)) /* don't close stderr */
641 /* OK, we didn't find one less than our artificial maximum; return the
642 original file descriptor. */
646 /* Return non-zero if the characters from SAMPLE are not all valid
647 characters to be found in the first line of a shell script. We
648 check up to the first newline, or SAMPLE_LEN, whichever comes first.
649 All of the characters must be printable or whitespace. */
652 check_binary_file (sample
, sample_len
)
659 for (i
= 0; i
< sample_len
; i
++)
671 /* **************************************************************** */
673 /* Functions to manipulate pipes */
675 /* **************************************************************** */
683 if ((r
= pipe (pv
)) < 0)
686 pv
[0] = move_to_high_fd (pv
[0], 1, 64);
687 pv
[1] = move_to_high_fd (pv
[1], 1, 64);
706 /* **************************************************************** */
708 /* Functions to inspect pathnames */
710 /* **************************************************************** */
718 return (stat (fn
, &sb
) == 0);
727 return ((stat (fn
, &sb
) == 0) && S_ISDIR (sb
.st_mode
));
734 return (file_isdir (fn
) && sh_eaccess (fn
, W_OK
) == 0);
737 /* Return 1 if STRING is "." or "..", optionally followed by a directory
740 path_dot_or_dotdot (string
)
743 if (string
== 0 || *string
== '\0' || *string
!= '.')
746 /* string[0] == '.' */
747 if (PATHSEP(string
[1]) || (string
[1] == '.' && PATHSEP(string
[2])))
753 /* Return 1 if STRING contains an absolute pathname, else 0. Used by `cd'
754 to decide whether or not to look up a directory name in $CDPATH. */
756 absolute_pathname (string
)
759 if (string
== 0 || *string
== '\0')
765 if (string
[0] == '.' && PATHSEP(string
[1])) /* . and ./ */
768 if (string
[0] == '.' && string
[1] == '.' && PATHSEP(string
[2])) /* .. and ../ */
774 /* Return 1 if STRING is an absolute program name; it is absolute if it
775 contains any slashes. This is used to decide whether or not to look
778 absolute_program (string
)
781 return ((char *)mbschr (string
, '/') != (char *)NULL
);
784 /* **************************************************************** */
786 /* Functions to manipulate pathnames */
788 /* **************************************************************** */
790 /* Turn STRING (a pathname) into an absolute pathname, assuming that
791 DOT_PATH contains the symbolic location of `.'. This always
792 returns a new string, even if STRING was an absolute pathname to
795 make_absolute (string
, dot_path
)
796 const char *string
, *dot_path
;
800 if (dot_path
== 0 || ABSPATH(string
))
803 char pathbuf
[PATH_MAX
+ 1];
805 /* WAS cygwin_conv_to_full_posix_path (string, pathbuf); */
806 cygwin_conv_path (CCP_WIN_A_TO_POSIX
, string
, pathbuf
, PATH_MAX
);
807 result
= savestring (pathbuf
);
810 result
= savestring (string
);
813 result
= sh_makepath (dot_path
, string
, 0);
818 /* Return the `basename' of the pathname in STRING (the stuff after the
819 last '/'). If STRING is `/', just return it. */
821 base_pathname (string
)
827 if (absolute_pathname (string
) == 0)
831 if (string
[0] == '/' && string
[1] == 0)
834 p
= (char *)strrchr (string
, '/');
835 return (p
? ++p
: string
);
838 /* Return the full pathname of FILE. Easy. Filenames that begin
839 with a '/' are returned as themselves. Other filenames have
840 the current working directory prepended. A new string is
841 returned in either case. */
848 file
= (*file
== '~') ? bash_tilde_expand (file
, 0) : savestring (file
);
853 ret
= sh_makepath ((char *)NULL
, file
, (MP_DOCWD
|MP_RMDOT
));
859 /* A slightly related function. Get the prettiest name of this
860 directory possible. */
861 static char tdir
[PATH_MAX
];
863 /* Return a pretty pathname. If the first part of the pathname is
864 the same as $HOME, then replace that with `~'. */
866 polite_directory_format (name
)
872 home
= get_string_value ("HOME");
873 l
= home
? strlen (home
) : 0;
874 if (l
> 1 && strncmp (home
, name
, l
) == 0 && (!name
[l
] || name
[l
] == '/'))
876 strncpy (tdir
+ 1, name
+ l
, sizeof(tdir
) - 2);
878 tdir
[sizeof(tdir
) - 1] = '\0';
885 /* Trim NAME. If NAME begins with `~/', skip over tilde prefix. Trim to
886 keep any tilde prefix and PROMPT_DIRTRIM trailing directory components
887 and replace the intervening characters with `...' */
889 trim_pathname (name
, maxlen
)
895 char *nbeg
, *nend
, *ntail
, *v
;
897 if (name
== 0 || (nlen
= strlen (name
)) == 0)
901 v
= get_string_value ("PROMPT_DIRTRIM");
902 if (v
== 0 || *v
== 0)
904 if (legal_number (v
, &nskip
) == 0 || nskip
<= 0)
907 /* Skip over tilde prefix */
910 for (nbeg
= name
; *nbeg
; nbeg
++)
919 for (ndirs
= 0, ntail
= nbeg
; *ntail
; ntail
++)
925 for (ntail
= (*nend
== '/') ? nend
: nend
- 1; ntail
> nbeg
; ntail
--)
935 /* Now we want to return name[0..nbeg]+"..."+ntail, modifying name in place */
945 memmove (nbeg
, ntail
, nlen
);
951 /* Return a printable representation of FN without special characters. The
952 caller is responsible for freeing memory if this returns something other
953 than its argument. If FLAGS is non-zero, we are printing for portable
954 re-input and should single-quote filenames appropriately. */
956 printable_filename (fn
, flags
)
962 if (ansic_shouldquote (fn
))
963 newf
= ansic_quote (fn
, 0, NULL
);
964 else if (flags
&& sh_contains_shell_metas (fn
))
965 newf
= sh_single_quote (fn
);
972 /* Given a string containing units of information separated by colons,
973 return the next one pointed to by (P_INDEX), or NULL if there are no more.
974 Advance (P_INDEX) to the character after the colon. */
976 extract_colon_unit (string
, p_index
)
986 len
= strlen (string
);
988 return ((char *)NULL
);
992 /* Each call to this routine leaves the index pointing at a colon if
993 there is more to the path. If I is > 0, then increment past the
994 `:'. If I is 0, then the path has a leading colon. Trailing colons
995 are handled OK by the `else' part of the if statement; an empty
996 string is returned in that case. */
997 if (i
&& string
[i
] == ':')
1000 for (start
= i
; string
[i
] && string
[i
] != ':'; i
++)
1009 /* Return "" in the case of a trailing `:'. */
1010 value
= (char *)xmalloc (1);
1014 value
= substring (string
, start
, i
);
1019 /* **************************************************************** */
1021 /* Tilde Initialization and Expansion */
1023 /* **************************************************************** */
1025 #if defined (PUSHD_AND_POPD)
1026 extern char *get_dirstack_from_string
__P((char *));
1029 static char **bash_tilde_prefixes
;
1030 static char **bash_tilde_prefixes2
;
1031 static char **bash_tilde_suffixes
;
1032 static char **bash_tilde_suffixes2
;
1034 /* If tilde_expand hasn't been able to expand the text, perhaps it
1035 is a special shell expansion. This function is installed as the
1036 tilde_expansion_preexpansion_hook. It knows how to expand ~- and ~+.
1037 If PUSHD_AND_POPD is defined, ~[+-]N expands to directories from the
1040 bash_special_tilde_expansions (text
)
1045 result
= (char *)NULL
;
1047 if (text
[0] == '+' && text
[1] == '\0')
1048 result
= get_string_value ("PWD");
1049 else if (text
[0] == '-' && text
[1] == '\0')
1050 result
= get_string_value ("OLDPWD");
1051 #if defined (PUSHD_AND_POPD)
1052 else if (DIGIT (*text
) || ((*text
== '+' || *text
== '-') && DIGIT (text
[1])))
1053 result
= get_dirstack_from_string (text
);
1056 return (result
? savestring (result
) : (char *)NULL
);
1059 /* Initialize the tilde expander. In Bash, we handle `~-' and `~+', as
1060 well as handling special tilde prefixes; `:~" and `=~' are indications
1061 that we should do tilde expansion. */
1065 static int times_called
= 0;
1067 /* Tell the tilde expander that we want a crack first. */
1068 tilde_expansion_preexpansion_hook
= bash_special_tilde_expansions
;
1070 /* Tell the tilde expander about special strings which start a tilde
1071 expansion, and the special strings that end one. Only do this once.
1072 tilde_initialize () is called from within bashline_reinitialize (). */
1073 if (times_called
++ == 0)
1075 bash_tilde_prefixes
= strvec_create (3);
1076 bash_tilde_prefixes
[0] = "=~";
1077 bash_tilde_prefixes
[1] = ":~";
1078 bash_tilde_prefixes
[2] = (char *)NULL
;
1080 bash_tilde_prefixes2
= strvec_create (2);
1081 bash_tilde_prefixes2
[0] = ":~";
1082 bash_tilde_prefixes2
[1] = (char *)NULL
;
1084 tilde_additional_prefixes
= bash_tilde_prefixes
;
1086 bash_tilde_suffixes
= strvec_create (3);
1087 bash_tilde_suffixes
[0] = ":";
1088 bash_tilde_suffixes
[1] = "=~"; /* XXX - ?? */
1089 bash_tilde_suffixes
[2] = (char *)NULL
;
1091 tilde_additional_suffixes
= bash_tilde_suffixes
;
1093 bash_tilde_suffixes2
= strvec_create (2);
1094 bash_tilde_suffixes2
[0] = ":";
1095 bash_tilde_suffixes2
[1] = (char *)NULL
;
1099 /* POSIX.2, 3.6.1: A tilde-prefix consists of an unquoted tilde character
1100 at the beginning of the word, followed by all of the characters preceding
1101 the first unquoted slash in the word, or all the characters in the word
1102 if there is no slash...If none of the characters in the tilde-prefix are
1103 quoted, the characters in the tilde-prefix following the tilde shell be
1104 treated as a possible login name. */
1106 #define TILDE_END(c) ((c) == '\0' || (c) == '/' || (c) == ':')
1109 unquoted_tilde_word (s
)
1114 for (r
= s
; TILDE_END(*r
) == 0; r
++)
1127 /* Find the end of the tilde-prefix starting at S, and return the tilde
1128 prefix in newly-allocated memory. Return the length of the string in
1129 *LENP. FLAGS tells whether or not we're in an assignment context --
1130 if so, `:' delimits the end of the tilde prefix as well. */
1132 bash_tilde_find_word (s
, flags
, lenp
)
1140 for (r
= s
; *r
&& *r
!= '/'; r
++)
1142 /* Short-circuit immediately if we see a quote character. Even though
1143 POSIX says that `the first unquoted slash' (or `:') terminates the
1144 tilde-prefix, in practice, any quoted portion of the tilde prefix
1145 will cause it to not be expanded. */
1146 if (*r
== '\\' || *r
== '\'' || *r
== '"')
1148 ret
= savestring (s
);
1153 else if (flags
&& *r
== ':')
1157 ret
= xmalloc (l
+ 1);
1158 strncpy (ret
, s
, l
);
1165 /* Tilde-expand S by running it through the tilde expansion library.
1166 ASSIGN_P is 1 if this is a variable assignment, so the alternate
1167 tilde prefixes should be enabled (`=~' and `:~', see above). If
1168 ASSIGN_P is 2, we are expanding the rhs of an assignment statement,
1169 so `=~' is not valid. */
1171 bash_tilde_expand (s
, assign_p
)
1175 int old_immed
, old_term
, r
;
1179 old_immed
= interrupt_immediately
;
1180 old_term
= terminate_immediately
;
1181 /* We want to be able to interrupt tilde expansion. Ordinarily, we can just
1182 jump to top_level, but we don't want to run any trap commands in a signal
1183 handler context. We might be able to get away with just checking for
1184 things like SIGINT and SIGQUIT. */
1185 if (any_signals_trapped () < 0)
1186 interrupt_immediately
= 1;
1187 terminate_immediately
= 1;
1190 tilde_additional_prefixes
= assign_p
== 0 ? (char **)0
1191 : (assign_p
== 2 ? bash_tilde_prefixes2
: bash_tilde_prefixes
);
1193 tilde_additional_suffixes
= bash_tilde_suffixes2
;
1195 r
= (*s
== '~') ? unquoted_tilde_word (s
) : 1;
1196 ret
= r
? tilde_expand (s
) : savestring (s
);
1199 interrupt_immediately
= old_immed
;
1200 terminate_immediately
= old_term
;
1208 /* **************************************************************** */
1210 /* Functions to manipulate and search the group list */
1212 /* **************************************************************** */
1214 static int ngroups
, maxgroups
;
1216 /* The set of groups that this user is a member of. */
1217 static GETGROUPS_T
*group_array
= (GETGROUPS_T
*)NULL
;
1219 #if !defined (NOGROUP)
1220 # define NOGROUP (gid_t) -1
1224 initialize_group_array ()
1229 maxgroups
= getmaxgroups ();
1232 group_array
= (GETGROUPS_T
*)xrealloc (group_array
, maxgroups
* sizeof (GETGROUPS_T
));
1234 #if defined (HAVE_GETGROUPS)
1235 ngroups
= getgroups (maxgroups
, group_array
);
1238 /* If getgroups returns nothing, or the OS does not support getgroups(),
1239 make sure the groups array includes at least the current gid. */
1242 group_array
[0] = current_user
.gid
;
1246 /* If the primary group is not in the groups array, add it as group_array[0]
1247 and shuffle everything else up 1, if there's room. */
1248 for (i
= 0; i
< ngroups
; i
++)
1249 if (current_user
.gid
== (gid_t
)group_array
[i
])
1251 if (i
== ngroups
&& ngroups
< maxgroups
)
1253 for (i
= ngroups
; i
> 0; i
--)
1254 group_array
[i
] = group_array
[i
- 1];
1255 group_array
[0] = current_user
.gid
;
1259 /* If the primary group is not group_array[0], swap group_array[0] and
1260 whatever the current group is. The vast majority of systems should
1261 not need this; a notable exception is Linux. */
1262 if (group_array
[0] != current_user
.gid
)
1264 for (i
= 0; i
< ngroups
; i
++)
1265 if (group_array
[i
] == current_user
.gid
)
1269 group_array
[i
] = group_array
[0];
1270 group_array
[0] = current_user
.gid
;
1275 /* Return non-zero if GID is one that we have in our groups list. */
1277 #if defined (__STDC__) || defined ( _MINIX)
1278 group_member (gid_t gid
)
1282 #endif /* !__STDC__ && !_MINIX */
1284 #if defined (HAVE_GETGROUPS)
1288 /* Short-circuit if possible, maybe saving a call to getgroups(). */
1289 if (gid
== current_user
.gid
|| gid
== current_user
.egid
)
1292 #if defined (HAVE_GETGROUPS)
1294 initialize_group_array ();
1296 /* In case of error, the user loses. */
1300 /* Search through the list looking for GID. */
1301 for (i
= 0; i
< ngroups
; i
++)
1302 if (gid
== (gid_t
)group_array
[i
])
1310 get_group_list (ngp
)
1313 static char **group_vector
= (char **)NULL
;
1320 return group_vector
;
1324 initialize_group_array ();
1330 return (char **)NULL
;
1333 group_vector
= strvec_create (ngroups
);
1334 for (i
= 0; i
< ngroups
; i
++)
1335 group_vector
[i
] = itos (group_array
[i
]);
1339 return group_vector
;
1343 get_group_array (ngp
)
1347 static int *group_iarray
= (int *)NULL
;
1353 return (group_iarray
);
1357 initialize_group_array ();
1366 group_iarray
= (int *)xmalloc (ngroups
* sizeof (int));
1367 for (i
= 0; i
< ngroups
; i
++)
1368 group_iarray
[i
] = (int)group_array
[i
];
1372 return group_iarray
;
1375 /* **************************************************************** */
1377 /* Miscellaneous functions */
1379 /* **************************************************************** */
1381 /* Return a value for PATH that is guaranteed to find all of the standard
1382 utilities. This uses Posix.2 configuration variables, if present. It
1383 uses a value defined in config.h as a last resort. */
1385 conf_standard_path ()
1387 #if defined (_CS_PATH) && defined (HAVE_CONFSTR)
1391 len
= (size_t)confstr (_CS_PATH
, (char *)NULL
, (size_t)0);
1394 p
= (char *)xmalloc (len
+ 2);
1396 confstr (_CS_PATH
, p
, len
);
1400 return (savestring (STANDARD_UTILS_PATH
));
1401 #else /* !_CS_PATH || !HAVE_CONFSTR */
1402 # if defined (CS_PATH)
1403 return (savestring (CS_PATH
));
1405 return (savestring (STANDARD_UTILS_PATH
));
1406 # endif /* !CS_PATH */
1407 #endif /* !_CS_PATH || !HAVE_CONFSTR */
1417 v
= get_string_value ("COLUMNS");
1425 if (check_window_size
)
1426 get_new_window_size (0, (int *)0, &c
);
1428 return (c
> 0 ? c
: 80);