Mercurial > vim
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); |