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