aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorKate Ward <kate.ward@forestent.com>2018-01-25 17:28:23 +0100
committerKate Ward <kate.ward@forestent.com>2018-01-25 17:28:23 +0100
commit30a53b24f9f583a28f41dda8d4c16d4a1becd943 (patch)
tree01265ddbd97f65eb76f19488296144391665ec9d /examples
parent864c72eaf7ba1cae381b985f458cc5c466eeea04 (diff)
downloadshflags-30a53b24f9f583a28f41dda8d4c16d4a1becd943.tar.gz
Additional work on dealing with race condition.
Diffstat (limited to 'examples')
-rwxr-xr-xexamples/write_date.sh39
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}\"."