@@ -602,7 +602,7 @@ extract_tar_from_url() {
602602 log_info " Extracting $( basename " $tarfile " ) ..."
603603 if tar -xvf " $tarfile " ; then
604604 : > " $markfile " 2> /dev/null || true
605- # Clear the minimal/offline sentinel only if it exists (SC2015-safe)
605+ # Clear the minimal/offline sentinel only if it exists (SC2015-safe)
606606 if [ -f " $skip_sentinel " ]; then
607607 rm -f " $skip_sentinel " 2> /dev/null || true
608608 fi
@@ -706,7 +706,7 @@ weston_stop() {
706706 log_info " Stopping Weston..."
707707 pkill -x weston
708708 for i in $( seq 1 10) ; do
709- log_info " Waiting for Weston to stop with $i attempt "
709+ log_info " Waiting for Weston to stop with $i attempt "
710710 if ! weston_is_running; then
711711 log_info " Weston stopped successfully"
712712 return 0
@@ -3684,3 +3684,143 @@ ensure_network_online() {
36843684 unset net_script_path net_ifaces net_wifi net_ifc net_rc net_had_any_ip
36853685 return 1
36863686}
3687+
3688+ kill_process () {
3689+ TERM_GRACE=" ${KILL_TERM_GRACE:- 3} "
3690+ KILL_GRACE=" ${KILL_KILL_GRACE:- 2} "
3691+ pid_alive () {
3692+ p=" $1 "
3693+ [ -d " /proc/$p " ] || return 1
3694+ st=" $( awk ' {print $3}' " /proc/$p /stat" 2> /dev/null) "
3695+ [ " $st " = " Z" ] && return 1
3696+ return 0
3697+ }
3698+ list_children () {
3699+ p=" $1 "
3700+ if [ -r " /proc/$p /task/$p /children" ]; then
3701+ tr ' \n' ' ' < " /proc/$p /task/$p /children" 2> /dev/null
3702+ return
3703+ fi
3704+ if command -v ps > /dev/null 2>&1 ; then
3705+ ps -o pid= --ppid " $p " 2> /dev/null | tr ' \n' ' '
3706+ fi
3707+ }
3708+ list_descendants () {
3709+ root=" $1 "
3710+ out=" "
3711+ seen=" "
3712+ queue=" $root "
3713+ while [ -n " $queue " ]; do
3714+ next=" "
3715+ for p in $queue ; do
3716+ case " $seen " in * " $p " * ) continue ;; esac
3717+ seen=" $seen$p "
3718+ kids=" $( list_children " $p " ) "
3719+ for c in $kids ; do
3720+ case " $seen " in * " $c " * ) : ;; * )
3721+ out=" $out $c "
3722+ next=" $next $c "
3723+ esac
3724+ done
3725+ done
3726+ queue=" $next "
3727+ done
3728+ printf ' %s\n' " $out " | awk ' NF' | tr ' \n' ' '
3729+ }
3730+ collect_pids_from_pattern () {
3731+ pat=" $1 "
3732+ out=" "
3733+ if command -v pgrep > /dev/null 2>&1 ; then
3734+ out=" $( pgrep -f -- " $pat " 2> /dev/null | tr ' \n' ' ' ) "
3735+ else
3736+ for d in /proc/[0-9]* ; do
3737+ [ -d " $d " ] || continue
3738+ p=" $( basename " $d " ) "
3739+ [ " $p " -eq " $$ " ] && continue
3740+ cmd=" $( tr ' \0' ' ' < " $d /cmdline" 2> /dev/null) "
3741+ [ -n " $cmd " ] || continue
3742+ printf ' %s' " $cmd " | grep -F -- " $pat " > /dev/null 2>&1 && out=" $out $p "
3743+ done
3744+ fi
3745+ for x in $out ; do [ " $x " -ne " $$ " ] && printf ' %s\n' " $x " ; done \
3746+ | awk ' !seen[$0]++' | tr ' \n' ' '
3747+ }
3748+ kill_tree () {
3749+ sig=" $1 " ; p=" $2 "
3750+ [ -n " $p " ] || return 0
3751+ [ " $p " -eq 1 ] && return 0
3752+ [ " $p " -eq " $$ " ] && return 0
3753+ pid_alive " $p " || return 0
3754+ # Try process group (uses pgrp from /proc if available)
3755+ pgrp=" $( awk ' {print $5}' " /proc/$p /stat" 2> /dev/null) "
3756+ [ -n " $pgrp " ] && kill " -$sig " " -$pgrp " 2> /dev/null || true
3757+ all=" $p $( list_descendants " $p " ) "
3758+ for t in $all ; do
3759+ [ " $t " -eq 1 ] && continue
3760+ [ " $t " -eq " $$ " ] && continue
3761+ kill " -$sig " " $t " 2> /dev/null || true
3762+ done
3763+ }
3764+ wait_gone () {
3765+ p=" $1 " ; timeout=" $2 " ; waited=0
3766+ while [ " $waited " -lt " $timeout " ]; do
3767+ pid_alive " $p " || return 0
3768+ sleep 1
3769+ waited=$(( waited+ 1 ))
3770+ done
3771+ return 1
3772+ }
3773+ # -------- Build target set --------
3774+ targets=" "
3775+ if [ " $# " -gt 0 ]; then
3776+ for a in " $@ " ; do
3777+ case " $a " in
3778+ ' ' ) continue ;;
3779+ * [!0-9]* ) pids=" $( collect_pids_from_pattern " $a " ) " ; [ -n " $pids " ] && targets=" $targets $pids " ;;
3780+ * ) targets=" $targets $a " ;;
3781+ esac
3782+ done
3783+ elif [ -n " ${PID:- } " ]; then
3784+ targets=" $PID "
3785+ fi
3786+ if [ -z " $targets " ]; then
3787+ log_warn " kill_process: no targets (neither args nor \$ PID set)."
3788+ return 0
3789+ fi
3790+ # Normalize / de-dup / filter
3791+ uniq=" "
3792+ for t in $targets ; do
3793+ printf ' %s\n' " $t "
3794+ done | awk ' !seen[$0]++' | while IFS= read -r t; do
3795+ printf ' %s' " $t " | grep -Eq ' ^[0-9]+$' || continue
3796+ [ " $t " -eq 1 ] && continue
3797+ [ " $t " -eq " $$ " ] && continue
3798+ if pid_alive " $t " ; then
3799+ uniq=" $uniq $t "
3800+ fi
3801+ done
3802+ targets=" $uniq "
3803+ [ -n " $targets " ] || { log_info " kill_process: nothing running." ; return 0; }
3804+ log_info " Killing process tree(s):$targets "
3805+ rc=0
3806+ for pid in $targets ; do
3807+ kill_tree TERM " $pid "
3808+ if wait_gone " $pid " " $TERM_GRACE " ; then
3809+ log_info " PID $pid terminated with SIGTERM."
3810+ continue
3811+ fi
3812+ log_warn " PID $pid still alive after ${TERM_GRACE} s; escalating to SIGKILL."
3813+ kill_tree KILL " $pid "
3814+ if wait_gone " $pid " " $KILL_GRACE " ; then
3815+ log_info " PID $pid killed with SIGKILL."
3816+ continue
3817+ fi
3818+ if ! pid_alive " $pid " ; then
3819+ log_info " PID $pid no longer running (exited/zombie reaped)."
3820+ continue
3821+ fi
3822+ log_error " PID $pid could not be terminated."
3823+ rc=1
3824+ done
3825+ return " $rc "
3826+ }
0 commit comments