From 48083e54b502afb2768066394074d29423162dc8 Mon Sep 17 00:00:00 2001 From: Lukas Larsson Date: Thu, 26 Jun 2014 18:55:47 +0200 Subject: kernel,ssh: Add synchronous user_drv protocol Added a put_chars_sync to the protocol that can be used to talk to user_drv and made group use it. This is needed in order to guarantee that bytes has been pushed to the tty port when doing something like this: io:format("halting\n"),erlang:halt(0). Before this change the halting message could be lost in the message queue of the user_drv process, this is no longer possible. This commit also fixes ssh_cli as that plugs itself in as a user_drv process. OTP-12240 --- erts/emulator/drivers/win32/ttsl_drv.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'erts/emulator/drivers/win32') diff --git a/erts/emulator/drivers/win32/ttsl_drv.c b/erts/emulator/drivers/win32/ttsl_drv.c index 502cb58dfa..851c336a11 100644 --- a/erts/emulator/drivers/win32/ttsl_drv.c +++ b/erts/emulator/drivers/win32/ttsl_drv.c @@ -46,6 +46,7 @@ static int rows; /* Number of rows available. */ #define OP_INSC 2 #define OP_DELC 3 #define OP_BEEP 4 +#define OP_PUTC_SYNC 5 /* Control op */ #define CTRL_OP_GET_WINSIZE 100 @@ -458,6 +459,7 @@ static void ttysl_from_erlang(ErlDrvData ttysl_data, char* buf, ErlDrvSizeT coun switch (buf[0]) { case OP_PUTC: + case OP_PUTC_SYNC: DEBUGLOG(("OP: Putc(%I64u)",(unsigned long long)count-1)); if (check_buf_size((byte*)buf+1, count-1) == 0) return; @@ -481,6 +483,20 @@ static void ttysl_from_erlang(ErlDrvData ttysl_data, char* buf, ErlDrvSizeT coun /* Unknown op, just ignore. */ break; } + + if (buf[0] == OP_PUTC_SYNC) { + /* On windows we do a blocking write to the tty so we just + send the ack immidiately. If at some point in the future + someone has a problem with tty output being blocking + this has to be changed. */ + ErlDrvTermData spec[] = { + ERL_DRV_PORT, driver_mk_port(ttysl_port), + ERL_DRV_ATOM, driver_mk_atom("ok"), + ERL_DRV_TUPLE, 2 + }; + erl_drv_output_term(driver_mk_port(ttysl_port), spec, + sizeof(spec) / sizeof(spec[0])); + } return; } -- cgit v1.2.3