]> git.ipfire.org Git - thirdparty/bash.git/blob - shell.c
Imported from ../bash-2.02.tar.gz.
[thirdparty/bash.git] / shell.c
1 /* shell.c -- GNU's idea of the POSIX shell specification.
2
3 This file is part of Bash, the Bourne Again SHell. Bash is free
4 software; no one can prevent you from reading the source code, or
5 giving it to someone else. This file is copyrighted under the GNU
6 General Public License, which can be found in the file called
7 COPYING.
8
9 Copyright (C) 1988, 1991 Free Software Foundation, Inc.
10
11 This file is part of GNU Bash.
12
13 Bash is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY. No author or distributor accepts responsibility to
15 anyone for the consequences of using it or for whether it serves
16 any particular purpose or works at all, unless he says so in
17 writing. Refer to the GNU Emacs General Public License for full
18 details.
19
20 Everyone is granted permission to copy, modify and redistribute
21 Bash, but only under the conditions described in the GNU General
22 Public License. A copy of this license is supposed to have been
23 given to you along with GNU Emacs so you can know your rights and
24 responsibilities. It should be in a file named COPYING.
25
26 Among other things, the copyright notice and this notice must be
27 preserved on all copies.
28
29 Birthdate:
30 Sunday, January 10th, 1988.
31 Initial author: Brian Fox
32 */
33 #define INSTALL_DEBUG_MODE
34
35 #include "config.h"
36
37 #include "bashtypes.h"
38 #ifndef _MINIX
39 # include <sys/file.h>
40 #endif
41 #include "posixstat.h"
42 #include "bashansi.h"
43 #include <stdio.h>
44 #include <signal.h>
45 #include <errno.h>
46 #include "filecntl.h"
47 #include <pwd.h>
48
49 #if defined (HAVE_UNISTD_H)
50 # include <unistd.h>
51 #endif
52
53 #include "shell.h"
54 #include "flags.h"
55 #include "trap.h"
56 #include "mailcheck.h"
57 #include "builtins.h"
58 #include "builtins/common.h"
59
60 #if defined (JOB_CONTROL)
61 #include "jobs.h"
62 #endif /* JOB_CONTROL */
63
64 #include "input.h"
65 #include "execute_cmd.h"
66 #include "findcmd.h"
67
68 #if defined (HISTORY)
69 # include "bashhist.h"
70 # include <readline/history.h>
71 #endif
72
73 #include <tilde/tilde.h>
74 #include <glob/fnmatch.h>
75
76 #if !defined (HAVE_GETPW_DECLS)
77 extern struct passwd *getpwuid ();
78 #endif /* !HAVE_GETPW_DECLS */
79
80 #if !defined (errno)
81 extern int errno;
82 #endif
83
84 extern char *dist_version, *release_status;
85 extern int patch_level, build_version;
86 extern int subshell_environment;
87 extern int last_command_exit_value;
88 extern int line_number;
89 extern char *primary_prompt, *secondary_prompt;
90 extern int expand_aliases;
91 extern char *this_command_name;
92 extern int array_needs_making;
93
94 /* Non-zero means that this shell has already been run; i.e. you should
95 call shell_reinitialize () if you need to start afresh. */
96 int shell_initialized = 0;
97
98 COMMAND *global_command = (COMMAND *)NULL;
99
100 /* Information about the current user. */
101 struct user_info current_user =
102 {
103 -1, -1, -1, -1, (char *)NULL, (char *)NULL, (char *)NULL
104 };
105
106 /* The current host's name. */
107 char *current_host_name = (char *)NULL;
108
109 /* Non-zero means that this shell is a login shell.
110 Specifically:
111 0 = not login shell.
112 1 = login shell from getty (or equivalent fake out)
113 -1 = login shell from "-login" flag.
114 -2 = both from getty, and from flag.
115 */
116 int login_shell = 0;
117
118 /* Non-zero means that at this moment, the shell is interactive. In
119 general, this means that the shell is at this moment reading input
120 from the keyboard. */
121 int interactive = 0;
122
123 /* Non-zero means that the shell was started as an interactive shell. */
124 int interactive_shell = 0;
125
126 /* Non-zero means to send a SIGHUP to all jobs when an interactive login
127 shell exits. */
128 int hup_on_exit = 0;
129
130 /* Tells what state the shell was in when it started:
131 0 = non-interactive shell script
132 1 = interactive
133 2 = -c command
134 This is a superset of the information provided by interactive_shell.
135 */
136 int startup_state = 0;
137
138 /* Special debugging helper. */
139 int debugging_login_shell = 0;
140
141 /* The environment that the shell passes to other commands. */
142 char **shell_environment;
143
144 /* Non-zero when we are executing a top-level command. */
145 int executing = 0;
146
147 /* The number of commands executed so far. */
148 int current_command_number = 1;
149
150 /* Non-zero is the recursion depth for commands. */
151 int indirection_level = 0;
152
153 /* The name of this shell, as taken from argv[0]. */
154 char *shell_name = (char *)NULL;
155
156 /* time in seconds when the shell was started */
157 time_t shell_start_time;
158
159 /* Are we running in an emacs shell window? */
160 int running_under_emacs;
161
162 /* The name of the .(shell)rc file. */
163 static char *bashrc_file = "~/.bashrc";
164
165 /* Non-zero means to act more like the Bourne shell on startup. */
166 static int act_like_sh;
167
168 /* Non-zero if this shell is being run by `su'. */
169 static int su_shell;
170
171 /* Non-zero if we have already expanded and sourced $ENV. */
172 static int sourced_env;
173
174 /* Is this shell running setuid? */
175 static int running_setuid;
176
177 /* Values for the long-winded argument names. */
178 static int debugging; /* Do debugging things. */
179 static int no_rc; /* Don't execute ~/.bashrc */
180 static int no_profile; /* Don't execute .profile */
181 static int do_version; /* Display interesting version info. */
182 static int make_login_shell; /* Make this shell be a `-bash' shell. */
183 static int want_initial_help; /* --help option */
184
185 int no_line_editing = 0; /* Don't do fancy line editing. */
186 int posixly_correct = 0; /* Non-zero means posix.2 superset. */
187 int dump_translatable_strings; /* Dump strings in $"...", don't execute. */
188 int dump_po_strings; /* Dump strings in $"..." in po format */
189 int wordexp_only = 0; /* Do word expansion only */
190
191 /* Some long-winded argument names. These are obviously new. */
192 #define Int 1
193 #define Charp 2
194 struct {
195 char *name;
196 int type;
197 int *int_value;
198 char **char_value;
199 } long_args[] = {
200 { "debug", Int, &debugging, (char **)0x0 },
201 { "dump-po-strings", Int, &dump_po_strings, (char **)0x0 },
202 { "dump-strings", Int, &dump_translatable_strings, (char **)0x0 },
203 { "help", Int, &want_initial_help, (char **)0x0 },
204 { "login", Int, &make_login_shell, (char **)0x0 },
205 { "noediting", Int, &no_line_editing, (char **)0x0 },
206 { "noprofile", Int, &no_profile, (char **)0x0 },
207 { "norc", Int, &no_rc, (char **)0x0 },
208 { "posix", Int, &posixly_correct, (char **)0x0 },
209 { "rcfile", Charp, (int *)0x0, &bashrc_file },
210 #if defined (RESTRICTED_SHELL)
211 { "restricted", Int, &restricted, (char **)0x0 },
212 #endif
213 { "verbose", Int, &echo_input_at_read, (char **)0x0 },
214 { "version", Int, &do_version, (char **)0x0 },
215 { "wordexp", Int, &wordexp_only, (char **)0x0 },
216 { (char *)0x0, Int, (int *)0x0, (char **)0x0 }
217 };
218
219 /* These are extern so execute_simple_command can set them, and then
220 longjmp back to main to execute a shell script, instead of calling
221 main () again and resulting in indefinite, possibly fatal, stack
222 growth. */
223 procenv_t subshell_top_level;
224 int subshell_argc;
225 char **subshell_argv;
226 char **subshell_envp;
227
228 #if defined (BUFFERED_INPUT)
229 /* The file descriptor from which the shell is reading input. */
230 int default_buffered_input = -1;
231 #endif
232
233 static int read_from_stdin; /* -s flag supplied */
234 static int want_pending_command; /* -c flag supplied */
235 static char *local_pending_command;
236
237 static FILE *default_input;
238
239 static int parse_long_options ();
240 static int parse_shell_options ();
241 static void run_startup_files ();
242 static int bind_args ();
243 static int open_shell_script ();
244 static void set_bash_input ();
245 static int run_one_command ();
246 static int run_wordexp ();
247
248 static int uidget ();
249 static int isnetconn ();
250
251 static void init_interactive (), init_noninteractive ();
252 static void set_shell_name ();
253 static void shell_initialize ();
254 static void shell_reinitialize ();
255
256 static void show_shell_usage ();
257
258 #ifdef __CYGWIN32__
259 static void
260 _cygwin32_check_tmp ()
261 {
262 struct stat sb;
263
264 if (stat ("/tmp", &sb) < 0)
265 internal_warning ("could not find /tmp, please create!");
266 else
267 {
268 if (S_ISDIR (sb.st_mode) == 0)
269 internal_warning ("/tmp must be a valid directory name");
270 }
271 }
272 #endif /* __CYGWIN32__ */
273
274 int
275 main (argc, argv, env)
276 int argc;
277 char **argv, **env;
278 {
279 register int i;
280 int code, saverst;
281 volatile int locally_skip_execution;
282 volatile int arg_index, top_level_arg_index;
283
284 /* Catch early SIGINTs. */
285 code = setjmp (top_level);
286 if (code)
287 exit (2);
288
289 check_dev_tty ();
290
291 #ifdef __CYGWIN32__
292 _cygwin32_check_tmp ();
293 #endif
294
295 /* Wait forever if we are debugging a login shell. */
296 while (debugging_login_shell);
297
298 set_default_locale ();
299
300 running_setuid = uidget ();
301
302 posixly_correct = (getenv ("POSIXLY_CORRECT") != (char *)NULL) ||
303 (getenv ("POSIX_PEDANTIC") != (char *)NULL);
304
305 #if defined (USE_GNU_MALLOC_LIBRARY)
306 mcheck (programming_error, (void (*) ())0);
307 #endif /* USE_GNU_MALLOC_LIBRARY */
308
309 if (setjmp (subshell_top_level))
310 {
311 argc = subshell_argc;
312 argv = subshell_argv;
313 env = subshell_envp;
314 sourced_env = 0;
315 }
316
317 /* Initialize `local' variables for all `invocations' of main (). */
318 arg_index = 1;
319 local_pending_command = (char *)NULL;
320 want_pending_command = locally_skip_execution = read_from_stdin = 0;
321 default_input = stdin;
322 #if defined (BUFFERED_INPUT)
323 default_buffered_input = -1;
324 #endif
325
326 /* Fix for the `infinite process creation' bug when running shell scripts
327 from startup files on System V. */
328 login_shell = make_login_shell = 0;
329
330 /* If this shell has already been run, then reinitialize it to a
331 vanilla state. */
332 if (shell_initialized || shell_name)
333 {
334 /* Make sure that we do not infinitely recurse as a login shell. */
335 if (*shell_name == '-')
336 shell_name++;
337
338 shell_reinitialize ();
339 if (setjmp (top_level))
340 exit (2);
341 }
342
343 shell_environment = env;
344 set_shell_name (argv[0]);
345 shell_start_time = NOW; /* NOW now defined in general.h */
346
347 /* Parse argument flags from the input line. */
348
349 /* Find full word arguments first. */
350 arg_index = parse_long_options (argv, arg_index, argc);
351
352 if (want_initial_help)
353 {
354 show_shell_usage (stdout, 1);
355 exit (EXECUTION_SUCCESS);
356 }
357
358 if (do_version)
359 {
360 show_shell_version (1);
361 exit (EXECUTION_SUCCESS);
362 }
363
364 /* If user supplied the "--login" flag, then set and invert LOGIN_SHELL. */
365 if (make_login_shell)
366 {
367 login_shell++;
368 login_shell = -login_shell;
369 }
370
371 /* All done with full word options; do standard shell option parsing.*/
372 this_command_name = shell_name; /* for error reporting */
373 arg_index = parse_shell_options (argv, arg_index, argc);
374
375 if (dump_po_strings)
376 dump_translatable_strings = 1;
377
378 if (dump_translatable_strings)
379 read_but_dont_execute = 1;
380
381 if (running_setuid && privileged_mode == 0)
382 disable_priv_mode ();
383
384 /* Need to get the argument to a -c option processed in the
385 above loop. The next arg is a command to execute, and the
386 following args are $0...$n respectively. */
387 if (want_pending_command)
388 {
389 local_pending_command = argv[arg_index];
390 if (local_pending_command == 0)
391 {
392 report_error ("option `-c' requires an argument");
393 exit (EX_USAGE);
394 }
395 arg_index++;
396 }
397 this_command_name = (char *)NULL;
398
399 /* First, let the outside world know about our interactive status.
400 A shell is interactive if the `-i' flag was given, or if all of
401 the following conditions are met:
402 no -c command
403 no arguments remaining or the -s flag given
404 standard input is a terminal
405 standard output is a terminal
406 Refer to Posix.2, the description of the `sh' utility. */
407
408 if (forced_interactive || /* -i flag */
409 (!local_pending_command && /* No -c command and ... */
410 wordexp_only == 0 && /* No --wordexp and ... */
411 ((arg_index == argc) || /* no remaining args or... */
412 read_from_stdin) && /* -s flag with args, and */
413 isatty (fileno (stdin)) && /* Input is a terminal and */
414 isatty (fileno (stdout)))) /* output is a terminal. */
415 init_interactive ();
416 else
417 init_noninteractive ();
418
419 #define CLOSE_FDS_AT_LOGIN
420 #if defined (CLOSE_FDS_AT_LOGIN)
421 /*
422 * Some systems have the bad habit of starting login shells with lots of open
423 * file descriptors. For instance, most systems that have picked up the
424 * pre-4.0 Sun YP code leave a file descriptor open each time you call one
425 * of the getpw* functions, and it's set to be open across execs. That
426 * means one for login, one for xterm, one for shelltool, etc.
427 */
428 if (login_shell && interactive_shell)
429 {
430 for (i = 3; i < 20; i++)
431 close (i);
432 }
433 #endif /* CLOSE_FDS_AT_LOGIN */
434
435 /* If we're in a strict Posix.2 mode, turn on interactive comments and
436 other Posix.2 things. */
437 if (posixly_correct)
438 {
439 posix_initialize (posixly_correct);
440 #if defined (READLINE)
441 if (interactive_shell)
442 posix_readline_initialize (posixly_correct);
443 #endif
444 }
445
446 /* From here on in, the shell must be a normal functioning shell.
447 Variables from the environment are expected to be set, etc. */
448 shell_initialize ();
449
450 set_default_locale_vars ();
451
452 if (interactive_shell)
453 {
454 char *term;
455
456 term = getenv ("TERM");
457 no_line_editing |= term && (STREQ (term, "emacs"));
458 term = getenv ("EMACS");
459 running_under_emacs = term ? ((fnmatch ("*term*", term, 0) == 0) ? 2 : 1)
460 : 0;
461 }
462
463 top_level_arg_index = arg_index;
464
465 /* Give this shell a place to longjmp to before executing the
466 startup files. This allows users to press C-c to abort the
467 lengthy startup. */
468 code = setjmp (top_level);
469 if (code)
470 {
471 if (code == EXITPROG)
472 exit_shell (last_command_exit_value);
473 else
474 {
475 #if defined (JOB_CONTROL)
476 /* Reset job control, since run_startup_files turned it off. */
477 set_job_control (interactive_shell);
478 #endif
479 locally_skip_execution++;
480 }
481 }
482
483 arg_index = top_level_arg_index;
484
485 /* Execute the start-up scripts. */
486
487 if (interactive_shell == 0)
488 {
489 makunbound ("PS1", shell_variables);
490 makunbound ("PS2", shell_variables);
491 interactive = expand_aliases = 0;
492 }
493 else
494 {
495 change_flag ('i', FLAG_ON);
496 interactive = 1;
497 }
498
499 #if defined (RESTRICTED_SHELL)
500 /* If the `-r' option is supplied at invocation, make sure that the shell
501 is not in restricted mode when running the startup files. */
502 saverst = restricted;
503 restricted = 0;
504 #endif
505
506 if (locally_skip_execution == 0 && running_setuid == 0)
507 run_startup_files ();
508
509 /* If we are invoked as `sh', turn on Posix mode. */
510 if (act_like_sh)
511 {
512 posix_initialize (posixly_correct = 1);
513 #if defined (READLINE)
514 if (interactive_shell)
515 posix_readline_initialize (posixly_correct);
516 #endif
517 }
518
519 #if defined (RESTRICTED_SHELL)
520 /* Turn on the restrictions after executing the startup files. This
521 means that `bash -r' or `set -r' invoked from a startup file will
522 turn on the restrictions after the startup files are executed. */
523 restricted = saverst || restricted;
524 maybe_make_restricted (shell_name);
525 #endif /* RESTRICTED_SHELL */
526
527 if (wordexp_only)
528 {
529 startup_state = 3;
530 last_command_exit_value = run_wordexp (argv[arg_index]);
531 exit_shell (last_command_exit_value);
532 }
533
534 if (local_pending_command)
535 {
536 arg_index = bind_args (argv, arg_index, argc, 0);
537
538 startup_state = 2;
539 #if defined (ONESHOT)
540 run_one_command (local_pending_command);
541 exit_shell (last_command_exit_value);
542 #else /* ONESHOT */
543 with_input_from_string (local_pending_command, "-c");
544 goto read_and_execute;
545 #endif /* !ONESHOT */
546 }
547
548 /* Get possible input filename and set up default_buffered_input or
549 default_input as appropriate. */
550 if (arg_index != argc && read_from_stdin == 0)
551 {
552 open_shell_script (argv[arg_index]);
553 arg_index++;
554 }
555 else if (interactive == 0)
556 /* In this mode, bash is reading a script from stdin, which is a
557 pipe or redirected file. */
558 #if defined (BUFFERED_INPUT)
559 default_buffered_input = fileno (stdin); /* == 0 */
560 #else
561 setbuf (default_input, (char *)NULL);
562 #endif /* !BUFFERED_INPUT */
563
564 set_bash_input ();
565
566 /* Bind remaining args to $1 ... $n */
567 arg_index = bind_args (argv, arg_index, argc, 1);
568
569 /* Do the things that should be done only for interactive shells. */
570 if (interactive_shell)
571 {
572 /* Set up for checking for presence of mail. */
573 remember_mail_dates ();
574 reset_mail_timer ();
575
576 #if defined (HISTORY)
577 /* Initialize the interactive history stuff. */
578 bash_initialize_history ();
579 if (shell_initialized == 0)
580 load_history ();
581 #endif /* HISTORY */
582
583 /* Initialize terminal state for interactive shells after the
584 .bash_profile and .bashrc are interpreted. */
585 get_tty_state ();
586 }
587
588 #if !defined (ONESHOT)
589 read_and_execute:
590 #endif /* !ONESHOT */
591
592 shell_initialized = 1;
593
594 /* Read commands until exit condition. */
595 reader_loop ();
596 exit_shell (last_command_exit_value);
597 }
598
599 static int
600 parse_long_options (argv, arg_start, arg_end)
601 char **argv;
602 int arg_start, arg_end;
603 {
604 int arg_index, longarg, i;
605 char *arg_string;
606
607 arg_index = arg_start;
608 while ((arg_index != arg_end) && (arg_string = argv[arg_index]) &&
609 (*arg_string == '-'))
610 {
611 longarg = 0;
612
613 /* Make --login equivalent to -login. */
614 if (arg_string[1] == '-' && arg_string[2])
615 {
616 longarg = 1;
617 arg_string++;
618 }
619
620 for (i = 0; long_args[i].name; i++)
621 {
622 if (STREQ (arg_string + 1, long_args[i].name))
623 {
624 if (long_args[i].type == Int)
625 *long_args[i].int_value = 1;
626 else if (argv[++arg_index] == 0)
627 {
628 report_error ("option `%s' requires an argument",
629 long_args[i].name);
630 exit (EX_USAGE);
631 }
632 else
633 *long_args[i].char_value = argv[arg_index];
634
635 break;
636 }
637 }
638 if (long_args[i].name == 0)
639 {
640 if (longarg)
641 {
642 report_error ("%s: unrecognized option", argv[arg_index]);
643 show_shell_usage (stderr, 0);
644 exit (EX_USAGE);
645 }
646 break; /* No such argument. Maybe flag arg. */
647 }
648
649 arg_index++;
650 }
651
652 return (arg_index);
653 }
654
655 static int
656 parse_shell_options (argv, arg_start, arg_end)
657 char **argv;
658 int arg_start, arg_end;
659 {
660 int arg_index;
661 int arg_character, on_or_off, next_arg, i;
662 char *o_option, *arg_string;
663
664 arg_index = arg_start;
665 while (arg_index != arg_end && (arg_string = argv[arg_index]) &&
666 (*arg_string == '-' || *arg_string == '+'))
667 {
668 /* There are flag arguments, so parse them. */
669 next_arg = arg_index + 1;
670
671 /* A single `-' signals the end of options. From the 4.3 BSD sh.
672 An option `--' means the same thing; this is the standard
673 getopt(3) meaning. */
674 if (arg_string[0] == '-' &&
675 (arg_string[1] == '\0' ||
676 (arg_string[1] == '-' && arg_string[2] == '\0')))
677 return (next_arg);
678
679 i = 1;
680 on_or_off = arg_string[0];
681 while (arg_character = arg_string[i++])
682 {
683 switch (arg_character)
684 {
685 case 'c':
686 want_pending_command = 1;
687 break;
688
689 case 's':
690 read_from_stdin = 1;
691 break;
692
693 case 'o':
694 o_option = argv[next_arg];
695 if (o_option == 0)
696 {
697 list_minus_o_opts (-1, (on_or_off == '-') ? 0 : 1);
698 break;
699 }
700 if (set_minus_o_option (on_or_off, o_option) != EXECUTION_SUCCESS)
701 exit (EX_USAGE);
702 next_arg++;
703 break;
704
705 case 'D':
706 dump_translatable_strings = 1;
707 break;
708
709 default:
710 if (change_flag (arg_character, on_or_off) == FLAG_ERROR)
711 {
712 report_error ("%c%c: unrecognized option", on_or_off, arg_character);
713 show_shell_usage (stderr, 0);
714 exit (EX_USAGE);
715 }
716 }
717 }
718 /* Can't do just a simple increment anymore -- what about
719 "bash -abouo emacs ignoreeof -hP"? */
720 arg_index = next_arg;
721 }
722
723 return (arg_index);
724 }
725
726 /* Exit the shell with status S. */
727 void
728 exit_shell (s)
729 int s;
730 {
731 /* Do trap[0] if defined. Allow it to override the exit status
732 passed to us. */
733 if (signal_is_trapped (0))
734 s = run_exit_trap ();
735
736 #if defined (PROCESS_SUBSTITUTION)
737 unlink_fifo_list ();
738 #endif /* PROCESS_SUBSTITUTION */
739
740 #if defined (HISTORY)
741 if (interactive_shell)
742 maybe_save_shell_history ();
743 #endif /* HISTORY */
744
745 #if defined (JOB_CONTROL)
746 /* If the user has run `shopt -s huponexit', hangup all jobs when we exit
747 an interactive login shell. ksh does this unconditionally. */
748 if (interactive_shell && login_shell && hup_on_exit)
749 hangup_all_jobs ();
750
751 /* If this shell is interactive, terminate all stopped jobs and
752 restore the original terminal process group. */
753 end_job_control ();
754 #endif /* JOB_CONTROL */
755
756 /* Always return the exit status of the last command to our parent. */
757 exit (s);
758 }
759
760 /* Source the bash startup files. If POSIXLY_CORRECT is non-zero, we obey
761 the Posix.2 startup file rules: $ENV is expanded, and if the file it
762 names exists, that file is sourced. The Posix.2 rules are in effect
763 for interactive shells only. (section 4.56.5.3) */
764
765 /* Execute ~/.bashrc for most shells. Never execute it if
766 ACT_LIKE_SH is set, or if NO_RC is set.
767
768 If the executable file "/usr/gnu/src/bash/foo" contains:
769
770 #!/usr/gnu/bin/bash
771 echo hello
772
773 then:
774
775 COMMAND EXECUTE BASHRC
776 --------------------------------
777 bash -c foo NO
778 bash foo NO
779 foo NO
780 rsh machine ls YES (for rsh, which calls `bash -c')
781 rsh machine foo YES (for shell started by rsh) NO (for foo!)
782 echo ls | bash NO
783 login NO
784 bash YES
785 */
786
787 static void
788 execute_env_file (env_file)
789 char *env_file;
790 {
791 char *fn;
792 WORD_LIST *list;
793
794 if (env_file && *env_file)
795 {
796 list = expand_string_unsplit (env_file, Q_DOUBLE_QUOTES);
797 if (list)
798 {
799 fn = string_list (list);
800 dispose_words (list);
801
802 if (fn && *fn)
803 maybe_execute_file (fn, 1);
804 FREE (fn);
805 }
806 }
807 }
808
809 static void
810 run_startup_files ()
811 {
812 #if defined (JOB_CONTROL)
813 int old_job_control;
814 #endif
815 int sourced_login, run_by_ssh;
816 SHELL_VAR *sshvar;
817
818 /* get the rshd/sshd case out of the way first. */
819 if (interactive_shell == 0 && no_rc == 0 && login_shell == 0 &&
820 act_like_sh == 0 && local_pending_command)
821 {
822 /* Find out if we were invoked by ssh. If so, set RUN_BY_SSH to 1. */
823 sshvar = find_variable ("SSH_CLIENT");
824 if (sshvar)
825 {
826 run_by_ssh = 1;
827 /* Now that we've tested the variable, we need to unexport it. */
828 sshvar->attributes &= ~att_exported;
829 array_needs_making = 1;
830 }
831 else
832 run_by_ssh = 0;
833
834 /* If we were run by sshd or we think we were run by rshd, execute
835 ~/.bashrc. */
836 if (run_by_ssh || isnetconn (fileno (stdin)))
837 {
838 #ifdef SYS_BASHRC
839 maybe_execute_file (SYS_BASHRC, 1);
840 #endif
841 maybe_execute_file (bashrc_file, 1);
842 return;
843 }
844 }
845
846 #if defined (JOB_CONTROL)
847 /* Startup files should be run without job control enabled. */
848 old_job_control = interactive_shell ? set_job_control (0) : 0;
849 #endif
850
851 sourced_login = 0;
852
853 #if defined (NON_INTERACTIVE_LOGIN_SHELLS)
854 if (login_shell)
855 {
856 /* We don't execute .bashrc for login shells. */
857 no_rc++;
858
859 /* Execute /etc/profile and one of the personal login shell
860 initialization files. */
861 if (no_profile == 0)
862 {
863 maybe_execute_file (SYS_PROFILE, 1);
864
865 if (act_like_sh) /* sh */
866 maybe_execute_file ("~/.profile", 1);
867 else if ((maybe_execute_file ("~/.bash_profile", 1) == 0) &&
868 (maybe_execute_file ("~/.bash_login", 1) == 0)) /* bash */
869 maybe_execute_file ("~/.profile", 1);
870 }
871
872 sourced_login = 1;
873 }
874 #endif /* NON_INTERACTIVE_LOGIN_SHELLS */
875
876 /* A non-interactive shell not named `sh' and not in posix mode reads and
877 executes commands from $BASH_ENV. If `su' starts a shell with `-c cmd'
878 and `-su' as the name of the shell, we want to read the startup files.
879 No other non-interactive shells read any startup files. */
880 if (interactive_shell == 0 && !(su_shell && login_shell))
881 {
882 if (posixly_correct == 0 && act_like_sh == 0 && privileged_mode == 0 &&
883 sourced_env++ == 0)
884 execute_env_file (get_string_value ("BASH_ENV"));
885 return;
886 }
887
888 /* Interactive shell or `-su' shell. */
889 if (posixly_correct == 0) /* bash, sh */
890 {
891 if (login_shell && sourced_login++ == 0)
892 {
893 /* We don't execute .bashrc for login shells. */
894 no_rc++;
895
896 /* Execute /etc/profile and one of the personal login shell
897 initialization files. */
898 if (no_profile == 0)
899 {
900 maybe_execute_file (SYS_PROFILE, 1);
901
902 if (act_like_sh) /* sh */
903 maybe_execute_file ("~/.profile", 1);
904 else if ((maybe_execute_file ("~/.bash_profile", 1) == 0) &&
905 (maybe_execute_file ("~/.bash_login", 1) == 0)) /* bash */
906 maybe_execute_file ("~/.profile", 1);
907 }
908 }
909
910 /* bash */
911 if (act_like_sh == 0 && no_rc == 0)
912 {
913 #ifdef SYS_BASHRC
914 maybe_execute_file (SYS_BASHRC, 1);
915 #endif
916 maybe_execute_file (bashrc_file, 1);
917 }
918 /* sh */
919 else if (act_like_sh && privileged_mode == 0 && sourced_env++ == 0)
920 execute_env_file (get_string_value ("ENV"));
921 }
922 else /* bash --posix, sh --posix */
923 {
924 /* bash and sh */
925 if (interactive_shell && privileged_mode == 0 && sourced_env++ == 0)
926 execute_env_file (get_string_value ("ENV"));
927 }
928
929 #if defined (JOB_CONTROL)
930 set_job_control (old_job_control);
931 #endif
932 }
933
934 #if defined (RESTRICTED_SHELL)
935 /* Perhaps make this shell a `restricted' one, based on NAME. If the
936 basename of NAME is "rbash", then this shell is restricted. The
937 name of the restricted shell is a configurable option, see config.h.
938 In a restricted shell, PATH and SHELL are read-only and non-unsettable.
939 Do this also if `restricted' is already set to 1; maybe the shell was
940 started with -r. */
941 int
942 maybe_make_restricted (name)
943 char *name;
944 {
945 char *temp;
946
947 temp = base_pathname (shell_name);
948 if (restricted || (STREQ (temp, RESTRICTED_SHELL_NAME)))
949 {
950 set_var_read_only ("PATH");
951 set_var_read_only ("SHELL");
952 restricted++;
953 }
954 return (restricted);
955 }
956 #endif /* RESTRICTED_SHELL */
957
958 /* Fetch the current set of uids and gids and return 1 if we're running
959 setuid or setgid. */
960 static int
961 uidget ()
962 {
963 uid_t u;
964
965 u = getuid ();
966 if (current_user.uid != u)
967 {
968 FREE (current_user.user_name);
969 FREE (current_user.shell);
970 FREE (current_user.home_dir);
971 current_user.user_name = current_user.shell = current_user.home_dir = (char *)NULL;
972 }
973 current_user.uid = u;
974 current_user.gid = getgid ();
975 current_user.euid = geteuid ();
976 current_user.egid = getegid ();
977
978 /* See whether or not we are running setuid or setgid. */
979 return (current_user.uid != current_user.euid) ||
980 (current_user.gid != current_user.egid);
981 }
982
983 void
984 disable_priv_mode ()
985 {
986 setuid (current_user.uid);
987 setgid (current_user.gid);
988 current_user.euid = current_user.uid;
989 current_user.egid = current_user.gid;
990 }
991
992 static int
993 run_wordexp (words)
994 char *words;
995 {
996 int code, nw, nb;
997 WORD_DESC *w;
998 WORD_LIST *wl, *result;
999
1000 code = setjmp (top_level);
1001
1002 if (code != NOT_JUMPED)
1003 {
1004 switch (code)
1005 {
1006 /* Some kind of throw to top_level has occured. */
1007 case FORCE_EOF:
1008 return last_command_exit_value = 127;
1009 case EXITPROG:
1010 return last_command_exit_value;
1011 case DISCARD:
1012 return last_command_exit_value = 1;
1013 default:
1014 programming_error ("run_wordexp: bad jump: code %d", code);
1015 }
1016 }
1017
1018 /* Run it through the parser to get a list of words and expand them */
1019 if (words && *words)
1020 {
1021 with_input_from_string (words, "--wordexp");
1022 if (parse_command () != 0)
1023 return (126);
1024 if (global_command == 0)
1025 {
1026 printf ("0\n0\n");
1027 return (0);
1028 }
1029 if (global_command->type != cm_simple)
1030 return (126);
1031 wl = global_command->value.Simple->words;
1032 result = wl ? expand_words_no_vars (wl) : (WORD_LIST *)0;
1033 }
1034 else
1035 result = (WORD_LIST *)0;
1036
1037 last_command_exit_value = 0;
1038
1039 if (result == 0)
1040 {
1041 printf ("0\n0\n");
1042 return (0);
1043 }
1044
1045 /* Count up the number of words and bytes, and print them. Don't count
1046 the trailing NUL byte. */
1047 for (nw = nb = 0, wl = result; wl; wl = wl->next)
1048 {
1049 nw++;
1050 nb += strlen (wl->word->word);
1051 }
1052 printf ("%u\n%u\n", nw, nb);
1053 /* Print each word on a separate line. This will have to be changed when
1054 the interface to glibc is completed. */
1055 for (wl = result; wl; wl = wl->next)
1056 printf ("%s\n", wl->word->word);
1057
1058 return (0);
1059 }
1060
1061 #if defined (ONESHOT)
1062 /* Run one command, given as the argument to the -c option. Tell
1063 parse_and_execute not to fork for a simple command. */
1064 static int
1065 run_one_command (command)
1066 char *command;
1067 {
1068 int code;
1069
1070 code = setjmp (top_level);
1071
1072 if (code != NOT_JUMPED)
1073 {
1074 #if defined (PROCESS_SUBSTITUTION)
1075 unlink_fifo_list ();
1076 #endif /* PROCESS_SUBSTITUTION */
1077 switch (code)
1078 {
1079 /* Some kind of throw to top_level has occured. */
1080 case FORCE_EOF:
1081 return last_command_exit_value = 127;
1082 case EXITPROG:
1083 return last_command_exit_value;
1084 case DISCARD:
1085 return last_command_exit_value = 1;
1086 default:
1087 programming_error ("run_one_command: bad jump: code %d", code);
1088 }
1089 }
1090 return (parse_and_execute (savestring (command), "-c", SEVAL_NOHIST));
1091 }
1092 #endif /* ONESHOT */
1093
1094 static int
1095 bind_args (argv, arg_start, arg_end, start_index)
1096 char **argv;
1097 int arg_start, arg_end, start_index;
1098 {
1099 register int i;
1100 WORD_LIST *args;
1101
1102 for (i = arg_start, args = (WORD_LIST *)NULL; i != arg_end; i++)
1103 args = make_word_list (make_word (argv[i]), args);
1104 if (args)
1105 {
1106 args = REVERSE_LIST (args, WORD_LIST *);
1107 if (start_index == 0) /* bind to $0...$n for sh -c command */
1108 {
1109 /* Posix.2 4.56.3 says that the first argument after sh -c command
1110 becomes $0, and the rest of the arguments become $1...$n */
1111 shell_name = savestring (args->word->word);
1112 FREE (dollar_vars[0]);
1113 dollar_vars[0] = savestring (args->word->word);
1114 remember_args (args->next, 1);
1115 }
1116 else /* bind to $1...$n for shell script */
1117 remember_args (args, 1);
1118
1119 dispose_words (args);
1120 }
1121
1122 return (i);
1123 }
1124
1125 void
1126 unbind_args ()
1127 {
1128 remember_args ((WORD_LIST *)NULL, 1);
1129 }
1130
1131 static int
1132 open_shell_script (script_name)
1133 char *script_name;
1134 {
1135 int fd, e;
1136 char *filename, *path_filename;
1137 unsigned char sample[80];
1138 int sample_len;
1139 struct stat sb;
1140
1141 free (dollar_vars[0]);
1142 dollar_vars[0] = savestring (script_name);
1143 filename = savestring (script_name);
1144
1145 fd = open (filename, O_RDONLY);
1146 if ((fd < 0) && (errno == ENOENT) && (absolute_program (filename) == 0))
1147 {
1148 e = errno;
1149 /* If it's not in the current directory, try looking through PATH
1150 for it. */
1151 path_filename = find_path_file (script_name);
1152 if (path_filename)
1153 {
1154 free (filename);
1155 filename = path_filename;
1156 fd = open (filename, O_RDONLY);
1157 }
1158 else
1159 errno = e;
1160 }
1161
1162 if (fd < 0)
1163 {
1164 e = errno;
1165 file_error (filename);
1166 exit ((e == ENOENT) ? EX_NOTFOUND : EX_NOINPUT);
1167 }
1168
1169 /* Only do this with file descriptors we can seek on. */
1170 if (lseek (fd, 0L, 1) != -1)
1171 {
1172 /* Check to see if the `file' in `bash file' is a binary file
1173 according to the same tests done by execute_simple_command (),
1174 and report an error and exit if it is. */
1175 sample_len = read (fd, sample, sizeof (sample));
1176 if (sample_len < 0)
1177 {
1178 e = errno;
1179 if ((fstat (fd, &sb) == 0) && S_ISDIR (sb.st_mode))
1180 internal_error ("%s: is a directory", filename);
1181 else
1182 {
1183 errno = e;
1184 file_error (filename);
1185 }
1186 exit (EX_NOEXEC);
1187 }
1188 else if (sample_len > 0 && (check_binary_file (sample, sample_len)))
1189 {
1190 internal_error ("%s: cannot execute binary file", filename);
1191 exit (EX_BINARY_FILE);
1192 }
1193 /* Now rewind the file back to the beginning. */
1194 lseek (fd, 0L, 0);
1195 }
1196
1197 #if defined (BUFFERED_INPUT)
1198 default_buffered_input = fd;
1199 # if 0
1200 /* This is never executed. */
1201 if (default_buffered_input == -1)
1202 {
1203 file_error (filename);
1204 exit (EX_NOTFOUND);
1205 }
1206 # endif
1207 SET_CLOSE_ON_EXEC (default_buffered_input);
1208 #else /* !BUFFERED_INPUT */
1209 /* Open the script. But try to move the file descriptor to a randomly
1210 large one, in the hopes that any descriptors used by the script will
1211 not match with ours. */
1212 fd = move_to_high_fd (fd, 0, -1);
1213
1214 default_input = fdopen (fd, "r");
1215
1216 if (default_input == 0)
1217 {
1218 file_error (filename);
1219 exit (EX_NOTFOUND);
1220 }
1221
1222 SET_CLOSE_ON_EXEC (fd);
1223 if (fileno (default_input) != fd)
1224 SET_CLOSE_ON_EXEC (fileno (default_input));
1225 #endif /* !BUFFERED_INPUT */
1226
1227 if (interactive_shell == 0 || isatty (fd) == 0)
1228 /* XXX - does this really need to be called again here? */
1229 init_noninteractive ();
1230 else
1231 {
1232 /* I don't believe that this code is ever executed, even in
1233 the presence of /dev/fd. */
1234 dup2 (fd, 0);
1235 close (fd);
1236 fd = 0;
1237 #if defined (BUFFERED_INPUT)
1238 default_buffered_input = 0;
1239 #else
1240 fclose (default_input);
1241 default_input = stdin;
1242 #endif
1243 }
1244 free (filename);
1245 return (fd);
1246 }
1247
1248 /* Initialize the input routines for the parser. */
1249 static void
1250 set_bash_input ()
1251 {
1252 /* Make sure the fd from which we are reading input is not in
1253 no-delay mode. */
1254 #if defined (BUFFERED_INPUT)
1255 if (interactive == 0)
1256 unset_nodelay_mode (default_buffered_input);
1257 else
1258 #endif /* !BUFFERED_INPUT */
1259 unset_nodelay_mode (fileno (stdin));
1260
1261 /* with_input_from_stdin really means `with_input_from_readline' */
1262 if (interactive && no_line_editing == 0)
1263 with_input_from_stdin ();
1264 else
1265 #if defined (BUFFERED_INPUT)
1266 {
1267 if (interactive == 0)
1268 with_input_from_buffered_stream (default_buffered_input, dollar_vars[0]);
1269 else
1270 with_input_from_stream (default_input, dollar_vars[0]);
1271 }
1272 #else /* !BUFFERED_INPUT */
1273 with_input_from_stream (default_input, dollar_vars[0]);
1274 #endif /* !BUFFERED_INPUT */
1275 }
1276
1277 /* Close the current shell script input source and forget about it. This is
1278 extern so execute_cmd.c:initialize_subshell() can call it. If CHECK_ZERO
1279 is non-zero, we close default_buffered_input even if it's the standard
1280 input (fd 0). */
1281 void
1282 unset_bash_input (check_zero)
1283 int check_zero;
1284 {
1285 #if defined (BUFFERED_INPUT)
1286 if ((check_zero && default_buffered_input >= 0) ||
1287 (check_zero == 0 && default_buffered_input > 0))
1288 {
1289 close_buffered_fd (default_buffered_input);
1290 default_buffered_input = bash_input.location.buffered_fd = -1;
1291 }
1292 #else /* !BUFFERED_INPUT */
1293 if (default_input)
1294 {
1295 fclose (default_input);
1296 default_input = (FILE *)NULL;
1297 }
1298 #endif /* !BUFFERED_INPUT */
1299 }
1300
1301
1302 #if !defined (PROGRAM)
1303 # define PROGRAM "bash"
1304 #endif
1305
1306 static void
1307 set_shell_name (argv0)
1308 char *argv0;
1309 {
1310 /* Here's a hack. If the name of this shell is "sh", then don't do
1311 any startup files; just try to be more like /bin/sh. */
1312 shell_name = base_pathname (argv0);
1313 if (*shell_name == '-')
1314 shell_name++;
1315 if (shell_name[0] == 's' && shell_name[1] == 'h' && shell_name[2] == '\0')
1316 act_like_sh++;
1317 if (shell_name[0] == 's' && shell_name[1] == 'u' && shell_name[2] == '\0')
1318 su_shell++;
1319
1320 shell_name = argv0;
1321 FREE (dollar_vars[0]);
1322 dollar_vars[0] = savestring (shell_name);
1323
1324 if (*shell_name == '-')
1325 {
1326 shell_name++;
1327 login_shell++;
1328 }
1329
1330 /* A program may start an interactive shell with
1331 "execl ("/bin/bash", "-", NULL)".
1332 If so, default the name of this shell to our name. */
1333 if (!shell_name || !*shell_name || (shell_name[0] == '-' && !shell_name[1]))
1334 shell_name = PROGRAM;
1335 }
1336
1337 static void
1338 init_interactive ()
1339 {
1340 interactive_shell = startup_state = interactive = 1;
1341 expand_aliases = 1;
1342 }
1343
1344 static void
1345 init_noninteractive ()
1346 {
1347 #if defined (HISTORY)
1348 bash_history_reinit (0);
1349 #endif /* HISTORY */
1350 interactive_shell = startup_state = interactive = 0;
1351 expand_aliases = 0;
1352 no_line_editing = 1;
1353 #if defined (JOB_CONTROL)
1354 set_job_control (0);
1355 #endif /* JOB_CONTROL */
1356 }
1357
1358 void
1359 get_current_user_info ()
1360 {
1361 struct passwd *entry;
1362
1363 /* Don't fetch this more than once. */
1364 if (current_user.user_name == 0)
1365 {
1366 entry = getpwuid (current_user.uid);
1367 if (entry)
1368 {
1369 current_user.user_name = savestring (entry->pw_name);
1370 current_user.shell = (entry->pw_shell && entry->pw_shell[0])
1371 ? savestring (entry->pw_shell)
1372 : savestring ("/bin/sh");
1373 current_user.home_dir = savestring (entry->pw_dir);
1374 }
1375 else
1376 {
1377 current_user.user_name = savestring ("I have no name!");
1378 current_user.shell = savestring ("/bin/sh");
1379 current_user.home_dir = savestring ("/");
1380 }
1381 endpwent ();
1382 }
1383 }
1384
1385 /* Do whatever is necessary to initialize the shell.
1386 Put new initializations in here. */
1387 static void
1388 shell_initialize ()
1389 {
1390 char hostname[256];
1391
1392 /* Line buffer output for stderr and stdout. */
1393 #if defined (SunOS5)
1394 if (shell_initialized == 0)
1395 #endif
1396 {
1397 setlinebuf (stderr);
1398 setlinebuf (stdout);
1399 }
1400
1401 /* Sort the array of shell builtins so that the binary search in
1402 find_shell_builtin () works correctly. */
1403 initialize_shell_builtins ();
1404
1405 /* Initialize the trap signal handlers before installing our own
1406 signal handlers. traps.c:restore_original_signals () is responsible
1407 for restoring the original default signal handlers. That function
1408 is called when we make a new child. */
1409 initialize_traps ();
1410 initialize_signals ();
1411
1412 /* It's highly unlikely that this will change. */
1413 if (current_host_name == 0)
1414 {
1415 /* Initialize current_host_name. */
1416 if (gethostname (hostname, 255) < 0)
1417 current_host_name = "??host??";
1418 else
1419 current_host_name = savestring (hostname);
1420 }
1421
1422 /* Initialize the stuff in current_user that comes from the password
1423 file. We don't need to do this right away if the shell is not
1424 interactive. */
1425 if (interactive_shell)
1426 get_current_user_info ();
1427
1428 /* Initialize our interface to the tilde expander. */
1429 tilde_initialize ();
1430
1431 /* Initialize internal and environment variables. Don't import shell
1432 functions from the environment if we are running in privileged or
1433 restricted mode or if the shell is running setuid. */
1434 #if defined (RESTRICTED_SHELL)
1435 initialize_shell_variables (shell_environment, privileged_mode||restricted||running_setuid);
1436 #else
1437 initialize_shell_variables (shell_environment, privileged_mode||running_setuid);
1438 #endif
1439
1440 #if 0
1441 /* Initialize filename hash tables. */
1442 initialize_filename_hashing ();
1443 #endif
1444
1445 /* Initialize the data structures for storing and running jobs. */
1446 initialize_job_control (0);
1447
1448 /* Initialize input streams to null. */
1449 initialize_bash_input ();
1450
1451 /* Initialize the shell options. Don't import the shell options
1452 from the environment variable $SHELLOPTS if we are running in
1453 privileged or restricted mode or if the shell is running setuid. */
1454 #if defined (RESTRICTED_SHELL)
1455 initialize_shell_options (privileged_mode||restricted||running_setuid);
1456 #else
1457 initialize_shell_options (privileged_mode||running_setuid);
1458 #endif
1459 }
1460
1461 /* Function called by main () when it appears that the shell has already
1462 had some initialization performed. This is supposed to reset the world
1463 back to a pristine state, as if we had been exec'ed. */
1464 static void
1465 shell_reinitialize ()
1466 {
1467 /* The default shell prompts. */
1468 primary_prompt = PPROMPT;
1469 secondary_prompt = SPROMPT;
1470
1471 /* Things that get 1. */
1472 current_command_number = 1;
1473
1474 /* We have decided that the ~/.bashrc file should not be executed
1475 for the invocation of each shell script. If the variable $ENV
1476 (or $BASH_ENV) is set, its value is used as the name of a file
1477 to source. */
1478 no_rc = no_profile = 1;
1479
1480 /* Things that get 0. */
1481 login_shell = make_login_shell = interactive = executing = 0;
1482 debugging = do_version = line_number = last_command_exit_value = 0;
1483 forced_interactive = interactive_shell = subshell_environment = 0;
1484 expand_aliases = 0;
1485
1486 #if defined (HISTORY)
1487 bash_history_reinit (0);
1488 #endif /* HISTORY */
1489
1490 #if defined (RESTRICTED_SHELL)
1491 restricted = 0;
1492 #endif /* RESTRICTED_SHELL */
1493
1494 /* Ensure that the default startup file is used. (Except that we don't
1495 execute this file for reinitialized shells). */
1496 bashrc_file = "~/.bashrc";
1497
1498 /* Delete all variables and functions. They will be reinitialized when
1499 the environment is parsed. */
1500 delete_all_variables (shell_variables);
1501 delete_all_variables (shell_functions);
1502
1503 #if 0
1504 /* Pretend the PATH variable has changed. */
1505 flush_hashed_filenames ();
1506 #endif
1507 }
1508
1509 static void
1510 show_shell_usage (fp, extra)
1511 FILE *fp;
1512 int extra;
1513 {
1514 int i;
1515 char *set_opts, *s, *t;
1516
1517 if (extra)
1518 fprintf (fp, "GNU bash, version %s-(%s)\n", shell_version_string (), MACHTYPE);
1519 fprintf (fp, "Usage:\t%s [GNU long option] [option] ...\n\t%s [GNU long option] [option] script-file ...\n",
1520 shell_name, shell_name);
1521 fputs ("GNU long options:\n", fp);
1522 for (i = 0; long_args[i].name; i++)
1523 fprintf (fp, "\t--%s\n", long_args[i].name);
1524
1525 fputs ("Shell options:\n", fp);
1526 fputs ("\t-irsD or -c command\t\t(invocation only)\n", fp);
1527
1528 for (i = 0, set_opts = 0; shell_builtins[i].name; i++)
1529 if (STREQ (shell_builtins[i].name, "set"))
1530 set_opts = savestring (shell_builtins[i].short_doc);
1531 if (set_opts)
1532 {
1533 s = strchr (set_opts, '[');
1534 if (s == 0)
1535 s = set_opts;
1536 while (*++s == '-')
1537 ;
1538 t = strchr (s, ']');
1539 if (t)
1540 *t = '\0';
1541 fprintf (fp, "\t-%s or -o option\n", s);
1542 free (set_opts);
1543 }
1544
1545 if (extra)
1546 {
1547 fprintf (fp, "Type `%s -c \"help set\"' for more information about shell options.\n", shell_name);
1548 fprintf (fp, "Type `%s -c help' for more information about shell builtin commands.\n", shell_name);
1549 fprintf (fp, "Use the `bashbug' command to report bugs.\n");
1550 }
1551 }
1552
1553 /* The second and subsequent conditions must match those used to decide
1554 whether or not to call getpeername() in isnetconn(). */
1555 #if defined (HAVE_SYS_SOCKET_H) && defined (HAVE_GETPEERNAME) && !defined (SVR4_2)
1556 # include <sys/socket.h>
1557 #endif
1558
1559 /* Is FD a socket or network connection? */
1560 static int
1561 isnetconn (fd)
1562 int fd;
1563 {
1564 #if defined (HAVE_GETPEERNAME) && !defined (SVR4_2)
1565 int rv, l;
1566 struct sockaddr sa;
1567
1568 l = sizeof(sa);
1569 rv = getpeername(fd, &sa, &l);
1570 /* Solaris 2.5 getpeername() returns EINVAL if the fd is not a socket. */
1571 return ((rv < 0 && (errno == ENOTSOCK || errno == EINVAL)) ? 0 : 1);
1572 #else /* !HAVE_GETPEERNAME || SVR4_2 */
1573 # if defined (SVR4) || defined (SVR4_2)
1574 /* Sockets on SVR4 and SVR4.2 are character special (streams) devices. */
1575 struct stat sb;
1576
1577 if (isatty (fd))
1578 return (0);
1579 if (fstat (fd, &sb) < 0)
1580 return (0);
1581 # if defined (S_ISFIFO)
1582 if (S_ISFIFO (sb.st_mode))
1583 return (0);
1584 # endif /* S_ISFIFO */
1585 return (S_ISCHR (sb.st_mode));
1586 # else /* !SVR4 && !SVR4_2 */
1587 # if defined (S_ISSOCK)
1588 struct stat sb;
1589
1590 if (fstat (fd, &sb) < 0)
1591 return (0);
1592 return (S_ISSOCK (sb.st_mode));
1593 # else /* !S_ISSOCK */
1594 return (0);
1595 # endif /* !S_ISSOCK */
1596 # endif /* !SVR4 && !SVR4_2 */
1597 #endif /* !HAVE_GETPEERNAME || SVR4_2 */
1598 }