diff options
| -rw-r--r-- | meta/recipes-devtools/distcc/distcc_3.1.bb (renamed from meta/recipes-devtools/distcc/distcc_2.18.3.bb) | 19 | ||||
| -rw-r--r-- | meta/recipes-devtools/distcc/files/distcc-avahi.patch | 1738 | ||||
| -rw-r--r-- | meta/recipes-devtools/distcc/files/makefile-param-order.patch | 20 |
3 files changed, 9 insertions, 1768 deletions
diff --git a/meta/recipes-devtools/distcc/distcc_2.18.3.bb b/meta/recipes-devtools/distcc/distcc_3.1.bb index bd2af4a1b5..eeda054c74 100644 --- a/meta/recipes-devtools/distcc/distcc_2.18.3.bb +++ b/meta/recipes-devtools/distcc/distcc_3.1.bb | |||
| @@ -4,7 +4,7 @@ compilation of C/C++/ObjC code across machines on a network." | |||
| 4 | SECTION = "devel" | 4 | SECTION = "devel" |
| 5 | LICENSE = "GPLv2" | 5 | LICENSE = "GPLv2" |
| 6 | LIC_FILES_CHKSUM = "file://COPYING;md5=94d55d512a9ba36caa9b7df079bae19f" | 6 | LIC_FILES_CHKSUM = "file://COPYING;md5=94d55d512a9ba36caa9b7df079bae19f" |
| 7 | PR = "r9" | 7 | PR = "r0" |
| 8 | 8 | ||
| 9 | DEPENDS = "avahi" | 9 | DEPENDS = "avahi" |
| 10 | 10 | ||
| @@ -16,20 +16,18 @@ PACKAGECONFIG[gtk] = "--with-gtk,--without-gtk --without-gnome,gtk+" | |||
| 16 | 16 | ||
| 17 | RRECOMMENDS_${PN} = "avahi-daemon" | 17 | RRECOMMENDS_${PN} = "avahi-daemon" |
| 18 | 18 | ||
| 19 | # Upstream change this patch periodically so store locally | ||
| 20 | # http://0pointer.de/public/distcc-avahi.patch | ||
| 21 | SRC_URI = "http://distcc.googlecode.com/files/${BPN}-${PV}.tar.bz2 \ | 19 | SRC_URI = "http://distcc.googlecode.com/files/${BPN}-${PV}.tar.bz2 \ |
| 22 | file://distcc-avahi.patch \ | 20 | file://default \ |
| 23 | file://makefile-param-order.patch \ | 21 | file://distccmon-gnome.desktop \ |
| 24 | file://default \ | 22 | file://distcc" |
| 25 | file://distccmon-gnome.desktop \ | ||
| 26 | file://distcc" | ||
| 27 | 23 | ||
| 28 | SRC_URI[md5sum] = "0d6b80a1efc3a3d816c4f4175f63eaa2" | 24 | SRC_URI[md5sum] = "a1a9d3853df7133669fffec2a9aab9f3" |
| 29 | SRC_URI[sha256sum] = "6500f1bc2a30b1f044ebed79c6ce15457d1712263e65f0db7d6046af262ba434" | 25 | SRC_URI[sha256sum] = "f55dbafd76bed3ce57e1bbcdab1329227808890d90f4c724fcd2d53f934ddd89" |
| 30 | 26 | ||
| 31 | inherit autotools pkgconfig update-rc.d useradd | 27 | inherit autotools pkgconfig update-rc.d useradd |
| 32 | 28 | ||
| 29 | EXTRA_OECONF += "--disable-Werror PYTHON=/dev/null" | ||
| 30 | |||
| 33 | USERADD_PACKAGES = "${PN}" | 31 | USERADD_PACKAGES = "${PN}" |
| 34 | USERADD_PARAM_${PN} = "--system \ | 32 | USERADD_PARAM_${PN} = "--system \ |
| 35 | --home /dev/null \ | 33 | --home /dev/null \ |
| @@ -55,6 +53,7 @@ PACKAGES += "distcc-distmon-gnome" | |||
| 55 | 53 | ||
| 56 | FILES_${PN} = " ${sysconfdir} \ | 54 | FILES_${PN} = " ${sysconfdir} \ |
| 57 | ${bindir}/distcc \ | 55 | ${bindir}/distcc \ |
| 56 | ${bindir}/lsdistcc \ | ||
| 58 | ${bindir}/distccd \ | 57 | ${bindir}/distccd \ |
| 59 | ${bindir}/distccmon-text" | 58 | ${bindir}/distccmon-text" |
| 60 | FILES_distcc-distmon-gnome = " ${bindir}/distccmon-gnome \ | 59 | FILES_distcc-distmon-gnome = " ${bindir}/distccmon-gnome \ |
diff --git a/meta/recipes-devtools/distcc/files/distcc-avahi.patch b/meta/recipes-devtools/distcc/files/distcc-avahi.patch deleted file mode 100644 index 1f15d4b82a..0000000000 --- a/meta/recipes-devtools/distcc/files/distcc-avahi.patch +++ /dev/null | |||
| @@ -1,1738 +0,0 @@ | |||
| 1 | Upstream-Status: Pending | ||
| 2 | |||
| 3 | --- upstream/aclocal.m4 1970-01-01 01:00:00.000000000 +0100 | ||
| 4 | +++ lennart/aclocal.m4 2005-11-18 04:19:18.000000000 +0100 | ||
| 5 | @@ -0,0 +1,171 @@ | ||
| 6 | +# generated automatically by aclocal 1.9.6 -*- Autoconf -*- | ||
| 7 | + | ||
| 8 | +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, | ||
| 9 | +# 2005 Free Software Foundation, Inc. | ||
| 10 | +# This file is free software; the Free Software Foundation | ||
| 11 | +# gives unlimited permission to copy and/or distribute it, | ||
| 12 | +# with or without modifications, as long as this notice is preserved. | ||
| 13 | + | ||
| 14 | +# This program is distributed in the hope that it will be useful, | ||
| 15 | +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without | ||
| 16 | +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A | ||
| 17 | +# PARTICULAR PURPOSE. | ||
| 18 | + | ||
| 19 | +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- | ||
| 20 | +# | ||
| 21 | +# Copyright © 2004 Scott James Remnant <scott@netsplit.com>. | ||
| 22 | +# | ||
| 23 | +# This program is free software; you can redistribute it and/or modify | ||
| 24 | +# it under the terms of the GNU General Public License as published by | ||
| 25 | +# the Free Software Foundation; either version 2 of the License, or | ||
| 26 | +# (at your option) any later version. | ||
| 27 | +# | ||
| 28 | +# This program is distributed in the hope that it will be useful, but | ||
| 29 | +# WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 30 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 31 | +# General Public License for more details. | ||
| 32 | +# | ||
| 33 | +# You should have received a copy of the GNU General Public License | ||
| 34 | +# along with this program; if not, write to the Free Software | ||
| 35 | +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 36 | +# | ||
| 37 | +# As a special exception to the GNU General Public License, if you | ||
| 38 | +# distribute this file as part of a program that contains a | ||
| 39 | +# configuration script generated by Autoconf, you may include it under | ||
| 40 | +# the same distribution terms that you use for the rest of that program. | ||
| 41 | + | ||
| 42 | +# PKG_PROG_PKG_CONFIG([MIN-VERSION]) | ||
| 43 | +# ---------------------------------- | ||
| 44 | +AC_DEFUN([PKG_PROG_PKG_CONFIG], | ||
| 45 | +[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) | ||
| 46 | +m4_pattern_allow([^PKG_CONFIG(_PATH)?$]) | ||
| 47 | +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl | ||
| 48 | +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then | ||
| 49 | + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) | ||
| 50 | +fi | ||
| 51 | +if test -n "$PKG_CONFIG"; then | ||
| 52 | + _pkg_min_version=m4_default([$1], [0.9.0]) | ||
| 53 | + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) | ||
| 54 | + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then | ||
| 55 | + AC_MSG_RESULT([yes]) | ||
| 56 | + else | ||
| 57 | + AC_MSG_RESULT([no]) | ||
| 58 | + PKG_CONFIG="" | ||
| 59 | + fi | ||
| 60 | + | ||
| 61 | +fi[]dnl | ||
| 62 | +])# PKG_PROG_PKG_CONFIG | ||
| 63 | + | ||
| 64 | +# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) | ||
| 65 | +# | ||
| 66 | +# Check to see whether a particular set of modules exists. Similar | ||
| 67 | +# to PKG_CHECK_MODULES(), but does not set variables or print errors. | ||
| 68 | +# | ||
| 69 | +# | ||
| 70 | +# Similar to PKG_CHECK_MODULES, make sure that the first instance of | ||
| 71 | +# this or PKG_CHECK_MODULES is called, or make sure to call | ||
| 72 | +# PKG_CHECK_EXISTS manually | ||
| 73 | +# -------------------------------------------------------------- | ||
| 74 | +AC_DEFUN([PKG_CHECK_EXISTS], | ||
| 75 | +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl | ||
| 76 | +if test -n "$PKG_CONFIG" && \ | ||
| 77 | + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then | ||
| 78 | + m4_ifval([$2], [$2], [:]) | ||
| 79 | +m4_ifvaln([$3], [else | ||
| 80 | + $3])dnl | ||
| 81 | +fi]) | ||
| 82 | + | ||
| 83 | + | ||
| 84 | +# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) | ||
| 85 | +# --------------------------------------------- | ||
| 86 | +m4_define([_PKG_CONFIG], | ||
| 87 | +[if test -n "$PKG_CONFIG"; then | ||
| 88 | + if test -n "$$1"; then | ||
| 89 | + pkg_cv_[]$1="$$1" | ||
| 90 | + else | ||
| 91 | + PKG_CHECK_EXISTS([$3], | ||
| 92 | + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`], | ||
| 93 | + [pkg_failed=yes]) | ||
| 94 | + fi | ||
| 95 | +else | ||
| 96 | + pkg_failed=untried | ||
| 97 | +fi[]dnl | ||
| 98 | +])# _PKG_CONFIG | ||
| 99 | + | ||
| 100 | +# _PKG_SHORT_ERRORS_SUPPORTED | ||
| 101 | +# ----------------------------- | ||
| 102 | +AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], | ||
| 103 | +[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) | ||
| 104 | +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then | ||
| 105 | + _pkg_short_errors_supported=yes | ||
| 106 | +else | ||
| 107 | + _pkg_short_errors_supported=no | ||
| 108 | +fi[]dnl | ||
| 109 | +])# _PKG_SHORT_ERRORS_SUPPORTED | ||
| 110 | + | ||
| 111 | + | ||
| 112 | +# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], | ||
| 113 | +# [ACTION-IF-NOT-FOUND]) | ||
| 114 | +# | ||
| 115 | +# | ||
| 116 | +# Note that if there is a possibility the first call to | ||
| 117 | +# PKG_CHECK_MODULES might not happen, you should be sure to include an | ||
| 118 | +# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac | ||
| 119 | +# | ||
| 120 | +# | ||
| 121 | +# -------------------------------------------------------------- | ||
| 122 | +AC_DEFUN([PKG_CHECK_MODULES], | ||
| 123 | +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl | ||
| 124 | +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl | ||
| 125 | +AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl | ||
| 126 | + | ||
| 127 | +pkg_failed=no | ||
| 128 | +AC_MSG_CHECKING([for $1]) | ||
| 129 | + | ||
| 130 | +_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) | ||
| 131 | +_PKG_CONFIG([$1][_LIBS], [libs], [$2]) | ||
| 132 | + | ||
| 133 | +m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS | ||
| 134 | +and $1[]_LIBS to avoid the need to call pkg-config. | ||
| 135 | +See the pkg-config man page for more details.]) | ||
| 136 | + | ||
| 137 | +if test $pkg_failed = yes; then | ||
| 138 | + _PKG_SHORT_ERRORS_SUPPORTED | ||
| 139 | + if test $_pkg_short_errors_supported = yes; then | ||
| 140 | + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "$2"` | ||
| 141 | + else | ||
| 142 | + $1[]_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"` | ||
| 143 | + fi | ||
| 144 | + # Put the nasty error message in config.log where it belongs | ||
| 145 | + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD | ||
| 146 | + | ||
| 147 | + ifelse([$4], , [AC_MSG_ERROR(dnl | ||
| 148 | +[Package requirements ($2) were not met: | ||
| 149 | + | ||
| 150 | +$$1_PKG_ERRORS | ||
| 151 | + | ||
| 152 | +Consider adjusting the PKG_CONFIG_PATH environment variable if you | ||
| 153 | +installed software in a non-standard prefix. | ||
| 154 | + | ||
| 155 | +_PKG_TEXT | ||
| 156 | +])], | ||
| 157 | + [$4]) | ||
| 158 | +elif test $pkg_failed = untried; then | ||
| 159 | + ifelse([$4], , [AC_MSG_FAILURE(dnl | ||
| 160 | +[The pkg-config script could not be found or is too old. Make sure it | ||
| 161 | +is in your PATH or set the PKG_CONFIG environment variable to the full | ||
| 162 | +path to pkg-config. | ||
| 163 | + | ||
| 164 | +_PKG_TEXT | ||
| 165 | + | ||
| 166 | +To get pkg-config, see <http://www.freedesktop.org/software/pkgconfig>.])], | ||
| 167 | + [$4]) | ||
| 168 | +else | ||
| 169 | + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS | ||
| 170 | + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS | ||
| 171 | + AC_MSG_RESULT([yes]) | ||
| 172 | + ifelse([$3], , :, [$3]) | ||
| 173 | +fi[]dnl | ||
| 174 | +])# PKG_CHECK_MODULES | ||
| 175 | + | ||
| 176 | +m4_include([acinclude.m4]) | ||
| 177 | --- upstream/Makefile.in 2005-11-18 16:15:40.000000000 +0100 | ||
| 178 | +++ lennart/Makefile.in 2005-11-18 01:14:43.000000000 +0100 | ||
| 179 | @@ -171,6 +171,7 @@ | ||
| 180 | src/ssh.o src/state.o src/strip.o \ | ||
| 181 | src/timefile.o src/traceenv.o \ | ||
| 182 | src/where.o \ | ||
| 183 | + @ZEROCONF_DISTCC_OBJS@ \ | ||
| 184 | $(common_obj) | ||
| 185 | |||
| 186 | distccd_obj = src/access.o \ | ||
| 187 | @@ -178,6 +179,7 @@ | ||
| 188 | src/ncpus.o \ | ||
| 189 | src/prefork.o \ | ||
| 190 | src/serve.o src/setuid.o src/srvnet.o src/srvrpc.o src/state.o \ | ||
| 191 | + @ZEROCONF_DISTCCD_OBJS@ \ | ||
| 192 | $(common_obj) @BUILD_POPT@ | ||
| 193 | |||
| 194 | # Objects that need to be linked in to build monitors | ||
| 195 | --- upstream/src/distcc.c 2005-11-18 16:15:40.000000000 +0100 | ||
| 196 | +++ lennart/src/distcc.c 2005-11-18 01:14:43.000000000 +0100 | ||
| 197 | @@ -83,6 +83,9 @@ | ||
| 198 | " COMPILER defaults to \"cc\"\n" | ||
| 199 | " --help explain usage and exit\n" | ||
| 200 | " --version show version and exit\n" | ||
| 201 | +" --show-hosts show host list and exit\n" | ||
| 202 | +" -j calculate the concurrency level from\n" | ||
| 203 | +" the host list.\n" | ||
| 204 | "\n" | ||
| 205 | "Environment variables:\n" | ||
| 206 | " See the manual page for a complete list.\n" | ||
| 207 | @@ -135,7 +138,46 @@ | ||
| 208 | signal(SIGHUP, &dcc_client_signalled); | ||
| 209 | } | ||
| 210 | |||
| 211 | +static void dcc_free_hostlist(struct dcc_hostdef *list) { | ||
| 212 | + while (list) { | ||
| 213 | + struct dcc_hostdef *l = list; | ||
| 214 | + list = list->next; | ||
| 215 | + dcc_free_hostdef(l); | ||
| 216 | + } | ||
| 217 | +} | ||
| 218 | + | ||
| 219 | +static void dcc_show_hosts(void) { | ||
| 220 | + struct dcc_hostdef *list, *l; | ||
| 221 | + int nhosts; | ||
| 222 | + | ||
| 223 | + if (dcc_get_hostlist(&list, &nhosts) != 0) { | ||
| 224 | + rs_log_crit("Failed to get host list"); | ||
| 225 | + return; | ||
| 226 | + } | ||
| 227 | + | ||
| 228 | + for (l = list; l; l = l->next) | ||
| 229 | + printf("%s\n", l->hostdef_string); | ||
| 230 | + | ||
| 231 | + dcc_free_hostlist(list); | ||
| 232 | +} | ||
| 233 | + | ||
| 234 | +static void dcc_concurrency_level(void) { | ||
| 235 | + struct dcc_hostdef *list, *l; | ||
| 236 | + int nhosts; | ||
| 237 | + int nslots = 0; | ||
| 238 | + | ||
| 239 | + if (dcc_get_hostlist(&list, &nhosts) != 0) { | ||
| 240 | + rs_log_crit("Failed to get host list"); | ||
| 241 | + return; | ||
| 242 | + } | ||
| 243 | + | ||
| 244 | + for (l = list; l; l = l->next) | ||
| 245 | + nslots += l->n_slots; | ||
| 246 | |||
| 247 | + dcc_free_hostlist(list); | ||
| 248 | + | ||
| 249 | + printf("%i\n", nslots); | ||
| 250 | +} | ||
| 251 | |||
| 252 | /** | ||
| 253 | * distcc client entry point. | ||
| 254 | @@ -182,6 +224,18 @@ | ||
| 255 | ret = 0; | ||
| 256 | goto out; | ||
| 257 | } | ||
| 258 | + | ||
| 259 | + if (!strcmp(argv[1], "--show-hosts")) { | ||
| 260 | + dcc_show_hosts(); | ||
| 261 | + ret = 0; | ||
| 262 | + goto out; | ||
| 263 | + } | ||
| 264 | + | ||
| 265 | + if (!strcmp(argv[1], "-j")) { | ||
| 266 | + dcc_concurrency_level(); | ||
| 267 | + ret = 0; | ||
| 268 | + goto out; | ||
| 269 | + } | ||
| 270 | |||
| 271 | dcc_find_compiler(argv, &compiler_args); | ||
| 272 | /* compiler_args is now respectively either "cc -c hello.c" or | ||
| 273 | --- upstream/src/distcc.h 2005-11-18 16:15:40.000000000 +0100 | ||
| 274 | +++ lennart/src/distcc.h 2005-11-18 01:14:43.000000000 +0100 | ||
| 275 | @@ -112,7 +112,7 @@ | ||
| 276 | int *ret_nhosts); | ||
| 277 | int dcc_parse_hosts(const char *where, const char *source_name, | ||
| 278 | struct dcc_hostdef **ret_list, | ||
| 279 | - int *ret_nhosts); | ||
| 280 | + int *ret_nhosts, struct dcc_hostdef **ret_prev); | ||
| 281 | |||
| 282 | /* ncpu.c */ | ||
| 283 | int dcc_ncpus(int *); | ||
| 284 | @@ -226,6 +226,7 @@ | ||
| 285 | int dcc_make_tmpnam(const char *, const char *suffix, char **); | ||
| 286 | |||
| 287 | int dcc_mkdir(const char *path) WARN_UNUSED; | ||
| 288 | +int dcc_get_subdir(const char *name, char **path_ret) WARN_UNUSED; | ||
| 289 | int dcc_get_lock_dir(char **path_ret) WARN_UNUSED; | ||
| 290 | int dcc_get_state_dir(char **path_ret) WARN_UNUSED; | ||
| 291 | int dcc_get_top_dir(char **path_ret) WARN_UNUSED; | ||
| 292 | --- upstream/src/dopt.c 2005-11-18 16:15:40.000000000 +0100 | ||
| 293 | +++ lennart/src/dopt.c 2005-11-18 04:14:26.000000000 +0100 | ||
| 294 | @@ -93,6 +93,10 @@ | ||
| 295 | opt_log_level | ||
| 296 | }; | ||
| 297 | |||
| 298 | +#ifdef HAVE_AVAHI | ||
| 299 | +/* Flag for enabling/disabling Zeroconf using Avahi */ | ||
| 300 | +int opt_zeroconf = 0; | ||
| 301 | +#endif | ||
| 302 | |||
| 303 | const struct poptOption options[] = { | ||
| 304 | { "allow", 'a', POPT_ARG_STRING, 0, 'a', 0, 0 }, | ||
| 305 | @@ -115,6 +119,9 @@ | ||
| 306 | { "verbose", 0, POPT_ARG_NONE, 0, 'v', 0, 0 }, | ||
| 307 | { "version", 0, POPT_ARG_NONE, 0, 'V', 0, 0 }, | ||
| 308 | { "wizard", 'W', POPT_ARG_NONE, 0, 'W', 0, 0 }, | ||
| 309 | +#ifdef HAVE_AVAHI | ||
| 310 | + { "zeroconf", 0, POPT_ARG_NONE, &opt_zeroconf, 0, 0, 0 }, | ||
| 311 | +#endif | ||
| 312 | { 0, 0, 0, 0, 0, 0, 0 } | ||
| 313 | }; | ||
| 314 | |||
| 315 | @@ -137,6 +144,9 @@ | ||
| 316 | " -p, --port PORT TCP port to listen on\n" | ||
| 317 | " --listen ADDRESS IP address to listen on\n" | ||
| 318 | " -a, --allow IP[/BITS] client address access control\n" | ||
| 319 | +#ifdef HAVE_AVAHI | ||
| 320 | +" --zeroconf register via mDNS/DNS-SD\n" | ||
| 321 | +#endif | ||
| 322 | " Debug and trace:\n" | ||
| 323 | " --log-level=LEVEL set detail level for log file\n" | ||
| 324 | " levels: critical, error, warning, notice, info, debug\n" | ||
| 325 | --- upstream/src/dopt.h 2005-11-18 16:15:40.000000000 +0100 | ||
| 326 | +++ lennart/src/dopt.h 2005-11-18 02:27:45.000000000 +0100 | ||
| 327 | @@ -38,3 +38,7 @@ | ||
| 328 | extern int opt_lifetime; | ||
| 329 | extern char *opt_listen_addr; | ||
| 330 | extern int opt_niceness; | ||
| 331 | + | ||
| 332 | +#ifdef HAVE_AVAHI | ||
| 333 | +extern int opt_zeroconf; | ||
| 334 | +#endif | ||
| 335 | --- upstream/src/dparent.c 2005-11-18 16:15:40.000000000 +0100 | ||
| 336 | +++ lennart/src/dparent.c 2005-11-18 04:13:23.000000000 +0100 | ||
| 337 | @@ -70,6 +70,7 @@ | ||
| 338 | #include "types.h" | ||
| 339 | #include "daemon.h" | ||
| 340 | #include "netutil.h" | ||
| 341 | +#include "zeroconf.h" | ||
| 342 | |||
| 343 | static void dcc_nofork_parent(int listen_fd) NORETURN; | ||
| 344 | static void dcc_detach(void); | ||
| 345 | @@ -94,6 +95,9 @@ | ||
| 346 | int listen_fd; | ||
| 347 | int n_cpus; | ||
| 348 | int ret; | ||
| 349 | +#ifdef HAVE_AVAHI | ||
| 350 | + void *avahi = NULL; | ||
| 351 | +#endif | ||
| 352 | |||
| 353 | if ((ret = dcc_socket_listen(arg_port, &listen_fd, opt_listen_addr)) != 0) | ||
| 354 | return ret; | ||
| 355 | @@ -131,6 +135,14 @@ | ||
| 356 | /* Don't catch signals until we've detached or created a process group. */ | ||
| 357 | dcc_daemon_catch_signals(); | ||
| 358 | |||
| 359 | +#ifdef HAVE_AVAHI | ||
| 360 | + /* Zeroconf registration */ | ||
| 361 | + if (opt_zeroconf) { | ||
| 362 | + if (!(avahi = dcc_zeroconf_register((uint16_t) arg_port, n_cpus))) | ||
| 363 | + return EXIT_CONNECT_FAILED; | ||
| 364 | + } | ||
| 365 | +#endif | ||
| 366 | + | ||
| 367 | /* This is called in the master daemon, whether that is detached or | ||
| 368 | * not. */ | ||
| 369 | dcc_master_pid = getpid(); | ||
| 370 | @@ -138,10 +150,21 @@ | ||
| 371 | if (opt_no_fork) { | ||
| 372 | dcc_log_daemon_started("non-forking daemon"); | ||
| 373 | dcc_nofork_parent(listen_fd); | ||
| 374 | + ret = 0; | ||
| 375 | } else { | ||
| 376 | dcc_log_daemon_started("preforking daemon"); | ||
| 377 | - return dcc_preforking_parent(listen_fd); | ||
| 378 | + ret = dcc_preforking_parent(listen_fd); | ||
| 379 | } | ||
| 380 | + | ||
| 381 | +#ifdef HAVE_AVAHI | ||
| 382 | + /* Remove zeroconf registration */ | ||
| 383 | + if (opt_zeroconf) { | ||
| 384 | + if (dcc_zeroconf_unregister(avahi) != 0) | ||
| 385 | + return EXIT_CONNECT_FAILED; | ||
| 386 | + } | ||
| 387 | +#endif | ||
| 388 | + | ||
| 389 | + return ret; | ||
| 390 | } | ||
| 391 | |||
| 392 | |||
| 393 | --- upstream/src/help.c 2005-11-18 16:15:40.000000000 +0100 | ||
| 394 | +++ lennart/src/help.c 2005-11-18 02:27:45.000000000 +0100 | ||
| 395 | @@ -62,6 +62,9 @@ | ||
| 396 | "distcc comes with ABSOLUTELY NO WARRANTY. distcc is free software, and\n" | ||
| 397 | "you may use, modify and redistribute it under the terms of the GNU \n" | ||
| 398 | "General Public License version 2 or later.\n" | ||
| 399 | +#ifdef HAVE_AVAHI | ||
| 400 | +"\nBuilt with Zeroconf support.\n" | ||
| 401 | +#endif | ||
| 402 | "\n" | ||
| 403 | , | ||
| 404 | prog, PACKAGE_VERSION, GNU_HOST, DISTCC_DEFAULT_PORT, | ||
| 405 | --- upstream/src/hostfile.c 2005-11-18 16:15:40.000000000 +0100 | ||
| 406 | +++ lennart/src/hostfile.c 2005-11-18 01:14:43.000000000 +0100 | ||
| 407 | @@ -59,7 +59,7 @@ | ||
| 408 | if ((ret = dcc_load_file_string(fname, &body)) != 0) | ||
| 409 | return ret; | ||
| 410 | |||
| 411 | - ret = dcc_parse_hosts(body, fname, ret_list, ret_nhosts); | ||
| 412 | + ret = dcc_parse_hosts(body, fname, ret_list, ret_nhosts, NULL); | ||
| 413 | |||
| 414 | free(body); | ||
| 415 | |||
| 416 | --- upstream/src/hosts.c 2005-11-18 16:15:40.000000000 +0100 | ||
| 417 | +++ lennart/src/hosts.c 2005-11-18 02:27:45.000000000 +0100 | ||
| 418 | @@ -96,6 +96,10 @@ | ||
| 419 | #include "hosts.h" | ||
| 420 | #include "exitcode.h" | ||
| 421 | #include "snprintf.h" | ||
| 422 | +#ifdef HAVE_AVAHI | ||
| 423 | +#include "zeroconf.h" | ||
| 424 | +#define ZEROCONF_MAGIC "+zeroconf" | ||
| 425 | +#endif | ||
| 426 | |||
| 427 | const int dcc_default_port = DISTCC_DEFAULT_PORT; | ||
| 428 | |||
| 429 | @@ -134,9 +138,12 @@ | ||
| 430 | char *path, *top; | ||
| 431 | int ret; | ||
| 432 | |||
| 433 | + *ret_list = NULL; | ||
| 434 | + *ret_nhosts = 0; | ||
| 435 | + | ||
| 436 | if ((env = getenv("DISTCC_HOSTS")) != NULL) { | ||
| 437 | rs_trace("read hosts from environment"); | ||
| 438 | - return dcc_parse_hosts(env, "$DISTCC_HOSTS", ret_list, ret_nhosts); | ||
| 439 | + return dcc_parse_hosts(env, "$DISTCC_HOSTS", ret_list, ret_nhosts, NULL); | ||
| 440 | } | ||
| 441 | |||
| 442 | /* $DISTCC_DIR or ~/.distcc */ | ||
| 443 | @@ -163,7 +170,7 @@ | ||
| 444 | rs_trace("not reading %s: %s", path, strerror(errno)); | ||
| 445 | free(path); | ||
| 446 | } | ||
| 447 | - | ||
| 448 | + | ||
| 449 | /* FIXME: Clearer message? */ | ||
| 450 | rs_log_warning("no hostlist is set; can't distribute work"); | ||
| 451 | |||
| 452 | @@ -346,17 +353,19 @@ | ||
| 453 | **/ | ||
| 454 | int dcc_parse_hosts(const char *where, const char *source_name, | ||
| 455 | struct dcc_hostdef **ret_list, | ||
| 456 | - int *ret_nhosts) | ||
| 457 | + int *ret_nhosts, struct dcc_hostdef **ret_prev) | ||
| 458 | { | ||
| 459 | int ret; | ||
| 460 | - struct dcc_hostdef *prev, *curr; | ||
| 461 | + struct dcc_hostdef *curr, *_prev; | ||
| 462 | + | ||
| 463 | + if (!ret_prev) { | ||
| 464 | + ret_prev = &_prev; | ||
| 465 | + _prev = NULL; | ||
| 466 | + } | ||
| 467 | |||
| 468 | /* TODO: Check for '/' in places where it might cause trouble with | ||
| 469 | * a lock file name. */ | ||
| 470 | |||
| 471 | - prev = NULL; | ||
| 472 | - *ret_list = NULL; | ||
| 473 | - *ret_nhosts = 0; | ||
| 474 | /* A simple, hardcoded scanner. Some of the GNU routines might be | ||
| 475 | * useful here, but they won't work on less capable systems. | ||
| 476 | * | ||
| 477 | @@ -390,6 +399,15 @@ | ||
| 478 | token_start = where; | ||
| 479 | token_len = strcspn(where, " #\t\n\f\r"); | ||
| 480 | |||
| 481 | +#ifdef HAVE_AVAHI | ||
| 482 | + if (token_len == sizeof(ZEROCONF_MAGIC)-1 && | ||
| 483 | + !strncmp(token_start, ZEROCONF_MAGIC, (unsigned) token_len)) { | ||
| 484 | + if ((ret = dcc_zeroconf_add_hosts(ret_list, ret_nhosts, 4, ret_prev) != 0)) | ||
| 485 | + return ret; | ||
| 486 | + goto skip; | ||
| 487 | + } | ||
| 488 | +#endif | ||
| 489 | + | ||
| 490 | /* Allocate new list item */ | ||
| 491 | curr = calloc(1, sizeof(struct dcc_hostdef)); | ||
| 492 | if (!curr) { | ||
| 493 | @@ -404,8 +422,8 @@ | ||
| 494 | } | ||
| 495 | |||
| 496 | /* Link into list */ | ||
| 497 | - if (prev) { | ||
| 498 | - prev->next = curr; | ||
| 499 | + if (*ret_prev) { | ||
| 500 | + (*ret_prev)->next = curr; | ||
| 501 | } else { | ||
| 502 | *ret_list = curr; /* first */ | ||
| 503 | } | ||
| 504 | @@ -434,10 +452,15 @@ | ||
| 505 | return ret; | ||
| 506 | } | ||
| 507 | |||
| 508 | + (*ret_nhosts)++; | ||
| 509 | + *ret_prev = curr; | ||
| 510 | + | ||
| 511 | +#ifdef HAVE_AVAHI | ||
| 512 | + skip: | ||
| 513 | +#endif | ||
| 514 | + | ||
| 515 | /* continue to next token if any */ | ||
| 516 | where = token_start + token_len; | ||
| 517 | - prev = curr; | ||
| 518 | - (*ret_nhosts)++; | ||
| 519 | } | ||
| 520 | |||
| 521 | if (*ret_nhosts) { | ||
| 522 | --- upstream/src/io.c 2005-11-18 16:15:40.000000000 +0100 | ||
| 523 | +++ lennart/src/io.c 2005-11-18 01:14:43.000000000 +0100 | ||
| 524 | @@ -163,7 +163,7 @@ | ||
| 525 | return ret; | ||
| 526 | else | ||
| 527 | continue; | ||
| 528 | - } else if (r == -1 && errno == EAGAIN) { | ||
| 529 | + } else if (r == -1 && errno == EINTR) { | ||
| 530 | continue; | ||
| 531 | } else if (r == -1) { | ||
| 532 | rs_log_error("failed to read: %s", strerror(errno)); | ||
| 533 | @@ -205,9 +205,6 @@ | ||
| 534 | } else if (r == -1) { | ||
| 535 | rs_log_error("failed to write: %s", strerror(errno)); | ||
| 536 | return EXIT_IO_ERROR; | ||
| 537 | - } else if (r == 0) { | ||
| 538 | - rs_log_error("unexpected eof on fd%d", fd); | ||
| 539 | - return EXIT_TRUNCATED; | ||
| 540 | } else { | ||
| 541 | buf = &((char *) buf)[r]; | ||
| 542 | len -= r; | ||
| 543 | --- upstream/src/tempfile.c 2005-11-18 16:15:40.000000000 +0100 | ||
| 544 | +++ lennart/src/tempfile.c 2005-11-18 01:14:43.000000000 +0100 | ||
| 545 | @@ -161,7 +161,7 @@ | ||
| 546 | * Return a subdirectory of the DISTCC_DIR of the given name, making | ||
| 547 | * sure that the directory exists. | ||
| 548 | **/ | ||
| 549 | -static int dcc_get_subdir(const char *name, | ||
| 550 | +int dcc_get_subdir(const char *name, | ||
| 551 | char **dir_ret) | ||
| 552 | { | ||
| 553 | int ret; | ||
| 554 | --- upstream/configure.ac 2005-11-18 16:15:40.000000000 +0100 | ||
| 555 | +++ lennart/configure.ac 2005-11-18 04:18:07.000000000 +0100 | ||
| 556 | @@ -388,6 +388,23 @@ | ||
| 557 | AC_DEFINE(HAVE_SOCKADDR_STORAGE, 1, [define if you have struct sockaddr_storage]),, | ||
| 558 | [#include <sys/socket.h>]) | ||
| 559 | |||
| 560 | +dnl check for avahi | ||
| 561 | +PKG_CHECK_MODULES(AVAHI, [avahi-client >= 0.6], | ||
| 562 | +[AC_DEFINE(HAVE_AVAHI, 1, [defined if Avahi is available]) | ||
| 563 | +CFLAGS="$CFLAGS $AVAHI_CFLAGS" | ||
| 564 | +LIBS="$LIBS $AVAHI_LIBS" | ||
| 565 | +ZEROCONF_DISTCC_OBJS="src/zeroconf.o" | ||
| 566 | +ZEROCONF_DISTCCD_OBJS="src/zeroconf-reg.o"], | ||
| 567 | +[ZEROCONF_DISTCC_OBJS="" | ||
| 568 | +ZEROCONF_DISTCCD_OBJS=""]) | ||
| 569 | +AC_SUBST(ZEROCONF_DISTCC_OBJS) | ||
| 570 | +AC_SUBST(ZEROCONF_DISTCCD_OBJS) | ||
| 571 | + | ||
| 572 | +ACX_PTHREAD | ||
| 573 | +LIBS="$PTHREAD_LIBS $LIBS" | ||
| 574 | +CFLAGS="$CFLAGS $PTHREAD_CFLAGS" | ||
| 575 | +CC="$PTHREAD_CC" | ||
| 576 | + | ||
| 577 | dnl ##### Output | ||
| 578 | AC_SUBST(docdir) | ||
| 579 | AC_SUBST(CFLAGS) | ||
| 580 | --- upstream/acinclude.m4 1970-01-01 01:00:00.000000000 +0100 | ||
| 581 | +++ lennart/acinclude.m4 2005-11-18 04:17:08.000000000 +0100 | ||
| 582 | @@ -0,0 +1,235 @@ | ||
| 583 | +dnl @synopsis ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) | ||
| 584 | +dnl | ||
| 585 | +dnl This macro figures out how to build C programs using POSIX threads. | ||
| 586 | +dnl It sets the PTHREAD_LIBS output variable to the threads library and | ||
| 587 | +dnl linker flags, and the PTHREAD_CFLAGS output variable to any special | ||
| 588 | +dnl C compiler flags that are needed. (The user can also force certain | ||
| 589 | +dnl compiler flags/libs to be tested by setting these environment | ||
| 590 | +dnl variables.) | ||
| 591 | +dnl | ||
| 592 | +dnl Also sets PTHREAD_CC to any special C compiler that is needed for | ||
| 593 | +dnl multi-threaded programs (defaults to the value of CC otherwise). | ||
| 594 | +dnl (This is necessary on AIX to use the special cc_r compiler alias.) | ||
| 595 | +dnl | ||
| 596 | +dnl NOTE: You are assumed to not only compile your program with these | ||
| 597 | +dnl flags, but also link it with them as well. e.g. you should link | ||
| 598 | +dnl with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS | ||
| 599 | +dnl $LIBS | ||
| 600 | +dnl | ||
| 601 | +dnl If you are only building threads programs, you may wish to use | ||
| 602 | +dnl these variables in your default LIBS, CFLAGS, and CC: | ||
| 603 | +dnl | ||
| 604 | +dnl LIBS="$PTHREAD_LIBS $LIBS" | ||
| 605 | +dnl CFLAGS="$CFLAGS $PTHREAD_CFLAGS" | ||
| 606 | +dnl CC="$PTHREAD_CC" | ||
| 607 | +dnl | ||
| 608 | +dnl In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute | ||
| 609 | +dnl constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to | ||
| 610 | +dnl that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). | ||
| 611 | +dnl | ||
| 612 | +dnl ACTION-IF-FOUND is a list of shell commands to run if a threads | ||
| 613 | +dnl library is found, and ACTION-IF-NOT-FOUND is a list of commands to | ||
| 614 | +dnl run it if it is not found. If ACTION-IF-FOUND is not specified, the | ||
| 615 | +dnl default action will define HAVE_PTHREAD. | ||
| 616 | +dnl | ||
| 617 | +dnl Please let the authors know if this macro fails on any platform, or | ||
| 618 | +dnl if you have any other suggestions or comments. This macro was based | ||
| 619 | +dnl on work by SGJ on autoconf scripts for FFTW (www.fftw.org) (with | ||
| 620 | +dnl help from M. Frigo), as well as ac_pthread and hb_pthread macros | ||
| 621 | +dnl posted by Alejandro Forero Cuervo to the autoconf macro repository. | ||
| 622 | +dnl We are also grateful for the helpful feedback of numerous users. | ||
| 623 | +dnl | ||
| 624 | +dnl @category InstalledPackages | ||
| 625 | +dnl @author Steven G. Johnson <stevenj@alum.mit.edu> | ||
| 626 | +dnl @version 2005-01-14 | ||
| 627 | +dnl @license GPLWithACException | ||
| 628 | + | ||
| 629 | +AC_DEFUN([ACX_PTHREAD], [ | ||
| 630 | +AC_REQUIRE([AC_CANONICAL_HOST]) | ||
| 631 | +AC_LANG_SAVE | ||
| 632 | +AC_LANG_C | ||
| 633 | +acx_pthread_ok=no | ||
| 634 | + | ||
| 635 | +# We used to check for pthread.h first, but this fails if pthread.h | ||
| 636 | +# requires special compiler flags (e.g. on True64 or Sequent). | ||
| 637 | +# It gets checked for in the link test anyway. | ||
| 638 | + | ||
| 639 | +# First of all, check if the user has set any of the PTHREAD_LIBS, | ||
| 640 | +# etcetera environment variables, and if threads linking works using | ||
| 641 | +# them: | ||
| 642 | +if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then | ||
| 643 | + save_CFLAGS="$CFLAGS" | ||
| 644 | + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" | ||
| 645 | + save_LIBS="$LIBS" | ||
| 646 | + LIBS="$PTHREAD_LIBS $LIBS" | ||
| 647 | + AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) | ||
| 648 | + AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes) | ||
| 649 | + AC_MSG_RESULT($acx_pthread_ok) | ||
| 650 | + if test x"$acx_pthread_ok" = xno; then | ||
| 651 | + PTHREAD_LIBS="" | ||
| 652 | + PTHREAD_CFLAGS="" | ||
| 653 | + fi | ||
| 654 | + LIBS="$save_LIBS" | ||
| 655 | + CFLAGS="$save_CFLAGS" | ||
| 656 | +fi | ||
| 657 | + | ||
| 658 | +# We must check for the threads library under a number of different | ||
| 659 | +# names; the ordering is very important because some systems | ||
| 660 | +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the | ||
| 661 | +# libraries is broken (non-POSIX). | ||
| 662 | + | ||
| 663 | +# Create a list of thread flags to try. Items starting with a "-" are | ||
| 664 | +# C compiler flags, and other items are library names, except for "none" | ||
| 665 | +# which indicates that we try without any flags at all, and "pthread-config" | ||
| 666 | +# which is a program returning the flags for the Pth emulation library. | ||
| 667 | + | ||
| 668 | +acx_pthread_flags="pthreads pthread none -Kthread -kthread lthread -pthread -pthreads -mthreads --thread-safe -mt pthread-config" | ||
| 669 | + | ||
| 670 | +# The ordering *is* (sometimes) important. Some notes on the | ||
| 671 | +# individual items follow: | ||
| 672 | + | ||
| 673 | +# pthreads: AIX (must check this before -lpthread) | ||
| 674 | +# none: in case threads are in libc; should be tried before -Kthread and | ||
| 675 | +# other compiler flags to prevent continual compiler warnings | ||
| 676 | +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) | ||
| 677 | +# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) | ||
| 678 | +# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) | ||
| 679 | +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) | ||
| 680 | +# -pthreads: Solaris/gcc | ||
| 681 | +# -mthreads: Mingw32/gcc, Lynx/gcc | ||
| 682 | +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it | ||
| 683 | +# doesn't hurt to check since this sometimes defines pthreads too; | ||
| 684 | +# also defines -D_REENTRANT) | ||
| 685 | +# pthread: Linux, etcetera | ||
| 686 | +# --thread-safe: KAI C++ | ||
| 687 | +# pthread-config: use pthread-config program (for GNU Pth library) | ||
| 688 | + | ||
| 689 | +case "${host_cpu}-${host_os}" in | ||
| 690 | + *solaris*) | ||
| 691 | + | ||
| 692 | + # On Solaris (at least, for some versions), libc contains stubbed | ||
| 693 | + # (non-functional) versions of the pthreads routines, so link-based | ||
| 694 | + # tests will erroneously succeed. (We need to link with -pthread or | ||
| 695 | + # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather | ||
| 696 | + # a function called by this macro, so we could check for that, but | ||
| 697 | + # who knows whether they'll stub that too in a future libc.) So, | ||
| 698 | + # we'll just look for -pthreads and -lpthread first: | ||
| 699 | + | ||
| 700 | + acx_pthread_flags="-pthread -pthreads pthread -mt $acx_pthread_flags" | ||
| 701 | + ;; | ||
| 702 | +esac | ||
| 703 | + | ||
| 704 | +if test x"$acx_pthread_ok" = xno; then | ||
| 705 | +for flag in $acx_pthread_flags; do | ||
| 706 | + | ||
| 707 | + case $flag in | ||
| 708 | + none) | ||
| 709 | + AC_MSG_CHECKING([whether pthreads work without any flags]) | ||
| 710 | + ;; | ||
| 711 | + | ||
| 712 | + -*) | ||
| 713 | + AC_MSG_CHECKING([whether pthreads work with $flag]) | ||
| 714 | + PTHREAD_CFLAGS="$flag" | ||
| 715 | + ;; | ||
| 716 | + | ||
| 717 | + pthread-config) | ||
| 718 | + AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no) | ||
| 719 | + if test x"$acx_pthread_config" = xno; then continue; fi | ||
| 720 | + PTHREAD_CFLAGS="`pthread-config --cflags`" | ||
| 721 | + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" | ||
| 722 | + ;; | ||
| 723 | + | ||
| 724 | + *) | ||
| 725 | + AC_MSG_CHECKING([for the pthreads library -l$flag]) | ||
| 726 | + PTHREAD_LIBS="-l$flag" | ||
| 727 | + ;; | ||
| 728 | + esac | ||
| 729 | + | ||
| 730 | + save_LIBS="$LIBS" | ||
| 731 | + save_CFLAGS="$CFLAGS" | ||
| 732 | + LIBS="$PTHREAD_LIBS $LIBS" | ||
| 733 | + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" | ||
| 734 | + | ||
| 735 | + # Check for various functions. We must include pthread.h, | ||
| 736 | + # since some functions may be macros. (On the Sequent, we | ||
| 737 | + # need a special flag -Kthread to make this header compile.) | ||
| 738 | + # We check for pthread_join because it is in -lpthread on IRIX | ||
| 739 | + # while pthread_create is in libc. We check for pthread_attr_init | ||
| 740 | + # due to DEC craziness with -lpthreads. We check for | ||
| 741 | + # pthread_cleanup_push because it is one of the few pthread | ||
| 742 | + # functions on Solaris that doesn't have a non-functional libc stub. | ||
| 743 | + # We try pthread_create on general principles. | ||
| 744 | + AC_TRY_LINK([#include <pthread.h>], | ||
| 745 | + [pthread_t th; pthread_join(th, 0); | ||
| 746 | + pthread_attr_init(0); pthread_cleanup_push(0, 0); | ||
| 747 | + pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], | ||
| 748 | + [acx_pthread_ok=yes]) | ||
| 749 | + | ||
| 750 | + LIBS="$save_LIBS" | ||
| 751 | + CFLAGS="$save_CFLAGS" | ||
| 752 | + | ||
| 753 | + AC_MSG_RESULT($acx_pthread_ok) | ||
| 754 | + if test "x$acx_pthread_ok" = xyes; then | ||
| 755 | + break; | ||
| 756 | + fi | ||
| 757 | + | ||
| 758 | + PTHREAD_LIBS="" | ||
| 759 | + PTHREAD_CFLAGS="" | ||
| 760 | +done | ||
| 761 | +fi | ||
| 762 | + | ||
| 763 | +# Various other checks: | ||
| 764 | +if test "x$acx_pthread_ok" = xyes; then | ||
| 765 | + save_LIBS="$LIBS" | ||
| 766 | + LIBS="$PTHREAD_LIBS $LIBS" | ||
| 767 | + save_CFLAGS="$CFLAGS" | ||
| 768 | + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" | ||
| 769 | + | ||
| 770 | + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. | ||
| 771 | + AC_MSG_CHECKING([for joinable pthread attribute]) | ||
| 772 | + attr_name=unknown | ||
| 773 | + for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do | ||
| 774 | + AC_TRY_LINK([#include <pthread.h>], [int attr=$attr;], | ||
| 775 | + [attr_name=$attr; break]) | ||
| 776 | + done | ||
| 777 | + AC_MSG_RESULT($attr_name) | ||
| 778 | + if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then | ||
| 779 | + AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name, | ||
| 780 | + [Define to necessary symbol if this constant | ||
| 781 | + uses a non-standard name on your system.]) | ||
| 782 | + fi | ||
| 783 | + | ||
| 784 | + AC_MSG_CHECKING([if more special flags are required for pthreads]) | ||
| 785 | + flag=no | ||
| 786 | + case "${host_cpu}-${host_os}" in | ||
| 787 | + *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";; | ||
| 788 | + *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";; | ||
| 789 | + esac | ||
| 790 | + AC_MSG_RESULT(${flag}) | ||
| 791 | + if test "x$flag" != xno; then | ||
| 792 | + PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" | ||
| 793 | + fi | ||
| 794 | + | ||
| 795 | + LIBS="$save_LIBS" | ||
| 796 | + CFLAGS="$save_CFLAGS" | ||
| 797 | + | ||
| 798 | + # More AIX lossage: must compile with cc_r | ||
| 799 | + AC_CHECK_PROG(PTHREAD_CC, cc_r, cc_r, ${CC}) | ||
| 800 | +else | ||
| 801 | + PTHREAD_CC="$CC" | ||
| 802 | +fi | ||
| 803 | + | ||
| 804 | +AC_SUBST(PTHREAD_LIBS) | ||
| 805 | +AC_SUBST(PTHREAD_CFLAGS) | ||
| 806 | +AC_SUBST(PTHREAD_CC) | ||
| 807 | + | ||
| 808 | +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: | ||
| 809 | +if test x"$acx_pthread_ok" = xyes; then | ||
| 810 | + ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) | ||
| 811 | + : | ||
| 812 | +else | ||
| 813 | + acx_pthread_ok=no | ||
| 814 | + $2 | ||
| 815 | +fi | ||
| 816 | +AC_LANG_RESTORE | ||
| 817 | +])dnl ACX_PTHREAD | ||
| 818 | --- upstream/src/zeroconf.h 1970-01-01 01:00:00.000000000 +0100 | ||
| 819 | +++ lennart/src/zeroconf.h 2005-11-18 04:06:29.000000000 +0100 | ||
| 820 | @@ -0,0 +1,13 @@ | ||
| 821 | +#ifndef foozeroconfhfoo | ||
| 822 | +#define foozeroconfhfoo | ||
| 823 | + | ||
| 824 | +#include <inttypes.h> | ||
| 825 | + | ||
| 826 | +int dcc_zeroconf_add_hosts(struct dcc_hostdef **re_list, int *ret_nhosts, int slots, struct dcc_hostdef **ret_prev); | ||
| 827 | + | ||
| 828 | +void * dcc_zeroconf_register(uint16_t port, int n_cpus); | ||
| 829 | +int dcc_zeroconf_unregister(void*); | ||
| 830 | + | ||
| 831 | +#define DCC_DNS_SERVICE_TYPE "_distcc._tcp" | ||
| 832 | + | ||
| 833 | +#endif | ||
| 834 | --- upstream/src/zeroconf.c 1970-01-01 01:00:00.000000000 +0100 | ||
| 835 | +++ lennart/src/zeroconf.c 2005-11-18 15:51:45.000000000 +0100 | ||
| 836 | @@ -0,0 +1,602 @@ | ||
| 837 | +/* -*- c-file-style: "java"; indent-tabs-mode: nil -*- */ | ||
| 838 | + | ||
| 839 | +#include "config.h" | ||
| 840 | + | ||
| 841 | +#include <assert.h> | ||
| 842 | +#include <stdio.h> | ||
| 843 | +#include <sys/select.h> | ||
| 844 | +#include <signal.h> | ||
| 845 | +#include <sys/file.h> | ||
| 846 | +#include <sys/time.h> | ||
| 847 | +#include <time.h> | ||
| 848 | +#include <sys/stat.h> | ||
| 849 | +#include <string.h> | ||
| 850 | +#include <errno.h> | ||
| 851 | +#include <unistd.h> | ||
| 852 | +#include <stdlib.h> | ||
| 853 | +#include <limits.h> | ||
| 854 | + | ||
| 855 | +#include <avahi-common/domain.h> | ||
| 856 | +#include <avahi-common/error.h> | ||
| 857 | +#include <avahi-common/malloc.h> | ||
| 858 | +#include <avahi-common/address.h> | ||
| 859 | +#include <avahi-common/simple-watch.h> | ||
| 860 | +#include <avahi-client/lookup.h> | ||
| 861 | + | ||
| 862 | +#include "distcc.h" | ||
| 863 | +#include "hosts.h" | ||
| 864 | +#include "zeroconf.h" | ||
| 865 | +#include "trace.h" | ||
| 866 | +#include "exitcode.h" | ||
| 867 | + | ||
| 868 | +/* How long shall the background daemon be idle before i terminates itself? */ | ||
| 869 | +#define MAX_IDLE_TIME 20 | ||
| 870 | + | ||
| 871 | +/* Maxium size of host file to load */ | ||
| 872 | +#define MAX_FILE_SIZE (1024*100) | ||
| 873 | + | ||
| 874 | +/* General daemon data */ | ||
| 875 | +struct daemon_data { | ||
| 876 | + struct host *hosts; | ||
| 877 | + int fd; | ||
| 878 | + int n_slots; | ||
| 879 | + | ||
| 880 | + AvahiClient *client; | ||
| 881 | + AvahiServiceBrowser *browser; | ||
| 882 | + AvahiSimplePoll *simple_poll; | ||
| 883 | +}; | ||
| 884 | + | ||
| 885 | +/* Zeroconf service wrapper */ | ||
| 886 | +struct host { | ||
| 887 | + struct daemon_data *daemon_data; | ||
| 888 | + struct host *next; | ||
| 889 | + | ||
| 890 | + AvahiIfIndex interface; | ||
| 891 | + AvahiProtocol protocol; | ||
| 892 | + char *service; | ||
| 893 | + char *domain; | ||
| 894 | + | ||
| 895 | + AvahiAddress address; | ||
| 896 | + uint16_t port; | ||
| 897 | + int n_cpus; | ||
| 898 | + | ||
| 899 | + AvahiServiceResolver *resolver; | ||
| 900 | +}; | ||
| 901 | + | ||
| 902 | +/* A generic, system-independent lock routine, similar to sys_lock, | ||
| 903 | + * but more powerful: | ||
| 904 | + * rw: if non-zero: r/w lock instead of r/o lock | ||
| 905 | + * enable: lock or unlock | ||
| 906 | + * block: block when locking */ | ||
| 907 | +static int generic_lock(int fd, int rw, int enable, int block) { | ||
| 908 | +#if defined(F_SETLK) | ||
| 909 | + struct flock lockparam; | ||
| 910 | + | ||
| 911 | + lockparam.l_type = enable ? (rw ? F_WRLCK : F_RDLCK) : F_UNLCK; | ||
| 912 | + lockparam.l_whence = SEEK_SET; | ||
| 913 | + lockparam.l_start = 0; | ||
| 914 | + lockparam.l_len = 0; /* whole file */ | ||
| 915 | + | ||
| 916 | + return fcntl(fd, block ? F_SETLKW : F_SETLK, &lockparam); | ||
| 917 | +#elif defined(HAVE_FLOCK) | ||
| 918 | + return flock(fd, (enable ? (rw ? LOCK_EX : LOCK_SH) : LOCK_UN) | (block ? LOCK_NB : 0)); | ||
| 919 | +#elif defined(HAVE_LOCKF) | ||
| 920 | + return lockf(fd, (enable ? (block ? F_LOCK : F_TLOCK) : F_ULOCK)); | ||
| 921 | +#else | ||
| 922 | +# error "No supported lock method. Please port this code." | ||
| 923 | +#endif | ||
| 924 | +} | ||
| 925 | + | ||
| 926 | +/* Return the number of seconds, when the specified file was last | ||
| 927 | + * read. If the atime of that file is < clip_time, use clip_time | ||
| 928 | + * instead */ | ||
| 929 | +static time_t fd_last_used(int fd, time_t clip_time) { | ||
| 930 | + struct stat st; | ||
| 931 | + time_t now, ft; | ||
| 932 | + assert(fd >= 0); | ||
| 933 | + | ||
| 934 | + if (fstat(fd, &st) < 0) { | ||
| 935 | + rs_log_crit("fstat() failed: %s\n", strerror(errno)); | ||
| 936 | + return -1; | ||
| 937 | + } | ||
| 938 | + | ||
| 939 | + if ((now = time(NULL)) == (time_t) -1) { | ||
| 940 | + rs_log_crit("time() failed: %s\n", strerror(errno)); | ||
| 941 | + return -1; | ||
| 942 | + } | ||
| 943 | + | ||
| 944 | + ft = clip_time ? (st.st_atime < clip_time ? clip_time : st.st_atime) : st.st_atime; | ||
| 945 | + assert(ft <= now); | ||
| 946 | + | ||
| 947 | + return now - ft; | ||
| 948 | +} | ||
| 949 | + | ||
| 950 | +/* Write host data to host file */ | ||
| 951 | +static int write_hosts(struct daemon_data *d) { | ||
| 952 | + struct host *h; | ||
| 953 | + int r = 0; | ||
| 954 | + assert(d); | ||
| 955 | + | ||
| 956 | + rs_log_info("writing zeroconf data.\n"); | ||
| 957 | + | ||
| 958 | + if (generic_lock(d->fd, 1, 1, 1) < 0) { | ||
| 959 | + rs_log_crit("lock failed: %s\n", strerror(errno)); | ||
| 960 | + return -1; | ||
| 961 | + } | ||
| 962 | + | ||
| 963 | + if (lseek(d->fd, 0, SEEK_SET) < 0) { | ||
| 964 | + rs_log_crit("lseek() failed: %s\n", strerror(errno)); | ||
| 965 | + return -1; | ||
| 966 | + } | ||
| 967 | + | ||
| 968 | + if (ftruncate(d->fd, 0) < 0) { | ||
| 969 | + rs_log_crit("ftruncate() failed: %s\n", strerror(errno)); | ||
| 970 | + return -1; | ||
| 971 | + } | ||
| 972 | + | ||
| 973 | + for (h = d->hosts; h; h = h->next) { | ||
| 974 | + char t[256], a[AVAHI_ADDRESS_STR_MAX]; | ||
| 975 | + | ||
| 976 | + if (h->resolver) | ||
| 977 | + /* Not yet fully resolved */ | ||
| 978 | + continue; | ||
| 979 | + | ||
| 980 | + snprintf(t, sizeof(t), "%s:%u/%i\n", avahi_address_snprint(a, sizeof(a), &h->address), h->port, d->n_slots * h->n_cpus); | ||
| 981 | + | ||
| 982 | + if (dcc_writex(d->fd, t, strlen(t)) != 0) { | ||
| 983 | + rs_log_crit("write() failed: %s\n", strerror(errno)); | ||
| 984 | + goto finish; | ||
| 985 | + } | ||
| 986 | + } | ||
| 987 | + | ||
| 988 | + r = 0; | ||
| 989 | + | ||
| 990 | +finish: | ||
| 991 | + | ||
| 992 | + generic_lock(d->fd, 1, 0, 1); | ||
| 993 | + return r; | ||
| 994 | + | ||
| 995 | +}; | ||
| 996 | + | ||
| 997 | +/* Free host data */ | ||
| 998 | +static void free_host(struct host *h) { | ||
| 999 | + assert(h); | ||
| 1000 | + | ||
| 1001 | + if (h->resolver) | ||
| 1002 | + avahi_service_resolver_free(h->resolver); | ||
| 1003 | + | ||
| 1004 | + free(h->service); | ||
| 1005 | + free(h->domain); | ||
| 1006 | + free(h); | ||
| 1007 | +} | ||
| 1008 | + | ||
| 1009 | +/* Remove a service from the host list */ | ||
| 1010 | +static void remove_service(struct daemon_data *d, AvahiIfIndex interface, AvahiProtocol protocol, const char *name, const char *domain) { | ||
| 1011 | + struct host *h, *p = NULL; | ||
| 1012 | + assert(d); | ||
| 1013 | + | ||
| 1014 | + for (h = d->hosts; h; h = h->next) { | ||
| 1015 | + if (h->interface == interface && | ||
| 1016 | + h->protocol == protocol && | ||
| 1017 | + !strcmp(h->service, name) && | ||
| 1018 | + avahi_domain_equal(h->domain, domain)) { | ||
| 1019 | + | ||
| 1020 | + if (p) | ||
| 1021 | + p->next = h->next; | ||
| 1022 | + else | ||
| 1023 | + d->hosts = h->next; | ||
| 1024 | + | ||
| 1025 | + free_host(h); | ||
| 1026 | + | ||
| 1027 | + break; | ||
| 1028 | + } else | ||
| 1029 | + p = h; | ||
| 1030 | + } | ||
| 1031 | +} | ||
| 1032 | + | ||
| 1033 | +/* Called when a resolve call completes */ | ||
| 1034 | +static void resolve_reply(AvahiServiceResolver *UNUSED(r), | ||
| 1035 | + AvahiIfIndex UNUSED(interface), | ||
| 1036 | + AvahiProtocol UNUSED(protocol), | ||
| 1037 | + AvahiResolverEvent event, | ||
| 1038 | + const char *name, | ||
| 1039 | + const char *UNUSED(type), | ||
| 1040 | + const char *UNUSED(domain), | ||
| 1041 | + const char *UNUSED(host_name), | ||
| 1042 | + const AvahiAddress *a, | ||
| 1043 | + uint16_t port, | ||
| 1044 | + AvahiStringList *txt, | ||
| 1045 | + AvahiLookupResultFlags UNUSED(flags), | ||
| 1046 | + void *userdata) { | ||
| 1047 | + | ||
| 1048 | + struct host *h = userdata; | ||
| 1049 | + | ||
| 1050 | + switch (event) { | ||
| 1051 | + | ||
| 1052 | + case AVAHI_RESOLVER_FOUND: { | ||
| 1053 | + AvahiStringList *i; | ||
| 1054 | + | ||
| 1055 | + /* Look for the number of CPUs in TXT RRs */ | ||
| 1056 | + for (i = txt; i; i = i->next) { | ||
| 1057 | + char *key, *value; | ||
| 1058 | + | ||
| 1059 | + if (avahi_string_list_get_pair(i, &key, &value, NULL) < 0) | ||
| 1060 | + continue; | ||
| 1061 | + | ||
| 1062 | + if (!strcmp(key, "cpus")) | ||
| 1063 | + if ((h->n_cpus = atoi(value)) <= 0) | ||
| 1064 | + h->n_cpus = 1; | ||
| 1065 | + | ||
| 1066 | + avahi_free(key); | ||
| 1067 | + avahi_free(value); | ||
| 1068 | + } | ||
| 1069 | + | ||
| 1070 | + h->address = *a; | ||
| 1071 | + h->port = port; | ||
| 1072 | + | ||
| 1073 | + avahi_service_resolver_free(h->resolver); | ||
| 1074 | + h->resolver = NULL; | ||
| 1075 | + | ||
| 1076 | + /* Write modified hosts file */ | ||
| 1077 | + write_hosts(h->daemon_data); | ||
| 1078 | + | ||
| 1079 | + break; | ||
| 1080 | + } | ||
| 1081 | + | ||
| 1082 | + case AVAHI_RESOLVER_FAILURE: | ||
| 1083 | + | ||
| 1084 | + rs_log_warning("Failed to resolve service '%s': %s\n", name, | ||
| 1085 | + avahi_strerror(avahi_client_errno(h->daemon_data->client))); | ||
| 1086 | + | ||
| 1087 | + free_host(h); | ||
| 1088 | + break; | ||
| 1089 | + } | ||
| 1090 | + | ||
| 1091 | +} | ||
| 1092 | + | ||
| 1093 | +/* Called whenever a new service is found or removed */ | ||
| 1094 | +static void browse_reply(AvahiServiceBrowser *UNUSED(b), | ||
| 1095 | + AvahiIfIndex interface, | ||
| 1096 | + AvahiProtocol protocol, | ||
| 1097 | + AvahiBrowserEvent event, | ||
| 1098 | + const char *name, | ||
| 1099 | + const char *type, | ||
| 1100 | + const char *domain, | ||
| 1101 | + AvahiLookupResultFlags UNUSED(flags), | ||
| 1102 | + void *userdata) { | ||
| 1103 | + | ||
| 1104 | + struct daemon_data *d = userdata; | ||
| 1105 | + assert(d); | ||
| 1106 | + | ||
| 1107 | + switch (event) { | ||
| 1108 | + case AVAHI_BROWSER_NEW: { | ||
| 1109 | + struct host *h; | ||
| 1110 | + | ||
| 1111 | + h = malloc(sizeof(struct host)); | ||
| 1112 | + assert(h); | ||
| 1113 | + | ||
| 1114 | + rs_log_info("new service: %s\n", name); | ||
| 1115 | + | ||
| 1116 | + if (!(h->resolver = avahi_service_resolver_new(d->client, | ||
| 1117 | + interface, | ||
| 1118 | + protocol, | ||
| 1119 | + name, | ||
| 1120 | + type, | ||
| 1121 | + domain, | ||
| 1122 | + AVAHI_PROTO_UNSPEC, | ||
| 1123 | + 0, | ||
| 1124 | + resolve_reply, | ||
| 1125 | + h))) { | ||
| 1126 | + rs_log_warning("Failed to create service resolver for '%s': %s\n", name, | ||
| 1127 | + avahi_strerror(avahi_client_errno(d->client))); | ||
| 1128 | + | ||
| 1129 | + free(h); | ||
| 1130 | + | ||
| 1131 | + } else { | ||
| 1132 | + | ||
| 1133 | + /* Fill in missing data */ | ||
| 1134 | + h->service = strdup(name); | ||
| 1135 | + assert(h->service); | ||
| 1136 | + h->domain = strdup(domain); | ||
| 1137 | + assert(h->domain); | ||
| 1138 | + h->daemon_data = d; | ||
| 1139 | + h->interface = interface; | ||
| 1140 | + h->protocol = protocol; | ||
| 1141 | + h->next = d->hosts; | ||
| 1142 | + h->n_cpus = 1; | ||
| 1143 | + d->hosts = h; | ||
| 1144 | + } | ||
| 1145 | + | ||
| 1146 | + break; | ||
| 1147 | + } | ||
| 1148 | + | ||
| 1149 | + case AVAHI_BROWSER_REMOVE: | ||
| 1150 | + | ||
| 1151 | + rs_log_info("Removed service: %s\n", name); | ||
| 1152 | + | ||
| 1153 | + remove_service(d, interface, protocol, name, domain); | ||
| 1154 | + write_hosts(d); | ||
| 1155 | + break; | ||
| 1156 | + | ||
| 1157 | + case AVAHI_BROWSER_FAILURE: | ||
| 1158 | + rs_log_crit("Service Browser failure '%s': %s\n", name, | ||
| 1159 | + avahi_strerror(avahi_client_errno(d->client))); | ||
| 1160 | + | ||
| 1161 | + avahi_simple_poll_quit(d->simple_poll); | ||
| 1162 | + break; | ||
| 1163 | + | ||
| 1164 | + case AVAHI_BROWSER_CACHE_EXHAUSTED: | ||
| 1165 | + case AVAHI_BROWSER_ALL_FOR_NOW: | ||
| 1166 | + ; | ||
| 1167 | + | ||
| 1168 | + } | ||
| 1169 | +} | ||
| 1170 | + | ||
| 1171 | +static void client_callback(AvahiClient *client, AvahiClientState state, void *userdata) { | ||
| 1172 | + struct daemon_data *d = userdata; | ||
| 1173 | + | ||
| 1174 | + switch (state) { | ||
| 1175 | + | ||
| 1176 | + case AVAHI_CLIENT_FAILURE: | ||
| 1177 | + rs_log_crit("Client failure: %s\n", avahi_strerror(avahi_client_errno(client))); | ||
| 1178 | + avahi_simple_poll_quit(d->simple_poll); | ||
| 1179 | + break; | ||
| 1180 | + | ||
| 1181 | + case AVAHI_CLIENT_S_COLLISION: | ||
| 1182 | + case AVAHI_CLIENT_S_REGISTERING: | ||
| 1183 | + case AVAHI_CLIENT_S_RUNNING: | ||
| 1184 | + case AVAHI_CLIENT_CONNECTING: | ||
| 1185 | + ; | ||
| 1186 | + } | ||
| 1187 | +} | ||
| 1188 | + | ||
| 1189 | +/* The main function of the background daemon */ | ||
| 1190 | +static void daemon_proc(const char *host_file, const char *lock_file, int n_slots) { | ||
| 1191 | + int ret = 1; | ||
| 1192 | + int lock_fd = -1; | ||
| 1193 | + struct daemon_data d; | ||
| 1194 | + time_t clip_time; | ||
| 1195 | + int error; | ||
| 1196 | + | ||
| 1197 | + rs_add_logger(rs_logger_syslog, RS_LOG_DEBUG, NULL, 0); | ||
| 1198 | + | ||
| 1199 | + /* Prepare daemon data structure */ | ||
| 1200 | + d.fd = -1; | ||
| 1201 | + d.hosts = NULL; | ||
| 1202 | + d.n_slots = n_slots; | ||
| 1203 | + d.simple_poll = NULL; | ||
| 1204 | + d.browser = NULL; | ||
| 1205 | + d.client = NULL; | ||
| 1206 | + clip_time = time(NULL); | ||
| 1207 | + | ||
| 1208 | + rs_log_info("Zeroconf daemon running.\n"); | ||
| 1209 | + | ||
| 1210 | + /* Open daemon lock file and lock it */ | ||
| 1211 | + if ((lock_fd = open(lock_file, O_RDWR|O_CREAT, 0666)) < 0) { | ||
| 1212 | + rs_log_crit("open('%s') failed: %s\n", lock_file, strerror(errno)); | ||
| 1213 | + goto finish; | ||
| 1214 | + } | ||
| 1215 | + | ||
| 1216 | + if (generic_lock(lock_fd, 1, 1, 0) < 0) { | ||
| 1217 | + /* lock failed, there's probably already another daemon running */ | ||
| 1218 | + goto finish; | ||
| 1219 | + } | ||
| 1220 | + | ||
| 1221 | + /* Open host file */ | ||
| 1222 | + if ((d.fd = open(host_file, O_RDWR|O_CREAT, 0666)) < 0) { | ||
| 1223 | + rs_log_crit("open('%s') failed: %s\n", host_file, strerror(errno)); | ||
| 1224 | + goto finish; | ||
| 1225 | + } | ||
| 1226 | + | ||
| 1227 | + /* Clear host file */ | ||
| 1228 | + write_hosts(&d); | ||
| 1229 | + | ||
| 1230 | + if (!(d.simple_poll = avahi_simple_poll_new())) { | ||
| 1231 | + rs_log_crit("Failed to create simple poll object.\n"); | ||
| 1232 | + goto finish; | ||
| 1233 | + } | ||
| 1234 | + | ||
| 1235 | + if (!(d.client = avahi_client_new(avahi_simple_poll_get(d.simple_poll), | ||
| 1236 | + 0, | ||
| 1237 | + client_callback, | ||
| 1238 | + &d, | ||
| 1239 | + &error))) { | ||
| 1240 | + rs_log_crit("Failed to create Avahi client object: %s\n", avahi_strerror(error)); | ||
| 1241 | + goto finish; | ||
| 1242 | + } | ||
| 1243 | + | ||
| 1244 | + if (!(d.browser = avahi_service_browser_new(d.client, | ||
| 1245 | + AVAHI_IF_UNSPEC, | ||
| 1246 | + AVAHI_PROTO_UNSPEC, | ||
| 1247 | + DCC_DNS_SERVICE_TYPE, | ||
| 1248 | + NULL, | ||
| 1249 | + 0, | ||
| 1250 | + browse_reply, | ||
| 1251 | + &d))) { | ||
| 1252 | + rs_log_crit("Failed to create service browser object: %s\n", avahi_strerror(avahi_client_errno(d.client))); | ||
| 1253 | + goto finish; | ||
| 1254 | + } | ||
| 1255 | + | ||
| 1256 | + /* Check whether the host file has been used recently */ | ||
| 1257 | + while (fd_last_used(d.fd, clip_time) <= MAX_IDLE_TIME) { | ||
| 1258 | + | ||
| 1259 | + /* Iterate the main loop for 500ms */ | ||
| 1260 | + if (avahi_simple_poll_iterate(d.simple_poll, 500) != 0) { | ||
| 1261 | + rs_log_crit("Event loop exited abnormaly.\n"); | ||
| 1262 | + goto finish; | ||
| 1263 | + } | ||
| 1264 | + } | ||
| 1265 | + | ||
| 1266 | + /* Wer are idle */ | ||
| 1267 | + rs_log_info("Zeroconf daemon unused.\n"); | ||
| 1268 | + | ||
| 1269 | + ret = 0; | ||
| 1270 | + | ||
| 1271 | +finish: | ||
| 1272 | + | ||
| 1273 | + /* Cleanup */ | ||
| 1274 | + if (lock_fd >= 0) { | ||
| 1275 | + generic_lock(lock_fd, 1, 0, 0); | ||
| 1276 | + close(lock_fd); | ||
| 1277 | + } | ||
| 1278 | + | ||
| 1279 | + if (d.fd >= 0) | ||
| 1280 | + close(d.fd); | ||
| 1281 | + | ||
| 1282 | + while (d.hosts) { | ||
| 1283 | + struct host *h = d.hosts; | ||
| 1284 | + d.hosts = d.hosts->next; | ||
| 1285 | + free_host(h); | ||
| 1286 | + } | ||
| 1287 | + | ||
| 1288 | + if (d.client) | ||
| 1289 | + avahi_client_free(d.client); | ||
| 1290 | + | ||
| 1291 | + if (d.simple_poll) | ||
| 1292 | + avahi_simple_poll_free(d.simple_poll); | ||
| 1293 | + | ||
| 1294 | + rs_log_info("zeroconf daemon ended.\n"); | ||
| 1295 | + | ||
| 1296 | + _exit(ret); | ||
| 1297 | +} | ||
| 1298 | + | ||
| 1299 | +/* Return path to the zeroconf directory in ~/.distcc */ | ||
| 1300 | +static int get_zeroconf_dir(char **dir_ret) { | ||
| 1301 | + static char *cached; | ||
| 1302 | + int ret; | ||
| 1303 | + | ||
| 1304 | + if (cached) { | ||
| 1305 | + *dir_ret = cached; | ||
| 1306 | + return 0; | ||
| 1307 | + } else { | ||
| 1308 | + ret = dcc_get_subdir("zeroconf", dir_ret); | ||
| 1309 | + if (ret == 0) | ||
| 1310 | + cached = *dir_ret; | ||
| 1311 | + return ret; | ||
| 1312 | + } | ||
| 1313 | +} | ||
| 1314 | + | ||
| 1315 | +/* Get the host list from zeroconf */ | ||
| 1316 | +int dcc_zeroconf_add_hosts(struct dcc_hostdef **ret_list, int *ret_nhosts, int n_slots, struct dcc_hostdef **ret_prev) { | ||
| 1317 | + char host_file[PATH_MAX], lock_file[PATH_MAX], *s = NULL; | ||
| 1318 | + int lock_fd = -1, host_fd = -1; | ||
| 1319 | + int fork_daemon = 0; | ||
| 1320 | + int r = -1; | ||
| 1321 | + char *dir; | ||
| 1322 | + struct stat st; | ||
| 1323 | + | ||
| 1324 | + if (get_zeroconf_dir(&dir) != 0) { | ||
| 1325 | + rs_log_crit("failed to get zeroconf dir.\n"); | ||
| 1326 | + goto finish; | ||
| 1327 | + } | ||
| 1328 | + | ||
| 1329 | + snprintf(lock_file, sizeof(lock_file), "%s/lock", dir); | ||
| 1330 | + snprintf(host_file, sizeof(host_file), "%s/hosts", dir); | ||
| 1331 | + | ||
| 1332 | + /* Open lock file */ | ||
| 1333 | + if ((lock_fd = open(lock_file, O_RDWR|O_CREAT, 0666)) < 0) { | ||
| 1334 | + rs_log_crit("open('%s') failed: %s\n", lock_file, strerror(errno)); | ||
| 1335 | + goto finish; | ||
| 1336 | + } | ||
| 1337 | + | ||
| 1338 | + /* Try to lock the lock file */ | ||
| 1339 | + if (generic_lock(lock_fd, 1, 1, 0) >= 0) { | ||
| 1340 | + /* The lock succeeded => there's no daemon running yet! */ | ||
| 1341 | + fork_daemon = 1; | ||
| 1342 | + generic_lock(lock_fd, 1, 0, 0); | ||
| 1343 | + } | ||
| 1344 | + | ||
| 1345 | + close(lock_fd); | ||
| 1346 | + | ||
| 1347 | + /* Shall we fork a new daemon? */ | ||
| 1348 | + if (fork_daemon) { | ||
| 1349 | + pid_t pid; | ||
| 1350 | + | ||
| 1351 | + rs_log_info("Spawning zeroconf daemon.\n"); | ||
| 1352 | + | ||
| 1353 | + if ((pid = fork()) == -1) { | ||
| 1354 | + rs_log_crit("fork() failed: %s\n", strerror(errno)); | ||
| 1355 | + goto finish; | ||
| 1356 | + } else if (pid == 0) { | ||
| 1357 | + int fd; | ||
| 1358 | + /* Child */ | ||
| 1359 | + | ||
| 1360 | + /* Close file descriptors and replace them by /dev/null */ | ||
| 1361 | + close(0); | ||
| 1362 | + close(1); | ||
| 1363 | + close(2); | ||
| 1364 | + fd = open("/dev/null", O_RDWR); | ||
| 1365 | + assert(fd == 0); | ||
| 1366 | + fd = dup(0); | ||
| 1367 | + assert(fd == 1); | ||
| 1368 | + fd = dup(0); | ||
| 1369 | + assert(fd == 2); | ||
| 1370 | + | ||
| 1371 | +#ifdef HAVE_SETSID | ||
| 1372 | + setsid(); | ||
| 1373 | +#endif | ||
| 1374 | + | ||
| 1375 | + chdir("/"); | ||
| 1376 | + rs_add_logger(rs_logger_syslog, RS_LOG_DEBUG, NULL, 0); | ||
| 1377 | + daemon_proc(host_file, lock_file, n_slots); | ||
| 1378 | + } | ||
| 1379 | + | ||
| 1380 | + /* Parent */ | ||
| 1381 | + | ||
| 1382 | + /* Wait some time for initial host gathering */ | ||
| 1383 | + usleep(1000000); /* 1000 ms */ | ||
| 1384 | + | ||
| 1385 | + } | ||
| 1386 | + | ||
| 1387 | + /* Open host list read-only */ | ||
| 1388 | + if ((host_fd = open(host_file, O_RDONLY)) < 0) { | ||
| 1389 | + rs_log_crit("open('%s') failed: %s\n", host_file, strerror(errno)); | ||
| 1390 | + goto finish; | ||
| 1391 | + } | ||
| 1392 | + | ||
| 1393 | + /* A read lock */ | ||
| 1394 | + if (generic_lock(host_fd, 0, 1, 1) < 0) { | ||
| 1395 | + rs_log_crit("lock failed: %s\n", strerror(errno)); | ||
| 1396 | + goto finish; | ||
| 1397 | + } | ||
| 1398 | + | ||
| 1399 | + /* Get file size */ | ||
| 1400 | + if (fstat(host_fd, &st) < 0) { | ||
| 1401 | + rs_log_crit("stat() failed: %s\n", strerror(errno)); | ||
| 1402 | + goto finish; | ||
| 1403 | + } | ||
| 1404 | + | ||
| 1405 | + if (st.st_size >= MAX_FILE_SIZE) { | ||
| 1406 | + rs_log_crit("file too large.\n"); | ||
| 1407 | + goto finish; | ||
| 1408 | + } | ||
| 1409 | + | ||
| 1410 | + /* read file data */ | ||
| 1411 | + s = malloc((size_t) st.st_size+1); | ||
| 1412 | + assert(s); | ||
| 1413 | + | ||
| 1414 | + if (dcc_readx(host_fd, s, (size_t) st.st_size) != 0) { | ||
| 1415 | + rs_log_crit("failed to read from file.\n"); | ||
| 1416 | + goto finish; | ||
| 1417 | + } | ||
| 1418 | + s[st.st_size] = 0; | ||
| 1419 | + | ||
| 1420 | + /* Parse host data */ | ||
| 1421 | + if (dcc_parse_hosts(s, host_file, ret_list, ret_nhosts, ret_prev) != 0) { | ||
| 1422 | + rs_log_crit("failed to parse host file.\n"); | ||
| 1423 | + goto finish; | ||
| 1424 | + } | ||
| 1425 | + | ||
| 1426 | + r = 0; | ||
| 1427 | + | ||
| 1428 | +finish: | ||
| 1429 | + if (host_fd >= 0) { | ||
| 1430 | + generic_lock(host_fd, 0, 0, 1); | ||
| 1431 | + close(host_fd); | ||
| 1432 | + } | ||
| 1433 | + | ||
| 1434 | + free(s); | ||
| 1435 | + | ||
| 1436 | + return r; | ||
| 1437 | +} | ||
| 1438 | + | ||
| 1439 | --- upstream/src/zeroconf-reg.c 1970-01-01 01:00:00.000000000 +0100 | ||
| 1440 | +++ lennart/src/zeroconf-reg.c 2005-11-18 15:34:00.000000000 +0100 | ||
| 1441 | @@ -0,0 +1,297 @@ | ||
| 1442 | +/* -*- c-file-style: "java"; indent-tabs-mode: nil -*- */ | ||
| 1443 | + | ||
| 1444 | +#include "config.h" | ||
| 1445 | + | ||
| 1446 | +#include <assert.h> | ||
| 1447 | +#include <stdio.h> | ||
| 1448 | +#include <sys/select.h> | ||
| 1449 | +#include <signal.h> | ||
| 1450 | +#include <sys/file.h> | ||
| 1451 | +#include <sys/time.h> | ||
| 1452 | +#include <time.h> | ||
| 1453 | +#include <sys/stat.h> | ||
| 1454 | +#include <sys/poll.h> | ||
| 1455 | +#include <pthread.h> | ||
| 1456 | +#include <stdlib.h> | ||
| 1457 | +#include <unistd.h> | ||
| 1458 | +#include <string.h> | ||
| 1459 | +#include <errno.h> | ||
| 1460 | + | ||
| 1461 | +#include <avahi-common/simple-watch.h> | ||
| 1462 | +#include <avahi-common/error.h> | ||
| 1463 | +#include <avahi-common/alternative.h> | ||
| 1464 | +#include <avahi-common/malloc.h> | ||
| 1465 | +#include <avahi-client/publish.h> | ||
| 1466 | + | ||
| 1467 | +#include "distcc.h" | ||
| 1468 | +#include "zeroconf.h" | ||
| 1469 | +#include "trace.h" | ||
| 1470 | +#include "exitcode.h" | ||
| 1471 | + | ||
| 1472 | +struct context { | ||
| 1473 | + int thread_running; | ||
| 1474 | + pthread_t thread_id; | ||
| 1475 | + pthread_mutex_t mutex; | ||
| 1476 | + char *name; | ||
| 1477 | + AvahiSimplePoll *simple_poll; | ||
| 1478 | + AvahiClient *client; | ||
| 1479 | + AvahiEntryGroup *group; | ||
| 1480 | + uint16_t port; | ||
| 1481 | + int n_cpus; | ||
| 1482 | +}; | ||
| 1483 | + | ||
| 1484 | +static void publish_reply(AvahiEntryGroup *g, AvahiEntryGroupState state, void *userdata); | ||
| 1485 | + | ||
| 1486 | +static void register_stuff(struct context *ctx) { | ||
| 1487 | + | ||
| 1488 | + if (!ctx->group) { | ||
| 1489 | + | ||
| 1490 | + if (!(ctx->group = avahi_entry_group_new(ctx->client, publish_reply, ctx))) { | ||
| 1491 | + rs_log_crit("Failed to create entry group: %s\n", avahi_strerror(avahi_client_errno(ctx->client))); | ||
| 1492 | + goto fail; | ||
| 1493 | + } | ||
| 1494 | + | ||
| 1495 | + } | ||
| 1496 | + | ||
| 1497 | + if (avahi_entry_group_is_empty(ctx->group)) { | ||
| 1498 | + char cpus[32]; | ||
| 1499 | + | ||
| 1500 | + snprintf(cpus, sizeof(cpus), "cpus=%i", ctx->n_cpus); | ||
| 1501 | + | ||
| 1502 | + /* Register our service */ | ||
| 1503 | + | ||
| 1504 | + if (avahi_entry_group_add_service(ctx->group, | ||
| 1505 | + AVAHI_IF_UNSPEC, | ||
| 1506 | + AVAHI_PROTO_UNSPEC, | ||
| 1507 | + 0, | ||
| 1508 | + ctx->name, | ||
| 1509 | + DCC_DNS_SERVICE_TYPE, | ||
| 1510 | + NULL, | ||
| 1511 | + NULL, | ||
| 1512 | + ctx->port, | ||
| 1513 | + "txtvers=1", | ||
| 1514 | + cpus, | ||
| 1515 | + "distcc="PACKAGE_VERSION, | ||
| 1516 | + "gnuhost="GNU_HOST, | ||
| 1517 | + NULL) < 0) { | ||
| 1518 | + rs_log_crit("Failed to add service: %s\n", avahi_strerror(avahi_client_errno(ctx->client))); | ||
| 1519 | + goto fail; | ||
| 1520 | + } | ||
| 1521 | + | ||
| 1522 | + if (avahi_entry_group_commit(ctx->group) < 0) { | ||
| 1523 | + rs_log_crit("Failed to commit entry group: %s\n", avahi_strerror(avahi_client_errno(ctx->client))); | ||
| 1524 | + goto fail; | ||
| 1525 | + } | ||
| 1526 | + } | ||
| 1527 | + | ||
| 1528 | + return; | ||
| 1529 | + | ||
| 1530 | + fail: | ||
| 1531 | + avahi_simple_poll_quit(ctx->simple_poll); | ||
| 1532 | +} | ||
| 1533 | + | ||
| 1534 | +/* Called when publishing of service data completes */ | ||
| 1535 | +static void publish_reply(AvahiEntryGroup *UNUSED(g), AvahiEntryGroupState state, void *userdata) { | ||
| 1536 | + struct context *ctx = userdata; | ||
| 1537 | + | ||
| 1538 | + switch (state) { | ||
| 1539 | + | ||
| 1540 | + case AVAHI_ENTRY_GROUP_COLLISION: { | ||
| 1541 | + char *n; | ||
| 1542 | + | ||
| 1543 | + /* Pick a new name for our service */ | ||
| 1544 | + | ||
| 1545 | + n = avahi_alternative_service_name(ctx->name); | ||
| 1546 | + assert(n); | ||
| 1547 | + | ||
| 1548 | + avahi_free(ctx->name); | ||
| 1549 | + ctx->name = n; | ||
| 1550 | + | ||
| 1551 | + register_stuff(ctx); | ||
| 1552 | + break; | ||
| 1553 | + } | ||
| 1554 | + | ||
| 1555 | + case AVAHI_ENTRY_GROUP_FAILURE: | ||
| 1556 | + rs_log_crit("Failed to register service: %s\n", avahi_strerror(avahi_client_errno(ctx->client))); | ||
| 1557 | + avahi_simple_poll_quit(ctx->simple_poll); | ||
| 1558 | + break; | ||
| 1559 | + | ||
| 1560 | + case AVAHI_ENTRY_GROUP_UNCOMMITED: | ||
| 1561 | + case AVAHI_ENTRY_GROUP_REGISTERING: | ||
| 1562 | + case AVAHI_ENTRY_GROUP_ESTABLISHED: | ||
| 1563 | + ; | ||
| 1564 | + } | ||
| 1565 | +} | ||
| 1566 | + | ||
| 1567 | +static void client_callback(AvahiClient *client, AvahiClientState state, void *userdata) { | ||
| 1568 | + struct context *ctx = userdata; | ||
| 1569 | + | ||
| 1570 | + ctx->client = client; | ||
| 1571 | + | ||
| 1572 | + switch (state) { | ||
| 1573 | + | ||
| 1574 | + case AVAHI_CLIENT_S_RUNNING: | ||
| 1575 | + | ||
| 1576 | + register_stuff(ctx); | ||
| 1577 | + break; | ||
| 1578 | + | ||
| 1579 | + case AVAHI_CLIENT_S_COLLISION: | ||
| 1580 | + | ||
| 1581 | + if (ctx->group) | ||
| 1582 | + avahi_entry_group_reset(ctx->group); | ||
| 1583 | + break; | ||
| 1584 | + | ||
| 1585 | + case AVAHI_CLIENT_FAILURE: | ||
| 1586 | + | ||
| 1587 | + if (avahi_client_errno(client) == AVAHI_ERR_DISCONNECTED) { | ||
| 1588 | + int error; | ||
| 1589 | + | ||
| 1590 | + avahi_client_free(ctx->client); | ||
| 1591 | + ctx->client = NULL; | ||
| 1592 | + ctx->group = NULL; | ||
| 1593 | + | ||
| 1594 | + /* Reconnect to the server */ | ||
| 1595 | + | ||
| 1596 | + if (!(ctx->client = avahi_client_new(avahi_simple_poll_get(ctx->simple_poll), | ||
| 1597 | + AVAHI_CLIENT_NO_FAIL, | ||
| 1598 | + client_callback, | ||
| 1599 | + ctx, | ||
| 1600 | + &error))) { | ||
| 1601 | + | ||
| 1602 | + rs_log_crit("Failed to contact server: %s\n", avahi_strerror(error)); | ||
| 1603 | + avahi_simple_poll_quit(ctx->simple_poll); | ||
| 1604 | + } | ||
| 1605 | + | ||
| 1606 | + } else { | ||
| 1607 | + rs_log_crit("Client failure: %s\n", avahi_strerror(avahi_client_errno(client))); | ||
| 1608 | + avahi_simple_poll_quit(ctx->simple_poll); | ||
| 1609 | + } | ||
| 1610 | + | ||
| 1611 | + break; | ||
| 1612 | + | ||
| 1613 | + case AVAHI_CLIENT_S_REGISTERING: | ||
| 1614 | + case AVAHI_CLIENT_CONNECTING: | ||
| 1615 | + ; | ||
| 1616 | + } | ||
| 1617 | +} | ||
| 1618 | + | ||
| 1619 | +static void* thread(void *userdata) { | ||
| 1620 | + struct context *ctx = userdata; | ||
| 1621 | + sigset_t mask; | ||
| 1622 | + int r; | ||
| 1623 | + | ||
| 1624 | + /* Make sure that signals are delivered to the main thread */ | ||
| 1625 | + sigfillset(&mask); | ||
| 1626 | + pthread_sigmask(SIG_BLOCK, &mask, NULL); | ||
| 1627 | + | ||
| 1628 | + pthread_mutex_lock(&ctx->mutex); | ||
| 1629 | + | ||
| 1630 | + /* Run the main loop */ | ||
| 1631 | + r = avahi_simple_poll_loop(ctx->simple_poll); | ||
| 1632 | + | ||
| 1633 | + /* Cleanup some stuff */ | ||
| 1634 | + if (ctx->client) | ||
| 1635 | + avahi_client_free(ctx->client); | ||
| 1636 | + ctx->client = NULL; | ||
| 1637 | + ctx->group = NULL; | ||
| 1638 | + | ||
| 1639 | + pthread_mutex_unlock(&ctx->mutex); | ||
| 1640 | + | ||
| 1641 | + return NULL; | ||
| 1642 | +} | ||
| 1643 | + | ||
| 1644 | +static int poll_func(struct pollfd *ufds, unsigned int nfds, int timeout, void *userdata) { | ||
| 1645 | + pthread_mutex_t *mutex = userdata; | ||
| 1646 | + int r; | ||
| 1647 | + | ||
| 1648 | + /* Before entering poll() we unlock the mutex, so that | ||
| 1649 | + * avahi_simple_poll_quit() can succeed from another thread. */ | ||
| 1650 | + | ||
| 1651 | + pthread_mutex_unlock(mutex); | ||
| 1652 | + r = poll(ufds, nfds, timeout); | ||
| 1653 | + pthread_mutex_lock(mutex); | ||
| 1654 | + | ||
| 1655 | + return r; | ||
| 1656 | +} | ||
| 1657 | + | ||
| 1658 | +/* register a distcc service in DNS-SD/mDNS with the given port and number of CPUs */ | ||
| 1659 | +void* dcc_zeroconf_register(uint16_t port, int n_cpus) { | ||
| 1660 | + struct context *ctx = NULL; | ||
| 1661 | + | ||
| 1662 | + char service[256] = "distcc@"; | ||
| 1663 | + int error, ret; | ||
| 1664 | + | ||
| 1665 | + ctx = malloc(sizeof(struct context)); | ||
| 1666 | + assert(ctx); | ||
| 1667 | + ctx->client = NULL; | ||
| 1668 | + ctx->group = NULL; | ||
| 1669 | + ctx->simple_poll = NULL; | ||
| 1670 | + ctx->thread_running = 0; | ||
| 1671 | + ctx->port = port; | ||
| 1672 | + ctx->n_cpus = n_cpus; | ||
| 1673 | + pthread_mutex_init(&ctx->mutex, NULL); | ||
| 1674 | + | ||
| 1675 | + /* Prepare service name */ | ||
| 1676 | + gethostname(service+7, sizeof(service)-8); | ||
| 1677 | + service[sizeof(service)-1] = 0; | ||
| 1678 | + | ||
| 1679 | + ctx->name = strdup(service); | ||
| 1680 | + assert(ctx->name); | ||
| 1681 | + | ||
| 1682 | + if (!(ctx->simple_poll = avahi_simple_poll_new())) { | ||
| 1683 | + rs_log_crit("Failed to create event loop object.\n"); | ||
| 1684 | + goto fail; | ||
| 1685 | + } | ||
| 1686 | + | ||
| 1687 | + avahi_simple_poll_set_func(ctx->simple_poll, poll_func, &ctx->mutex); | ||
| 1688 | + | ||
| 1689 | + if (!(ctx->client = avahi_client_new(avahi_simple_poll_get(ctx->simple_poll), AVAHI_CLIENT_NO_FAIL, client_callback, ctx, &error))) { | ||
| 1690 | + rs_log_crit("Failed to create client object: %s\n", avahi_strerror(avahi_client_errno(ctx->client))); | ||
| 1691 | + goto fail; | ||
| 1692 | + } | ||
| 1693 | + | ||
| 1694 | + /* Create the mDNS event handler */ | ||
| 1695 | + if ((ret = pthread_create(&ctx->thread_id, NULL, thread, ctx)) < 0) { | ||
| 1696 | + rs_log_crit("Failed to create thread: %s\n", strerror(ret)); | ||
| 1697 | + goto fail; | ||
| 1698 | + } | ||
| 1699 | + | ||
| 1700 | + ctx->thread_running = 1; | ||
| 1701 | + | ||
| 1702 | + return ctx; | ||
| 1703 | + | ||
| 1704 | + fail: | ||
| 1705 | + | ||
| 1706 | + if (ctx) | ||
| 1707 | + dcc_zeroconf_unregister(ctx); | ||
| 1708 | + | ||
| 1709 | + return NULL; | ||
| 1710 | +} | ||
| 1711 | + | ||
| 1712 | +/* Unregister this server from DNS-SD/mDNS */ | ||
| 1713 | +int dcc_zeroconf_unregister(void *u) { | ||
| 1714 | + struct context *ctx = u; | ||
| 1715 | + | ||
| 1716 | + if (ctx->thread_running) { | ||
| 1717 | + pthread_mutex_lock(&ctx->mutex); | ||
| 1718 | + avahi_simple_poll_quit(ctx->simple_poll); | ||
| 1719 | + pthread_mutex_unlock(&ctx->mutex); | ||
| 1720 | + | ||
| 1721 | + pthread_join(ctx->thread_id, NULL); | ||
| 1722 | + ctx->thread_running = 0; | ||
| 1723 | + } | ||
| 1724 | + | ||
| 1725 | + avahi_free(ctx->name); | ||
| 1726 | + | ||
| 1727 | + if (ctx->client) | ||
| 1728 | + avahi_client_free(ctx->client); | ||
| 1729 | + | ||
| 1730 | + if (ctx->simple_poll) | ||
| 1731 | + avahi_simple_poll_free(ctx->simple_poll); | ||
| 1732 | + | ||
| 1733 | + pthread_mutex_destroy(&ctx->mutex); | ||
| 1734 | + | ||
| 1735 | + free(ctx); | ||
| 1736 | + | ||
| 1737 | + return 0; | ||
| 1738 | +} | ||
diff --git a/meta/recipes-devtools/distcc/files/makefile-param-order.patch b/meta/recipes-devtools/distcc/files/makefile-param-order.patch deleted file mode 100644 index fc57414f12..0000000000 --- a/meta/recipes-devtools/distcc/files/makefile-param-order.patch +++ /dev/null | |||
| @@ -1,20 +0,0 @@ | |||
| 1 | distcc: Put the "-lLIB" parameter in the end of the gcc command. | ||
| 2 | |||
| 3 | Signed-off-by: Dongxiao Xu <dongxiao.xu@intel.com> | ||
| 4 | |||
| 5 | Upstream-Status: Pending | ||
| 6 | |||
| 7 | diff -ruN distcc-2.18.3-orig/Makefile.in distcc-2.18.3/Makefile.in | ||
| 8 | --- distcc-2.18.3-orig/Makefile.in 2011-07-25 16:43:21.000000000 +0800 | ||
| 9 | +++ distcc-2.18.3/Makefile.in 2011-07-25 16:45:39.000000000 +0800 | ||
| 10 | @@ -378,8 +378,8 @@ | ||
| 11 | |||
| 12 | distccmon-gnome@EXEEXT@: $(mon_obj) $(gnome_obj) | ||
| 13 | $(CC) -o $@ $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(LIBS) \ | ||
| 14 | - $(GNOME_CFLAGS) $(GNOME_LIBS) \ | ||
| 15 | - $(mon_obj) $(gnome_obj) | ||
| 16 | + $(GNOME_CFLAGS) \ | ||
| 17 | + $(mon_obj) $(gnome_obj) $(GNOME_LIBS) | ||
| 18 | |||
| 19 | |||
| 20 | ## Dist targets | ||
