gint ide_vte_pty_create_slave (VtePty *pty) { gint master_fd; #ifdef HAVE_PTSNAME_R char name[PATH_MAX + 1]; #else const char *name; #endif g_assert (VTE_IS_PTY (pty)); if (-1 == (master_fd = vte_pty_get_fd (pty))) return -1; if (grantpt (master_fd) != 0) return -1; if (unlockpt (master_fd) != 0) return -1; #ifdef HAVE_PTSNAME_R if (ptsname_r (master_fd, name, sizeof name - 1) != 0) return -1; name[sizeof name - 1] = '\0'; #else if (NULL == (name = ptsname (master_fd))) return -1; #endif return open (name, O_RDWR | O_CLOEXEC); }
/** * vte_pty_get_fd: * @pty: a #VtePty * * Returns: (transfer none): the file descriptor of the PTY master in @pty. The * file descriptor belongs to @pty and must not be closed */ int vte_pty_get_fd (VtePty *pty) { VtePtyPrivate *priv; g_return_val_if_fail(VTE_IS_PTY(pty), -1); priv = pty->priv; g_return_val_if_fail(priv->pty_fd != -1, -1); return priv->pty_fd; }
void ide_terminal_page_set_pty (IdeTerminalPage *self, VtePty *pty) { g_return_if_fail (IDE_IS_TERMINAL_PAGE (self)); g_return_if_fail (VTE_IS_PTY (pty)); if (g_set_object (&self->pty, pty)) { vte_terminal_reset (VTE_TERMINAL (self->terminal_top), TRUE, TRUE); vte_terminal_set_pty (VTE_TERMINAL (self->terminal_top), pty); } }
/** * vte_pty_get_size: * @pty: a #VtePty * @rows: (out) (allow-none): a location to store the number of rows, or %NULL * @columns: (out) (allow-none): a location to store the number of columns, or %NULL * @error: return location to store a #GError, or %NULL * * Reads the pseudo terminal's window size. * * If getting the window size failed, @error will be set to a #GIOError. * * Returns: %TRUE on success, %FALSE on failure with @error filled in */ gboolean vte_pty_get_size(VtePty *pty, int *rows, int *columns, GError **error) { struct winsize size; int master; int ret; g_return_val_if_fail(VTE_IS_PTY(pty), FALSE); master = vte_pty_get_fd(pty); memset(&size, 0, sizeof(size)); ret = ioctl(master, TIOCGWINSZ, &size); if (ret == 0) { if (columns != NULL) { *columns = size.ws_col; } if (rows != NULL) { *rows = size.ws_row; } _vte_debug_print(VTE_DEBUG_PTY, "Size on fd %d is (%d,%d).\n", master, size.ws_col, size.ws_row); return TRUE; } else { int errsv = errno; g_set_error(error, G_IO_ERROR, g_io_error_from_errno(errsv), "Failed to get window size: %s", g_strerror(errsv)); _vte_debug_print(VTE_DEBUG_PTY, "Failed to read size from fd %d: %s\n", master, g_strerror(errsv)); errno = errsv; return FALSE; } }
void gb_terminal_view_set_pty (GbTerminalView *self, VtePty *pty) { g_return_if_fail (GB_IS_TERMINAL_VIEW (self)); g_return_if_fail (VTE_IS_PTY (pty)); if (self->manage_spawn) { g_warning ("Cannot set pty when GbTerminalView manages tty"); return; } if (self->terminal_top) { vte_terminal_reset (self->terminal_top, TRUE, TRUE); vte_terminal_set_pty (self->terminal_top, pty); } }
/** * vte_pty_set_utf8: * @pty: a #VtePty * @utf8: whether or not the pty is in UTF-8 mode * @error: (allow-none): return location to store a #GError, or %NULL * * Tells the kernel whether the terminal is UTF-8 or not, in case it can make * use of the info. Linux 2.6.5 or so defines IUTF8 to make the line * discipline do multibyte backspace correctly. * * Returns: %TRUE on success, %FALSE on failure with @error filled in */ gboolean vte_pty_set_utf8(VtePty *pty, gboolean utf8, GError **error) { #if defined(HAVE_TCSETATTR) && defined(IUTF8) VtePtyPrivate *priv; struct termios tio; tcflag_t saved_cflag; g_return_val_if_fail(VTE_IS_PTY(pty), FALSE); priv = pty->priv; g_return_val_if_fail (priv->pty_fd > 0, FALSE); if (tcgetattr(priv->pty_fd, &tio) == -1) { int errsv = errno; g_set_error(error, G_IO_ERROR, g_io_error_from_errno(errsv), "%s failed: %s", "tcgetattr", g_strerror(errsv)); errno = errsv; return FALSE; } saved_cflag = tio.c_iflag; if (utf8) { tio.c_iflag |= IUTF8; } else { tio.c_iflag &= ~IUTF8; } /* Only set the flag if it changes */ if (saved_cflag != tio.c_iflag && tcsetattr(priv->pty_fd, TCSANOW, &tio) == -1) { int errsv = errno; g_set_error(error, G_IO_ERROR, g_io_error_from_errno(errsv), "%s failed: %s", "tcgetattr", g_strerror(errsv)); errno = errsv; return FALSE; } #endif return TRUE; }
/** * vte_pty_set_size: * @pty: a #VtePty * @rows: the desired number of rows * @columns: the desired number of columns * @error: (allow-none): return location to store a #GError, or %NULL * * Attempts to resize the pseudo terminal's window size. If successful, the * OS kernel will send #SIGWINCH to the child process group. * * If setting the window size failed, @error will be set to a #GIOError. * * Returns: %TRUE on success, %FALSE on failure with @error filled in */ gboolean vte_pty_set_size(VtePty *pty, int rows, int columns, GError **error) { struct winsize size; int master; int ret; g_return_val_if_fail(VTE_IS_PTY(pty), FALSE); master = vte_pty_get_fd(pty); memset(&size, 0, sizeof(size)); size.ws_row = rows > 0 ? rows : 24; size.ws_col = columns > 0 ? columns : 80; _vte_debug_print(VTE_DEBUG_PTY, "Setting size on fd %d to (%d,%d).\n", master, columns, rows); ret = ioctl(master, TIOCSWINSZ, &size); if (ret != 0) { int errsv = errno; g_set_error(error, G_IO_ERROR, g_io_error_from_errno(errsv), "Failed to set window size: %s", g_strerror(errsv)); _vte_debug_print(VTE_DEBUG_PTY, "Failed to set size on %d: %s.\n", master, g_strerror(errsv)); errno = errsv; return FALSE; } return TRUE; }