--- src/distcc.c.orig Mon May 5 07:25:00 2003 +++ src/distcc.c Mon May 5 21:07:30 2003 @@ -117,8 +117,14 @@ "Each host can be given in any of these forms:\n" "\n" " localhost run in place\n" -" HOST TCP connection, port %d\n" -" HOST:PORT TCP connection, specified port\n" +" HOST[:PORT][,OPT...] TCP connection (default port=%d)\n" +"\n" +"OPT Values:\n" +" slots=N Maximum of N simultaneous jobs allowed\n" +" N Abbreviation of the slots=N option\n" +"\n" +"Hostname examples:\n" +" foo foo:4242 foo,4 bar:4100,2 bar,slots=3\n" " @HOST SSH connection\n" " USER$HOST SSH connection to specified host\n" "\n" --- src/hosts.c.orig Mon May 5 06:59:53 2003 +++ src/hosts.c Mon May 5 21:01:23 2003 @@ -176,21 +176,43 @@ } -static int dcc_parse_multiplier(const char **psrc, struct dcc_hostdef *hostdef) +static int dcc_parse_options(const char **psrc, struct dcc_hostdef *hostdef) { - char *mul; - const char *token = *psrc; + char *opt, *arg; + const char *token; int ret; - if ((*psrc)[0] == '/') { - (*psrc)++; - if ((ret = dcc_dup_part(psrc, &mul, "/: \t\n\f")) != 0) + while ((*psrc)[0] == ',') { + token = (*psrc)++; + if ((ret = dcc_dup_part(psrc, &opt, ", \t\n\f")) != 0) return ret; - if (!mul || atoi(mul) == 0) { - rs_log_error("bad multiplier \"%s\" in host specification", token); + if (opt) { + if ((arg = strchr(opt, '=')) != NULL) + *arg++ = '\0'; + else if (isdigit(*opt)) { + arg = opt; + opt = NULL; + } + else + arg = NULL; + } + else + arg = NULL; + if (!arg) { + rs_log_error("malformed option in host specification: \"%s\"", token); + return EXIT_BAD_HOSTSPEC; + } + if (!opt || strcmp(opt, "slots") == 0) { + hostdef->n_slots = atoi(arg); + if (hostdef->n_slots <= 0) { + rs_log_error("invalid number of slots in host specification: \"%s\"", token); + return EXIT_BAD_HOSTSPEC; + } + } + else { + rs_log_error("unknown option in host specification: \"%s\"", token); return EXIT_BAD_HOSTSPEC; } - hostdef->n_slots = atoi(mul); } return 0; } @@ -211,7 +233,7 @@ token++; - if ((ret = dcc_dup_part(&token, &hostdef->hostname, "/: \t\n\f")) != 0) + if ((ret = dcc_dup_part(&token, &hostdef->hostname, ",: \t\n\f")) != 0) return ret; if (!hostdef->hostname) { @@ -220,15 +242,15 @@ return EXIT_BAD_HOSTSPEC; } - if ((ret = dcc_parse_multiplier(&token, hostdef)) != 0) - return ret; - if (token[0] == ':') { token++; - if ((ret = dcc_dup_part(&token, &hostdef->ssh_command, " \t\n\f")) != 0) + if ((ret = dcc_dup_part(&token, &hostdef->ssh_command, ", \t\n\f")) != 0) return ret; } - + + if ((ret = dcc_parse_options(&token, hostdef)) != 0) + return ret; + hostdef->mode = DCC_MODE_SSH; return 0; } @@ -241,7 +263,7 @@ int ret; const char *token = token_start; - if ((ret = dcc_dup_part(&token, &hostdef->hostname, "/: \t\n\f")) != 0) + if ((ret = dcc_dup_part(&token, &hostdef->hostname, ",: \t\n\f")) != 0) return ret; if (!hostdef->hostname) { @@ -250,14 +272,11 @@ return EXIT_BAD_HOSTSPEC; } - if ((ret = dcc_parse_multiplier(&token, hostdef)) != 0) - return ret; - hostdef->port = dcc_default_port; if (token[0] == ':') { token++; - if ((ret = dcc_dup_part(&token, &port_str, " \t\n\f")) != 0) + if ((ret = dcc_dup_part(&token, &port_str, ", \t\n\f")) != 0) return ret; if (port_str) { @@ -270,7 +289,10 @@ free(port_str); } } - + + if ((ret = dcc_parse_options(&token, hostdef)) != 0) + return ret; + hostdef->mode = DCC_MODE_TCP; return 0; } @@ -279,13 +301,13 @@ static int dcc_parse_localhost(struct dcc_hostdef *hostdef, const char * token_start) { - const char *token = token_start + strlen("localhost"); + const char *token = token_start + (sizeof "localhost") - 1; hostdef->mode = DCC_MODE_LOCAL; hostdef->hostname = strdup("localhost"); hostdef->n_slots = 1; - return dcc_parse_multiplier(&token, hostdef); + return dcc_parse_options(&token, hostdef); } @@ -316,7 +338,7 @@ * definition. We then duplicate the relevant subcomponents into * the relevant fields. */ while (1) { - int token_len; + unsigned int token_len; const char *token_start; int has_at; @@ -347,8 +369,10 @@ has_at = (memchr(token_start, '@', token_len) != NULL); - if (!strncmp(token_start, "localhost", token_len) - || !strncmp(token_start, "localhost/", strlen("localhost/"))) { + if (token_len >= (sizeof "localhost")-1 + && strncmp(token_start, "localhost", (sizeof "localhost")-1) == 0 + && (token_len == (sizeof "localhost")-1 + || token_start[(sizeof "localhost")-1] == ',')) { if ((ret = dcc_parse_localhost(curr, token_start)) != 0) return ret; } else if (has_at) { --- linuxdoc/distcc.sgml.orig Fri May 16 08:43:29 2003 +++ linuxdoc/distcc.sgml Sat May 17 21:38:13 2003 @@ -174,7 +174,7 @@ On the client, set the DISTCC_HOSTS environment variable to indicate which volunteer machines to use. For example: - DISTCC_HOSTS='angry toey:4202 localhost' + HOSTNAME[:PORT][,OPT...] Set the CC variable or edit Makefiles to prefix @@ -182,6 +182,13 @@ distcc gcc -o hello.o -c hello.c

+ +

+ You can specify one or more host-specific options at the end of the + host-spec by appending each one after a comma. The current option + is slots=N (abbreviated as just N, if desired). + The "slots" option specifies the maximum number of jobs that the + associated host should be given simultaneously (e.g. "localhost,2").