diff options
author | Kate Ward <kate.ward@forestent.com> | 2018-01-25 17:28:23 +0100 |
---|---|---|
committer | Kate Ward <kate.ward@forestent.com> | 2018-01-25 17:28:23 +0100 |
commit | 30a53b24f9f583a28f41dda8d4c16d4a1becd943 (patch) | |
tree | 01265ddbd97f65eb76f19488296144391665ec9d /examples | |
parent | 864c72eaf7ba1cae381b985f458cc5c466eeea04 (diff) | |
download | shflags-30a53b24f9f583a28f41dda8d4c16d4a1becd943.tar.gz |
Additional work on dealing with race condition.
Diffstat (limited to 'examples')
-rwxr-xr-x | examples/write_date.sh | 39 |
1 files changed, 24 insertions, 15 deletions
diff --git a/examples/write_date.sh b/examples/write_date.sh index 2fa6895..d9ae3ec 100755 --- a/examples/write_date.sh +++ b/examples/write_date.sh @@ -20,22 +20,15 @@ # $ ./write_date.sh -f now.out # $ cat now.out -# Prevent overwriting files with redirection operators. -set -C >/dev/null 2>&1 - # Source shFlags. -. ../shflags || ( echo "fatal: unable to source shflags" >&2; exit 64; ) +. ../shflags # Configure shFlags. DEFINE_boolean 'force' false 'force overwriting' 'f' FLAGS_HELP="USAGE: $0 [flags] filename" -write_date() { - date >"$1" -} - die() { - [ $# -gt 0 ] && echo "error: $@" >&2 + [ $# -gt 0 ] && echo "error: $@" flags_help exit 1 } @@ -44,11 +37,27 @@ die() { FLAGS "$@" || exit 1 eval set -- "${FLAGS_ARGV}" -# Check for filename. -[ $# -gt 0 ] || die 'filename missing' +# Check for filename on command-line. +[ $# -gt 0 ] || die 'filename missing.' filename=$1 -[ -f "${filename}" -a ${FLAGS_force} -eq ${FLAGS_FALSE} ] && \ - die "output file \"${filename}\" exists, not overwriting" - -write_date "${filename}" +# Redirect STDOUT to the file ($1). This seemingly complicated method using exec +# is used so that a potential race condition between checking for the presence +# of the file and writing to the file is mitigated. +if [ ${FLAGS_force} -eq ${FLAGS_FALSE} ] ; then + [ ! -f "${filename}" ] || die "file \"${filename}\" already exists." + # Set noclobber, redirect STDOUT to the file, first saving STDOUT to fd 4. + set -C + exec 4>&1 >"${filename}" # This fails if the file exists. +else + # Forcefully overwrite (clobber) the file. + exec 4>&1 >|"${filename}" +fi + +# What time is it? +date + +# Restore STDOUT from file descriptor 4, and close fd 4. +exec 1>&4 4>&- + +echo "The current date was written to \"${filename}\"." |