aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Ryder <tom@sanctum.geek.nz>2016-03-25 01:15:28 +1300
committerTom Ryder <tom@sanctum.geek.nz>2016-03-25 01:15:28 +1300
commitbfcf32ca87c7a06365c9247f92e114ccfcb8e349 (patch)
tree0aa84b1bf3e40e56705f8517ba9a1a6ff0a09238
downloaddoomsh-bfcf32ca87c7a06365c9247f92e114ccfcb8e349.tar.gz
doomsh-bfcf32ca87c7a06365c9247f92e114ccfcb8e349.zip
First commit
-rw-r--r--LICENSE.markdown23
-rw-r--r--README.markdown25
-rwxr-xr-xdoomsh137
3 files changed, 185 insertions, 0 deletions
diff --git a/LICENSE.markdown b/LICENSE.markdown
new file mode 100644
index 0000000..e55879c
--- /dev/null
+++ b/LICENSE.markdown
@@ -0,0 +1,23 @@
+MIT License
+===========
+
+Copyright (c) 2016 Tom Ryder
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
diff --git a/README.markdown b/README.markdown
new file mode 100644
index 0000000..0ab49d1
--- /dev/null
+++ b/README.markdown
@@ -0,0 +1,25 @@
+doomsh
+======
+
+Use ulimit to severely restrict your Bash shell's resources, and see how long
+you can last before segfaulting or giving up.
+
+Not really important or useful in any way, but kind of fun to see what breaks
+when resources are really tight, especially when it exposes problems in
+programs like failing to check for NULL returns from malloc(3).
+
+On the author's machine, at level 5, even ls(1) doesn't work, let alone Vim.
+
+If you're really crazy, you'll try and launch X processes from it, and watch
+them twitch as they die.
+
+READ THE LICENSE. THE AUTHOR WAIVES ALL RESPONSIBILITY FOR ANYTHING THIS DOES
+DO TO YOUR COMPUTER, YOUR DATA, OR YOUR DOG.
+
+Author
+: Tom Ryder
+Copyright
+: 2016
+License:
+: MIT (see LICENSE.markdown)
+
diff --git a/doomsh b/doomsh
new file mode 100755
index 0000000..4133ff7
--- /dev/null
+++ b/doomsh
@@ -0,0 +1,137 @@
+#!/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
+# <http://www.gamers.org/~fpv/doombann.html>
+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 <<EOF
+______ _____ _____ __ ___
+| __ \ _ | _ | \ / |
+| | \ | | | | | | | . V . |
+| | / | \_/ | \_/ | |\ /| |
+| |/ / \ / \ /| | V | |
+| ' / \_/ \_/ \_| | |
+|__/ \_|
+EOF
+printf >&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 <<EOF
+
+1. I'm too young to die
+2. Hey, not too rough
+3. Hurt me plenty
+4. Ultra-Violence
+5. Nightmare!
+
+EOF
+ read -er -p '[1-5]: ' skill
+
+ # If the user chose "Nightmare!" mode, get them to confirm, in the true
+ # spirit of things; otherwise, quit
+ if ((skill == 5)) ; then
+ while IFS= read -r line ; do
+ printf '%s\n' "$line" >&2
+ done <<EOF
+
+Are you sure? This skill level isn't even remotely fair.
+EOF
+ read -er -p '[y/N]: ' confirm
+ [[ $confirm == [Yy]* ]] || exit 1
+ fi
+fi
+
+# Don't accept any other skill level settings
+case $skill in
+ 1|2|3|4|5)
+ ;;
+ *)
+ printf '%s: Unknown skill level\n' \
+ "$self" >&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"
+