@@ -15,25 +15,96 @@ _STUB_RESULT="${PROGRAM}_STUB_RESULT"
1515_STUB_END=" ${PROGRAM} _STUB_END"
1616_STUB_LOG=" ${PROGRAM} _STUB_LOG"
1717
18+
19+ STUB_LOCKFILE=" ${TMPDIR} /${program} -stub.lock"
20+
21+ release_lock () {
22+ rm -f " $STUB_LOCKFILE "
23+ trap - EXIT
24+ }
25+
26+ acquire_lock () {
27+ local start=$SECONDS
28+ local acquire_timeout=60
29+ local acquired=
30+ while (( SECONDS <= start + $acquire_timeout )) ; do
31+
32+ set -o noclobber
33+ echo -n > " $STUB_LOCKFILE " 2> /dev/null && acquired=1
34+ set +o noclobber
35+
36+ if [[ -n $acquired ]]; then
37+ trap release_lock EXIT
38+ break
39+ else
40+ # POSIX sleep(1) doesn't provide subsecond precision, but many others do
41+ sleep 0.1 2> /dev/null || sleep 1
42+ fi
43+ done
44+ if [[ -z $acquired ]]; then
45+ echo " $0 : error: could not acquire stub lock in ${acquire_timeout} seconds" >&2
46+ exit 2
47+ done
48+ )
49+
50+ acquire_lock
51+
1852[ -n " ${! _STUB_LOG} " ] || eval " ${_STUB_LOG} " =" ${TMPDIR} /${program} -stub-log"
53+
1954if test -z " ${! _STUB_END} " ; then echo " $program " " $@ " >> " ${! _STUB_LOG} " ; fi
2055
2156[ -e " ${! _STUB_PLAN} " ] || exit 1
2257[ -n " ${! _STUB_RUN} " ] || eval " ${_STUB_RUN} " =" ${TMPDIR} /${program} -stub-run"
2358
2459
2560# Initialize or load the stub run information.
61+ read_runfile () {
62+ if test -e " ${! _STUB_RUN} " ; then source " ${! _STUB_RUN} " ; fi
63+ }
64+ write_runfile () {
65+ {
66+ echo " ${_STUB_INDEX} =${! _STUB_INDEX} "
67+ echo " ${_STUB_RESULT} =${! _STUB_RESULT} "
68+ } > " ${! _STUB_RUN} "
69+ }
70+ update_runfile_index () {
71+ ( eval " ${_STUB_INDEX} =$(( ${! _STUB_INDEX} + 1 )) "
72+ write_runfile
73+ )
74+ }
75+ update_runfile_result () {
76+ (
77+ old_result=" ${! _STUB_RESULT} "
78+ read_runfile
79+ new_result = $(( $old_result | ${! _STUB_RESULT} ))
80+ eval " ${_STUB_RESULT} =\$ new_result"
81+ write_runfile
82+ )
83+ }
84+
2685eval " ${_STUB_INDEX} " =1
2786eval " ${_STUB_RESULT} " =0
28- if test -e " ${! _STUB_RUN} " ; then source " ${! _STUB_RUN} " ; fi
29-
30-
31- # Loop over each line in the plan.
32- index=0
33- while IFS= read -r line; do
34- index=$(( $index + 1 ))
35-
36- if [ -z " ${! _STUB_END} " ] && [ $index -eq " ${! _STUB_INDEX} " ]; then
87+ read_runfile
88+
89+ # !_STUB_END is set externally to trigger verification mode for `unstub'
90+ # Execution mode
91+ if [ -z " ${! _STUB_END} " ]; then
92+
93+ update_runfile_index
94+ # Release the lock while the payload is run to allow another `stub'
95+ # of the same program to run concurrently (e.g. in a pipeline).
96+ # The plan file is supposed to be finalized before stubs are run
97+ # so no need to hold the lock while reading it.
98+ release_lock
99+
100+ # Loop over each line in the plan.
101+ index=0
102+ while IFS= read -r line; do
103+ index=$(( $index + 1 ))
104+ if [ $index -ne " ${! _STUB_INDEX} " ]; then
105+ continue ;
106+ fi
107+
37108 # We found the plan line we're interested in.
38109 # Start off by assuming success.
39110 result=0
@@ -76,14 +147,34 @@ while IFS= read -r line; do
76147 else
77148 eval " ${_STUB_RESULT} " =1
78149 fi
150+
151+ break
152+ done < " ${! _STUB_PLAN} "
153+
154+ # If the requested index is larger than the number
155+ # of lines in the plan file, we failed.
156+ if [ " ${! _STUB_INDEX} " -gt $index ]; then
157+ eval " ${_STUB_RESULT} " =1
79158 fi
80- done < " ${! _STUB_PLAN} "
81159
160+ # Write out the run information.
161+ acquire_lock
162+ update_runfile_result
163+ release_lock
164+
165+ exit " $status "
82166
167+ fi
168+
169+ # Verification mode (`unstub')
83170if [ -n " ${! _STUB_END} " ]; then
171+
172+ # `unstub' is supposed to run after any stubs are finished
173+ release_lock
174+
84175 # If the number of lines in the plan is larger than
85176 # the requested index, we failed.
86- if [ $index -ge " ${! _STUB_INDEX} " ]; then
177+ if [ " $( wc -l " ${ ! _STUB_PLAN} " ) " -ge " ${! _STUB_INDEX} " ]; then
87178 eval " ${_STUB_RESULT} " =1
88179 fi
89180 if [ " ${! _STUB_RESULT} " -ne 0 ]; then
@@ -102,18 +193,4 @@ if [ -n "${!_STUB_END}" ]; then
102193 # Return the result.
103194 exit " ${! _STUB_RESULT} "
104195
105- else
106- # If the requested index is larger than the number
107- # of lines in the plan file, we failed.
108- if [ " ${! _STUB_INDEX} " -gt $index ]; then
109- eval " ${_STUB_RESULT} " =1
110- fi
111-
112- # Write out the run information.
113- { echo " ${_STUB_INDEX} =$(( ${! _STUB_INDEX} + 1 )) "
114- echo " ${_STUB_RESULT} =${! _STUB_RESULT} "
115- } > " ${! _STUB_RUN} "
116-
117- exit " $status "
118-
119196fi
0 commit comments