diff --git a/src/envmon.sh b/src/envmon.sh
new file mode 100644
index 0000000..40c2f1e
--- /dev/null
+++ b/src/envmon.sh
@@ -0,0 +1,98 @@
+#!/bin/bash
+# Environment monitor
+#
+# Copyright (C) 2014 Mike Gerwitz
+#
+# This file is part of pkgsh.
+#
+# pkgsh 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.
+#
+# This program 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 this program. If not, see .
+#
+# It is highly recommended that you monitor a clean environment (e.g. using
+# `env -i`) to avoid as much overhead as possible.
+##
+
+[ -z $__PKGSH_INC_ENVMON ] || return
+__PKGSH_INC_ENVMON=1
+
+declare -A __pkgsh_envmon_env=()
+
+
+##
+# Map environment to a callback
+#
+# For each environment variable, $callback will be invoked with two
+# arguments: the variable name and its value.
+#
+_pkgsh-envmon-env-map()
+{
+ local -r callback="$1"
+ local var= val=
+
+ while read -d $'\0' env; do
+ var="${env%%=*}"
+ val="${env#*=}"
+
+ "$callback" "$var" "$val"
+ done < <( env -0 )
+}
+
+
+##
+# Prepares the environment monitor for use
+#
+_pkgsh-envmon-init()
+{
+ _pkgsh-envmon-env-map __pkgsh-envmon-envload
+}
+
+
+##
+# Load the provided variable name and value into the cache
+#
+# This produces a local copy of the environment in memory, which can be used
+# to check against a later environment state for changes.
+#
+__pkgsh-envmon-envload()
+{
+ local -r var="$1" val="$2"
+ __pkgsh_envmon_env[$var]="$val"
+}
+
+
+##
+# Output null-byte-delimited names and values of variables added to the
+# environment since the last diff and update the environment cache
+#
+_pkgsh-envmon-diff-adds()
+{
+ _pkgsh-envmon-env-map __pkgsh-envmon-dodiff-adds
+}
+
+
+##
+# Output provided value with terminating null byte if $name does not exist
+# in the environment cache, then immediately add $name to the cache
+__pkgsh-envmon-dodiff-adds()
+{
+ local -r var="$1" val="$2"
+
+ # ignore if it already exists (FIXME: this will fail if the in-memory
+ # value is empty)
+ [ -z "${__pkgsh_envmon_env[$var]}" ] || return 0
+
+ # output the difference and immediately add to the environment in memory
+ echo -ne "$var=$val\000"
+ __pkgsh_envmon_env[$var]="$val"
+}
+
diff --git a/test/envmon/test-diff-adds.sh b/test/envmon/test-diff-adds.sh
new file mode 100644
index 0000000..401fa3f
--- /dev/null
+++ b/test/envmon/test-diff-adds.sh
@@ -0,0 +1,50 @@
+#!/bin/bash
+# Tests monitoring for environment additions
+#
+# Copyright (C) 2014 Mike Gerwitz
+#
+# This file is part of pkgsh.
+#
+# pkgsh 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.
+#
+# This program 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 this program. If not, see .
+#
+# Tests monitoring the environment for variable additions
+##
+
+source src/envmon.sh
+
+# initialize to the current state of the environment
+_pkgsh-envmon-init
+
+# add two variables to the environment (note that one contains newlines to
+# ensure that they do not cause problems)
+export foo=a bar=newline$'\n'test
+declare -A found=()
+
+# perform env addition diff
+while read -d $'\0' env; do
+ var="${env%%=*}"
+ val="${env#*=}"
+
+ found[$var]="$val"
+done < <( _pkgsh-envmon-diff-adds )
+
+# ensure each was found
+for name in foo bar; do
+ eval chk="\$$name"
+ assert "${found[$name]}" == "$chk"
+done
+
+# ensure that no others were found
+assert "${#found[@]}" -eq 2
+