comparison src/os_unix.c @ 167:c93c9cad9618

updated for version 7.0051
author vimboss
date Tue, 22 Feb 2005 08:39:57 +0000
parents 8b0ee9d57d7f
children 84c21eb4fc40
comparison
equal deleted inserted replaced
166:3a28ed993bbe 167:c93c9cad9618
163 static RETSIGTYPE sig_alarm __ARGS(SIGPROTOARG); 163 static RETSIGTYPE sig_alarm __ARGS(SIGPROTOARG);
164 static int sig_alarm_called; 164 static int sig_alarm_called;
165 #endif 165 #endif
166 static RETSIGTYPE deathtrap __ARGS(SIGPROTOARG); 166 static RETSIGTYPE deathtrap __ARGS(SIGPROTOARG);
167 167
168 static void catch_int_signal __ARGS((void));
168 static void set_signals __ARGS((void)); 169 static void set_signals __ARGS((void));
169 static void catch_signals __ARGS((RETSIGTYPE (*func_deadly)(), RETSIGTYPE (*func_other)())); 170 static void catch_signals __ARGS((RETSIGTYPE (*func_deadly)(), RETSIGTYPE (*func_other)()));
170 #ifndef __EMX__ 171 #ifndef __EMX__
171 static int have_wildcard __ARGS((int, char_u **)); 172 static int have_wildcard __ARGS((int, char_u **));
172 static int have_dollars __ARGS((int, char_u **)); 173 static int have_dollars __ARGS((int, char_u **));
173 #endif 174 #endif
174 175
175 #ifndef NO_EXPANDPATH 176 #ifndef NO_EXPANDPATH
176 static int pstrcmp __ARGS((const void *, const void *)); 177 static int pstrcmp __ARGS((const void *, const void *));
177 static int unix_expandpath __ARGS((garray_T *gap, char_u *path, int wildoff, int flags)); 178 static int unix_expandpath __ARGS((garray_T *gap, char_u *path, int wildoff, int flags));
179 # if defined(MACOS_X) && defined(FEAT_MBYTE)
180 extern char_u *mac_precompose_path __ARGS((char_u *decompPath, size_t decompLen, size_t *precompLen));
181 # endif
182 #endif
183
184 #if defined(MACOS_X) && defined(FEAT_MBYTE)
185 extern void mac_conv_init __ARGS((void));
186 extern void mac_conv_cleanup __ARGS((void));
178 #endif 187 #endif
179 188
180 #ifndef __EMX__ 189 #ifndef __EMX__
181 static int save_patterns __ARGS((int num_pat, char_u **pat, int *num_file, char_u ***file)); 190 static int save_patterns __ARGS((int num_pat, char_u **pat, int *num_file, char_u ***file));
182 #endif 191 #endif
1081 Columns = 80; 1090 Columns = 80;
1082 Rows = 24; 1091 Rows = 24;
1083 1092
1084 out_flush(); 1093 out_flush();
1085 set_signals(); 1094 set_signals();
1095
1096 #if defined(MACOS_X) && defined(FEAT_MBYTE)
1097 mac_conv_init();
1098 #endif
1086 } 1099 }
1087 1100
1088 static void 1101 static void
1089 set_signals() 1102 set_signals()
1090 { 1103 {
1111 */ 1124 */
1112 #ifdef SIGPIPE 1125 #ifdef SIGPIPE
1113 signal(SIGPIPE, SIG_IGN); 1126 signal(SIGPIPE, SIG_IGN);
1114 #endif 1127 #endif
1115 1128
1116 /*
1117 * We want to catch CTRL-C (only works while in Cooked mode).
1118 */
1119 #ifdef SIGINT 1129 #ifdef SIGINT
1120 signal(SIGINT, (RETSIGTYPE (*)())catch_sigint); 1130 catch_int_signal();
1121 #endif 1131 #endif
1122 1132
1123 /* 1133 /*
1124 * Ignore alarm signals (Perl's alarm() generates it). 1134 * Ignore alarm signals (Perl's alarm() generates it).
1125 */ 1135 */
1146 */ 1156 */
1147 if (gui.in_use) 1157 if (gui.in_use)
1148 signal(SIGHUP, SIG_IGN); 1158 signal(SIGHUP, SIG_IGN);
1149 #endif 1159 #endif
1150 } 1160 }
1161
1162 #if defined(SIGINT) || defined(PROTO)
1163 /*
1164 * Catch CTRL-C (only works while in Cooked mode).
1165 */
1166 static void
1167 catch_int_signal()
1168 {
1169 signal(SIGINT, (RETSIGTYPE (*)())catch_sigint);
1170 }
1171 #endif
1151 1172
1152 void 1173 void
1153 reset_signals() 1174 reset_signals()
1154 { 1175 {
1155 catch_signals(SIG_DFL, SIG_DFL); 1176 catch_signals(SIG_DFL, SIG_DFL);
2692 * Make sure the newline goes to the same stream as the text. 2713 * Make sure the newline goes to the same stream as the text.
2693 */ 2714 */
2694 static void 2715 static void
2695 exit_scroll() 2716 exit_scroll()
2696 { 2717 {
2718 if (silent_mode)
2719 return;
2697 if (newline_on_exit || msg_didout) 2720 if (newline_on_exit || msg_didout)
2698 { 2721 {
2699 if (msg_use_printf()) 2722 if (msg_use_printf())
2700 { 2723 {
2701 if (info_message) 2724 if (info_message)
2762 may_core_dump(); 2785 may_core_dump();
2763 #ifdef FEAT_GUI 2786 #ifdef FEAT_GUI
2764 if (gui.in_use) 2787 if (gui.in_use)
2765 gui_exit(r); 2788 gui_exit(r);
2766 #endif 2789 #endif
2790
2791 #if defined(MACOS_X) && defined(FEAT_MBYTE)
2792 mac_conv_cleanup();
2793 #endif
2794
2767 #ifdef __QNX__ 2795 #ifdef __QNX__
2768 /* A core dump won't be created if the signal handler 2796 /* A core dump won't be created if the signal handler
2769 * doesn't return, so we can't call exit() */ 2797 * doesn't return, so we can't call exit() */
2770 if (deadly_signal != 0) 2798 if (deadly_signal != 0)
2771 return; 2799 return;
3280 mch_new_shellsize() 3308 mch_new_shellsize()
3281 { 3309 {
3282 /* Nothing to do. */ 3310 /* Nothing to do. */
3283 } 3311 }
3284 3312
3313 #ifndef USE_SYSTEM
3314 static void append_ga_line __ARGS((garray_T *gap));
3315
3316 /*
3317 * Append the text in "gap" below the cursor line and clear "gap".
3318 */
3319 static void
3320 append_ga_line(gap)
3321 garray_T *gap;
3322 {
3323 /* Remove trailing CR. */
3324 if (gap->ga_len > 0
3325 && !curbuf->b_p_bin
3326 && ((char_u *)gap->ga_data)[gap->ga_len - 1] == CAR)
3327 --gap->ga_len;
3328 ga_append(gap, NUL);
3329 ml_append(curwin->w_cursor.lnum++, gap->ga_data, 0, FALSE);
3330 gap->ga_len = 0;
3331 }
3332 #endif
3333
3285 int 3334 int
3286 mch_call_shell(cmd, options) 3335 mch_call_shell(cmd, options)
3287 char_u *cmd; 3336 char_u *cmd;
3288 int options; /* SHELL_*, see vim.h */ 3337 int options; /* SHELL_*, see vim.h */
3289 { 3338 {
3396 # endif 3445 # endif
3397 return x; 3446 return x;
3398 3447
3399 #else /* USE_SYSTEM */ /* don't use system(), use fork()/exec() */ 3448 #else /* USE_SYSTEM */ /* don't use system(), use fork()/exec() */
3400 3449
3401 #define EXEC_FAILED 122 /* Exit code when shell didn't execute. Don't use 3450 # define EXEC_FAILED 122 /* Exit code when shell didn't execute. Don't use
3402 127, some shell use that already */ 3451 127, some shells use that already */
3403 3452
3404 char_u *newcmd = NULL; 3453 char_u *newcmd = NULL;
3405 pid_t pid; 3454 pid_t pid;
3455 pid_t wpid = 0;
3406 pid_t wait_pid = 0; 3456 pid_t wait_pid = 0;
3407 # ifdef HAVE_UNION_WAIT 3457 # ifdef HAVE_UNION_WAIT
3408 union wait status; 3458 union wait status;
3409 # else 3459 # else
3410 int status = -1; 3460 int status = -1;
3413 char **argv = NULL; 3463 char **argv = NULL;
3414 int argc; 3464 int argc;
3415 int i; 3465 int i;
3416 char_u *p; 3466 char_u *p;
3417 int inquote; 3467 int inquote;
3468 int pty_master_fd = -1; /* for pty's */
3418 # ifdef FEAT_GUI 3469 # ifdef FEAT_GUI
3419 int pty_master_fd = -1; /* for pty's */
3420 int pty_slave_fd = -1; 3470 int pty_slave_fd = -1;
3421 char *tty_name; 3471 char *tty_name;
3472 # endif
3422 int fd_toshell[2]; /* for pipes */ 3473 int fd_toshell[2]; /* for pipes */
3423 int fd_fromshell[2]; 3474 int fd_fromshell[2];
3424 int pipe_error = FALSE; 3475 int pipe_error = FALSE;
3425 # ifdef HAVE_SETENV 3476 # ifdef HAVE_SETENV
3426 char envbuf[50]; 3477 char envbuf[50];
3427 # else 3478 # else
3428 static char envbuf_Rows[20]; 3479 static char envbuf_Rows[20];
3429 static char envbuf_Columns[20]; 3480 static char envbuf_Columns[20];
3430 # endif
3431 # endif 3481 # endif
3432 int did_settmode = FALSE; /* TRUE when settmode(TMODE_RAW) called */ 3482 int did_settmode = FALSE; /* TRUE when settmode(TMODE_RAW) called */
3433 3483
3434 out_flush(); 3484 out_flush();
3435 if (options & SHELL_COOKED) 3485 if (options & SHELL_COOKED)
3478 argv[argc++] = (char *)p_shcf; 3528 argv[argc++] = (char *)p_shcf;
3479 argv[argc++] = (char *)cmd; 3529 argv[argc++] = (char *)cmd;
3480 } 3530 }
3481 argv[argc] = NULL; 3531 argv[argc] = NULL;
3482 3532
3533 /*
3534 * For the GUI, when writing the output into the buffer and when reading
3535 * input from the buffer: Try using a pseudo-tty to get the stdin/stdout
3536 * of the executed command into the Vim window. Or use a pipe.
3537 */
3538 if ((options & (SHELL_READ|SHELL_WRITE))
3483 # ifdef FEAT_GUI 3539 # ifdef FEAT_GUI
3484 /* 3540 || (gui.in_use && show_shell_mess)
3485 * For the GUI: Try using a pseudo-tty to get the stdin/stdout of the 3541 # endif
3486 * executed command into the Vim window. Or use a pipe. 3542 )
3487 */ 3543 {
3488 if (gui.in_use && show_shell_mess) 3544 # ifdef FEAT_GUI
3489 {
3490 /* 3545 /*
3491 * Try to open a master pty. 3546 * Try to open a master pty.
3492 * If this works, open the slave pty. 3547 * If this works, open the slave pty.
3493 * If the slave can't be opened, close the master pty. 3548 * If the slave can't be opened, close the master pty.
3494 */ 3549 */
3495 if (p_guipty) 3550 if (p_guipty && !(options & (SHELL_READ|SHELL_WRITE)))
3496 { 3551 {
3497 pty_master_fd = OpenPTY(&tty_name); /* open pty */ 3552 pty_master_fd = OpenPTY(&tty_name); /* open pty */
3498 if (pty_master_fd >= 0 && ((pty_slave_fd = 3553 if (pty_master_fd >= 0 && ((pty_slave_fd =
3499 open(tty_name, O_RDWR | O_EXTRA, 0)) < 0)) 3554 open(tty_name, O_RDWR | O_EXTRA, 0)) < 0))
3500 { 3555 {
3504 } 3559 }
3505 /* 3560 /*
3506 * If not opening a pty or it didn't work, try using pipes. 3561 * If not opening a pty or it didn't work, try using pipes.
3507 */ 3562 */
3508 if (pty_master_fd < 0) 3563 if (pty_master_fd < 0)
3564 # endif
3509 { 3565 {
3510 pipe_error = (pipe(fd_toshell) < 0); 3566 pipe_error = (pipe(fd_toshell) < 0);
3511 if (!pipe_error) /* pipe create OK */ 3567 if (!pipe_error) /* pipe create OK */
3512 { 3568 {
3513 pipe_error = (pipe(fd_fromshell) < 0); 3569 pipe_error = (pipe(fd_fromshell) < 0);
3524 } 3580 }
3525 } 3581 }
3526 } 3582 }
3527 3583
3528 if (!pipe_error) /* pty or pipe opened or not used */ 3584 if (!pipe_error) /* pty or pipe opened or not used */
3529 # endif
3530
3531 { 3585 {
3532 # ifdef __BEOS__ 3586 # ifdef __BEOS__
3533 beos_cleanup_read_thread(); 3587 beos_cleanup_read_thread();
3534 # endif 3588 # endif
3535 if ((pid = fork()) == -1) /* maybe we should use vfork() */ 3589 if ((pid = fork()) == -1) /* maybe we should use vfork() */
3536 { 3590 {
3537 MSG_PUTS(_("\nCannot fork\n")); 3591 MSG_PUTS(_("\nCannot fork\n"));
3592 if ((options & (SHELL_READ|SHELL_WRITE))
3538 # ifdef FEAT_GUI 3593 # ifdef FEAT_GUI
3539 if (gui.in_use && show_shell_mess) 3594 || (gui.in_use && show_shell_mess)
3595 # endif
3596 )
3540 { 3597 {
3598 # ifdef FEAT_GUI
3541 if (pty_master_fd >= 0) /* close the pseudo tty */ 3599 if (pty_master_fd >= 0) /* close the pseudo tty */
3542 { 3600 {
3543 close(pty_master_fd); 3601 close(pty_master_fd);
3544 close(pty_slave_fd); 3602 close(pty_slave_fd);
3545 } 3603 }
3546 else /* close the pipes */ 3604 else /* close the pipes */
3605 # endif
3547 { 3606 {
3548 close(fd_toshell[0]); 3607 close(fd_toshell[0]);
3549 close(fd_toshell[1]); 3608 close(fd_toshell[1]);
3550 close(fd_fromshell[0]); 3609 close(fd_fromshell[0]);
3551 close(fd_fromshell[1]); 3610 close(fd_fromshell[1]);
3552 } 3611 }
3553 } 3612 }
3554 # endif
3555 } 3613 }
3556 else if (pid == 0) /* child */ 3614 else if (pid == 0) /* child */
3557 { 3615 {
3558 reset_signals(); /* handle signals normally */ 3616 reset_signals(); /* handle signals normally */
3559 3617
3591 3649
3592 /* Don't need this now that we've duplicated it */ 3650 /* Don't need this now that we've duplicated it */
3593 close(fd); 3651 close(fd);
3594 } 3652 }
3595 } 3653 }
3654 else if ((options & (SHELL_READ|SHELL_WRITE))
3596 # ifdef FEAT_GUI 3655 # ifdef FEAT_GUI
3597 else if (gui.in_use) 3656 || gui.in_use
3657 # endif
3658 )
3598 { 3659 {
3599 3660
3600 # ifdef HAVE_SETSID 3661 # ifdef HAVE_SETSID
3601 (void)setsid(); 3662 (void)setsid();
3602 # endif 3663 # endif
3664 # ifdef FEAT_GUI
3603 /* push stream discipline modules */ 3665 /* push stream discipline modules */
3604 if (options & SHELL_COOKED) 3666 if (options & SHELL_COOKED)
3605 SetupSlavePTY(pty_slave_fd); 3667 SetupSlavePTY(pty_slave_fd);
3606 # ifdef TIOCSCTTY 3668 # ifdef TIOCSCTTY
3607 /* try to become controlling tty (probably doesn't work, 3669 /* try to become controlling tty (probably doesn't work,
3608 * unless run by root) */ 3670 * unless run by root) */
3609 ioctl(pty_slave_fd, TIOCSCTTY, (char *)NULL); 3671 ioctl(pty_slave_fd, TIOCSCTTY, (char *)NULL);
3610 # endif 3672 # endif
3673 # endif
3611 /* Simulate to have a dumb terminal (for now) */ 3674 /* Simulate to have a dumb terminal (for now) */
3612 # ifdef HAVE_SETENV 3675 # ifdef HAVE_SETENV
3613 setenv("TERM", "dumb", 1); 3676 setenv("TERM", "dumb", 1);
3614 sprintf((char *)envbuf, "%ld", Rows); 3677 sprintf((char *)envbuf, "%ld", Rows);
3615 setenv("ROWS", (char *)envbuf, 1); 3678 setenv("ROWS", (char *)envbuf, 1);
3616 sprintf((char *)envbuf, "%ld", Rows); 3679 sprintf((char *)envbuf, "%ld", Rows);
3617 setenv("LINES", (char *)envbuf, 1); 3680 setenv("LINES", (char *)envbuf, 1);
3618 sprintf((char *)envbuf, "%ld", Columns); 3681 sprintf((char *)envbuf, "%ld", Columns);
3619 setenv("COLUMNS", (char *)envbuf, 1); 3682 setenv("COLUMNS", (char *)envbuf, 1);
3620 # else 3683 # else
3621 /* 3684 /*
3622 * Putenv does not copy the string, it has to remain valid. 3685 * Putenv does not copy the string, it has to remain valid.
3623 * Use a static array to avoid loosing allocated memory. 3686 * Use a static array to avoid loosing allocated memory.
3624 */ 3687 */
3625 putenv("TERM=dumb"); 3688 putenv("TERM=dumb");
3627 putenv(envbuf_Rows); 3690 putenv(envbuf_Rows);
3628 sprintf(envbuf_Rows, "LINES=%ld", Rows); 3691 sprintf(envbuf_Rows, "LINES=%ld", Rows);
3629 putenv(envbuf_Rows); 3692 putenv(envbuf_Rows);
3630 sprintf(envbuf_Columns, "COLUMNS=%ld", Columns); 3693 sprintf(envbuf_Columns, "COLUMNS=%ld", Columns);
3631 putenv(envbuf_Columns); 3694 putenv(envbuf_Columns);
3632 # endif 3695 # endif
3633 3696
3697 # ifdef FEAT_GUI
3634 if (pty_master_fd >= 0) 3698 if (pty_master_fd >= 0)
3635 { 3699 {
3636 close(pty_master_fd); /* close master side of pty */ 3700 close(pty_master_fd); /* close master side of pty */
3637 3701
3638 /* set up stdin/stdout/stderr for the child */ 3702 /* set up stdin/stdout/stderr for the child */
3644 dup(pty_slave_fd); 3708 dup(pty_slave_fd);
3645 3709
3646 close(pty_slave_fd); /* has been dupped, close it now */ 3710 close(pty_slave_fd); /* has been dupped, close it now */
3647 } 3711 }
3648 else 3712 else
3713 # endif
3649 { 3714 {
3650 /* set up stdin for the child */ 3715 /* set up stdin for the child */
3651 close(fd_toshell[1]); 3716 close(fd_toshell[1]);
3652 close(0); 3717 close(0);
3653 dup(fd_toshell[0]); 3718 dup(fd_toshell[0]);
3662 /* set up stderr for the child */ 3727 /* set up stderr for the child */
3663 close(2); 3728 close(2);
3664 dup(1); 3729 dup(1);
3665 } 3730 }
3666 } 3731 }
3667 # endif /* FEAT_GUI */ 3732
3668 /* 3733 /*
3669 * There is no type cast for the argv, because the type may be 3734 * There is no type cast for the argv, because the type may be
3670 * different on different machines. This may cause a warning 3735 * different on different machines. This may cause a warning
3671 * message with strict compilers, don't worry about it. 3736 * message with strict compilers, don't worry about it.
3672 * Call _exit() instead of exit() to avoid closing the connection 3737 * Call _exit() instead of exit() to avoid closing the connection
3677 } 3742 }
3678 else /* parent */ 3743 else /* parent */
3679 { 3744 {
3680 /* 3745 /*
3681 * While child is running, ignore terminating signals. 3746 * While child is running, ignore terminating signals.
3747 * Do catch CTRL-C, so that "got_int" is set.
3682 */ 3748 */
3683 catch_signals(SIG_IGN, SIG_ERR); 3749 catch_signals(SIG_IGN, SIG_ERR);
3684 3750 catch_int_signal();
3685 # ifdef FEAT_GUI
3686 3751
3687 /* 3752 /*
3688 * For the GUI we redirect stdin, stdout and stderr to our window. 3753 * For the GUI we redirect stdin, stdout and stderr to our window.
3754 * This is also used to pipe stdin/stdout to/from the external
3755 * command.
3689 */ 3756 */
3690 if (gui.in_use && show_shell_mess) 3757 if ((options & (SHELL_READ|SHELL_WRITE))
3758 # ifdef FEAT_GUI
3759 || (gui.in_use && show_shell_mess)
3760 # endif
3761 )
3691 { 3762 {
3692 # define BUFLEN 100 /* length for buffer, pseudo tty limit is 128 */ 3763 # define BUFLEN 100 /* length for buffer, pseudo tty limit is 128 */
3693 char_u buffer[BUFLEN + 1]; 3764 char_u buffer[BUFLEN + 1];
3694 # ifdef FEAT_MBYTE 3765 # ifdef FEAT_MBYTE
3695 int buffer_off = 0; /* valid bytes in buffer[] */ 3766 int buffer_off = 0; /* valid bytes in buffer[] */
3696 # endif 3767 # endif
3697 char_u ta_buf[BUFLEN + 1]; /* TypeAHead */ 3768 char_u ta_buf[BUFLEN + 1]; /* TypeAHead */
3698 int ta_len = 0; /* valid bytes in ta_buf[] */ 3769 int ta_len = 0; /* valid bytes in ta_buf[] */
3699 int len; 3770 int len;
3700 int p_more_save; 3771 int p_more_save;
3701 int old_State; 3772 int old_State;
3702 int c; 3773 int c;
3703 int toshell_fd; 3774 int toshell_fd;
3704 int fromshell_fd; 3775 int fromshell_fd;
3705 3776 garray_T ga;
3777 int noread_cnt;
3778
3779 # ifdef FEAT_GUI
3706 if (pty_master_fd >= 0) 3780 if (pty_master_fd >= 0)
3707 { 3781 {
3708 close(pty_slave_fd); /* close slave side of pty */ 3782 close(pty_slave_fd); /* close slave side of pty */
3709 fromshell_fd = pty_master_fd; 3783 fromshell_fd = pty_master_fd;
3710 toshell_fd = dup(pty_master_fd); 3784 toshell_fd = dup(pty_master_fd);
3711 } 3785 }
3712 else 3786 else
3787 # endif
3713 { 3788 {
3714 close(fd_toshell[0]); 3789 close(fd_toshell[0]);
3715 close(fd_fromshell[1]); 3790 close(fd_fromshell[1]);
3716 toshell_fd = fd_toshell[1]; 3791 toshell_fd = fd_toshell[1];
3717 fromshell_fd = fd_fromshell[0]; 3792 fromshell_fd = fd_fromshell[0];
3736 p_more_save = p_more; 3811 p_more_save = p_more;
3737 p_more = FALSE; 3812 p_more = FALSE;
3738 old_State = State; 3813 old_State = State;
3739 State = EXTERNCMD; /* don't redraw at window resize */ 3814 State = EXTERNCMD; /* don't redraw at window resize */
3740 3815
3816 if (options & SHELL_WRITE && toshell_fd >= 0)
3817 {
3818 /* Fork a process that will write the lines to the
3819 * external program. */
3820 if ((wpid = fork()) == -1)
3821 {
3822 MSG_PUTS(_("\nCannot fork\n"));
3823 }
3824 else if (wpid == 0)
3825 {
3826 linenr_T lnum = curbuf->b_op_start.lnum;
3827 int written = 0;
3828 char_u *p = ml_get(lnum);
3829 char_u *s;
3830 size_t l;
3831
3832 /* child */
3833 for (;;)
3834 {
3835 l = STRLEN(p + written);
3836 if (l == 0)
3837 len = 0;
3838 else if (p[written] == NL)
3839 /* NL -> NUL translation */
3840 len = write(toshell_fd, "", (size_t)1);
3841 else
3842 {
3843 s = vim_strchr(p + written, NL);
3844 len = write(toshell_fd, (char *)p + written,
3845 s == NULL ? l : s - (p + written));
3846 }
3847 if (len == l)
3848 {
3849 /* Finished a line, add a NL, unless this line
3850 * should not have one. */
3851 if (lnum != curbuf->b_op_end.lnum
3852 || !curbuf->b_p_bin
3853 || (lnum != write_no_eol_lnum
3854 && (lnum !=
3855 curbuf->b_ml.ml_line_count
3856 || curbuf->b_p_eol)))
3857 write(toshell_fd, "\n", (size_t)1);
3858 ++lnum;
3859 if (lnum > curbuf->b_op_end.lnum)
3860 {
3861 /* finished all the lines, close pipe */
3862 close(toshell_fd);
3863 toshell_fd = -1;
3864 break;
3865 }
3866 p = ml_get(lnum);
3867 written = 0;
3868 }
3869 else if (len > 0)
3870 written += len;
3871 }
3872 _exit(0);
3873 }
3874 else
3875 {
3876 close(toshell_fd);
3877 toshell_fd = -1;
3878 }
3879 }
3880
3881 if (options & SHELL_READ)
3882 ga_init2(&ga, 1, BUFLEN);
3883
3884 noread_cnt = 0;
3885
3741 for (;;) 3886 for (;;)
3742 { 3887 {
3743 /* 3888 /*
3744 * Check if keys have been typed, write them to the child 3889 * Check if keys have been typed, write them to the child
3745 * if there are any. Don't do this if we are expanding 3890 * if there are any. Don't do this if we are expanding
3746 * wild cards (would eat typeahead). Don't get extra 3891 * wild cards (would eat typeahead). Don't get extra
3747 * characters when we already have one. 3892 * characters when we already have one.
3893 * Don't read characters unless we didn't get output for a
3894 * while, avoids that ":r !ls" eats typeahead.
3748 */ 3895 */
3749 len = 0; 3896 len = 0;
3750 if (!(options & SHELL_EXPAND) 3897 if (!(options & SHELL_EXPAND)
3751 && (ta_len > 0 3898 && (ta_len > 0
3752 || (len = ui_inchar(ta_buf, BUFLEN, 10L, 3899 || (noread_cnt > 4
3753 0)) > 0)) 3900 && (len = ui_inchar(ta_buf,
3901 BUFLEN, 10L, 0)) > 0)))
3754 { 3902 {
3755 /* 3903 /*
3756 * For pipes: 3904 * For pipes:
3757 * Check for CTRL-C: send interrupt signal to child. 3905 * Check for CTRL-C: send interrupt signal to child.
3758 * Check for CTRL-D: EOF, close pipe to child. 3906 * Check for CTRL-D: EOF, close pipe to child.
3759 */ 3907 */
3760 if (len == 1 && (pty_master_fd < 0 || cmd != NULL)) 3908 if (len == 1 && (pty_master_fd < 0 || cmd != NULL))
3761 { 3909 {
3762 # ifdef SIGINT 3910 # ifdef SIGINT
3763 /* 3911 /*
3764 * Send SIGINT to the child's group or all 3912 * Send SIGINT to the child's group or all
3765 * processes in our group. 3913 * processes in our group.
3766 */ 3914 */
3767 if (ta_buf[ta_len] == Ctrl_C 3915 if (ta_buf[ta_len] == Ctrl_C
3768 || ta_buf[ta_len] == intr_char) 3916 || ta_buf[ta_len] == intr_char)
3769 # ifdef HAVE_SETSID 3917 {
3918 # ifdef HAVE_SETSID
3770 kill(-pid, SIGINT); 3919 kill(-pid, SIGINT);
3771 # else 3920 # else
3772 kill(0, SIGINT); 3921 kill(0, SIGINT);
3773 # endif
3774 # endif 3922 # endif
3923 if (wpid > 0)
3924 kill(wpid, SIGINT);
3925 }
3926 # endif
3775 if (pty_master_fd < 0 && toshell_fd >= 0 3927 if (pty_master_fd < 0 && toshell_fd >= 0
3776 && ta_buf[ta_len] == Ctrl_D) 3928 && ta_buf[ta_len] == Ctrl_D)
3777 { 3929 {
3778 close(toshell_fd); 3930 close(toshell_fd);
3779 toshell_fd = -1; 3931 toshell_fd = -1;
3797 len -= 2; 3949 len -= 2;
3798 } 3950 }
3799 } 3951 }
3800 else if (ta_buf[i] == '\r') 3952 else if (ta_buf[i] == '\r')
3801 ta_buf[i] = '\n'; 3953 ta_buf[i] = '\n';
3802 # ifdef FEAT_MBYTE 3954 # ifdef FEAT_MBYTE
3803 if (has_mbyte) 3955 if (has_mbyte)
3804 i += (*mb_ptr2len_check)(ta_buf + i) - 1; 3956 i += (*mb_ptr2len_check)(ta_buf + i) - 1;
3805 # endif 3957 # endif
3806 } 3958 }
3807 3959
3808 /* 3960 /*
3809 * For pipes: echo the typed characters. 3961 * For pipes: echo the typed characters.
3810 * For a pty this does not seem to work. 3962 * For a pty this does not seem to work.
3813 { 3965 {
3814 for (i = ta_len; i < ta_len + len; ++i) 3966 for (i = ta_len; i < ta_len + len; ++i)
3815 { 3967 {
3816 if (ta_buf[i] == '\n' || ta_buf[i] == '\b') 3968 if (ta_buf[i] == '\n' || ta_buf[i] == '\b')
3817 msg_putchar(ta_buf[i]); 3969 msg_putchar(ta_buf[i]);
3818 # ifdef FEAT_MBYTE 3970 # ifdef FEAT_MBYTE
3819 else if (has_mbyte) 3971 else if (has_mbyte)
3820 { 3972 {
3821 int l = (*mb_ptr2len_check)(ta_buf + i); 3973 int l = (*mb_ptr2len_check)(ta_buf + i);
3822 3974
3823 msg_outtrans_len(ta_buf + i, l); 3975 msg_outtrans_len(ta_buf + i, l);
3824 i += l - 1; 3976 i += l - 1;
3825 } 3977 }
3826 # endif 3978 # endif
3827 else 3979 else
3828 msg_outtrans_len(ta_buf + i, 1); 3980 msg_outtrans_len(ta_buf + i, 1);
3829 } 3981 }
3830 windgoto(msg_row, msg_col); 3982 windgoto(msg_row, msg_col);
3831 out_flush(); 3983 out_flush();
3835 3987
3836 /* 3988 /*
3837 * Write the characters to the child, unless EOF has 3989 * Write the characters to the child, unless EOF has
3838 * been typed for pipes. Write one character at a 3990 * been typed for pipes. Write one character at a
3839 * time, to avoid loosing too much typeahead. 3991 * time, to avoid loosing too much typeahead.
3992 * When writing buffer lines, drop the typed
3993 * characters (only check for CTRL-C).
3840 */ 3994 */
3841 if (toshell_fd >= 0) 3995 if (options & SHELL_WRITE)
3996 ta_len = 0;
3997 else if (toshell_fd >= 0)
3842 { 3998 {
3843 len = write(toshell_fd, (char *)ta_buf, (size_t)1); 3999 len = write(toshell_fd, (char *)ta_buf, (size_t)1);
3844 if (len > 0) 4000 if (len > 0)
3845 { 4001 {
3846 ta_len -= len; 4002 ta_len -= len;
3847 mch_memmove(ta_buf, ta_buf + len, ta_len); 4003 mch_memmove(ta_buf, ta_buf + len, ta_len);
4004 noread_cnt = 0;
3848 } 4005 }
3849 } 4006 }
4007 }
4008
4009 if (got_int)
4010 {
4011 /* CTRL-C sends a signal to the child, we ignore it
4012 * ourselves */
4013 # ifdef HAVE_SETSID
4014 kill(-pid, SIGINT);
4015 # else
4016 kill(0, SIGINT);
4017 # endif
4018 if (wpid > 0)
4019 kill(wpid, SIGINT);
4020 got_int = FALSE;
3850 } 4021 }
3851 4022
3852 /* 4023 /*
3853 * Check if the child has any characters to be printed. 4024 * Check if the child has any characters to be printed.
3854 * Read them and write them to our window. Repeat this as 4025 * Read them and write them to our window. Repeat this as
3856 * for mch_inchar(), or sending typeahead characters to 4027 * for mch_inchar(), or sending typeahead characters to
3857 * the external process. 4028 * the external process.
3858 * TODO: This should handle escape sequences, compatible 4029 * TODO: This should handle escape sequences, compatible
3859 * to some terminal (vt52?). 4030 * to some terminal (vt52?).
3860 */ 4031 */
4032 ++noread_cnt;
3861 while (RealWaitForChar(fromshell_fd, 10L, NULL)) 4033 while (RealWaitForChar(fromshell_fd, 10L, NULL))
3862 { 4034 {
3863 len = read(fromshell_fd, (char *)buffer 4035 len = read(fromshell_fd, (char *)buffer
3864 # ifdef FEAT_MBYTE 4036 # ifdef FEAT_MBYTE
3865 + buffer_off, (size_t)(BUFLEN - buffer_off) 4037 + buffer_off, (size_t)(BUFLEN - buffer_off)
3866 # else 4038 # else
3867 , (size_t)BUFLEN 4039 , (size_t)BUFLEN
3868 # endif 4040 # endif
3869 ); 4041 );
3870 if (len <= 0) /* end of file or error */ 4042 if (len <= 0) /* end of file or error */
3871 goto finished; 4043 goto finished;
3872 # ifdef FEAT_MBYTE 4044
3873 len += buffer_off; 4045 noread_cnt = 0;
3874 buffer[len] = NUL; 4046 if (options & SHELL_READ)
3875 if (has_mbyte) 4047 {
4048 /* Do NUL -> NL translation, append NL separated
4049 * lines to the current buffer. */
4050 for (i = 0; i < len; ++i)
4051 {
4052 if (buffer[i] == NL)
4053 append_ga_line(&ga);
4054 else if (buffer[i] == NUL)
4055 ga_append(&ga, NL);
4056 else
4057 ga_append(&ga, buffer[i]);
4058 }
4059 }
4060 # ifdef FEAT_MBYTE
4061 else if (has_mbyte)
3876 { 4062 {
3877 int l; 4063 int l;
4064
4065 len += buffer_off;
4066 buffer[len] = NUL;
3878 4067
3879 /* Check if the last character in buffer[] is 4068 /* Check if the last character in buffer[] is
3880 * incomplete, keep these bytes for the next 4069 * incomplete, keep these bytes for the next
3881 * round. */ 4070 * round. */
3882 for (p = buffer; p < buffer + len; p += l) 4071 for (p = buffer; p < buffer + len; p += l)
3911 mch_memmove(buffer, p, buffer_off); 4100 mch_memmove(buffer, p, buffer_off);
3912 continue; 4101 continue;
3913 } 4102 }
3914 buffer_off = 0; 4103 buffer_off = 0;
3915 } 4104 }
4105 # endif /* FEAT_MBYTE */
3916 else 4106 else
3917 # endif /* FEAT_MBYTE */
3918 { 4107 {
3919 buffer[len] = NUL; 4108 buffer[len] = NUL;
3920 msg_puts(buffer); 4109 msg_puts(buffer);
3921 } 4110 }
3922 4111
3929 4118
3930 /* 4119 /*
3931 * Check if the child still exists, before checking for 4120 * Check if the child still exists, before checking for
3932 * typed characters (otherwise we would loose typeahead). 4121 * typed characters (otherwise we would loose typeahead).
3933 */ 4122 */
3934 # ifdef __NeXT__ 4123 # ifdef __NeXT__
3935 wait_pid = wait4(pid, &status, WNOHANG, (struct rusage *) 0); 4124 wait_pid = wait4(pid, &status, WNOHANG, (struct rusage *) 0);
3936 # else 4125 # else
3937 wait_pid = waitpid(pid, &status, WNOHANG); 4126 wait_pid = waitpid(pid, &status, WNOHANG);
3938 # endif 4127 # endif
3939 if ((wait_pid == (pid_t)-1 && errno == ECHILD) 4128 if ((wait_pid == (pid_t)-1 && errno == ECHILD)
3940 || (wait_pid == pid && WIFEXITED(status))) 4129 || (wait_pid == pid && WIFEXITED(status)))
3941 { 4130 {
3942 wait_pid = pid; 4131 wait_pid = pid;
3943 break; 4132 break;
3944 } 4133 }
3945 wait_pid = 0; 4134 wait_pid = 0;
3946 } 4135 }
3947 finished: 4136 finished:
3948 p_more = p_more_save; 4137 p_more = p_more_save;
3949 4138 if (options & SHELL_READ)
3950 # ifndef MACOS_X_UNIX /* TODO: Is it needed for MACOS_X ? */ 4139 {
4140 if (ga.ga_len > 0)
4141 {
4142 append_ga_line(&ga);
4143 /* remember that the NL was missing */
4144 write_no_eol_lnum = curwin->w_cursor.lnum;
4145 }
4146 else
4147 write_no_eol_lnum = 0;
4148 ga_clear(&ga);
4149 }
4150
3951 /* 4151 /*
3952 * Give all typeahead that wasn't used back to ui_inchar(). 4152 * Give all typeahead that wasn't used back to ui_inchar().
3953 */ 4153 */
3954 if (ta_len) 4154 if (ta_len)
3955 ui_inchar_undo(ta_buf, ta_len); 4155 ui_inchar_undo(ta_buf, ta_len);
3956 # endif
3957 State = old_State; 4156 State = old_State;
3958 if (toshell_fd >= 0) 4157 if (toshell_fd >= 0)
3959 close(toshell_fd); 4158 close(toshell_fd);
3960 close(fromshell_fd); 4159 close(fromshell_fd);
3961 } 4160 }
3962 # endif /* FEAT_GUI */
3963 4161
3964 /* 4162 /*
3965 * Wait until our child has exited. 4163 * Wait until our child has exited.
3966 * Ignore wait() returning pids of other children and returning 4164 * Ignore wait() returning pids of other children and returning
3967 * because of some signal like SIGWINCH. 4165 * because of some signal like SIGWINCH.
3968 * Don't wait if wait_pid was already set above, indicating the 4166 * Don't wait if wait_pid was already set above, indicating the
3969 * child already exited. 4167 * child already exited.
3970 */ 4168 */
3971 while (wait_pid != pid) 4169 while (wait_pid != pid)
3972 { 4170 {
3973 #ifdef _THREAD_SAFE 4171 # ifdef _THREAD_SAFE
3974 /* Ugly hack: when compiled with Python threads are probably 4172 /* Ugly hack: when compiled with Python threads are probably
3975 * used, in which case wait() sometimes hangs for no obvious 4173 * used, in which case wait() sometimes hangs for no obvious
3976 * reason. Use waitpid() instead and loop (like the GUI). */ 4174 * reason. Use waitpid() instead and loop (like the GUI). */
3977 # ifdef __NeXT__ 4175 # ifdef __NeXT__
3978 wait_pid = wait4(pid, &status, WNOHANG, (struct rusage *)0); 4176 wait_pid = wait4(pid, &status, WNOHANG, (struct rusage *)0);
3983 { 4181 {
3984 /* Wait for 1/100 sec before trying again. */ 4182 /* Wait for 1/100 sec before trying again. */
3985 mch_delay(10L, TRUE); 4183 mch_delay(10L, TRUE);
3986 continue; 4184 continue;
3987 } 4185 }
3988 #else 4186 # else
3989 wait_pid = wait(&status); 4187 wait_pid = wait(&status);
3990 #endif 4188 # endif
3991 if (wait_pid <= 0 4189 if (wait_pid <= 0
3992 # ifdef ECHILD 4190 # ifdef ECHILD
3993 && errno == ECHILD 4191 && errno == ECHILD
3994 # endif 4192 # endif
3995 ) 4193 )
3996 break; 4194 break;
3997 } 4195 }
4196
4197 /* Make sure the child that writes to the external program is
4198 * dead. */
4199 if (wpid > 0)
4200 kill(wpid, SIGKILL);
3998 4201
3999 /* 4202 /*
4000 * Set to raw mode right now, otherwise a CTRL-C after 4203 * Set to raw mode right now, otherwise a CTRL-C after
4001 * catch_signals() will kill Vim. 4204 * catch_signals() will kill Vim.
4002 */ 4205 */
4654 /* no more wildcards, check if there is a match */ 4857 /* no more wildcards, check if there is a match */
4655 /* remove backslashes for the remaining components only */ 4858 /* remove backslashes for the remaining components only */
4656 if (*path_end != NUL) 4859 if (*path_end != NUL)
4657 backslash_halve(buf + len + 1); 4860 backslash_halve(buf + len + 1);
4658 if (mch_getperm(buf) >= 0) /* add existing file */ 4861 if (mch_getperm(buf) >= 0) /* add existing file */
4862 {
4863 #if defined(MACOS_X) && defined(FEAT_MBYTE)
4864 size_t precomp_len = STRLEN(buf)+1;
4865 char_u *precomp_buf =
4866 mac_precompose_path(buf, precomp_len, &precomp_len);
4867 if (precomp_buf)
4868 {
4869 mch_memmove(buf, precomp_buf, precomp_len);
4870 vim_free(precomp_buf);
4871 }
4872 #endif
4659 addfile(gap, buf, flags); 4873 addfile(gap, buf, flags);
4874 }
4660 } 4875 }
4661 } 4876 }
4662 } 4877 }
4663 4878
4664 closedir(dirp); 4879 closedir(dirp);