envmon added

ns
Mike Gerwitz 2014-06-14 22:21:59 -04:00
parent 778571cd06
commit 4152425af3
2 changed files with 148 additions and 0 deletions

98
src/envmon.sh 100644
View File

@ -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 <http://www.gnu.org/licenses/>.
#
# 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"
}

View File

@ -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 <http://www.gnu.org/licenses/>.
#
# 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