Package: distcc Version: 3.1-3.1+b1 Severity: normal Tags: patch When 'ccache' is installed and zeroconf enabled, the following error messages appear in the log and the zeroconf service is not available: (read_string_from_popen) CRITICAL! Failed to read string from C compiler. (register_stuff) Warning: Failed to determine CC version, not registering DNS-SD service subtype! The reason for the failure is that 'ccache' installation recommends a symbolic link from 'cc' to 'ccache', and distcc (gcc-id.c) tries to determine the gcc version using the command 'cc -dumpversion'. When ccache starts it tries to create it's cache directory at 'HOME/.ccache' if it doesn't already exist. But the distcc HOME directory is '/' and since distcc is running under $USER 'distccd' the directory creation fails (Permission denied). Attached is a short C program modeled after the code from 'gcc-id.c' that demonstrates the failure if invoked with 'env HOME=/ ./popen' but succeeds when invoked from command line under a normal user. Also attached is a patch to issue '/usr/bin/cc -dumpversion' and '/usr/bin/cc -dumpmachine' so the real (g)cc will be called to spit out the version and machine type.
-- System Information: Debian Release: squeeze/sid APT prefers testing APT policy: (990, 'testing'), (500, 'unstable') Architecture: i386 (i686) Kernel: Linux 2.6.32-3-686 (SMP w/2 CPU cores) Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) (ignored: LC_ALL set to en_US.UTF-8) Shell: /bin/sh linked to /bin/dash Versions of packages distcc depends on: ii adduser 3.112 add and remove users and groups ii debconf [debconf-2.0] 1.5.35 Debian configuration management sy ii libavahi-client3 0.6.27-2 Avahi client library ii libavahi-common3 0.6.27-2 Avahi common library ii libc6 2.11.2-2 Embedded GNU C Library: Shared lib ii libpopt0 1.16-1 lib for parsing cmdline parameters ii lsb-base 3.2-23.1 Linux Standard Base 3.2 init scrip ii netbase 4.42 Basic TCP/IP networking system distcc recommends no packages. Versions of packages distcc suggests: ii ccache 3.0.1-1 Compiler cache for fast recompilat ii dbus 1.2.24-3 simple interprocess messaging syst pn distcc-pump <none> (no description available) ii distccmon-gnome 3.1-3.1+b1 GTK+ monitor for distcc a distribu -- Configuration Files: /etc/init.d/distcc changed: PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin DAEMON=/usr/local/bin/distccd NAME=distccd DESC="Distributed Compiler Daemon" DAEMON_ARGS="--pid-file=/var/run/$NAME.pid --log-file=/var/log/$NAME.log --stats --daemon --verbose" ALLOWEDNETS="" LISTENER="" NICE="" ZEROCONF="" JOBS="" set -e . /lib/lsb/init-functions [ -r /etc/default/distcc ] && . /etc/default/distcc test -x $DAEMON || exit 0 for net in $ALLOWEDNETS do ALLOW="$ALLOW --allow $net" done . /usr/local/etc/distcc_allowed_hosts for hostname in $ALLOWEDHOSTS; do ALLOW="$ALLOW --allow $(host $hostname | awk '{ print $4 }')" done if test -n "$ALLOW"; then DAEMON_ARGS="$DAEMON_ARGS $ALLOW" fi if test -n "$LISTENER"; then DAEMON_ARGS="$DAEMON_ARGS --listen $LISTENER" fi if test -n "$NICE"; then if [ "$NICE" -gt 0 ] && [ "$NICE" -le 20 ]; then DAEMON_ARGS="$DAEMON_ARGS --nice $NICE" fi fi if test -n "$JOBS"; then DAEMON_ARGS="$DAEMON_ARGS --jobs $JOBS" fi if [ "$ZEROCONF" = "true" ] || [ "$ZEROCONF" = "YES" ]; then DAEMON_ARGS="$DAEMON_ARGS --zeroconf" fi should_start() { if [ "$STARTDISTCC" != "true" ] && [ "$STARTDISTCC" != "YES" ]; then log_warning_msg "STARTDISTCC is set to false in /etc/default/distcc" log_warning_msg "$DAEMON not starting" exit 0 fi # we need permission to write to the pid file touch /var/run/$NAME.pid chown distccd /var/run/$NAME.pid } case "$1" in start) should_start log_begin_msg "Starting $DESC: $NAME" start-stop-daemon --start --quiet --pidfile /var/run/$NAME.pid \ --chuid distccd \ --exec $DAEMON -- $DAEMON_ARGS || { code=$? log_warning_msg "$0: start failed with error code $code" >&2 log_end_msg $code exit $code } log_end_msg 0 ;; stop) log_begin_msg "Stopping $DESC: $NAME" start-stop-daemon --stop --quiet --pidfile /var/run/$NAME.pid \ --oknodo \ --exec $DAEMON || { code=$? log_warning_msg "$0: stop failed with error code $code" >&2 log_end_msg $code exit $code } rm -f /var/run/$NAME.pid >/dev/null 2>&1 log_end_msg 0 ;; restart|force-reload) # # If the "reload" option is implemented, move the "force-reload" # option to the "reload" entry above. If not, "force-reload" is # just the same as "restart". # log_begin_msg "Restarting $DESC: $NAME" start-stop-daemon --stop --quiet --pidfile /var/run/$NAME.pid \ --oknodo \ --exec $DAEMON sleep 1 should_start start-stop-daemon --start --quiet --pidfile /var/run/$NAME.pid \ --chuid distccd \ --exec $DAEMON -- $DAEMON_ARGS || { code=$? rm -f /var/run/$NAME.pid >/dev/null 2>&1 log_warning_msg "$0: restart failed with error code $code" >&2 log_end_msg $code exit $code } log_end_msg 0 ;; status) status_of_proc $DAEMON $NAME ;; *) N=/etc/init.d/$NAME echo "Usage: $N {start|stop|restart|force-reload|status}" >&2 exit 1 ;; esac exit 0 -- debconf information: distcc/daemon-listen: 192.168.2.45 distcc/daemon-jobs: distcc/daemon-allow: 192.168.2.0/24 127.0.0.0/8 distcc/daemon: true distcc/daemon-zeroconf: true distcc/daemon-nice: 10
#include <stdio.h> #include <errno.h> #include <stdlib.h> main(void) { FILE *p = NULL; char s[54]; //char *ret; char *cmdline="cc -dumpversion"; if (!(p = popen(cmdline, "r"))) { printf("popen failed: %s\n", errno ? strerror(errno) : "failure"); goto fail; } if (!fgets(s, (int) 53, p)) { printf("Failed to read string from C compiler.\n"); goto fail; } printf("gcc version = %s\n", s); fail: if (p) pclose(p); }
--- gcc-id-dist.c 2010-09-08 12:42:24.000000000 -0400 +++ gcc-id.c 2010-09-07 18:39:57.000000000 -0400 @@ -79,11 +79,11 @@ } char* dcc_get_gcc_version(char *s, size_t nbytes) { - return read_string_from_popen("cc -dumpversion", s, nbytes); + return read_string_from_popen("/usr/bin/cc -dumpversion", s, nbytes); } char* dcc_get_gcc_machine(char *s, size_t nbytes) { - return read_string_from_popen("cc -dumpmachine", s, nbytes); + return read_string_from_popen("/usr/bin/cc -dumpmachine", s, nbytes); } char* dcc_make_dnssd_subtype(char *stype, size_t nbytes, const char *v, const char *m) {