blob: 9542963aa2d04f9f2465da119c89e8dfb526c80e [file] [log] [blame]
Jari Aalto726f6381996-08-26 18:22:31 +00001/* general.c -- Stuff that is used by all files. */
2
Chet Rameya0c0a002016-09-15 16:59:08 -04003/* Copyright (C) 1987-2016 Free Software Foundation, Inc.
Jari Aalto726f6381996-08-26 18:22:31 +00004
5 This file is part of GNU Bash, the Bourne Again SHell.
6
Jari Aalto31859422009-01-12 13:36:28 +00007 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.
Jari Aalto726f6381996-08-26 18:22:31 +000011
Jari Aalto31859422009-01-12 13:36:28 +000012 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.
Jari Aalto726f6381996-08-26 18:22:31 +000016
Jari Aalto31859422009-01-12 13:36:28 +000017 You should have received a copy of the GNU General Public License
18 along with Bash. If not, see <http://www.gnu.org/licenses/>.
19*/
Jari Aalto726f6381996-08-26 18:22:31 +000020
Jari Aaltoccc6cda1996-12-23 17:02:34 +000021#include "config.h"
22
23#include "bashtypes.h"
Chet Rameyac50fba2014-02-26 09:36:43 -050024#if defined (HAVE_SYS_PARAM_H)
Jari Aaltocce855b1998-04-17 19:52:44 +000025# include <sys/param.h>
26#endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +000027#include "posixstat.h"
28
29#if defined (HAVE_UNISTD_H)
30# include <unistd.h>
31#endif
32
33#include "filecntl.h"
34#include "bashansi.h"
Jari Aalto726f6381996-08-26 18:22:31 +000035#include <stdio.h>
Jari Aaltof73dda02001-11-13 17:56:06 +000036#include "chartypes.h"
Jari Aalto726f6381996-08-26 18:22:31 +000037#include <errno.h>
Jari Aaltoccc6cda1996-12-23 17:02:34 +000038
Jari Aaltob80f6442004-07-27 13:29:18 +000039#include "bashintl.h"
40
Jari Aalto726f6381996-08-26 18:22:31 +000041#include "shell.h"
Chet Rameyd233b482019-01-07 09:27:52 -050042#include "parser.h"
43#include "flags.h"
44#include "findcmd.h"
Jari Aalto95732b42005-12-07 14:08:12 +000045#include "test.h"
Chet Rameyac50fba2014-02-26 09:36:43 -050046#include "trap.h"
Jari Aalto95732b42005-12-07 14:08:12 +000047
Chet Rameyd233b482019-01-07 09:27:52 -050048#include "builtins/common.h"
49
Chet Rameya0c0a002016-09-15 16:59:08 -040050#if defined (HAVE_MBSTR_H) && defined (HAVE_MBSCHR)
51# include <mbstr.h> /* mbschr */
52#endif
53
Jari Aalto726f6381996-08-26 18:22:31 +000054#include <tilde/tilde.h>
55
Jari Aalto726f6381996-08-26 18:22:31 +000056#if !defined (errno)
57extern int errno;
58#endif /* !errno */
59
Chet Rameyd233b482019-01-07 09:27:52 -050060#ifdef __CYGWIN__
61# include <sys/cygwin.h>
62#endif
Jari Aaltocce855b1998-04-17 19:52:44 +000063
Jari Aalto7117c2d2002-07-17 14:10:11 +000064static char *bash_special_tilde_expansions __P((char *));
65static int unquoted_tilde_word __P((const char *));
66static void initialize_group_array __P((void));
67
Jari Aaltocce855b1998-04-17 19:52:44 +000068/* A standard error message to use when getcwd() returns NULL. */
Jari Aalto31859422009-01-12 13:36:28 +000069const char * const bash_getcwd_errstr = N_("getcwd: cannot access parent directories");
Jari Aalto726f6381996-08-26 18:22:31 +000070
Chet Rameyd233b482019-01-07 09:27:52 -050071/* Do whatever is necessary to initialize `Posix mode'. This currently
72 modifies the following variables which are controlled via shopt:
73 interactive_comments
74 source_uses_path
75 expand_aliases
76 inherit_errexit
77 print_shift_error
78
79 and the following variables which cannot be user-modified:
80
81 source_searches_cwd
82
83 If we add to the first list, we need to change the table and functions
84 below */
85
86static struct {
87 int *posix_mode_var;
88} posix_vars[] =
89{
90 &interactive_comments,
91 &source_uses_path,
92 &expand_aliases,
93 &inherit_errexit,
94 &print_shift_error,
95 0
96};
97
Jari Aalto726f6381996-08-26 18:22:31 +000098void
Jari Aaltoccc6cda1996-12-23 17:02:34 +000099posix_initialize (on)
100 int on;
Jari Aalto726f6381996-08-26 18:22:31 +0000101{
Jari Aalto28ef6c32001-04-06 19:14:31 +0000102 /* Things that should be turned on when posix mode is enabled. */
103 if (on != 0)
104 {
105 interactive_comments = source_uses_path = expand_aliases = 1;
Chet Rameya0c0a002016-09-15 16:59:08 -0400106 inherit_errexit = 1;
Jari Aalto31859422009-01-12 13:36:28 +0000107 source_searches_cwd = 0;
Chet Rameyd233b482019-01-07 09:27:52 -0500108 print_shift_error = 1;
109
Jari Aalto28ef6c32001-04-06 19:14:31 +0000110 }
111
112 /* Things that should be turned on when posix mode is disabled. */
113 if (on == 0)
114 {
115 source_searches_cwd = 1;
116 expand_aliases = interactive_shell;
Chet Rameyd233b482019-01-07 09:27:52 -0500117 print_shift_error = 0;
Jari Aalto28ef6c32001-04-06 19:14:31 +0000118 }
Jari Aalto726f6381996-08-26 18:22:31 +0000119}
120
Chet Rameyd233b482019-01-07 09:27:52 -0500121int
122num_posix_options ()
123{
124 return ((sizeof (posix_vars) / sizeof (posix_vars[0])) - 1);
125}
126
127char *
128get_posix_options (bitmap)
129 char *bitmap;
130{
131 register int i;
132
133 if (bitmap == 0)
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);
137 return bitmap;
138}
139
140void
141set_posix_options (bitmap)
142 const char *bitmap;
143{
144 register int i;
145
146 for (i = 0; posix_vars[i].posix_mode_var; i++)
147 *(posix_vars[i].posix_mode_var) = bitmap[i];
148}
149
Jari Aalto726f6381996-08-26 18:22:31 +0000150/* **************************************************************** */
151/* */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000152/* Functions to convert to and from and display non-standard types */
153/* */
154/* **************************************************************** */
155
Jari Aalto726f6381996-08-26 18:22:31 +0000156#if defined (RLIMTYPE)
157RLIMTYPE
158string_to_rlimtype (s)
159 char *s;
160{
Jari Aaltocce855b1998-04-17 19:52:44 +0000161 RLIMTYPE ret;
162 int neg;
Jari Aalto726f6381996-08-26 18:22:31 +0000163
Jari Aaltocce855b1998-04-17 19:52:44 +0000164 ret = 0;
165 neg = 0;
Jari Aalto726f6381996-08-26 18:22:31 +0000166 while (s && *s && whitespace (*s))
167 s++;
Chet Ramey00018032011-11-21 20:51:19 -0500168 if (s && (*s == '-' || *s == '+'))
Jari Aalto726f6381996-08-26 18:22:31 +0000169 {
170 neg = *s == '-';
171 s++;
172 }
Jari Aaltof73dda02001-11-13 17:56:06 +0000173 for ( ; s && *s && DIGIT (*s); s++)
174 ret = (ret * 10) + TODIGIT (*s);
Jari Aalto726f6381996-08-26 18:22:31 +0000175 return (neg ? -ret : ret);
176}
177
178void
179print_rlimtype (n, addnl)
180 RLIMTYPE n;
181 int addnl;
182{
Jari Aaltof73dda02001-11-13 17:56:06 +0000183 char s[INT_STRLEN_BOUND (RLIMTYPE) + 1], *p;
Jari Aalto726f6381996-08-26 18:22:31 +0000184
Jari Aaltof73dda02001-11-13 17:56:06 +0000185 p = s + sizeof(s);
186 *--p = '\0';
Jari Aalto726f6381996-08-26 18:22:31 +0000187
188 if (n < 0)
189 {
Jari Aaltof73dda02001-11-13 17:56:06 +0000190 do
191 *--p = '0' - n % 10;
192 while ((n /= 10) != 0);
193
194 *--p = '-';
195 }
196 else
197 {
198 do
199 *--p = '0' + n % 10;
200 while ((n /= 10) != 0);
Jari Aalto726f6381996-08-26 18:22:31 +0000201 }
202
Jari Aaltof73dda02001-11-13 17:56:06 +0000203 printf ("%s%s", p, addnl ? "\n" : "");
Jari Aalto726f6381996-08-26 18:22:31 +0000204}
205#endif /* RLIMTYPE */
206
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000207/* **************************************************************** */
208/* */
209/* Input Validation Functions */
210/* */
211/* **************************************************************** */
212
213/* Return non-zero if all of the characters in STRING are digits. */
214int
215all_digits (string)
Chet Rameya0c0a002016-09-15 16:59:08 -0400216 const char *string;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000217{
Chet Rameya0c0a002016-09-15 16:59:08 -0400218 register const char *s;
Jari Aalto28ef6c32001-04-06 19:14:31 +0000219
220 for (s = string; *s; s++)
Jari Aaltof73dda02001-11-13 17:56:06 +0000221 if (DIGIT (*s) == 0)
Jari Aalto28ef6c32001-04-06 19:14:31 +0000222 return (0);
223
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000224 return (1);
225}
226
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
Jari Aaltof73dda02001-11-13 17:56:06 +0000229 not null. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000230int
231legal_number (string, result)
Jari Aalto31859422009-01-12 13:36:28 +0000232 const char *string;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000233 intmax_t *result;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000234{
Jari Aalto7117c2d2002-07-17 14:10:11 +0000235 intmax_t value;
Jari Aaltocce855b1998-04-17 19:52:44 +0000236 char *ep;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000237
238 if (result)
239 *result = 0;
240
Chet Rameyac50fba2014-02-26 09:36:43 -0500241 if (string == 0)
242 return 0;
243
Jari Aaltof73dda02001-11-13 17:56:06 +0000244 errno = 0;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000245 value = strtoimax (string, &ep, 10);
Jari Aalto31859422009-01-12 13:36:28 +0000246 if (errno || ep == string)
Jari Aaltof73dda02001-11-13 17:56:06 +0000247 return 0; /* errno is set on overflow or underflow */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000248
Jari Aalto7117c2d2002-07-17 14:10:11 +0000249 /* Skip any trailing whitespace, since strtoimax does not. */
Jari Aalto28ef6c32001-04-06 19:14:31 +0000250 while (whitespace (*ep))
251 ep++;
252
Jari Aaltocce855b1998-04-17 19:52:44 +0000253 /* If *string is not '\0' but *ep is '\0' on return, the entire string
254 is valid. */
Chet Rameyac50fba2014-02-26 09:36:43 -0500255 if (*string && *ep == '\0')
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000256 {
257 if (result)
Jari Aaltocce855b1998-04-17 19:52:44 +0000258 *result = value;
259 /* The SunOS4 implementation of strtol() will happily ignore
260 overflow conditions, so this cannot do overflow correctly
261 on those systems. */
262 return 1;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000263 }
Jari Aaltocce855b1998-04-17 19:52:44 +0000264
265 return (0);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000266}
267
Jari Aalto726f6381996-08-26 18:22:31 +0000268/* 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
270 digit. */
271int
272legal_identifier (name)
Chet Rameya0c0a002016-09-15 16:59:08 -0400273 const char *name;
Jari Aalto726f6381996-08-26 18:22:31 +0000274{
Chet Rameya0c0a002016-09-15 16:59:08 -0400275 register const char *s;
Jari Aaltof73dda02001-11-13 17:56:06 +0000276 unsigned char c;
Jari Aalto726f6381996-08-26 18:22:31 +0000277
Jari Aaltof73dda02001-11-13 17:56:06 +0000278 if (!name || !(c = *name) || (legal_variable_starter (c) == 0))
Jari Aalto726f6381996-08-26 18:22:31 +0000279 return (0);
280
Jari Aaltof73dda02001-11-13 17:56:06 +0000281 for (s = name + 1; (c = *s) != 0; s++)
Jari Aalto726f6381996-08-26 18:22:31 +0000282 {
Jari Aaltof73dda02001-11-13 17:56:06 +0000283 if (legal_variable_char (c) == 0)
Jari Aalto28ef6c32001-04-06 19:14:31 +0000284 return (0);
Jari Aalto726f6381996-08-26 18:22:31 +0000285 }
286 return (1);
287}
288
Chet Rameya0c0a002016-09-15 16:59:08 -0400289/* 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. */
294int
295valid_nameref_value (name, flags)
296 const char *name;
297 int flags;
298{
299 if (name == 0 || *name == 0)
300 return 0;
301
302 /* valid identifier */
303#if defined (ARRAY_VARS)
304 if (legal_identifier (name) || (flags != 2 && valid_array_reference (name, 0)))
305#else
306 if (legal_identifier (name))
307#endif
308 return 1;
309
310 return 0;
311}
312
313int
314check_selfref (name, value, flags)
315 const char *name;
316 char *value;
317 int flags;
318{
319 char *t;
320
321 if (STREQ (name, value))
322 return 1;
323
324#if defined (ARRAY_VARS)
325 if (valid_array_reference (value, 0))
326 {
Chet Rameyd233b482019-01-07 09:27:52 -0500327 t = array_variable_name (value, 0, (char **)NULL, (int *)NULL);
Chet Rameya0c0a002016-09-15 16:59:08 -0400328 if (t && STREQ (name, t))
329 {
330 free (t);
331 return 1;
332 }
333 free (t);
334 }
335#endif
336
337 return 0; /* not a self reference */
338}
339
Jari Aalto726f6381996-08-26 18:22:31 +0000340/* 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. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000345int
Jari Aalto726f6381996-08-26 18:22:31 +0000346check_identifier (word, check_word)
347 WORD_DESC *word;
348 int check_word;
349{
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000350 if ((word->flags & (W_HASDOLLAR|W_QUOTED)) || all_digits (word->word))
Jari Aalto726f6381996-08-26 18:22:31 +0000351 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000352 internal_error (_("`%s': not a valid identifier"), word->word);
Jari Aalto726f6381996-08-26 18:22:31 +0000353 return (0);
354 }
355 else if (check_word && legal_identifier (word->word) == 0)
356 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000357 internal_error (_("`%s': not a valid identifier"), word->word);
Jari Aalto726f6381996-08-26 18:22:31 +0000358 return (0);
359 }
360 else
361 return (1);
362}
363
Chet Rameya0c0a002016-09-15 16:59:08 -0400364/* 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
368 used yet. */
369int
370importable_function_name (string, len)
371 const char *string;
372 size_t len;
373{
374 if (absolute_program (string)) /* don't allow slash */
375 return 0;
376 if (*string == '\n') /* can't start with a newline */
377 return 0;
378 if (shellblank (*string) || shellblank(string[len-1]))
379 return 0;
380 return (posixly_correct ? legal_identifier (string) : 1);
381}
382
383int
384exportable_function_name (string)
385 const char *string;
386{
387 if (absolute_program (string))
388 return 0;
389 if (mbschr (string, '=') != 0)
390 return 0;
391 return 1;
392}
393
Jari Aaltob80f6442004-07-27 13:29:18 +0000394/* 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 `/'. */
397int
398legal_alias_name (string, flags)
Chet Rameya0c0a002016-09-15 16:59:08 -0400399 const char *string;
Jari Aaltob80f6442004-07-27 13:29:18 +0000400 int flags;
401{
Chet Rameya0c0a002016-09-15 16:59:08 -0400402 register const char *s;
Jari Aaltob80f6442004-07-27 13:29:18 +0000403
404 for (s = string; *s; s++)
405 if (shellbreak (*s) || shellxquote (*s) || shellexp (*s) || (*s == '/'))
406 return 0;
407 return 1;
408}
409
Jari Aalto7117c2d2002-07-17 14:10:11 +0000410/* Returns non-zero if STRING is an assignment statement. The returned value
Chet Rameyd233b482019-01-07 09:27:52 -0500411 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 `='. */
Jari Aalto7117c2d2002-07-17 14:10:11 +0000413int
Jari Aaltob80f6442004-07-27 13:29:18 +0000414assignment (string, flags)
Jari Aalto7117c2d2002-07-17 14:10:11 +0000415 const char *string;
Jari Aaltob80f6442004-07-27 13:29:18 +0000416 int flags;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000417{
418 register unsigned char c;
419 register int newi, indx;
420
421 c = string[indx = 0];
422
Jari Aaltob80f6442004-07-27 13:29:18 +0000423#if defined (ARRAY_VARS)
Chet Rameyd233b482019-01-07 09:27:52 -0500424 if ((legal_variable_starter (c) == 0) && ((flags&1) == 0 || c != '[')) /* ] */
Jari Aaltob80f6442004-07-27 13:29:18 +0000425#else
Jari Aalto7117c2d2002-07-17 14:10:11 +0000426 if (legal_variable_starter (c) == 0)
Jari Aaltob80f6442004-07-27 13:29:18 +0000427#endif
Jari Aalto7117c2d2002-07-17 14:10:11 +0000428 return (0);
429
430 while (c = string[indx])
431 {
432 /* The following is safe. Note that '=' at the start of a word
433 is not an assignment statement. */
434 if (c == '=')
435 return (indx);
436
437#if defined (ARRAY_VARS)
438 if (c == '[')
439 {
Chet Rameyd233b482019-01-07 09:27:52 -0500440 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? */
Jari Aalto7117c2d2002-07-17 14:10:11 +0000443 if (string[newi++] != ']')
444 return (0);
Jari Aalto95732b42005-12-07 14:08:12 +0000445 if (string[newi] == '+' && string[newi+1] == '=')
446 return (newi + 1);
Jari Aalto7117c2d2002-07-17 14:10:11 +0000447 return ((string[newi] == '=') ? newi : 0);
448 }
449#endif /* ARRAY_VARS */
450
Jari Aalto95732b42005-12-07 14:08:12 +0000451 /* Check for `+=' */
452 if (c == '+' && string[indx+1] == '=')
453 return (indx + 1);
454
Jari Aalto7117c2d2002-07-17 14:10:11 +0000455 /* Variable names in assignment statements may contain only letters,
456 digits, and `_'. */
457 if (legal_variable_char (c) == 0)
458 return (0);
459
460 indx++;
461 }
462 return (0);
463}
464
Chet Rameyd233b482019-01-07 09:27:52 -0500465int
466line_isblank (line)
467 const char *line;
468{
469 register int i;
470
471 if (line == 0)
472 return 0; /* XXX */
473 for (i = 0; line[i]; i++)
474 if (isblank ((unsigned char)line[i]) == 0)
475 break;
476 return (line[i] == '\0');
477}
478
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000479/* **************************************************************** */
480/* */
481/* Functions to manage files and file descriptors */
482/* */
483/* **************************************************************** */
484
Jari Aalto726f6381996-08-26 18:22:31 +0000485/* 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. */
488
489#if !defined (O_NDELAY)
490# if defined (FNDELAY)
491# define O_NDELAY FNDELAY
492# endif
493#endif /* O_NDELAY */
494
495/* Make sure no-delay mode is not set on file descriptor FD. */
Jari Aaltobb706242000-03-17 21:46:59 +0000496int
Jari Aalto28ef6c32001-04-06 19:14:31 +0000497sh_unset_nodelay_mode (fd)
Jari Aalto726f6381996-08-26 18:22:31 +0000498 int fd;
499{
Jari Aaltobb706242000-03-17 21:46:59 +0000500 int flags, bflags;
Jari Aalto726f6381996-08-26 18:22:31 +0000501
502 if ((flags = fcntl (fd, F_GETFL, 0)) < 0)
Jari Aaltobb706242000-03-17 21:46:59 +0000503 return -1;
Jari Aalto726f6381996-08-26 18:22:31 +0000504
Jari Aaltobb706242000-03-17 21:46:59 +0000505 bflags = 0;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000506
507 /* This is defined to O_NDELAY in filecntl.h if O_NONBLOCK is not present
508 and O_NDELAY is defined. */
Jari Aaltobb706242000-03-17 21:46:59 +0000509#ifdef O_NONBLOCK
510 bflags |= O_NONBLOCK;
511#endif
512
513#ifdef O_NDELAY
514 bflags |= O_NDELAY;
515#endif
516
517 if (flags & bflags)
Jari Aalto726f6381996-08-26 18:22:31 +0000518 {
Jari Aaltobb706242000-03-17 21:46:59 +0000519 flags &= ~bflags;
520 return (fcntl (fd, F_SETFL, flags));
Jari Aalto726f6381996-08-26 18:22:31 +0000521 }
Jari Aalto726f6381996-08-26 18:22:31 +0000522
Jari Aaltobb706242000-03-17 21:46:59 +0000523 return 0;
Jari Aalto726f6381996-08-26 18:22:31 +0000524}
525
Chet Rameyd233b482019-01-07 09:27:52 -0500526/* Just a wrapper for the define in include/filecntl.h */
527int
528sh_setclexec (fd)
529 int fd;
530{
531 return (SET_CLOSE_ON_EXEC (fd));
532}
533
Jari Aalto7117c2d2002-07-17 14:10:11 +0000534/* Return 1 if file descriptor FD is valid; 0 otherwise. */
535int
536sh_validfd (fd)
537 int fd;
538{
539 return (fcntl (fd, F_GETFD, 0) >= 0);
540}
541
Chet Ramey495aee42011-11-22 19:11:26 -0500542int
543fd_ispipe (fd)
544 int fd;
545{
546 errno = 0;
Chet Rameya0c0a002016-09-15 16:59:08 -0400547 return ((lseek (fd, 0L, SEEK_CUR) < 0) && (errno == ESPIPE));
Chet Ramey495aee42011-11-22 19:11:26 -0500548}
549
Jari Aaltob72432f1999-02-19 17:11:39 +0000550/* There is a bug in the NeXT 2.1 rlogind that causes opens
551 of /dev/tty to fail. */
552
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. */
556# undef O_NONBLOCK
557# define O_NONBLOCK 0
558#endif /* __BEOS__ */
559
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000560void
561check_dev_tty ()
562{
563 int tty_fd;
564 char *tty;
565
Jari Aaltod166f041997-06-05 14:59:13 +0000566 tty_fd = open ("/dev/tty", O_RDWR|O_NONBLOCK);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000567
568 if (tty_fd < 0)
569 {
570 tty = (char *)ttyname (fileno (stdin));
571 if (tty == 0)
572 return;
Jari Aaltod166f041997-06-05 14:59:13 +0000573 tty_fd = open (tty, O_RDWR|O_NONBLOCK);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000574 }
Chet Rameyac50fba2014-02-26 09:36:43 -0500575 if (tty_fd >= 0)
576 close (tty_fd);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000577}
578
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. */
582int
583same_file (path1, path2, stp1, stp2)
Chet Rameya0c0a002016-09-15 16:59:08 -0400584 const char *path1, *path2;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000585 struct stat *stp1, *stp2;
586{
587 struct stat st1, st2;
588
589 if (stp1 == NULL)
590 {
591 if (stat (path1, &st1) != 0)
592 return (0);
593 stp1 = &st1;
594 }
595
596 if (stp2 == NULL)
597 {
598 if (stat (path2, &st2) != 0)
599 return (0);
600 stp2 = &st2;
601 }
602
603 return ((stp1->st_dev == stp2->st_dev) && (stp1->st_ino == stp2->st_ino));
604}
605
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
Jari Aaltod166f041997-06-05 14:59:13 +0000610 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). */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000613int
Jari Aaltod166f041997-06-05 14:59:13 +0000614move_to_high_fd (fd, check_new, maxfd)
615 int fd, check_new, maxfd;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000616{
617 int script_fd, nfds, ignore;
618
Jari Aaltod166f041997-06-05 14:59:13 +0000619 if (maxfd < 20)
620 {
621 nfds = getdtablesize ();
622 if (nfds <= 0)
623 nfds = 20;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000624 if (nfds > HIGH_FD_MAX)
625 nfds = HIGH_FD_MAX; /* reasonable maximum */
Jari Aaltod166f041997-06-05 14:59:13 +0000626 }
627 else
628 nfds = maxfd;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000629
630 for (nfds--; check_new && nfds > 3; nfds--)
631 if (fcntl (nfds, F_GETFD, &ignore) == -1)
632 break;
633
Jari Aalto7117c2d2002-07-17 14:10:11 +0000634 if (nfds > 3 && fd != nfds && (script_fd = dup2 (fd, nfds)) != -1)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000635 {
636 if (check_new == 0 || fd != fileno (stderr)) /* don't close stderr */
637 close (fd);
638 return (script_fd);
639 }
640
Jari Aalto7117c2d2002-07-17 14:10:11 +0000641 /* OK, we didn't find one less than our artificial maximum; return the
642 original file descriptor. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000643 return (fd);
644}
645
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. */
650
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000651int
652check_binary_file (sample, sample_len)
Chet Rameya0c0a002016-09-15 16:59:08 -0400653 const char *sample;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000654 int sample_len;
655{
656 register int i;
Jari Aaltof73dda02001-11-13 17:56:06 +0000657 unsigned char c;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000658
659 for (i = 0; i < sample_len; i++)
660 {
Jari Aaltof73dda02001-11-13 17:56:06 +0000661 c = sample[i];
662 if (c == '\n')
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000663 return (0);
Jari Aalto06285672006-10-10 14:15:34 +0000664 if (c == '\0')
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000665 return (1);
666 }
667
668 return (0);
669}
Jari Aalto726f6381996-08-26 18:22:31 +0000670
671/* **************************************************************** */
672/* */
Jari Aalto31859422009-01-12 13:36:28 +0000673/* Functions to manipulate pipes */
674/* */
675/* **************************************************************** */
676
677int
678sh_openpipe (pv)
679 int *pv;
680{
681 int r;
682
683 if ((r = pipe (pv)) < 0)
684 return r;
685
686 pv[0] = move_to_high_fd (pv[0], 1, 64);
687 pv[1] = move_to_high_fd (pv[1], 1, 64);
688
689 return 0;
690}
691
692int
693sh_closepipe (pv)
694 int *pv;
695{
696 if (pv[0] >= 0)
697 close (pv[0]);
698
699 if (pv[1] >= 0)
700 close (pv[1]);
701
702 pv[0] = pv[1] = -1;
703 return 0;
704}
705
706/* **************************************************************** */
707/* */
Jari Aaltob80f6442004-07-27 13:29:18 +0000708/* Functions to inspect pathnames */
709/* */
710/* **************************************************************** */
711
712int
Jari Aalto31859422009-01-12 13:36:28 +0000713file_exists (fn)
Chet Rameya0c0a002016-09-15 16:59:08 -0400714 const char *fn;
Jari Aalto31859422009-01-12 13:36:28 +0000715{
716 struct stat sb;
717
718 return (stat (fn, &sb) == 0);
719}
720
721int
Jari Aaltob80f6442004-07-27 13:29:18 +0000722file_isdir (fn)
Chet Rameya0c0a002016-09-15 16:59:08 -0400723 const char *fn;
Jari Aaltob80f6442004-07-27 13:29:18 +0000724{
725 struct stat sb;
726
727 return ((stat (fn, &sb) == 0) && S_ISDIR (sb.st_mode));
728}
729
730int
731file_iswdir (fn)
Chet Rameya0c0a002016-09-15 16:59:08 -0400732 const char *fn;
Jari Aaltob80f6442004-07-27 13:29:18 +0000733{
Jari Aalto06285672006-10-10 14:15:34 +0000734 return (file_isdir (fn) && sh_eaccess (fn, W_OK) == 0);
Jari Aaltob80f6442004-07-27 13:29:18 +0000735}
736
Chet Ramey495aee42011-11-22 19:11:26 -0500737/* Return 1 if STRING is "." or "..", optionally followed by a directory
738 separator */
739int
Chet Rameyac50fba2014-02-26 09:36:43 -0500740path_dot_or_dotdot (string)
Chet Ramey495aee42011-11-22 19:11:26 -0500741 const char *string;
742{
743 if (string == 0 || *string == '\0' || *string != '.')
744 return (0);
745
746 /* string[0] == '.' */
747 if (PATHSEP(string[1]) || (string[1] == '.' && PATHSEP(string[2])))
748 return (1);
749
750 return (0);
751}
752
Jari Aalto95732b42005-12-07 14:08:12 +0000753/* 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. */
755int
756absolute_pathname (string)
757 const char *string;
758{
759 if (string == 0 || *string == '\0')
760 return (0);
761
762 if (ABSPATH(string))
763 return (1);
764
765 if (string[0] == '.' && PATHSEP(string[1])) /* . and ./ */
766 return (1);
767
768 if (string[0] == '.' && string[1] == '.' && PATHSEP(string[2])) /* .. and ../ */
769 return (1);
770
771 return (0);
772}
773
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
776 up through $PATH. */
777int
778absolute_program (string)
779 const char *string;
780{
Chet Ramey00018032011-11-21 20:51:19 -0500781 return ((char *)mbschr (string, '/') != (char *)NULL);
Jari Aalto95732b42005-12-07 14:08:12 +0000782}
Jari Aaltob80f6442004-07-27 13:29:18 +0000783
784/* **************************************************************** */
785/* */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000786/* Functions to manipulate pathnames */
Jari Aalto726f6381996-08-26 18:22:31 +0000787/* */
788/* **************************************************************** */
789
Jari Aalto726f6381996-08-26 18:22:31 +0000790/* 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
793 begin with. */
794char *
795make_absolute (string, dot_path)
Chet Rameya0c0a002016-09-15 16:59:08 -0400796 const char *string, *dot_path;
Jari Aalto726f6381996-08-26 18:22:31 +0000797{
798 char *result;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000799
Jari Aalto28ef6c32001-04-06 19:14:31 +0000800 if (dot_path == 0 || ABSPATH(string))
Jari Aaltob80f6442004-07-27 13:29:18 +0000801#ifdef __CYGWIN__
802 {
803 char pathbuf[PATH_MAX + 1];
804
Chet Rameyd233b482019-01-07 09:27:52 -0500805 /* WAS cygwin_conv_to_full_posix_path (string, pathbuf); */
806 cygwin_conv_path (CCP_WIN_A_TO_POSIX, string, pathbuf, PATH_MAX);
Jari Aaltob80f6442004-07-27 13:29:18 +0000807 result = savestring (pathbuf);
808 }
809#else
Jari Aalto726f6381996-08-26 18:22:31 +0000810 result = savestring (string);
Jari Aaltob80f6442004-07-27 13:29:18 +0000811#endif
Jari Aalto726f6381996-08-26 18:22:31 +0000812 else
Jari Aaltobb706242000-03-17 21:46:59 +0000813 result = sh_makepath (dot_path, string, 0);
Jari Aalto726f6381996-08-26 18:22:31 +0000814
815 return (result);
816}
817
Jari Aalto726f6381996-08-26 18:22:31 +0000818/* Return the `basename' of the pathname in STRING (the stuff after the
Jari Aalto95732b42005-12-07 14:08:12 +0000819 last '/'). If STRING is `/', just return it. */
Jari Aalto726f6381996-08-26 18:22:31 +0000820char *
821base_pathname (string)
822 char *string;
823{
824 char *p;
825
Jari Aalto95732b42005-12-07 14:08:12 +0000826#if 0
Jari Aalto28ef6c32001-04-06 19:14:31 +0000827 if (absolute_pathname (string) == 0)
Jari Aalto726f6381996-08-26 18:22:31 +0000828 return (string);
Jari Aalto95732b42005-12-07 14:08:12 +0000829#endif
830
831 if (string[0] == '/' && string[1] == 0)
832 return (string);
Jari Aalto726f6381996-08-26 18:22:31 +0000833
834 p = (char *)strrchr (string, '/');
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000835 return (p ? ++p : string);
Jari Aalto726f6381996-08-26 18:22:31 +0000836}
837
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. */
842char *
843full_pathname (file)
844 char *file;
845{
Jari Aaltobb706242000-03-17 21:46:59 +0000846 char *ret;
Jari Aalto726f6381996-08-26 18:22:31 +0000847
Jari Aalto7117c2d2002-07-17 14:10:11 +0000848 file = (*file == '~') ? bash_tilde_expand (file, 0) : savestring (file);
Jari Aalto726f6381996-08-26 18:22:31 +0000849
Jari Aalto28ef6c32001-04-06 19:14:31 +0000850 if (ABSPATH(file))
Jari Aalto726f6381996-08-26 18:22:31 +0000851 return (file);
852
Jari Aaltobb706242000-03-17 21:46:59 +0000853 ret = sh_makepath ((char *)NULL, file, (MP_DOCWD|MP_RMDOT));
854 free (file);
Jari Aalto726f6381996-08-26 18:22:31 +0000855
Jari Aaltobb706242000-03-17 21:46:59 +0000856 return (ret);
Jari Aalto726f6381996-08-26 18:22:31 +0000857}
858
Jari Aalto726f6381996-08-26 18:22:31 +0000859/* A slightly related function. Get the prettiest name of this
860 directory possible. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000861static char tdir[PATH_MAX];
Jari Aalto726f6381996-08-26 18:22:31 +0000862
863/* Return a pretty pathname. If the first part of the pathname is
864 the same as $HOME, then replace that with `~'. */
865char *
866polite_directory_format (name)
867 char *name;
868{
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000869 char *home;
870 int l;
Jari Aalto726f6381996-08-26 18:22:31 +0000871
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000872 home = get_string_value ("HOME");
873 l = home ? strlen (home) : 0;
Jari Aalto726f6381996-08-26 18:22:31 +0000874 if (l > 1 && strncmp (home, name, l) == 0 && (!name[l] || name[l] == '/'))
875 {
Jari Aaltoe8ce7751997-09-22 20:22:27 +0000876 strncpy (tdir + 1, name + l, sizeof(tdir) - 2);
Jari Aalto726f6381996-08-26 18:22:31 +0000877 tdir[0] = '~';
Jari Aaltoe8ce7751997-09-22 20:22:27 +0000878 tdir[sizeof(tdir) - 1] = '\0';
Jari Aalto726f6381996-08-26 18:22:31 +0000879 return (tdir);
880 }
881 else
882 return (name);
883}
884
Jari Aalto31859422009-01-12 13:36:28 +0000885/* 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 `...' */
888char *
889trim_pathname (name, maxlen)
890 char *name;
891 int maxlen;
892{
893 int nlen, ndirs;
894 intmax_t nskip;
895 char *nbeg, *nend, *ntail, *v;
896
897 if (name == 0 || (nlen = strlen (name)) == 0)
898 return name;
899 nend = name + nlen;
900
901 v = get_string_value ("PROMPT_DIRTRIM");
902 if (v == 0 || *v == 0)
903 return name;
904 if (legal_number (v, &nskip) == 0 || nskip <= 0)
905 return name;
906
907 /* Skip over tilde prefix */
908 nbeg = name;
909 if (name[0] == '~')
910 for (nbeg = name; *nbeg; nbeg++)
911 if (*nbeg == '/')
912 {
913 nbeg++;
914 break;
915 }
916 if (*nbeg == 0)
917 return name;
918
919 for (ndirs = 0, ntail = nbeg; *ntail; ntail++)
920 if (*ntail == '/')
921 ndirs++;
Chet Ramey00018032011-11-21 20:51:19 -0500922 if (ndirs < nskip)
Jari Aalto31859422009-01-12 13:36:28 +0000923 return name;
924
925 for (ntail = (*nend == '/') ? nend : nend - 1; ntail > nbeg; ntail--)
926 {
927 if (*ntail == '/')
928 nskip--;
929 if (nskip == 0)
930 break;
931 }
932 if (ntail == nbeg)
933 return name;
934
935 /* Now we want to return name[0..nbeg]+"..."+ntail, modifying name in place */
936 nlen = ntail - nbeg;
937 if (nlen <= 3)
938 return name;
939
940 *nbeg++ = '.';
941 *nbeg++ = '.';
942 *nbeg++ = '.';
943
944 nlen = nend - ntail;
Chet Rameyac50fba2014-02-26 09:36:43 -0500945 memmove (nbeg, ntail, nlen);
Jari Aalto31859422009-01-12 13:36:28 +0000946 nbeg[nlen] = '\0';
947
948 return name;
949}
950
Chet Rameya0c0a002016-09-15 16:59:08 -0400951/* 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. */
955char *
956printable_filename (fn, flags)
957 char *fn;
958 int flags;
959{
960 char *newf;
961
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);
966 else
967 newf = fn;
968
969 return newf;
970}
971
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000972/* 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. */
975char *
976extract_colon_unit (string, p_index)
977 char *string;
978 int *p_index;
Jari Aalto726f6381996-08-26 18:22:31 +0000979{
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000980 int i, start, len;
981 char *value;
982
983 if (string == 0)
984 return (string);
985
986 len = strlen (string);
987 if (*p_index >= len)
988 return ((char *)NULL);
989
990 i = *p_index;
991
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] == ':')
998 i++;
999
1000 for (start = i; string[i] && string[i] != ':'; i++)
1001 ;
1002
1003 *p_index = i;
1004
1005 if (i == start)
Jari Aalto726f6381996-08-26 18:22:31 +00001006 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001007 if (string[i])
1008 (*p_index)++;
1009 /* Return "" in the case of a trailing `:'. */
Jari Aaltof73dda02001-11-13 17:56:06 +00001010 value = (char *)xmalloc (1);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001011 value[0] = '\0';
Jari Aalto726f6381996-08-26 18:22:31 +00001012 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001013 else
Jari Aaltobb706242000-03-17 21:46:59 +00001014 value = substring (string, start, i);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001015
1016 return (value);
Jari Aalto726f6381996-08-26 18:22:31 +00001017}
1018
Jari Aalto726f6381996-08-26 18:22:31 +00001019/* **************************************************************** */
1020/* */
1021/* Tilde Initialization and Expansion */
1022/* */
1023/* **************************************************************** */
1024
Jari Aaltocce855b1998-04-17 19:52:44 +00001025#if defined (PUSHD_AND_POPD)
1026extern char *get_dirstack_from_string __P((char *));
1027#endif
1028
Jari Aaltof73dda02001-11-13 17:56:06 +00001029static char **bash_tilde_prefixes;
Jari Aalto95732b42005-12-07 14:08:12 +00001030static char **bash_tilde_prefixes2;
Jari Aaltof73dda02001-11-13 17:56:06 +00001031static char **bash_tilde_suffixes;
Jari Aalto95732b42005-12-07 14:08:12 +00001032static char **bash_tilde_suffixes2;
Jari Aaltof73dda02001-11-13 17:56:06 +00001033
Jari Aalto726f6381996-08-26 18:22:31 +00001034/* 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
Jari Aaltocce855b1998-04-17 19:52:44 +00001036 tilde_expansion_preexpansion_hook. It knows how to expand ~- and ~+.
1037 If PUSHD_AND_POPD is defined, ~[+-]N expands to directories from the
1038 directory stack. */
Jari Aalto726f6381996-08-26 18:22:31 +00001039static char *
Jari Aaltod166f041997-06-05 14:59:13 +00001040bash_special_tilde_expansions (text)
Jari Aalto726f6381996-08-26 18:22:31 +00001041 char *text;
1042{
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001043 char *result;
Jari Aalto726f6381996-08-26 18:22:31 +00001044
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001045 result = (char *)NULL;
Jari Aaltocce855b1998-04-17 19:52:44 +00001046
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)
Jari Aaltof73dda02001-11-13 17:56:06 +00001052 else if (DIGIT (*text) || ((*text == '+' || *text == '-') && DIGIT (text[1])))
Jari Aaltocce855b1998-04-17 19:52:44 +00001053 result = get_dirstack_from_string (text);
1054#endif
Jari Aalto726f6381996-08-26 18:22:31 +00001055
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001056 return (result ? savestring (result) : (char *)NULL);
Jari Aalto726f6381996-08-26 18:22:31 +00001057}
1058
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. */
1062void
1063tilde_initialize ()
1064{
1065 static int times_called = 0;
1066
Jari Aaltod166f041997-06-05 14:59:13 +00001067 /* Tell the tilde expander that we want a crack first. */
Jari Aaltof73dda02001-11-13 17:56:06 +00001068 tilde_expansion_preexpansion_hook = bash_special_tilde_expansions;
Jari Aalto726f6381996-08-26 18:22:31 +00001069
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 (). */
Jari Aaltocce855b1998-04-17 19:52:44 +00001073 if (times_called++ == 0)
Jari Aalto726f6381996-08-26 18:22:31 +00001074 {
Jari Aalto7117c2d2002-07-17 14:10:11 +00001075 bash_tilde_prefixes = strvec_create (3);
Jari Aaltof73dda02001-11-13 17:56:06 +00001076 bash_tilde_prefixes[0] = "=~";
1077 bash_tilde_prefixes[1] = ":~";
1078 bash_tilde_prefixes[2] = (char *)NULL;
Jari Aalto726f6381996-08-26 18:22:31 +00001079
Jari Aalto95732b42005-12-07 14:08:12 +00001080 bash_tilde_prefixes2 = strvec_create (2);
1081 bash_tilde_prefixes2[0] = ":~";
1082 bash_tilde_prefixes2[1] = (char *)NULL;
1083
Jari Aaltof73dda02001-11-13 17:56:06 +00001084 tilde_additional_prefixes = bash_tilde_prefixes;
1085
Jari Aalto7117c2d2002-07-17 14:10:11 +00001086 bash_tilde_suffixes = strvec_create (3);
Jari Aaltof73dda02001-11-13 17:56:06 +00001087 bash_tilde_suffixes[0] = ":";
1088 bash_tilde_suffixes[1] = "=~"; /* XXX - ?? */
1089 bash_tilde_suffixes[2] = (char *)NULL;
1090
1091 tilde_additional_suffixes = bash_tilde_suffixes;
Jari Aalto95732b42005-12-07 14:08:12 +00001092
1093 bash_tilde_suffixes2 = strvec_create (2);
1094 bash_tilde_suffixes2[0] = ":";
1095 bash_tilde_suffixes2[1] = (char *)NULL;
Jari Aalto726f6381996-08-26 18:22:31 +00001096 }
Jari Aalto726f6381996-08-26 18:22:31 +00001097}
1098
Jari Aaltof73dda02001-11-13 17:56:06 +00001099/* 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. */
1105
1106#define TILDE_END(c) ((c) == '\0' || (c) == '/' || (c) == ':')
1107
1108static int
1109unquoted_tilde_word (s)
1110 const char *s;
1111{
1112 const char *r;
1113
1114 for (r = s; TILDE_END(*r) == 0; r++)
1115 {
1116 switch (*r)
1117 {
1118 case '\\':
1119 case '\'':
1120 case '"':
1121 return 0;
1122 }
1123 }
1124 return 1;
1125}
1126
Jari Aalto95732b42005-12-07 14:08:12 +00001127/* 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. */
1131char *
1132bash_tilde_find_word (s, flags, lenp)
1133 const char *s;
1134 int flags, *lenp;
1135{
1136 const char *r;
1137 char *ret;
1138 int l;
1139
1140 for (r = s; *r && *r != '/'; r++)
1141 {
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 == '"')
1147 {
1148 ret = savestring (s);
1149 if (lenp)
1150 *lenp = 0;
1151 return ret;
1152 }
1153 else if (flags && *r == ':')
1154 break;
1155 }
1156 l = r - s;
1157 ret = xmalloc (l + 1);
1158 strncpy (ret, s, l);
1159 ret[l] = '\0';
1160 if (lenp)
1161 *lenp = l;
1162 return ret;
1163}
1164
Jari Aalto7117c2d2002-07-17 14:10:11 +00001165/* 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
Jari Aalto95732b42005-12-07 14:08:12 +00001167 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. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001170char *
Jari Aalto7117c2d2002-07-17 14:10:11 +00001171bash_tilde_expand (s, assign_p)
Jari Aaltof73dda02001-11-13 17:56:06 +00001172 const char *s;
Jari Aalto7117c2d2002-07-17 14:10:11 +00001173 int assign_p;
Jari Aalto726f6381996-08-26 18:22:31 +00001174{
Jari Aalto31859422009-01-12 13:36:28 +00001175 int old_immed, old_term, r;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001176 char *ret;
Jari Aalto726f6381996-08-26 18:22:31 +00001177
Chet Rameya0c0a002016-09-15 16:59:08 -04001178#if 0
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001179 old_immed = interrupt_immediately;
Jari Aalto31859422009-01-12 13:36:28 +00001180 old_term = terminate_immediately;
Chet Rameyac50fba2014-02-26 09:36:43 -05001181 /* 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;
Chet Rameya0c0a002016-09-15 16:59:08 -04001188#endif
Jari Aalto95732b42005-12-07 14:08:12 +00001189
1190 tilde_additional_prefixes = assign_p == 0 ? (char **)0
1191 : (assign_p == 2 ? bash_tilde_prefixes2 : bash_tilde_prefixes);
1192 if (assign_p == 2)
1193 tilde_additional_suffixes = bash_tilde_suffixes2;
1194
Jari Aaltof73dda02001-11-13 17:56:06 +00001195 r = (*s == '~') ? unquoted_tilde_word (s) : 1;
1196 ret = r ? tilde_expand (s) : savestring (s);
Chet Rameyac50fba2014-02-26 09:36:43 -05001197
Chet Rameya0c0a002016-09-15 16:59:08 -04001198#if 0
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001199 interrupt_immediately = old_immed;
Jari Aalto31859422009-01-12 13:36:28 +00001200 terminate_immediately = old_term;
Chet Rameya0c0a002016-09-15 16:59:08 -04001201#endif
Chet Rameyac50fba2014-02-26 09:36:43 -05001202
1203 QUIT;
1204
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001205 return (ret);
Jari Aalto726f6381996-08-26 18:22:31 +00001206}
Jari Aaltod166f041997-06-05 14:59:13 +00001207
1208/* **************************************************************** */
1209/* */
1210/* Functions to manipulate and search the group list */
1211/* */
1212/* **************************************************************** */
1213
1214static int ngroups, maxgroups;
1215
1216/* The set of groups that this user is a member of. */
1217static GETGROUPS_T *group_array = (GETGROUPS_T *)NULL;
1218
1219#if !defined (NOGROUP)
1220# define NOGROUP (gid_t) -1
1221#endif
1222
Jari Aaltod166f041997-06-05 14:59:13 +00001223static void
1224initialize_group_array ()
1225{
1226 register int i;
1227
1228 if (maxgroups == 0)
1229 maxgroups = getmaxgroups ();
1230
1231 ngroups = 0;
1232 group_array = (GETGROUPS_T *)xrealloc (group_array, maxgroups * sizeof (GETGROUPS_T));
1233
1234#if defined (HAVE_GETGROUPS)
1235 ngroups = getgroups (maxgroups, group_array);
1236#endif
1237
1238 /* If getgroups returns nothing, or the OS does not support getgroups(),
1239 make sure the groups array includes at least the current gid. */
1240 if (ngroups == 0)
1241 {
1242 group_array[0] = current_user.gid;
1243 ngroups = 1;
1244 }
1245
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])
1250 break;
1251 if (i == ngroups && ngroups < maxgroups)
1252 {
1253 for (i = ngroups; i > 0; i--)
Jari Aalto28ef6c32001-04-06 19:14:31 +00001254 group_array[i] = group_array[i - 1];
Jari Aaltod166f041997-06-05 14:59:13 +00001255 group_array[0] = current_user.gid;
1256 ngroups++;
1257 }
Jari Aaltocce855b1998-04-17 19:52:44 +00001258
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)
1263 {
1264 for (i = 0; i < ngroups; i++)
Jari Aalto28ef6c32001-04-06 19:14:31 +00001265 if (group_array[i] == current_user.gid)
1266 break;
Jari Aaltocce855b1998-04-17 19:52:44 +00001267 if (i < ngroups)
1268 {
1269 group_array[i] = group_array[0];
1270 group_array[0] = current_user.gid;
1271 }
1272 }
Jari Aaltod166f041997-06-05 14:59:13 +00001273}
1274
1275/* Return non-zero if GID is one that we have in our groups list. */
1276int
Jari Aaltocce855b1998-04-17 19:52:44 +00001277#if defined (__STDC__) || defined ( _MINIX)
1278group_member (gid_t gid)
1279#else
Jari Aaltod166f041997-06-05 14:59:13 +00001280group_member (gid)
1281 gid_t gid;
Jari Aaltocce855b1998-04-17 19:52:44 +00001282#endif /* !__STDC__ && !_MINIX */
Jari Aaltod166f041997-06-05 14:59:13 +00001283{
1284#if defined (HAVE_GETGROUPS)
1285 register int i;
1286#endif
1287
1288 /* Short-circuit if possible, maybe saving a call to getgroups(). */
1289 if (gid == current_user.gid || gid == current_user.egid)
1290 return (1);
1291
1292#if defined (HAVE_GETGROUPS)
1293 if (ngroups == 0)
1294 initialize_group_array ();
1295
1296 /* In case of error, the user loses. */
1297 if (ngroups <= 0)
1298 return (0);
1299
1300 /* Search through the list looking for GID. */
1301 for (i = 0; i < ngroups; i++)
1302 if (gid == (gid_t)group_array[i])
1303 return (1);
1304#endif
1305
1306 return (0);
1307}
1308
1309char **
1310get_group_list (ngp)
1311 int *ngp;
1312{
1313 static char **group_vector = (char **)NULL;
1314 register int i;
Jari Aaltod166f041997-06-05 14:59:13 +00001315
1316 if (group_vector)
1317 {
1318 if (ngp)
1319 *ngp = ngroups;
1320 return group_vector;
1321 }
1322
1323 if (ngroups == 0)
1324 initialize_group_array ();
1325
1326 if (ngroups <= 0)
1327 {
1328 if (ngp)
1329 *ngp = 0;
1330 return (char **)NULL;
1331 }
1332
Jari Aalto7117c2d2002-07-17 14:10:11 +00001333 group_vector = strvec_create (ngroups);
Jari Aaltod166f041997-06-05 14:59:13 +00001334 for (i = 0; i < ngroups; i++)
Jari Aalto7117c2d2002-07-17 14:10:11 +00001335 group_vector[i] = itos (group_array[i]);
Jari Aaltob72432f1999-02-19 17:11:39 +00001336
Jari Aaltod166f041997-06-05 14:59:13 +00001337 if (ngp)
1338 *ngp = ngroups;
1339 return group_vector;
1340}
Jari Aaltob72432f1999-02-19 17:11:39 +00001341
1342int *
1343get_group_array (ngp)
1344 int *ngp;
1345{
1346 int i;
1347 static int *group_iarray = (int *)NULL;
1348
1349 if (group_iarray)
1350 {
1351 if (ngp)
1352 *ngp = ngroups;
1353 return (group_iarray);
1354 }
1355
1356 if (ngroups == 0)
1357 initialize_group_array ();
1358
1359 if (ngroups <= 0)
1360 {
1361 if (ngp)
1362 *ngp = 0;
1363 return (int *)NULL;
1364 }
1365
1366 group_iarray = (int *)xmalloc (ngroups * sizeof (int));
1367 for (i = 0; i < ngroups; i++)
1368 group_iarray[i] = (int)group_array[i];
1369
1370 if (ngp)
1371 *ngp = ngroups;
1372 return group_iarray;
1373}
Chet Rameya0c0a002016-09-15 16:59:08 -04001374
1375/* **************************************************************** */
1376/* */
1377/* Miscellaneous functions */
1378/* */
1379/* **************************************************************** */
1380
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. */
1384char *
1385conf_standard_path ()
1386{
1387#if defined (_CS_PATH) && defined (HAVE_CONFSTR)
1388 char *p;
1389 size_t len;
1390
1391 len = (size_t)confstr (_CS_PATH, (char *)NULL, (size_t)0);
1392 if (len > 0)
1393 {
1394 p = (char *)xmalloc (len + 2);
1395 *p = '\0';
1396 confstr (_CS_PATH, p, len);
1397 return (p);
1398 }
1399 else
1400 return (savestring (STANDARD_UTILS_PATH));
1401#else /* !_CS_PATH || !HAVE_CONFSTR */
1402# if defined (CS_PATH)
1403 return (savestring (CS_PATH));
1404# else
1405 return (savestring (STANDARD_UTILS_PATH));
1406# endif /* !CS_PATH */
1407#endif /* !_CS_PATH || !HAVE_CONFSTR */
1408}
Chet Rameyd233b482019-01-07 09:27:52 -05001409
1410int
1411default_columns ()
1412{
1413 char *v;
1414 int c;
1415
1416 c = -1;
1417 v = get_string_value ("COLUMNS");
1418 if (v && *v)
1419 {
1420 c = atoi (v);
1421 if (c > 0)
1422 return c;
1423 }
1424
1425 if (check_window_size)
1426 get_new_window_size (0, (int *)0, &c);
1427
1428 return (c > 0 ? c : 80);
1429}
1430
1431