diff -ruN erts/emulator/drivers/unix/ttsl_drv.c erts/emulator/drivers/unix/ttsl_drv.c --- erts/emulator/drivers/unix/ttsl_drv.c 2008-06-10 07:47:20.000000000 -0500 +++ erts/emulator/drivers/unix/ttsl_drv.c 2008-06-18 15:43:28.000000000 -0500 @@ -61,7 +61,7 @@ /* Terminal capabilites in which we are interested. */ static char *capbuf; -static char *up, *down, *left, *right; +static char *up, *down, *left, *right, *clear; static int cols, xn; static volatile int cols_needs_update = FALSE; @@ -71,6 +71,7 @@ #define OP_INSC 2 #define OP_DELC 3 #define OP_BEEP 4 +#define OP_CLEAR 5 /* Control op */ #define CTRL_OP_GET_WINSIZE 100 @@ -344,6 +345,9 @@ case OP_BEEP: outc('\007'); break; + case OP_CLEAR: + tputs(clear, lpos > 0 ? lpos : 1, outc); + break; default: /* Unknown op, just ignore. */ break; @@ -532,7 +536,7 @@ /* Copy the string to lbuf expanding control characters. */ for (pos = lpos, start = lc; n > 0; --n, s++) { - if (isprint(*s)) { + if (isprint(*s) || *s == 27) { *lc++ = *s; pos++; } @@ -551,7 +555,6 @@ lc = start = lbuf; llen = lpos = pos = 0; } - else if (*s >= 128) { /* "Meta" characters printed as \nnn */ *lc++ = *s; *lc++ = PAD; @@ -579,7 +582,7 @@ update_cols(); while (n > 0) { - if (isprint(*s)) { + if (isprint(*s) || *s == 27) { outc(*s); --n; s++; } @@ -686,7 +689,8 @@ if (!(left = tgetflag("bs") ? "\b" : tgetstr("bc", &c))) left = "\b"; /* Can't happen - but does on Solaris 2 */ right = tgetstr("nd", &c); - if (up && down && left && right) + clear = tgetstr("cl", &c); + if (up && down && left && right && clear) return TRUE; false: if (env && env != capbuf) --- lib/kernel/src/group.erl 2008-06-10 07:47:25.000000000 -0500 +++ lib/kernel/src/group.erl 2008-06-18 17:20:56.000000000 -0500 @@ -146,7 +146,15 @@ after 2000 -> timeout end. - + +clear(Drv) -> + Drv ! {self(), clear}, + receive + {Drv, clear, Result} -> + Result + after 2000 -> + timeout + end. io_request(Req, From, ReplyAs, Drv, Buf0) -> case io_request(Req, Drv, Buf0) of @@ -205,6 +213,13 @@ _ -> {error,{error,enotsup},Buf} end; +io_request({clear},Drv,Buf) -> + case clear(Drv) of + ok -> + {ok, ok, Buf}; + _ -> + {error,{error,enotsup},Buf} + end; %% These are new in R9C io_request({get_chars,Prompt,N}, Drv, Buf) -> diff -ruN lib/kernel/src/user_drv.erl lib/kernel/src/user_drv.erl --- lib/kernel/src/user_drv.erl 2007-11-26 12:55:44.000000000 -0600 +++ lib/kernel/src/user_drv.erl 2008-06-18 16:24:35.000000000 -0500 @@ -28,6 +28,7 @@ -define(OP_INSC,2). -define(OP_DELC,3). -define(OP_BEEP,4). +-define(OP_CLEAR,5). % Control op -define(CTRL_OP_GET_WINSIZE,100). @@ -161,6 +162,10 @@ {Curr,tty_geometry} -> Curr ! {self(),tty_geometry,get_tty_geometry(Iport)}, server_loop(Iport, Oport, Curr, User, Gr); + {Curr, clear} -> + Oport ! {self(),{command,[?OP_CLEAR]}}, + Curr ! {self(), clear, ok}, + server_loop(Iport, Oport, Curr, User, Gr); {Curr,Req} -> io_request(Req, Iport, Oport), server_loop(Iport, Oport, Curr, User, Gr); @@ -212,6 +217,10 @@ port_bytes([$\^G|_Bs], Iport, Oport, _Curr, User, Gr) -> handle_escape(Iport, Oport, User, Gr); +port_bytes([$\^L|_Bs], Iport, Oport, Curr, User, Gr) -> + Oport ! {self(),{command,[?OP_CLEAR]}}, + server_loop(Iport, Oport, Curr, User, Gr); + port_bytes([$\^C|_Bs], Iport, Oport, Curr, User, Gr) -> interrupt_shell(Iport, Oport, Curr, User, Gr); Binary files lib/ssh/ebin/ssh_cli.beam and lib/ssh/ebin/ssh_cli.beam differ diff -ruN lib/ssh/src/ssh_cli.erl lib/ssh/src/ssh_cli.erl --- lib/ssh/src/ssh_cli.erl 2008-02-05 07:43:44.000000000 -0600 +++ lib/ssh/src/ssh_cli.erl 2008-06-18 15:38:22.000000000 -0500 @@ -135,8 +135,12 @@ {noreply, State#state{cm = CM, channel = Channel, remote_channel = RemoteChannel}}; handle_info({ssh_cm, CM, {data, Channel, _Type, Data}}, State) -> - ssh_cm:adjust_window(CM, Channel, size(Data)), - State#state.group ! {self(), {data, binary_to_list(Data)}}, + if Data /= <<"\f">> -> + ssh_cm:adjust_window(CM, Channel, size(Data)), + State#state.group ! {self(), {data, binary_to_list(Data)}}; + true -> + write_chars(CM, Channel,"\033[2J") + end, {noreply, State}; handle_info({ssh_cm, _CM, {pty, _Channel, _WantReply, Pty}}, State) -> {noreply, State#state{pty = Pty}}; @@ -305,7 +309,7 @@ AccW = string:chars(32, NSpaces) ++ [AccWrite], AccBT = nthtail(NSpaces, AccBufTail), conv_buf(Rest, AccB, AccBT, AccW, Col + NSpaces); -conv_buf([C | Rest], AccBuf, AccBufTail, AccWrite, Col) when C < 32 -> +conv_buf([C | Rest], AccBuf, AccBufTail, AccWrite, Col) when (C < 32 andalso C /= 27) -> AccB = [10, 10, 10, C | AccBuf], AccW = [oct_dig(C, 0), oct_dig(C, 1), oct_dig(C, 2), "\\" | AccWrite], conv_buf(Rest, AccB, tl4(AccBufTail), AccW, Col + 4); Binary files lib/stdlib/ebin/io.beam and lib/stdlib/ebin/io.beam differ Binary files lib/stdlib/ebin/shell.beam and lib/stdlib/ebin/shell.beam differ diff -ruN lib/stdlib/src/io.erl lib/stdlib/src/io.erl --- lib/stdlib/src/io.erl 2008-04-07 08:57:55.000000000 -0500 +++ lib/stdlib/src/io.erl 2008-06-18 16:23:14.000000000 -0500 @@ -22,7 +22,7 @@ get_password/0, get_password/1, setopts/1, setopts/2]). -export([write/1,write/2,read/1,read/2,read/3]). --export([columns/0,columns/1,rows/0,rows/1]). +-export([columns/0,columns/1,rows/0,rows/1,clear/0,clear/1]). -export([fwrite/1,fwrite/2,fwrite/3,fread/2,fread/3, format/1,format/2,format/3]). -export([scan_erl_exprs/1,scan_erl_exprs/2,scan_erl_exprs/3, @@ -96,8 +96,16 @@ _ -> {error,enotsup} end. - +clear() -> + clear(default_output()). +clear(Io) -> + case request(Io,{clear}) of + ok -> + ok; + _ -> + {error,enotsup} + end. get_chars(Prompt, N) -> get_chars(default_input(), Prompt, N). diff -ruN lib/stdlib/src/shell.erl lib/stdlib/src/shell.erl --- lib/stdlib/src/shell.erl 2008-04-07 08:57:55.000000000 -0500 +++ lib/stdlib/src/shell.erl 2008-06-18 17:30:08.000000000 -0500 @@ -773,6 +773,8 @@ true; not_restricted(b, []) -> true; +not_restricted(l, []) -> + true; not_restricted(which, [_]) -> true; not_restricted(import, [_]) -> @@ -885,6 +887,8 @@ {value,list_commands(Cs3, RT),Bs}; local_func(b, [], Bs, _Shell, RT, _Lf, _Ef) -> {value,list_bindings(erl_eval:bindings(Bs), RT),Bs}; +local_func(l, [], Bs, _Shell, _RT, _Lf, _Ef) -> + {value, io:clear(), Bs}; local_func(f, [], _Bs, _Shell, _RT, _Lf, _Ef) -> {value,ok,erl_eval:new_bindings()}; local_func(f, [{var,_,Name}], Bs, _Shell, _RT, _Lf, _Ef) ->