Skip to content

Commit

Permalink
edit: support "TMOUT" for the session timeout
Browse files Browse the repository at this point in the history
  • Loading branch information
akinomyoga committed Aug 19, 2021
1 parent 44e6ec1 commit 0e16dbd
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 2 deletions.
1 change: 1 addition & 0 deletions memo/ChangeLog.md
Expand Up @@ -63,6 +63,7 @@
- prompt: support a new backslash sequence `\g{...}` `#D1609` be31391
- complete: add a new option `bleopt complete_limit_auto_menu` `#D1618` 1829d80
- rlfunc: support vi word operations in `emacs` keymap (requested by SolarAquarion) `#D1624` 21d636a
- edit: support `TMOUT` for the session timeout `#D1631` 0000000

## Changes

Expand Down
51 changes: 51 additions & 0 deletions note.txt
Expand Up @@ -4668,6 +4668,57 @@ bash_tips

2021-07-19

* edit: support TMOUT for session timeout [#D1631]

またそれと並行して session TMOUT についても実装したい。うーん。振る舞いにつ
いて確認する。恐らく最後にコマンドを実行してからどれだけ時間が経ったのかで
timeout を実行するという仕組みになっている。これはどの様に実装すれば良いの
だろうか。

動作確認をして見た所、新しいコマンドを実行したタイミングというよりはやはり
accept をしたタイミング、或いは newline を挿入したタイミングでリセットされ
るという事の気がする。

例えば insert-newline に於いてログアウト時刻をセットするという仕組みにする
のが良い気がする。ログアウト時刻が設定されていたらそれまで sleep するという
事にする? 然し、それだと十分に長い timeout にしてたくさんコマンドを実行する
と、実行したコマンドの数だけ待ちタスクが増えて大変な事になってしまう。ユー
ザー入力または sleep で時間を測るというタスクが必要になる気がする。または、
後で外部からタスクの待ち時間を書き換える仕組みが必要になる気がする。

うーん。外部から既存のタスクの待ち時間を書き換える仕組みにするのが良い。

タスク番号を指定して書き換えられる様にする。その為にはタスク登録時に登録し
たタスクの番号が分かる様にするべきである。

? それから bash-4.0 未満で idle.push が使えない場合にはどうするのか…? これ
は諦めるしかない様な気がする。bash-3.2 以下では TMOUT は動かない。

# 或いは bash-3.2 以下でも read -t 0 もしくは select に対応する様な物を
# loadable builtin 等で用意できればそれはそれで良いのかもしれないが、実の
# ところライセンスなどの問題から loadable builtin で実装するかどうかは悩
# ましい所である。代わりに外部コマンドとして実装するという手もあるが。何
# れにしてもこれは散々別の場所で議論してきた所であるから今ここでは議論し
# ない。

? どのタイミングでタイマーをリセットするのが良いのか? insert-newline で実行
しようかと考えていたが、insert-newline はコマンド実行前に実施される。本来
はコマンド実行後にプロンプトが最初に表示された時点から実行するべきの様に
思われる。

うーん。という事を考えると POSTEXEC で実行するべきだろうか。また、この場
合には一番最初のプロンプトに対して timeout が設定されないので、ble-attach
に際しても同様に設定をするべきの気がする。

POSTEXEC だと複数回のコマンドが実行される時に余分に timeout が再計算され
る事になる。それよりは /.end 辺りで設定した方が良いのではないかという気も
する。うーん。

或いは、insert-newline で何か行番号等を更新して、PS1 の表示時にその行番号
が変化していたら更新するという具合にするのが良い気がする。

取り敢えず実装した。動いている。表示を多少調整した。

* global: "TMOUT: readonly variable" というエラーメッセージが表示される (reported by farmerbobathan) [#D1630]
https://github.com/akinomyoga/ble.sh/issues/129

Expand Down
32 changes: 32 additions & 0 deletions src/edit.sh
Expand Up @@ -1370,6 +1370,36 @@ function ble/prompt/unit:_ble_prompt_status/update {
#----------------------------------------------------------
# Update prompts for textarea

# process TMOUT
if ble/is-function ble/util/idle.push; then
_ble_prompt_timeout_task=
_ble_prompt_timeout_lineno=
function ble/prompt/timeout/process {
ble/util/idle.suspend # exit に失敗した時の為 task を suspend にする
_ble_edit_line_disabled=1 ble/widget/.insert-newline
ble/util/buffer.flush
ble/util/print "${_ble_term_setaf[12]}[ble: auto-logout]$_ble_term_sgr0 timed out waiting for input"
builtin exit 0 &>/dev/null
builtin exit 0 &>/dev/null
} >/dev/tty
function ble/prompt/timeout/check {
[[ $_ble_edit_lineno == "$_ble_prompt_timeout_lineno" ]] && return 0
_ble_prompt_timeout_lineno=$_ble_edit_lineno

if [[ ${TMOUT:-} =~ ^[0-9]+ ]] && ((BASH_REMATCH>0)); then
if [[ ! $_ble_prompt_timeout_task ]]; then
ble/util/idle.push -Z 'ble/prompt/timeout/process'
_ble_prompt_timeout_task=$_ble_util_idle_lasttask
fi
ble/util/idle#sleep "$_ble_prompt_timeout_task" $((BASH_REMATCH*1000))
elif [[ $_ble_prompt_timeout_task ]]; then
ble/util/idle#suspend "$_ble_prompt_timeout_task"
fi
}
else
function ble/prompt/timeout/check { ((1)); }
fi

function ble/prompt/update/.has-prompt_command {
[[ ${PROMPT_COMMAND[*]} ]]
}
Expand Down Expand Up @@ -1400,6 +1430,8 @@ function ble/prompt/update/.eval-prompt_command {
function ble/prompt/update {
local opts=:$1: dirty=

ble/prompt/timeout/check

# Update PS1 in PROMPT_COMMAND / PRECMD
local version=$COLUMNS:$_ble_edit_lineno:$_ble_history_count
if [[ $_ble_prompt_hash != "$version" && $opts != *:leave:* ]]; then
Expand Down
30 changes: 28 additions & 2 deletions src/util.sh
Expand Up @@ -4649,9 +4649,11 @@ if ((_ble_bash>=40000)); then
## C<command>
## コマンド <command> の実行結果が真になるのを待っているタスクです。
## タスク内から ble/util/idle.wait-condition で設定します。
## Z
## 停止中のタスクです。外部から状態を設定する事によって再開します。
##
_ble_util_idle_task=()

_ble_util_idle_lasttask=
_ble_util_idle_SEP=$_ble_term_FS

## @fn ble/util/idle.do
Expand Down Expand Up @@ -4690,6 +4692,7 @@ if ((_ble_bash>=40000)); then
(E) [[ -e ${_idle_status:1} ]] && _idle_to_process=1 ;;
(P) ! builtin kill -0 ${_idle_status:1} &>/dev/null && _idle_to_process=1 ;;
(C) builtin eval -- "${_idle_status:1}" && _idle_to_process=1 ;;
(Z) ;;
(*) builtin unset -v '_ble_util_idle_task[_idle_key]'
esac

Expand Down Expand Up @@ -4819,13 +4822,14 @@ if ((_ble_bash>=40000)); then
local i=$base
while [[ ${_ble_util_idle_task[i]-} ]]; do ((i++)); done
_ble_util_idle_task[i]=$entry
_ble_util_idle_lasttask=$i
}
function ble/util/idle.push {
local status=R nice=0
while [[ $1 == -* ]]; do
case $1 in
(-[SWPFEC]) status=${1:1}$2; shift 2 ;;
(-[SWPFECIR]*) status=${1:1}; shift ;;
(-[SWPFECIRZ]*) status=${1:1}; shift ;;
(-n) nice=$2; shift 2 ;;
(-n*) nice=${1#-n}; shift ;;
(*) break ;;
Expand All @@ -4849,6 +4853,10 @@ if ((_ble_bash>=40000)); then
function ble/util/is-running-in-idle {
[[ ${ble_util_idle_status+set} ]]
}
function ble/util/idle.suspend {
[[ ${ble_util_idle_status+set} ]] || return 2
ble_util_idle_status=Z
}
function ble/util/idle.sleep {
[[ ${ble_util_idle_status+set} ]] || return 2
local ret; ble/util/idle.clock
Expand Down Expand Up @@ -4900,6 +4908,24 @@ if ((_ble_bash>=40000)); then
ble_util_idle_status=R
}

function ble/util/idle/.delare-external-modifier {
local name=$1
builtin eval -- 'function ble/util/idle#'$name' {
local index=$1
[[ ${_ble_util_idle_task[index]+set} ]] || return 2
local ble_util_idle_status=${_ble_util_idle_task[index]%%"$_ble_util_idle_SEP"*}
local ble_util_idle_command=${_ble_util_idle_task[index]#*"$_ble_util_idle_SEP"}
ble/util/idle.'$name' "${@:2}"
_ble_util_idle_task[index]=$ble_util_idle_status$_ble_util_idle_SEP$ble_util_idle_command
}'
}
# @fn ble/util/idle#suspend
# @fn ble/util/idle#sleep time
# @fn ble/util/idle#isleep time
ble/util/idle/.delare-external-modifier suspend
ble/util/idle/.delare-external-modifier sleep
ble/util/idle/.delare-external-modifier isleep

ble/util/idle.push-background 'ble/util/msleep/calibrate'
else
function ble/util/idle.do { false; }
Expand Down

0 comments on commit 0e16dbd

Please sign in to comment.