]> git.ipfire.org Git - thirdparty/bash.git/blame - general.c
Bash-5.0 patch 17: better fix for reaping process substitution file descriptors
[thirdparty/bash.git] / general.c
CommitLineData
726f6388
JA
1/* general.c -- Stuff that is used by all files. */
2
a0c0a00f 3/* Copyright (C) 1987-2016 Free Software Foundation, Inc.
726f6388
JA
4
5 This file is part of GNU Bash, the Bourne Again SHell.
6
3185942a
JA
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.
726f6388 11
3185942a
JA
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.
726f6388 16
3185942a
JA
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/>.
19*/
726f6388 20
ccc6cda3
JA
21#include "config.h"
22
726f6388 23#include "bashtypes.h"
ac50fbac 24#if defined (HAVE_SYS_PARAM_H)
cce855bc
JA
25# include <sys/param.h>
26#endif
ccc6cda3
JA
27#include "posixstat.h"
28
29#if defined (HAVE_UNISTD_H)
30# include <unistd.h>
31#endif
32
726f6388
JA
33#include "filecntl.h"
34#include "bashansi.h"
ccc6cda3 35#include <stdio.h>
f73dda09 36#include "chartypes.h"
ccc6cda3
JA
37#include <errno.h>
38
b80f6443
JA
39#include "bashintl.h"
40
726f6388 41#include "shell.h"
d233b485
CR
42#include "parser.h"
43#include "flags.h"
44#include "findcmd.h"
95732b49 45#include "test.h"
ac50fbac 46#include "trap.h"
95732b49 47
d233b485
CR
48#include "builtins/common.h"
49
a0c0a00f
CR
50#if defined (HAVE_MBSTR_H) && defined (HAVE_MBSCHR)
51# include <mbstr.h> /* mbschr */
52#endif
53
726f6388
JA
54#include <tilde/tilde.h>
55
726f6388
JA
56#if !defined (errno)
57extern int errno;
58#endif /* !errno */
59
d233b485
CR
60#ifdef __CYGWIN__
61# include <sys/cygwin.h>
62#endif
cce855bc 63
7117c2d2
JA
64static char *bash_special_tilde_expansions __P((char *));
65static int unquoted_tilde_word __P((const char *));
66static void initialize_group_array __P((void));
67
cce855bc 68/* A standard error message to use when getcwd() returns NULL. */
3185942a 69const char * const bash_getcwd_errstr = N_("getcwd: cannot access parent directories");
726f6388 70
d233b485
CR
71/* 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
726f6388 98void
ccc6cda3
JA
99posix_initialize (on)
100 int on;
726f6388 101{
28ef6c31
JA
102 /* 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;
a0c0a00f 106 inherit_errexit = 1;
3185942a 107 source_searches_cwd = 0;
d233b485
CR
108 print_shift_error = 1;
109
28ef6c31
JA
110 }
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;
d233b485 117 print_shift_error = 0;
28ef6c31 118 }
726f6388
JA
119}
120
d233b485
CR
121int
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
ccc6cda3
JA
150/* **************************************************************** */
151/* */
152/* Functions to convert to and from and display non-standard types */
153/* */
154/* **************************************************************** */
155
726f6388
JA
156#if defined (RLIMTYPE)
157RLIMTYPE
158string_to_rlimtype (s)
159 char *s;
160{
cce855bc
JA
161 RLIMTYPE ret;
162 int neg;
726f6388 163
cce855bc
JA
164 ret = 0;
165 neg = 0;
726f6388
JA
166 while (s && *s && whitespace (*s))
167 s++;
0001803f 168 if (s && (*s == '-' || *s == '+'))
726f6388
JA
169 {
170 neg = *s == '-';
171 s++;
172 }
f73dda09
JA
173 for ( ; s && *s && DIGIT (*s); s++)
174 ret = (ret * 10) + TODIGIT (*s);
726f6388
JA
175 return (neg ? -ret : ret);
176}
177
178void
179print_rlimtype (n, addnl)
180 RLIMTYPE n;
181 int addnl;
182{
f73dda09 183 char s[INT_STRLEN_BOUND (RLIMTYPE) + 1], *p;
726f6388 184
f73dda09
JA
185 p = s + sizeof(s);
186 *--p = '\0';
726f6388
JA
187
188 if (n < 0)
189 {
f73dda09
JA
190 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);
726f6388
JA
201 }
202
f73dda09 203 printf ("%s%s", p, addnl ? "\n" : "");
726f6388
JA
204}
205#endif /* RLIMTYPE */
206
ccc6cda3
JA
207/* **************************************************************** */
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)
a0c0a00f 216 const char *string;
ccc6cda3 217{
a0c0a00f 218 register const char *s;
28ef6c31
JA
219
220 for (s = string; *s; s++)
f73dda09 221 if (DIGIT (*s) == 0)
28ef6c31
JA
222 return (0);
223
ccc6cda3
JA
224 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
f73dda09 229 not null. */
ccc6cda3
JA
230int
231legal_number (string, result)
3185942a 232 const char *string;
7117c2d2 233 intmax_t *result;
ccc6cda3 234{
7117c2d2 235 intmax_t value;
cce855bc 236 char *ep;
ccc6cda3
JA
237
238 if (result)
239 *result = 0;
240
ac50fbac
CR
241 if (string == 0)
242 return 0;
243
f73dda09 244 errno = 0;
7117c2d2 245 value = strtoimax (string, &ep, 10);
3185942a 246 if (errno || ep == string)
f73dda09 247 return 0; /* errno is set on overflow or underflow */
ccc6cda3 248
7117c2d2 249 /* Skip any trailing whitespace, since strtoimax does not. */
28ef6c31
JA
250 while (whitespace (*ep))
251 ep++;
252
cce855bc
JA
253 /* If *string is not '\0' but *ep is '\0' on return, the entire string
254 is valid. */
ac50fbac 255 if (*string && *ep == '\0')
ccc6cda3
JA
256 {
257 if (result)
cce855bc
JA
258 *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;
ccc6cda3 263 }
cce855bc
JA
264
265 return (0);
ccc6cda3
JA
266}
267
726f6388
JA
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
270 digit. */
271int
272legal_identifier (name)
a0c0a00f 273 const char *name;
726f6388 274{
a0c0a00f 275 register const char *s;
f73dda09 276 unsigned char c;
726f6388 277
f73dda09 278 if (!name || !(c = *name) || (legal_variable_starter (c) == 0))
726f6388
JA
279 return (0);
280
f73dda09 281 for (s = name + 1; (c = *s) != 0; s++)
726f6388 282 {
f73dda09 283 if (legal_variable_char (c) == 0)
28ef6c31 284 return (0);
726f6388
JA
285 }
286 return (1);
287}
288
a0c0a00f
CR
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. */
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 {
d233b485 327 t = array_variable_name (value, 0, (char **)NULL, (int *)NULL);
a0c0a00f
CR
328 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
726f6388
JA
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. */
ccc6cda3 345int
726f6388
JA
346check_identifier (word, check_word)
347 WORD_DESC *word;
348 int check_word;
349{
ccc6cda3 350 if ((word->flags & (W_HASDOLLAR|W_QUOTED)) || all_digits (word->word))
726f6388 351 {
b80f6443 352 internal_error (_("`%s': not a valid identifier"), word->word);
726f6388
JA
353 return (0);
354 }
355 else if (check_word && legal_identifier (word->word) == 0)
356 {
b80f6443 357 internal_error (_("`%s': not a valid identifier"), word->word);
726f6388
JA
358 return (0);
359 }
360 else
361 return (1);
362}
363
a0c0a00f
CR
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
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
b80f6443
JA
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 `/'. */
397int
398legal_alias_name (string, flags)
a0c0a00f 399 const char *string;
b80f6443
JA
400 int flags;
401{
a0c0a00f 402 register const char *s;
b80f6443
JA
403
404 for (s = string; *s; s++)
405 if (shellbreak (*s) || shellxquote (*s) || shellexp (*s) || (*s == '/'))
406 return 0;
407 return 1;
408}
409
7117c2d2 410/* Returns non-zero if STRING is an assignment statement. The returned value
d233b485
CR
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 `='. */
7117c2d2 413int
b80f6443 414assignment (string, flags)
7117c2d2 415 const char *string;
b80f6443 416 int flags;
7117c2d2
JA
417{
418 register unsigned char c;
419 register int newi, indx;
420
421 c = string[indx = 0];
422
b80f6443 423#if defined (ARRAY_VARS)
d233b485 424 if ((legal_variable_starter (c) == 0) && ((flags&1) == 0 || c != '[')) /* ] */
b80f6443 425#else
7117c2d2 426 if (legal_variable_starter (c) == 0)
b80f6443 427#endif
7117c2d2
JA
428 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 {
d233b485
CR
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? */
7117c2d2
JA
443 if (string[newi++] != ']')
444 return (0);
95732b49
JA
445 if (string[newi] == '+' && string[newi+1] == '=')
446 return (newi + 1);
7117c2d2
JA
447 return ((string[newi] == '=') ? newi : 0);
448 }
449#endif /* ARRAY_VARS */
450
95732b49
JA
451 /* Check for `+=' */
452 if (c == '+' && string[indx+1] == '=')
453 return (indx + 1);
454
7117c2d2
JA
455 /* 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
d233b485
CR
465int
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
ccc6cda3
JA
479/* **************************************************************** */
480/* */
481/* Functions to manage files and file descriptors */
482/* */
483/* **************************************************************** */
484
726f6388
JA
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. */
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. */
bb70624e 496int
28ef6c31 497sh_unset_nodelay_mode (fd)
726f6388
JA
498 int fd;
499{
bb70624e 500 int flags, bflags;
726f6388
JA
501
502 if ((flags = fcntl (fd, F_GETFL, 0)) < 0)
bb70624e 503 return -1;
726f6388 504
bb70624e 505 bflags = 0;
ccc6cda3
JA
506
507 /* This is defined to O_NDELAY in filecntl.h if O_NONBLOCK is not present
508 and O_NDELAY is defined. */
bb70624e
JA
509#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)
726f6388 518 {
bb70624e
JA
519 flags &= ~bflags;
520 return (fcntl (fd, F_SETFL, flags));
726f6388 521 }
726f6388 522
bb70624e 523 return 0;
726f6388
JA
524}
525
d233b485
CR
526/* 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
7117c2d2
JA
534/* 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
495aee44
CR
542int
543fd_ispipe (fd)
544 int fd;
545{
546 errno = 0;
a0c0a00f 547 return ((lseek (fd, 0L, SEEK_CUR) < 0) && (errno == ESPIPE));
495aee44
CR
548}
549
b72432fd
JA
550/* 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
726f6388 560void
ccc6cda3 561check_dev_tty ()
726f6388 562{
ccc6cda3
JA
563 int tty_fd;
564 char *tty;
726f6388 565
d166f048 566 tty_fd = open ("/dev/tty", O_RDWR|O_NONBLOCK);
726f6388 567
ccc6cda3 568 if (tty_fd < 0)
726f6388 569 {
ccc6cda3
JA
570 tty = (char *)ttyname (fileno (stdin));
571 if (tty == 0)
572 return;
d166f048 573 tty_fd = open (tty, O_RDWR|O_NONBLOCK);
726f6388 574 }
ac50fbac
CR
575 if (tty_fd >= 0)
576 close (tty_fd);
726f6388
JA
577}
578
ccc6cda3
JA
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. */
726f6388 582int
ccc6cda3 583same_file (path1, path2, stp1, stp2)
a0c0a00f 584 const char *path1, *path2;
ccc6cda3 585 struct stat *stp1, *stp2;
726f6388 586{
ccc6cda3 587 struct stat st1, st2;
726f6388 588
ccc6cda3 589 if (stp1 == NULL)
726f6388 590 {
ccc6cda3
JA
591 if (stat (path1, &st1) != 0)
592 return (0);
593 stp1 = &st1;
726f6388 594 }
726f6388 595
ccc6cda3
JA
596 if (stp2 == NULL)
597 {
598 if (stat (path2, &st2) != 0)
599 return (0);
600 stp2 = &st2;
601 }
726f6388 602
ccc6cda3 603 return ((stp1->st_dev == stp2->st_dev) && (stp1->st_ino == stp2->st_ino));
726f6388
JA
604}
605
ccc6cda3
JA
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
d166f048
JA
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). */
726f6388 613int
d166f048
JA
614move_to_high_fd (fd, check_new, maxfd)
615 int fd, check_new, maxfd;
726f6388 616{
ccc6cda3 617 int script_fd, nfds, ignore;
726f6388 618
d166f048
JA
619 if (maxfd < 20)
620 {
621 nfds = getdtablesize ();
622 if (nfds <= 0)
623 nfds = 20;
7117c2d2
JA
624 if (nfds > HIGH_FD_MAX)
625 nfds = HIGH_FD_MAX; /* reasonable maximum */
d166f048
JA
626 }
627 else
628 nfds = maxfd;
726f6388 629
ccc6cda3
JA
630 for (nfds--; check_new && nfds > 3; nfds--)
631 if (fcntl (nfds, F_GETFD, &ignore) == -1)
632 break;
726f6388 633
7117c2d2 634 if (nfds > 3 && fd != nfds && (script_fd = dup2 (fd, nfds)) != -1)
ccc6cda3
JA
635 {
636 if (check_new == 0 || fd != fileno (stderr)) /* don't close stderr */
637 close (fd);
638 return (script_fd);
639 }
726f6388 640
7117c2d2
JA
641 /* OK, we didn't find one less than our artificial maximum; return the
642 original file descriptor. */
ccc6cda3
JA
643 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. */
726f6388 650
726f6388 651int
ccc6cda3 652check_binary_file (sample, sample_len)
a0c0a00f 653 const char *sample;
ccc6cda3 654 int sample_len;
726f6388 655{
ccc6cda3 656 register int i;
f73dda09 657 unsigned char c;
726f6388 658
ccc6cda3
JA
659 for (i = 0; i < sample_len; i++)
660 {
f73dda09
JA
661 c = sample[i];
662 if (c == '\n')
ccc6cda3 663 return (0);
0628567a 664 if (c == '\0')
ccc6cda3
JA
665 return (1);
666 }
726f6388 667
ccc6cda3 668 return (0);
726f6388
JA
669}
670
3185942a
JA
671/* **************************************************************** */
672/* */
673/* 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
b80f6443
JA
706/* **************************************************************** */
707/* */
708/* Functions to inspect pathnames */
709/* */
710/* **************************************************************** */
711
3185942a
JA
712int
713file_exists (fn)
a0c0a00f 714 const char *fn;
3185942a
JA
715{
716 struct stat sb;
717
718 return (stat (fn, &sb) == 0);
719}
720
b80f6443
JA
721int
722file_isdir (fn)
a0c0a00f 723 const char *fn;
b80f6443
JA
724{
725 struct stat sb;
726
727 return ((stat (fn, &sb) == 0) && S_ISDIR (sb.st_mode));
728}
729
730int
731file_iswdir (fn)
a0c0a00f 732 const char *fn;
b80f6443 733{
0628567a 734 return (file_isdir (fn) && sh_eaccess (fn, W_OK) == 0);
b80f6443
JA
735}
736
495aee44
CR
737/* Return 1 if STRING is "." or "..", optionally followed by a directory
738 separator */
739int
ac50fbac 740path_dot_or_dotdot (string)
495aee44
CR
741 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
95732b49
JA
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. */
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{
0001803f 781 return ((char *)mbschr (string, '/') != (char *)NULL);
95732b49 782}
b80f6443 783
ccc6cda3
JA
784/* **************************************************************** */
785/* */
786/* Functions to manipulate pathnames */
787/* */
788/* **************************************************************** */
726f6388 789
726f6388
JA
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
793 begin with. */
794char *
795make_absolute (string, dot_path)
a0c0a00f 796 const char *string, *dot_path;
726f6388
JA
797{
798 char *result;
ccc6cda3 799
28ef6c31 800 if (dot_path == 0 || ABSPATH(string))
b80f6443
JA
801#ifdef __CYGWIN__
802 {
803 char pathbuf[PATH_MAX + 1];
804
d233b485
CR
805 /* WAS cygwin_conv_to_full_posix_path (string, pathbuf); */
806 cygwin_conv_path (CCP_WIN_A_TO_POSIX, string, pathbuf, PATH_MAX);
b80f6443
JA
807 result = savestring (pathbuf);
808 }
809#else
726f6388 810 result = savestring (string);
b80f6443 811#endif
726f6388 812 else
bb70624e 813 result = sh_makepath (dot_path, string, 0);
726f6388
JA
814
815 return (result);
816}
817
726f6388 818/* Return the `basename' of the pathname in STRING (the stuff after the
95732b49 819 last '/'). If STRING is `/', just return it. */
726f6388
JA
820char *
821base_pathname (string)
822 char *string;
823{
824 char *p;
825
95732b49 826#if 0
28ef6c31 827 if (absolute_pathname (string) == 0)
726f6388 828 return (string);
95732b49
JA
829#endif
830
831 if (string[0] == '/' && string[1] == 0)
832 return (string);
726f6388
JA
833
834 p = (char *)strrchr (string, '/');
ccc6cda3 835 return (p ? ++p : string);
726f6388
JA
836}
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{
bb70624e 846 char *ret;
726f6388 847
7117c2d2 848 file = (*file == '~') ? bash_tilde_expand (file, 0) : savestring (file);
726f6388 849
28ef6c31 850 if (ABSPATH(file))
726f6388
JA
851 return (file);
852
bb70624e
JA
853 ret = sh_makepath ((char *)NULL, file, (MP_DOCWD|MP_RMDOT));
854 free (file);
726f6388 855
bb70624e 856 return (ret);
726f6388 857}
726f6388
JA
858
859/* A slightly related function. Get the prettiest name of this
860 directory possible. */
ccc6cda3 861static char tdir[PATH_MAX];
726f6388
JA
862
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{
ccc6cda3
JA
869 char *home;
870 int l;
726f6388 871
ccc6cda3
JA
872 home = get_string_value ("HOME");
873 l = home ? strlen (home) : 0;
726f6388
JA
874 if (l > 1 && strncmp (home, name, l) == 0 && (!name[l] || name[l] == '/'))
875 {
e8ce775d 876 strncpy (tdir + 1, name + l, sizeof(tdir) - 2);
726f6388 877 tdir[0] = '~';
e8ce775d 878 tdir[sizeof(tdir) - 1] = '\0';
726f6388
JA
879 return (tdir);
880 }
881 else
882 return (name);
883}
884
3185942a
JA
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 `...' */
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++;
0001803f 922 if (ndirs < nskip)
3185942a
JA
923 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;
ac50fbac 945 memmove (nbeg, ntail, nlen);
3185942a
JA
946 nbeg[nlen] = '\0';
947
948 return name;
949}
950
a0c0a00f
CR
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. */
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
ccc6cda3
JA
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. */
975char *
976extract_colon_unit (string, p_index)
977 char *string;
978 int *p_index;
726f6388 979{
ccc6cda3
JA
980 int i, start, len;
981 char *value;
726f6388 982
ccc6cda3
JA
983 if (string == 0)
984 return (string);
726f6388 985
ccc6cda3
JA
986 len = strlen (string);
987 if (*p_index >= len)
988 return ((char *)NULL);
726f6388 989
ccc6cda3 990 i = *p_index;
726f6388 991
ccc6cda3
JA
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)
1006 {
1007 if (string[i])
1008 (*p_index)++;
1009 /* Return "" in the case of a trailing `:'. */
f73dda09 1010 value = (char *)xmalloc (1);
ccc6cda3
JA
1011 value[0] = '\0';
1012 }
1013 else
bb70624e 1014 value = substring (string, start, i);
ccc6cda3
JA
1015
1016 return (value);
726f6388 1017}
726f6388
JA
1018
1019/* **************************************************************** */
1020/* */
1021/* Tilde Initialization and Expansion */
1022/* */
1023/* **************************************************************** */
1024
cce855bc
JA
1025#if defined (PUSHD_AND_POPD)
1026extern char *get_dirstack_from_string __P((char *));
1027#endif
1028
f73dda09 1029static char **bash_tilde_prefixes;
95732b49 1030static char **bash_tilde_prefixes2;
f73dda09 1031static char **bash_tilde_suffixes;
95732b49 1032static char **bash_tilde_suffixes2;
f73dda09 1033
726f6388
JA
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
cce855bc
JA
1036 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. */
726f6388 1039static char *
d166f048 1040bash_special_tilde_expansions (text)
726f6388
JA
1041 char *text;
1042{
ccc6cda3 1043 char *result;
726f6388 1044
ccc6cda3 1045 result = (char *)NULL;
cce855bc
JA
1046
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)
f73dda09 1052 else if (DIGIT (*text) || ((*text == '+' || *text == '-') && DIGIT (text[1])))
cce855bc
JA
1053 result = get_dirstack_from_string (text);
1054#endif
726f6388 1055
ccc6cda3 1056 return (result ? savestring (result) : (char *)NULL);
726f6388
JA
1057}
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
d166f048 1067 /* Tell the tilde expander that we want a crack first. */
f73dda09 1068 tilde_expansion_preexpansion_hook = bash_special_tilde_expansions;
726f6388
JA
1069
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 (). */
cce855bc 1073 if (times_called++ == 0)
726f6388 1074 {
7117c2d2 1075 bash_tilde_prefixes = strvec_create (3);
f73dda09
JA
1076 bash_tilde_prefixes[0] = "=~";
1077 bash_tilde_prefixes[1] = ":~";
1078 bash_tilde_prefixes[2] = (char *)NULL;
1079
95732b49
JA
1080 bash_tilde_prefixes2 = strvec_create (2);
1081 bash_tilde_prefixes2[0] = ":~";
1082 bash_tilde_prefixes2[1] = (char *)NULL;
1083
f73dda09
JA
1084 tilde_additional_prefixes = bash_tilde_prefixes;
1085
7117c2d2 1086 bash_tilde_suffixes = strvec_create (3);
f73dda09
JA
1087 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;
95732b49
JA
1092
1093 bash_tilde_suffixes2 = strvec_create (2);
1094 bash_tilde_suffixes2[0] = ":";
1095 bash_tilde_suffixes2[1] = (char *)NULL;
726f6388 1096 }
726f6388
JA
1097}
1098
f73dda09
JA
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. */
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
95732b49
JA
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. */
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
7117c2d2
JA
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
95732b49
JA
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. */
ccc6cda3 1170char *
7117c2d2 1171bash_tilde_expand (s, assign_p)
f73dda09 1172 const char *s;
7117c2d2 1173 int assign_p;
726f6388 1174{
3185942a 1175 int old_immed, old_term, r;
ccc6cda3 1176 char *ret;
726f6388 1177
a0c0a00f 1178#if 0
ccc6cda3 1179 old_immed = interrupt_immediately;
3185942a 1180 old_term = terminate_immediately;
ac50fbac
CR
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;
a0c0a00f 1188#endif
95732b49
JA
1189
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
f73dda09
JA
1195 r = (*s == '~') ? unquoted_tilde_word (s) : 1;
1196 ret = r ? tilde_expand (s) : savestring (s);
ac50fbac 1197
a0c0a00f 1198#if 0
ccc6cda3 1199 interrupt_immediately = old_immed;
3185942a 1200 terminate_immediately = old_term;
a0c0a00f 1201#endif
ac50fbac
CR
1202
1203 QUIT;
1204
ccc6cda3 1205 return (ret);
726f6388 1206}
d166f048
JA
1207
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
d166f048
JA
1223static 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--)
28ef6c31 1254 group_array[i] = group_array[i - 1];
d166f048
JA
1255 group_array[0] = current_user.gid;
1256 ngroups++;
1257 }
cce855bc
JA
1258
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++)
28ef6c31
JA
1265 if (group_array[i] == current_user.gid)
1266 break;
cce855bc
JA
1267 if (i < ngroups)
1268 {
1269 group_array[i] = group_array[0];
1270 group_array[0] = current_user.gid;
1271 }
1272 }
d166f048
JA
1273}
1274
1275/* Return non-zero if GID is one that we have in our groups list. */
1276int
cce855bc
JA
1277#if defined (__STDC__) || defined ( _MINIX)
1278group_member (gid_t gid)
1279#else
d166f048
JA
1280group_member (gid)
1281 gid_t gid;
cce855bc 1282#endif /* !__STDC__ && !_MINIX */
d166f048
JA
1283{
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;
d166f048
JA
1315
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
7117c2d2 1333 group_vector = strvec_create (ngroups);
d166f048 1334 for (i = 0; i < ngroups; i++)
7117c2d2 1335 group_vector[i] = itos (group_array[i]);
b72432fd 1336
d166f048
JA
1337 if (ngp)
1338 *ngp = ngroups;
1339 return group_vector;
1340}
b72432fd
JA
1341
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}
a0c0a00f
CR
1374
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}
d233b485
CR
1409
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