diff options
Diffstat (limited to 'portage_with_autodep/bin/helper-functions.sh')
-rwxr-xr-x | portage_with_autodep/bin/helper-functions.sh | 67 |
1 files changed, 51 insertions, 16 deletions
diff --git a/portage_with_autodep/bin/helper-functions.sh b/portage_with_autodep/bin/helper-functions.sh index afe14af..b9bc74a 100755 --- a/portage_with_autodep/bin/helper-functions.sh +++ b/portage_with_autodep/bin/helper-functions.sh @@ -10,42 +10,45 @@ source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh # # API functions for doing parallel processing # -numjobs() { +makeopts_jobs() { # Copied from eutils.eclass:makeopts_jobs() local jobs=$(echo " ${MAKEOPTS} " | \ sed -r -n 's:.*[[:space:]](-j|--jobs[=[:space:]])[[:space:]]*([0-9]+).*:\2:p') echo ${jobs:-1} } -multijob_init() { +__multijob_init() { # Setup a pipe for children to write their pids to when they finish. - mj_control_pipe=$(mktemp -t multijob.XXXXXX) - rm "${mj_control_pipe}" - mkfifo "${mj_control_pipe}" - exec {mj_control_fd}<>${mj_control_pipe} - rm -f "${mj_control_pipe}" + # We have to allocate two fd's because POSIX has undefined behavior + # when you open a FIFO for simultaneous read/write. #487056 + local pipe=$(mktemp -t multijob.XXXXXX) + rm -f "${pipe}" + mkfifo -m 600 "${pipe}" + __redirect_alloc_fd mj_write_fd "${pipe}" + __redirect_alloc_fd mj_read_fd "${pipe}" + rm -f "${pipe}" # See how many children we can fork based on the user's settings. - mj_max_jobs=$(numjobs) + mj_max_jobs=$(makeopts_jobs "$@") mj_num_jobs=0 } -multijob_child_init() { - trap 'echo ${BASHPID} $? >&'${mj_control_fd} EXIT +__multijob_child_init() { + trap 'echo ${BASHPID:-$(__bashpid)} $? >&'${mj_write_fd} EXIT trap 'exit 1' INT TERM } -multijob_finish_one() { +__multijob_finish_one() { local pid ret - read -r -u ${mj_control_fd} pid ret + read -r -u ${mj_read_fd} pid ret : $(( --mj_num_jobs )) return ${ret} } -multijob_finish() { +__multijob_finish() { local ret=0 while [[ ${mj_num_jobs} -gt 0 ]] ; do - multijob_finish_one + __multijob_finish_one : $(( ret |= $? )) done # Let bash clean up its internal child tracking state. @@ -53,10 +56,42 @@ multijob_finish() { return ${ret} } -multijob_post_fork() { +__multijob_post_fork() { : $(( ++mj_num_jobs )) if [[ ${mj_num_jobs} -ge ${mj_max_jobs} ]] ; then - multijob_finish_one + __multijob_finish_one fi return $? } + +# @FUNCTION: __redirect_alloc_fd +# @USAGE: <var> <file> [redirection] +# @DESCRIPTION: +# Find a free fd and redirect the specified file via it. Store the new +# fd in the specified variable. Useful for the cases where we don't care +# about the exact fd #. +__redirect_alloc_fd() { + local var=$1 file=$2 redir=${3:-"<>"} + + if [[ $(( (BASH_VERSINFO[0] << 8) + BASH_VERSINFO[1] )) -ge $(( (4 << 8) + 1 )) ]] ; then + # Newer bash provides this functionality. + eval "exec {${var}}${redir}'${file}'" + else + # Need to provide the functionality ourselves. + local fd=10 + local fddir=/dev/fd + # Prefer /proc/self/fd if available (/dev/fd + # doesn't work on solaris, see bug #474536). + [[ -d /proc/self/fd ]] && fddir=/proc/self/fd + while :; do + # Make sure the fd isn't open. It could be a char device, + # or a symlink (possibly broken) to something else. + if [[ ! -e ${fddir}/${fd} ]] && [[ ! -L ${fddir}/${fd} ]] ; then + eval "exec ${fd}${redir}'${file}'" && break + fi + [[ ${fd} -gt 1024 ]] && die 'could not locate a free temp fd !?' + : $(( ++fd )) + done + : $(( ${var} = fd )) + fi +} |