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) {