# fail_after -- exits openMSX after timeout. # # Typically used in combination with the MSX-DOS 'omsxctl.com' utility. # # Adds two commands to openMSX; # # 'fail_after [timeunit] [fail_id] [fail_code]' # Schedules an openMSX exit after the timeout. # This can be canceled by requesting a timeout of 0 or new timeout. # The timeunit can be selected between (msx)'time' and (host)'realtime'. # The fail_id can be used to differentiate between multiple fail_after commands. # The failure exit code can be given too. # # 'fail_after_exit [fail_id] [fail_code]' # Exits openMSX with an failure exit code and if the FAIL_AFTER_PATH is # set it also creates a screenshot named from the failure id. # # Supported environment variables by this script; # # BOOT_WATCHDOG=30 # Enables the boot watchdog timer which will exit openMSX after the timeout(in seconds). # To cancel this timer give an `fail_after 0` or any new fail_after command. # (exits with status 124 see `man timeout`) # set fail_after_prev_timer 0 set fail_after_prev_id 0 set fail_after_boot_timeout 0 proc fail_after_exit {{fail_id "fail_after_exit"} {fail_code 2}} { if {[catch {screenshot -prefix $fail_id} err_msg]} { puts stderr "warning: $err_msg" } puts stderr "error: Failure request from $fail_id" exit $fail_code } proc fail_after { timeout {time_unit "time"} {fail_id "fail_after"} {fail_code 2}} { global fail_after_prev_timer global fail_after_prev_id set msg "" if {$fail_after_prev_timer != 0} { if {[catch {after cancel $fail_after_prev_timer} err_msg]} { puts stderr "error: $err_msg" fail_after_exit fail_after_cancel_error 1 } set msg "mb::fail canceled $fail_after_prev_id" } set fail_after_prev_id $fail_id if {$time_unit != "time"} { set time_unit "realtime" } if {$timeout != 0} { if {[catch {set fail_after_prev_timer [after $time_unit $timeout "fail_after_exit $fail_id $fail_code"]} err_msg]} { puts stderr "error: $err_msg" fail_after_exit fail_after_timer_error 1 } set msg "$msg\nmb::fail after $timeout $time_unit $fail_id" } else { set fail_after_prev_timer 0 } return $msg } proc fail_after_reboot_watchdog {} { global fail_after_boot_timeout if {$fail_after_boot_timeout != 0} { if {[catch {fail_after $fail_after_boot_timeout realtime err_boot 124} err_msg]} { puts stderr "error: $err_msg" fail_after_exit fail_after_reboot_install_error 1 } if {[catch {after boot "fail_after_reboot_watchdog"} err_msg]} { puts stderr "error: $err_msg" fail_after_exit fail_after_reboot_cycle_error 1 } } } if {[info exists ::env(BOOT_WATCHDOG)] && ([string trim $::env(BOOT_WATCHDOG)] != "")} { set fail_after_boot_timeout [string trim $::env(BOOT_WATCHDOG)] fail_after_reboot_watchdog }