Skip to content

Commit

Permalink
global: close all TTY for nohup background processes
Browse files Browse the repository at this point in the history
  • Loading branch information
akinomyoga committed Apr 3, 2023
1 parent 8d623c1 commit d92fa4a
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 19 deletions.
2 changes: 1 addition & 1 deletion ble.pp
Original file line number Diff line number Diff line change
Expand Up @@ -1543,7 +1543,7 @@ function ble/base/clean-up-runtime-directory {
removed[iremoved++]=$file
done
((iremoved)) && ble/bin/rm -rf "${removed[@]}" 2>/dev/null
((ibgpid)) && ({ ble/bin/sleep 3; kill "${bgpids[@]}"; } & disown) &>/dev/null </dev/null
((ibgpid)) && (ble/util/nohup 'ble/bin/sleep 3; kill "${bgpids[@]}"')

[[ $failglob ]] && shopt -s failglob
[[ $noglob ]] && set -f
Expand Down
2 changes: 1 addition & 1 deletion contrib
Submodule contrib updated 1 files
+1 −1 prompt-defer.bash
14 changes: 7 additions & 7 deletions lib/util.bgproc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -237,12 +237,12 @@ function ble/util/bgproc#start {
ble/fd#alloc 'bgproc[1]' '<> "${bgproc_fname[1]}"'
then
# Note: We want to assign a new process group to the background process
# without affecting the job table of the main shell so use the subshell
# `(...)'. The process group is later used to kill the process tree in
# stopping the background process. Note that the command substitutions
# $(...) do not create a new process group even if we specify `set -m' so
# cannot be used for the present purpose.
ble/util/assign 'bgproc[4]' '(set -m; ble/util/bgproc/.exec __ble_suppress_joblist__ >/dev/null & ble/util/print "$!")'
# without affecting the job table of the main shell so use the subshell
# `(...)'. The process group is later used to kill the process tree in
# stopping the background process. Note that the command substitutions
# $(...) do not create a new process group even if we specify `set -m' so
# cannot be used for the present purpose.
ble/util/assign 'bgproc[4]' '(set -m; ble/util/bgproc/.exec __ble_suppress_joblist__ >/dev/null & bgpid=$!; ble/util/print "$bgpid")'

if ble/util/bgproc/.alive; then
[[ :${bgproc[3]}: == *:no-close-on-unload:* ]] ||
Expand Down Expand Up @@ -315,7 +315,7 @@ function ble/util/bgproc#stop {
if ble/opts#extract-last-optarg "${bgproc[3]}" kill-timeout; then
close_timeout=$ret
fi
(ble/util/bgproc#stop/.kill "-${bgproc[4]}" "$close_timeout" </dev/null &>/dev/null & disown)
(ble/util/nohup 'ble/util/bgproc#stop/.kill "-${bgproc[4]}" "$close_timeout"')
fi

builtin eval -- "${prefix}_bgproc[0]="
Expand Down
12 changes: 9 additions & 3 deletions make_command.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1203,10 +1203,9 @@ function sub:scan/bash301bug-array-element-length {
grc '\$\{#[[:alnum:]]+\[[^@*]' --exclude={test,ChangeLog.md} | grep -Ev '^([^#]*[[:space:]])?#'
}

function sub:scan/bash501-arith-base {
function sub:scan/bash401-histexpand-bgpid {
echo "--- $FUNCNAME ---"
# bash-5.1 で $((10#)) の取り扱いが変わった。
grc '\b10#\$' --exclude={test,ChangeLog.md}
grc '"\$!"' --exclude={test,ChangeLog.md} | grep -Ev '#D2028'
}

function sub:scan/bash404-no-argument-return {
Expand All @@ -1225,6 +1224,12 @@ function sub:scan/bash404-no-argument-return {
g'
}

function sub:scan/bash501-arith-base {
echo "--- $FUNCNAME ---"
# bash-5.1 で $((10#)) の取り扱いが変わった。
grc '\b10#\$' --exclude={test,ChangeLog.md}
}

function sub:scan/bash502-patsub_replacement {
echo "--- $FUNCNAME ---"
# bash-5.2 patsub_replacement で ${var/pat/string} の string 中の & が特別な
Expand Down Expand Up @@ -1522,6 +1527,7 @@ function sub:scan {
sub:scan/check-todo-mark
sub:scan/bash300bug
sub:scan/bash301bug-array-element-length
sub:scan/bash401-histexpand-bgpid
sub:scan/bash404-no-argument-return
sub:scan/bash501-arith-base
sub:scan/bash502-patsub_replacement
Expand Down
27 changes: 27 additions & 0 deletions note.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6785,6 +6785,33 @@ bash_tips
即座に終了する方法について考えたがこれは単に kill-timeout を 0 に設定すれば
良いのでは。結局向こうで起こっている事が何か分からないのでどうしようもない。

* 2023-04-03 うーん。即座に終了しないのは subshell の stdout/stderr/stdin
を閉じていても、ble/fd で保持している fd が残っているからでは。
ble/fd#finalize を呼び出せば良いだろうか。或いは tty に関しては
ble/fd#finalize での自動 close を抑制していただろうか。

→確認してみると ble/fd#finalize には tty は登録されていない様だ。という
か寧ろ msleep 等が使っている fd を削除してしまう様だから中で sleep が使え
なくなってしまう。ble/fd#finalize は呼び出しても仕方がない。

うーん。待避している fd を閉じても駄目の様である。どうも builtin exit 0
を呼び出して終了しようとしているのだがその時に redirect をしている。その
redirect によって保管している fd が未だ生きている様だ。つまり、本当に全て
閉じようと思ったら redirect によって保管している物も全て閉じる必要がある。
すべて閉じる為には fd を列挙しなければならない。

a 一定の範囲の fd を全て閉じる? linux (もしくは bash) は現在の所は 255 付
近に redirect にの fd を保管している様だが os によってはもっと巨大な値
に保存しているかもしれない。なので可能性のある fd を全てスキャンすると
いう訳にも行かない気がする。

b 或いは /proc/$BASHPID/fd の中にある物を全て閉じる? 然しこれも使えるシス
テムが限られている。

また fd をスキャンして閉じるとしても msleep 等が使っている fd を閉じてし
まうとサブシェルの動作に問題を起こしてしまう。これについては -t で判定し
て端末だけを閉じる様にすれば良い気もする。

* make: インストール時に元のコメントなどの情報への pointer をつける (suggested by bkerin) [#D2027]
https://github.com/akinomyoga/ble.sh/discussions/309#discussioncomment-5498921

Expand Down
6 changes: 2 additions & 4 deletions src/history.sh
Original file line number Diff line number Diff line change
Expand Up @@ -327,8 +327,7 @@ if ((_ble_bash>=40000)); then

: >| "$history_tmpfile"
if [[ $opt_async ]]; then
_ble_history_load_bgpid=$(
shopt -u huponexit; ble/history:bash/load/.background-initialize </dev/null &>/dev/null & ble/util/print $!)
_ble_history_load_bgpid=$(ble/util/nohup 'ble/history:bash/load/.background-initialize' print-bgpid)

function ble/history:bash/load/.background-initialize-completed {
local history_tmpfile=$_ble_base_run/$$.history.load
Expand Down Expand Up @@ -769,8 +768,7 @@ if ((_ble_bash>=30100)); then

: >| "$history_tmpfile"
if [[ $opt_async ]]; then
_ble_history_mlfix_bgpid=$(
shopt -u huponexit; ble/history:bash/resolve-multiline/.worker </dev/null &>/dev/null & ble/util/print $!)
_ble_history_mlfix_bgpid=$(ble/util/nohup 'ble/history:bash/resolve-multiline/.worker' print-bgpid)

function ble/history:bash/resolve-multiline/.worker-completed {
local history_tmpfile=$_ble_base_run/$$.history.mlfix.sh
Expand Down
47 changes: 44 additions & 3 deletions src/util.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2200,9 +2200,9 @@ if ((_ble_bash>=40000)); then
#
# @remarks 将来的に ${ ...; } に切り替えることになった時に set -m でプロセス
# グループが作られるかどうかについて確認が必要。util.broc.sh では «
# ble/util/assign bgpid '(set -m; command & echo "$!")' » でプロセスグルー
# プが作られる事を想定している。例えば $(...) はプロセスグループが作られな
# いので使えない
# ble/util/assign bgpid '(set -m; command & bgpid=$!; ble/util/print
# "$bgpid")' » でプロセスグループが作られる事を想定している。例えば $(...)
# はプロセスグループが作られないので使えない
function ble/util/assign {
local _ble_local_tmpfile; ble/util/assign/.mktmp
builtin eval -- "$2" >| "$_ble_local_tmpfile"
Expand Down Expand Up @@ -2880,6 +2880,47 @@ ble/fd#alloc _ble_util_fd_null '<> /dev/null' base:inherit
[[ -c /dev/zero ]] &&
ble/fd#alloc _ble_util_fd_zero '< /dev/zero' base:inherit

function ble/fd#close-all-tty {
local -a fds=()
if [[ -d /proc/$$/fd ]]; then
ble/util/getpid
local fd
for fd in /proc/"$BASHPID"/fd/[0-9]*; do
ble/array#push fds "${fd##*/}"
done
else
fd=({0..255})
fi

# Note: 0 1 2 及び _ble_util_fd_std{in,out,err} を閉じる事を考えたが、どうも
# redirect によって待避されている物などたくさんある様なので全部チェックする事
# にした。
local fd
for fd in "${fds[@]}"; do
if ble/string#match "$fd" '^[0-9]+$' && [[ -t $fd ]]; then
builtin eval "exec $fd>&- $fd>&$_ble_util_fd_null"
ble/array#remove _ble_util_openat_fdlist "$fd"
fi
done
}
## @fn ble/util/nohup command [opts]
## @param[in] command
## @param[in,opt] opts
## @opts print-bgpid
function ble/util/nohup {
if ((!BASH_SUBSHELL)); then
(ble/util/nohup "$@")
return "$?"
fi

ble/fd#close-all-tty
shopt -u huponexit
builtin eval -- "$1" &>/dev/null </dev/null & { local pid=$!; disown; }
if [[ :$2: == *:print-bgpid:* ]]; then
ble/util/print "$pid"
fi
}

function ble/util/print-quoted-command {
local ret; ble/string#quote-command "$@"
ble/util/print "$ret"
Expand Down

0 comments on commit d92fa4a

Please sign in to comment.