#!/usr/bin/env bash # # doomsh: Play with low ulimits in Bash # # Author: Tom Ryder # Copyright: 2016 # License: MIT (see LICENSE.markdown) # 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 "$((1 << (10 - skill)))" \ -v "$((1 << (19 - skill)))" \ || 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"