#!bash # # Copyright (C) 2016, 2018, 2021 Tom Ryder # # This file is part of doomsh. # # doomsh is free software: you can redistribute it and/or modify it under the # terms of the GNU General Public License as published by the Free Software # Foundation, either version 3 of the License, or (at your option) any later # version. # # doomsh is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along with # doomsh. If not, see . # doomsh: Play with low ulimits in Bash self=doomsh # Don't try to play doomsh if already playing doomsh if [[ $DOOMSH ]] ; then printf '%s: Already playing doomsh!\n' \ "$self" >&2 exit 2 fi # Show the coloured logo; thanks to Frans P. de Vries for the classic ASCII art # printf >&2 %s "$( { tput AF 3 || tput setaf 3 tput md || tput bold } 2>/dev/null )" while IFS= read -r line ; do printf >&2 '%s\n' "$line" done <&2 %s "$( { tput me || tput sgr0 } 2>/dev/null )" # Need to figure out a skill level declare -i skill # If we have an argument, that must be the skill level if (($#)) ; then skill=$1 shift # Otherwise, we'll give the user a menu to choose from else while IFS= read -r line ; do printf >&2 '%s\n' "$line" done <&2 done <&2 exit 2 esac # Form a red prompt (hopefully) using terminal escapes ps1=$(printf '%sdoomsh[%u]\$%s ' \ "$( { tput AF 1 || tput setaf 1 } 2>/dev/null )" \ "$skill" \ "$( { tput me || tput sgr0 } 2>/dev/null )" ) # Set the limits based on the skill level declare -i filesize files stack memory filesize=$((1 << (8 - skill))) files=$((11 - skill)) stack=$((1 << (11 - skill))) memory=$((1 << (19 - skill))) # Display the limits printf >&2 '\n' printf >&2 'File size writing limit: %u blocks\n' \ "$filesize" printf >&2 'Open files limit: %u\n' \ "$files" printf >&2 'Stack size: %u kbytes\n' \ "$stack" printf >&2 'Memory size: %u kbytes\n' \ "$memory" printf >&2 '\n' # Record the current seconds since shell start, so we can tell how long the # user lasts before giving up or segfaulting declare -i start start=$SECONDS # Open a subshell so that the ulimit settings don't persist after the fork ( # We only proceed if the ulimit call succeeds ulimit \ -f "$filesize" \ -n "$files" \ -s "$stack" \ -v "$memory" \ || exit 2 DOOMSH=$skill PS1=$ps1 bash --norc ) # Give the user some statistics about their performance printf >&2 '%s: You lasted %u seconds at skill level %u!\n' \ "$self" "$((SECONDS - start))" "$skill"