I attached a possible fix for this. It will timeout if avahi-browse
doesn't respond in 250 miliseconds. This seems reasonable; if the answer
takes longer than that it's not useful for interactive use. This will
still work for people who care about avahi.

This seems more like a big in avahi or avahi's configuration in debian,
but I don't really care about why avahi takes a long time to answer. I
believe it's reasonable for bash-completion to include workarounds for
bugs in other programs. It's useful for the shell to work reliably even
if the system is otherwise misconfigured.

It seems that bash-completion debian bug mail also goes to the
bash-completion-devel upstream list. Patch is against latest upstream,
any feedback is welcome.

I had to mangle +o posix to get tests to pass. I don't know why the test
suite puts the shell into posix mode anyway.
diff --git a/CHANGES b/CHANGES
index 3845158..19a7696 100644
--- a/CHANGES
+++ b/CHANGES
@@ -78,6 +78,7 @@ bash-completion (2.x)
     Make it possible to run tests from any directory.
   * Add a --debug-xtrace option to test/run using BASH_XTRACEFD from bash-4.1.
   * Add a --timeout option to test/run to override the default expect timeout.
+  * Timeout when reading avahi-browse output to avoid hangs (Debian #551780).
 
   [ Raphaƫl Droz ]
   * Add xsltproc completion (Alioth: #311843).
diff --git a/bash_completion b/bash_completion
index 41197ac..f030847 100644
--- a/bash_completion
+++ b/bash_completion
@@ -1564,15 +1564,47 @@ _known_hosts_real()
     fi
 
     # Add hosts reported by avahi-browse, if it's available.
-    # The original call to avahi-browse also had "-k", to avoid lookups into
-    # avahi's services DB. We don't need the name of the service, and if it
-    # contains ";", it may mistify the result. But on Gentoo (at least),
-    # -k isn't available (even if mentioned in the manpage), so...
     if type avahi-browse >&/dev/null; then
-        COMPREPLY=( "${comprep...@]}" $( \
-            compgen -P "$prefix$user" -S "$suffix" -W \
-            "$( avahi-browse -cpr _workstation._tcp 2>/dev/null | \
-                 awk -F';' '/^=/ { print $7 }' | sort -u )" -- "$cur" ) )
+        # Process substitution is not available when set -o posix.
+        local posix_on=$(set -o | awk '/^posix/ { print $2 }')
+
+        set +o posix
+        # Sometimes avahi can take a long time to respond.
+        # If we don't get a response quickly just kill it and move on.
+        #
+        # The original call to avahi-browse also had "-k", to avoid lookups into
+        # avahi's services DB. We don't need the name of the service, and if it
+        # contains ";", it may mistify the result. But on Gentoo (at least),
+        # -k isn't available (even if mentioned in the manpage), so...
+        local avahi_fd=<(
+            echo $BASHPID
+            avahi-browse -cpr _workstation._tcp 2>/dev/null | \
+                    awk -F';' '/^=/ { print $7 }' | sort -u
+        )
+
+        # Read the pid of the avahi pipe.
+        # The processes will die on their own anyway but we don't want to leak
+        # one process every time the users tabs after "ssh "
+        local avahi_pid
+        read avahi_pid < $avahi_fd
+
+        local -a avahi_reply
+        while true; do
+            # Read with a timeout of 250 miliseconds
+            local read_reply read_ret
+            read -t 0.250 read_reply < $avahi_fd
+            read_ret=$?
+            [[ $read_ret -gt 128 ]] && kill $avahi_pid
+            [[ $read_ret -ne 0 ]] && break
+            #echo "Found avahi host $read_reply"
+            avahi_reply+=("$read_reply")
+        done
+
+        [[ $posix_on = 'on' ]] && set -o posix
+
+        COMPREPLY=( "${comprep...@]}"
+            $( compgen -P "$prefix$user" -S "$suffix" \
+                -W "${avahi_reply[*]}" -- "$cur" ) )
     fi
 
     # Add results of normal hostname completion, unless
_______________________________________________
Bash-completion-devel mailing list
Bash-completion-devel@lists.alioth.debian.org
http://lists.alioth.debian.org/mailman/listinfo/bash-completion-devel

Reply via email to