mirror of
https://github.com/PowerShell/Win32-OpenSSH.git
synced 2025-07-22 21:45:09 +02:00
Added PTY support to account for client TTY window size changes
This commit is contained in:
parent
d6a1ff42ae
commit
f5226a3b70
37
channels.c
37
channels.c
@ -3895,7 +3895,6 @@ channel_connect_to_path(const char *path, char *ctype, char *rname)
|
||||
return connect_to(path, PORT_STREAMLOCAL, ctype, rname);
|
||||
}
|
||||
|
||||
#ifndef WIN32_FIXME//N
|
||||
void
|
||||
channel_send_window_changes(void)
|
||||
{
|
||||
@ -3907,8 +3906,21 @@ channel_send_window_changes(void)
|
||||
if (channels[i] == NULL || !channels[i]->client_tty ||
|
||||
channels[i]->type != SSH_CHANNEL_OPEN)
|
||||
continue;
|
||||
#ifndef WIN32_FIXME
|
||||
if (ioctl(channels[i]->rfd, TIOCGWINSZ, &ws) < 0)
|
||||
continue;
|
||||
continue
|
||||
#else
|
||||
{
|
||||
CONSOLE_SCREEN_BUFFER_INFO c_info;
|
||||
/* TODO - Fix this for multiple channels*/
|
||||
if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &c_info))
|
||||
continue;
|
||||
ws.ws_col = c_info.dwSize.X;
|
||||
ws.ws_row = c_info.dwSize.Y;
|
||||
ws.ws_xpixel = 640;
|
||||
ws.ws_ypixel = 480;
|
||||
}
|
||||
#endif
|
||||
channel_request_start(i, "window-change", 0);
|
||||
packet_put_int((u_int)ws.ws_col);
|
||||
packet_put_int((u_int)ws.ws_row);
|
||||
@ -3918,27 +3930,6 @@ channel_send_window_changes(void)
|
||||
}
|
||||
}
|
||||
|
||||
#else // WIN32_FIXME
|
||||
void
|
||||
channel_send_window_changes(int col, int row, int xpixel, int ypixel)
|
||||
{
|
||||
u_int i;
|
||||
struct winsize ws;
|
||||
|
||||
for (i = 0; i < channels_alloc; i++) {
|
||||
if (channels[i] == NULL || !channels[i]->client_tty ||
|
||||
channels[i]->type != SSH_CHANNEL_OPEN)
|
||||
continue;
|
||||
channel_request_start(i, "window-change", 0);
|
||||
packet_put_int((u_int)col);
|
||||
packet_put_int((u_int)row);
|
||||
packet_put_int((u_int)xpixel);
|
||||
packet_put_int((u_int)ypixel);
|
||||
packet_send();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* -- X11 forwarding */
|
||||
|
||||
|
@ -226,11 +226,7 @@ void channel_register_status_confirm(int, channel_confirm_cb *,
|
||||
channel_confirm_abandon_cb *, void *);
|
||||
void channel_cancel_cleanup(int);
|
||||
int channel_close_fd(int *);
|
||||
#ifndef WIN32_FIXME
|
||||
void channel_send_window_changes(void);
|
||||
#else
|
||||
void channel_send_window_changes(int, int, int, int);
|
||||
#endif
|
||||
|
||||
|
||||
/* protocol handler */
|
||||
|
24
clientloop.c
24
clientloop.c
@ -537,7 +537,7 @@ client_make_packets_from_stdin_data(void)
|
||||
static void
|
||||
client_check_window_change(void)
|
||||
{
|
||||
#ifndef WIN32_FIXME
|
||||
|
||||
struct winsize ws;
|
||||
|
||||
if (! received_window_change_signal)
|
||||
@ -550,6 +550,7 @@ client_check_window_change(void)
|
||||
if (compat20) {
|
||||
channel_send_window_changes();
|
||||
} else {
|
||||
#ifndef WIN32_FIXME
|
||||
if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0)
|
||||
return;
|
||||
packet_start(SSH_CMSG_WINDOW_SIZE);
|
||||
@ -558,27 +559,8 @@ client_check_window_change(void)
|
||||
packet_put_int((u_int)ws.ws_xpixel);
|
||||
packet_put_int((u_int)ws.ws_ypixel);
|
||||
packet_send();
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
|
||||
if (! win_received_window_change_signal)
|
||||
return;
|
||||
/** XXX race */
|
||||
win_received_window_change_signal = 0;
|
||||
|
||||
debug2("client_check_window_change: changed");
|
||||
|
||||
if (compat20) {
|
||||
channel_send_window_changes(ScreenX, ScrollBottom, 640, 480);
|
||||
} else {
|
||||
packet_start(SSH_CMSG_WINDOW_SIZE);
|
||||
packet_put_int((u_int)ScreenX);
|
||||
packet_put_int((u_int)ScrollBottom);
|
||||
packet_put_int((u_int)640);
|
||||
packet_put_int((u_int)480);
|
||||
packet_send();
|
||||
}
|
||||
#endif /* !WIN32_FIXME */
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -86,6 +86,20 @@ native_sig_handler(DWORD dwCtrlType)
|
||||
}
|
||||
}
|
||||
|
||||
static VOID CALLBACK
|
||||
sigwinch_APCProc(
|
||||
_In_ ULONG_PTR dwParam
|
||||
) {
|
||||
debug3("SIGTERM APCProc()");
|
||||
sigaddset(&pending_signals, W32_SIGWINCH);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
queue_terminal_window_change_event() {
|
||||
QueueUserAPC(sigwinch_APCProc, main_thread, (ULONG_PTR)NULL);
|
||||
}
|
||||
|
||||
void
|
||||
sw_init_signal_handler_table() {
|
||||
int i;
|
||||
@ -163,7 +177,7 @@ sw_process_pending_signals() {
|
||||
BOOL sig_int = FALSE; /* has any signal actually interrupted */
|
||||
|
||||
debug3("process_signals()");
|
||||
int i, exp[] = { W32_SIGCHLD , W32_SIGINT , W32_SIGALRM, W32_SIGTERM, W32_SIGTSTP };
|
||||
int i, exp[] = { W32_SIGCHLD , W32_SIGINT , W32_SIGALRM, W32_SIGTERM, W32_SIGTSTP, W32_SIGWINCH };
|
||||
|
||||
/* check for expected signals*/
|
||||
for (i = 0; i < (sizeof(exp) / sizeof(exp[0])); i++)
|
||||
|
@ -116,6 +116,8 @@ BOOL DataAvailable(HANDLE h)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void queue_terminal_window_change_event();
|
||||
|
||||
int ReadConsoleForTermEmul(HANDLE hInput, char *destin, int destinlen)
|
||||
{
|
||||
HANDLE hHandle[] = { hInput, NULL };
|
||||
@ -148,11 +150,7 @@ int ReadConsoleForTermEmul(HANDLE hInput, char *destin, int destinlen)
|
||||
switch (InputRecord.EventType)
|
||||
{
|
||||
case WINDOW_BUFFER_SIZE_EVENT:
|
||||
memcpy(szResponse, NAWSSTR, 9);
|
||||
szResponse[4] = ConScreenSizeX();
|
||||
szResponse[6] = ConWindowSizeY();
|
||||
ScreenX = ConScreenSizeX();
|
||||
ScreenY = ConWindowSizeY();
|
||||
queue_terminal_window_change_event();
|
||||
break;
|
||||
|
||||
case FOCUS_EVENT:
|
||||
|
49
session.c
49
session.c
@ -497,6 +497,10 @@ do_authenticated1(Authctxt *authctxt)
|
||||
#define USE_PIPES 1
|
||||
#endif
|
||||
|
||||
#ifdef WIN32_FIXME
|
||||
extern int debug_flag;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is called to fork and execute a command when we have no tty. This
|
||||
* will call do_child from the child, and server_loop from the parent after
|
||||
@ -548,8 +552,6 @@ do_exec_no_pty(Session *s, const char *command)
|
||||
char *exec_command;
|
||||
char *laddr;
|
||||
char buf[256];
|
||||
int prot_scr_width = 80;
|
||||
int prot_scr_height = 25;
|
||||
#ifdef WIN32_PRAGMA_REMCON
|
||||
char exec_command_str[512];
|
||||
#endif
|
||||
@ -590,8 +592,6 @@ do_exec_no_pty(Session *s, const char *command)
|
||||
int retcode = -1;
|
||||
if ( (!s -> is_subsystem) && (s ->ttyfd != -1))
|
||||
{
|
||||
prot_scr_width = s->col;
|
||||
prot_scr_height = s->row;
|
||||
extern HANDLE hInputConsole;
|
||||
extern HANDLE hOutputConsole ;
|
||||
hInputConsole = GetConsoleInputHandle();
|
||||
@ -620,10 +620,10 @@ do_exec_no_pty(Session *s, const char *command)
|
||||
si.lpTitle = NULL; /* NULL means use exe name as title */
|
||||
si.dwX = 0;
|
||||
si.dwY = 0;
|
||||
si.dwXSize = 640;
|
||||
si.dwYSize = 480;
|
||||
si.dwXCountChars = prot_scr_width;
|
||||
si.dwYCountChars = prot_scr_height;
|
||||
si.dwXSize = 5;
|
||||
si.dwYSize = 5;
|
||||
si.dwXCountChars = s->col;
|
||||
si.dwYCountChars = s->row;
|
||||
si.dwFillAttribute = 0;
|
||||
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESIZE | STARTF_USECOUNTCHARS;
|
||||
si.wShowWindow = 0; // FALSE ;
|
||||
@ -794,32 +794,35 @@ do_exec_no_pty(Session *s, const char *command)
|
||||
wchar_t exec_command_w[MAX_PATH];
|
||||
|
||||
MultiByteToWideChar(CP_UTF8, 0, exec_command, -1, exec_command_w, MAX_PATH);
|
||||
DWORD dwStartupFlags = 0;// CREATE_SUSPENDED; // 0
|
||||
DWORD dwStartupFlags = DETACHED_PROCESS;// CREATE_SUSPENDED; // 0
|
||||
|
||||
SetConsoleCtrlHandler(NULL, FALSE);
|
||||
b = CreateProcessAsUserW(hToken, NULL, exec_command_w, NULL, NULL, TRUE,
|
||||
if (debug_flag)
|
||||
b = CreateProcessW(NULL, exec_command_w, NULL, NULL, TRUE,
|
||||
/*CREATE_NEW_PROCESS_GROUP*/ dwStartupFlags, NULL, s->pw->pw_dir,
|
||||
&si, &pi);
|
||||
else
|
||||
b = CreateProcessAsUserW(hToken, NULL, exec_command_w, NULL, NULL, TRUE,
|
||||
/*CREATE_NEW_PROCESS_GROUP*/ dwStartupFlags, NULL, s -> pw -> pw_dir,
|
||||
&si, &pi);
|
||||
/*
|
||||
* If CreateProcessAsUser() fails we will try CreateProcess()
|
||||
* but only if current user and login user are the same.
|
||||
*/
|
||||
|
||||
if ((!b) && (strcmp(name, s -> pw -> pw_name) == 0))
|
||||
{
|
||||
b = CreateProcessW(NULL, exec_command_w, NULL, NULL, TRUE,
|
||||
/*CREATE_NEW_PROCESS_GROUP*/ dwStartupFlags, NULL, s -> pw -> pw_dir,
|
||||
&si, &pi);
|
||||
}
|
||||
|
||||
if (!b)
|
||||
{
|
||||
debug("ERROR. Cannot create process as new user (%u).\n", GetLastError());
|
||||
debug("ERROR. Cannot create process (%u).\n", GetLastError());
|
||||
|
||||
CloseHandle(hToken);
|
||||
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
FreeConsole();
|
||||
if (!debug_flag)
|
||||
ImpersonateLoggedOnUser(hToken);
|
||||
while (AttachConsole(pi.dwProcessId) == FALSE) {
|
||||
Sleep(200);
|
||||
}
|
||||
if (!debug_flag)
|
||||
RevertToSelf();
|
||||
}
|
||||
|
||||
/*
|
||||
* Save token used for create child process. We'll need it on cleanup
|
||||
|
39
sshpty.c
39
sshpty.c
@ -197,32 +197,6 @@ pty_make_controlling_tty(int *ttyfd, const char *tty)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef WIN32_PRAGMA_REMCON
|
||||
/* Changes the window size associated with the pty. */
|
||||
|
||||
void pty_change_window_size_oob(int ptyfd, u_int row, u_int col, u_int xpixel, u_int ypixel)
|
||||
{
|
||||
int rc;
|
||||
char unsigned data[16];
|
||||
size_t data_len;
|
||||
|
||||
// IAC SB NAWS <16-bit value width> <16-bit value height> IAC
|
||||
//sprintf (data,"%c%c%c%c%c%c%c%c", 255, 250, 31, 0, col, 0, row, 255 );
|
||||
data[0] = 255; // IAC;
|
||||
data[1] = 250; // SB
|
||||
data[2] = 31; // NAWS
|
||||
data[3] = 0;
|
||||
data[4] = (unsigned char)col;
|
||||
data[5] = 0;
|
||||
data[6] = (unsigned char)row;
|
||||
data[7] = 255; // IAC
|
||||
data[8] = 240; // iac end
|
||||
data_len = 9; //strlen (data);
|
||||
rc = write(ptyfd, data, (DWORD)data_len);
|
||||
//rc = AsyncWrite(c->hInputHandle, (char *)data, (DWORD)data_len);
|
||||
}
|
||||
|
||||
#endif
|
||||
/* Changes the window size associated with the pty. */
|
||||
|
||||
void
|
||||
@ -239,15 +213,10 @@ pty_change_window_size(int ptyfd, u_int row, u_int col,
|
||||
w.ws_ypixel = ypixel;
|
||||
(void) ioctl(ptyfd, TIOCSWINSZ, &w);
|
||||
#else
|
||||
extern HANDLE hOutputConsole ;
|
||||
#ifndef WIN32_PRAGMA_REMCON
|
||||
if (hOutputConsole != NULL) {
|
||||
ConSetScreenSize(col, row);
|
||||
}
|
||||
#else
|
||||
if (ptyfd > 0 )
|
||||
pty_change_window_size_oob(ptyfd, row, col, xpixel, ypixel);
|
||||
#endif
|
||||
COORD coord;
|
||||
coord.X = col;
|
||||
coord.Y = row;
|
||||
SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coord);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user