Mercurial > vim
comparison src/os_unix.c @ 15632:d4a6d575e910 v8.1.0824
patch 8.1.0824: SunOS/Solaris has a problem with ttys
commit https://github.com/vim/vim/commit/1ecc5e4a995ade68ae216bb56f6ac9bd5c0b7e4b
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Jan 26 15:12:55 2019 +0100
patch 8.1.0824: SunOS/Solaris has a problem with ttys
Problem: SunOS/Solaris has a problem with ttys.
Solution: Add mch_isatty() with extra handling for SunOS. (Ozaki Kiichi,
closes #3865)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 26 Jan 2019 15:15:12 +0100 |
parents | 639b8318472c |
children | 59a1ff689b4d |
comparison
equal
deleted
inserted
replaced
15631:8896e3b99db4 | 15632:d4a6d575e910 |
---|---|
336 return chdir(path); | 336 return chdir(path); |
337 # endif | 337 # endif |
338 } | 338 } |
339 | 339 |
340 /* Why is NeXT excluded here (and not in os_unixx.h)? */ | 340 /* Why is NeXT excluded here (and not in os_unixx.h)? */ |
341 #if defined(ECHOE) && defined(ICANON) && (defined(HAVE_TERMIO_H) || defined(HAVE_TERMIOS_H)) && !defined(__NeXT__) | 341 #if defined(ECHOE) && defined(ICANON) \ |
342 && (defined(HAVE_TERMIO_H) || defined(HAVE_TERMIOS_H)) \ | |
343 && !defined(__NeXT__) | |
342 # define NEW_TTY_SYSTEM | 344 # define NEW_TTY_SYSTEM |
343 #endif | 345 #endif |
344 | 346 |
345 /* | 347 /* |
346 * Write s[len] to the screen (stdout). | 348 * Write s[len] to the screen (stdout). |
3446 } | 3448 } |
3447 } | 3449 } |
3448 | 3450 |
3449 #ifndef VMS | 3451 #ifndef VMS |
3450 | 3452 |
3453 /* | |
3454 * Get the file descriptor to use for tty operations. | |
3455 */ | |
3456 static int | |
3457 get_tty_fd(int fd) | |
3458 { | |
3459 int tty_fd = fd; | |
3460 | |
3461 #if defined(HAVE_SVR4_PTYS) && defined(SUN_SYSTEM) | |
3462 // On SunOS: Get the terminal parameters from "fd", or the slave device of | |
3463 // "fd" when it is a master device. | |
3464 if (mch_isatty(fd) > 1) | |
3465 { | |
3466 char *name; | |
3467 | |
3468 name = ptsname(fd); | |
3469 if (name == NULL) | |
3470 return -1; | |
3471 | |
3472 tty_fd = open(name, O_RDONLY | O_NOCTTY | O_EXTRA, 0); | |
3473 if (tty_fd < 0) | |
3474 return -1; | |
3475 } | |
3476 #endif | |
3477 return tty_fd; | |
3478 } | |
3479 | |
3480 static int | |
3481 mch_tcgetattr(int fd, void *term) | |
3482 { | |
3483 int tty_fd; | |
3484 int retval = -1; | |
3485 | |
3486 tty_fd = get_tty_fd(fd); | |
3487 if (tty_fd >= 0) | |
3488 { | |
3489 #ifdef NEW_TTY_SYSTEM | |
3490 # ifdef HAVE_TERMIOS_H | |
3491 retval = tcgetattr(tty_fd, (struct termios *)term); | |
3492 # else | |
3493 retval = ioctl(tty_fd, TCGETA, (struct termio *)term); | |
3494 # endif | |
3495 #else | |
3496 // for "old" tty systems | |
3497 retval = ioctl(tty_fd, TIOCGETP, (struct sgttyb *)term); | |
3498 #endif | |
3499 if (tty_fd != fd) | |
3500 close(tty_fd); | |
3501 } | |
3502 return retval; | |
3503 } | |
3504 | |
3451 void | 3505 void |
3452 mch_settmode(int tmode) | 3506 mch_settmode(int tmode) |
3453 { | 3507 { |
3454 static int first = TRUE; | 3508 static int first = TRUE; |
3455 | 3509 |
3463 # endif | 3517 # endif |
3464 | 3518 |
3465 if (first) | 3519 if (first) |
3466 { | 3520 { |
3467 first = FALSE; | 3521 first = FALSE; |
3468 # if defined(HAVE_TERMIOS_H) | 3522 mch_tcgetattr(read_cmd_fd, &told); |
3469 tcgetattr(read_cmd_fd, &told); | |
3470 # else | |
3471 ioctl(read_cmd_fd, TCGETA, &told); | |
3472 # endif | |
3473 } | 3523 } |
3474 | 3524 |
3475 tnew = told; | 3525 tnew = told; |
3476 if (tmode == TMODE_RAW) | 3526 if (tmode == TMODE_RAW) |
3477 { | 3527 { |
3525 struct sgttyb ttybnew; | 3575 struct sgttyb ttybnew; |
3526 | 3576 |
3527 if (first) | 3577 if (first) |
3528 { | 3578 { |
3529 first = FALSE; | 3579 first = FALSE; |
3530 ioctl(read_cmd_fd, TIOCGETP, &ttybold); | 3580 mch_tcgetattr(read_cmd_fd, &ttybold); |
3531 } | 3581 } |
3532 | 3582 |
3533 ttybnew = ttybold; | 3583 ttybnew = ttybold; |
3534 if (tmode == TMODE_RAW) | 3584 if (tmode == TMODE_RAW) |
3535 { | 3585 { |
3585 struct termios keys; | 3635 struct termios keys; |
3586 # else | 3636 # else |
3587 struct termio keys; | 3637 struct termio keys; |
3588 # endif | 3638 # endif |
3589 | 3639 |
3590 if ( | 3640 if (mch_tcgetattr(fd, &keys) != -1) |
3591 # if defined(HAVE_TERMIOS_H) | |
3592 tcgetattr(fd, &keys) != -1 | |
3593 # else | |
3594 ioctl(fd, TCGETA, &keys) != -1 | |
3595 # endif | |
3596 ) | |
3597 { | 3641 { |
3598 info->backspace = keys.c_cc[VERASE]; | 3642 info->backspace = keys.c_cc[VERASE]; |
3599 info->interrupt = keys.c_cc[VINTR]; | 3643 info->interrupt = keys.c_cc[VINTR]; |
3600 if (keys.c_iflag & ICRNL) | 3644 if (keys.c_iflag & ICRNL) |
3601 info->enter = NL; | 3645 info->enter = NL; |
3609 } | 3653 } |
3610 #else | 3654 #else |
3611 /* for "old" tty systems */ | 3655 /* for "old" tty systems */ |
3612 struct sgttyb keys; | 3656 struct sgttyb keys; |
3613 | 3657 |
3614 if (ioctl(fd, TIOCGETP, &keys) != -1) | 3658 if (mch_tcgetattr(fd, &keys) != -1) |
3615 { | 3659 { |
3616 info->backspace = keys.sg_erase; | 3660 info->backspace = keys.sg_erase; |
3617 info->interrupt = keys.sg_kill; | 3661 info->interrupt = keys.sg_kill; |
3618 info->enter = CAR; | 3662 info->enter = CAR; |
3619 info->nl_does_cr = TRUE; | 3663 info->nl_does_cr = TRUE; |
4068 * Report the windows size "rows" and "cols" to tty "fd". | 4112 * Report the windows size "rows" and "cols" to tty "fd". |
4069 */ | 4113 */ |
4070 int | 4114 int |
4071 mch_report_winsize(int fd, int rows, int cols) | 4115 mch_report_winsize(int fd, int rows, int cols) |
4072 { | 4116 { |
4073 # ifdef TIOCSWINSZ | 4117 int tty_fd; |
4074 struct winsize ws; | 4118 int retval = -1; |
4075 | 4119 |
4076 ws.ws_col = cols; | 4120 tty_fd = get_tty_fd(fd); |
4077 ws.ws_row = rows; | 4121 if (tty_fd >= 0) |
4078 ws.ws_xpixel = cols * 5; | 4122 { |
4079 ws.ws_ypixel = rows * 10; | 4123 # if defined(TIOCSWINSZ) |
4080 if (ioctl(fd, TIOCSWINSZ, &ws) == 0) | 4124 struct winsize ws; |
4081 { | 4125 |
4082 ch_log(NULL, "ioctl(TIOCSWINSZ) success"); | 4126 ws.ws_col = cols; |
4083 return OK; | 4127 ws.ws_row = rows; |
4084 } | 4128 ws.ws_xpixel = cols * 5; |
4085 ch_log(NULL, "ioctl(TIOCSWINSZ) failed"); | 4129 ws.ws_ypixel = rows * 10; |
4086 # else | 4130 retval = ioctl(tty_fd, TIOCSWINSZ, &ws); |
4087 # ifdef TIOCSSIZE | 4131 ch_log(NULL, "ioctl(TIOCSWINSZ) %s", |
4088 struct ttysize ts; | 4132 retval == 0 ? "success" : "failed"); |
4089 | 4133 # elif defined(TIOCSSIZE) |
4090 ts.ts_cols = cols; | 4134 struct ttysize ts; |
4091 ts.ts_lines = rows; | 4135 |
4092 if (ioctl(fd, TIOCSSIZE, &ws) == 0) | 4136 ts.ts_cols = cols; |
4093 { | 4137 ts.ts_lines = rows; |
4094 ch_log(NULL, "ioctl(TIOCSSIZE) success"); | 4138 retval = ioctl(tty_fd, TIOCSSIZE, &ts); |
4095 return OK; | 4139 ch_log(NULL, "ioctl(TIOCSSIZE) %s", |
4096 } | 4140 retval == 0 ? "success" : "failed"); |
4097 ch_log(NULL, "ioctl(TIOCSSIZE) failed"); | 4141 # endif |
4098 # endif | 4142 if (tty_fd != fd) |
4099 # endif | 4143 close(tty_fd); |
4100 return FAIL; | 4144 } |
4145 return retval == 0 ? OK : FAIL; | |
4101 } | 4146 } |
4102 #endif | 4147 #endif |
4103 | 4148 |
4104 /* | 4149 /* |
4105 * Try to set the window size to Rows and Columns. | 4150 * Try to set the window size to Rows and Columns. |
4271 static void | 4316 static void |
4272 open_pty(int *pty_master_fd, int *pty_slave_fd, char_u **namep) | 4317 open_pty(int *pty_master_fd, int *pty_slave_fd, char_u **namep) |
4273 { | 4318 { |
4274 char *tty_name; | 4319 char *tty_name; |
4275 | 4320 |
4276 *pty_master_fd = OpenPTY(&tty_name); /* open pty */ | 4321 *pty_master_fd = mch_openpty(&tty_name); // open pty |
4277 if (*pty_master_fd >= 0) | 4322 if (*pty_master_fd >= 0) |
4278 { | 4323 { |
4279 /* Leaving out O_NOCTTY may lead to waitpid() always returning | 4324 /* Leaving out O_NOCTTY may lead to waitpid() always returning |
4280 * 0 on Mac OS X 10.7 thereby causing freezes. Let's assume | 4325 * 0 on Mac OS X 10.7 thereby causing freezes. Let's assume |
4281 * adding O_NOCTTY always works when defined. */ | 4326 * adding O_NOCTTY always works when defined. */ |
4719 # ifdef FEAT_GUI | 4764 # ifdef FEAT_GUI |
4720 if (pty_slave_fd >= 0) | 4765 if (pty_slave_fd >= 0) |
4721 { | 4766 { |
4722 /* push stream discipline modules */ | 4767 /* push stream discipline modules */ |
4723 if (options & SHELL_COOKED) | 4768 if (options & SHELL_COOKED) |
4724 SetupSlavePTY(pty_slave_fd); | 4769 setup_slavepty(pty_slave_fd); |
4725 # ifdef TIOCSCTTY | 4770 # ifdef TIOCSCTTY |
4726 /* Try to become controlling tty (probably doesn't work, | 4771 /* Try to become controlling tty (probably doesn't work, |
4727 * unless run by root) */ | 4772 * unless run by root) */ |
4728 ioctl(pty_slave_fd, TIOCSCTTY, (char *)NULL); | 4773 ioctl(pty_slave_fd, TIOCSCTTY, (char *)NULL); |
4729 # endif | 4774 # endif |
5577 } | 5622 } |
5578 | 5623 |
5579 if (pty_slave_fd >= 0) | 5624 if (pty_slave_fd >= 0) |
5580 { | 5625 { |
5581 /* push stream discipline modules */ | 5626 /* push stream discipline modules */ |
5582 SetupSlavePTY(pty_slave_fd); | 5627 setup_slavepty(pty_slave_fd); |
5583 # ifdef TIOCSCTTY | 5628 # ifdef TIOCSCTTY |
5584 /* Try to become controlling tty (probably doesn't work, | 5629 /* Try to become controlling tty (probably doesn't work, |
5585 * unless run by root) */ | 5630 * unless run by root) */ |
5586 ioctl(pty_slave_fd, TIOCSCTTY, (char *)NULL); | 5631 ioctl(pty_slave_fd, TIOCSCTTY, (char *)NULL); |
5587 # endif | 5632 # endif |