#if defined(DARWIN)
#include <arpa/inet.h>
#include <errno.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include "config.h"
#include "distcc.h"
#include "io.h"
#include "rpc.h"
#include "trace.h"
#include "util.h"
#include "zeroconf_client.h"
#include "zeroconf_util.h"
static int open_socket_out(int port, int *errorVal)
{
int res;
struct sockaddr_in sock;
struct timeval timeout = { 1, 0 };
*errorVal = 0;
if (port < 1 || port > 65535) {
rs_log_error("port number out of range: %d", port);
return -1;
}
memset((char *) &sock, 0, sizeof(sock));
sock.sin_port = htons(port);
sock.sin_family = PF_INET;
sock.sin_addr.s_addr = INADDR_ANY;
res = socket(PF_INET, SOCK_STREAM, 0);
if (res == -1) {
rs_log_error("socket creation failed: %s", strerror(errno));
*errorVal = errno;
return -1;
}
setsockopt(res, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
if ( connect(res, (struct sockaddr *) &sock, (int) sizeof(sock)) == 0 ) {
rs_trace("client got connection to port %d on fd%d", port, res);
} else {
rs_log_error("failed to connect to port %d: (%d) %s", port,
errno, strerror(errno));
*errorVal = errno;
close(res);
return -1;
}
return res;
}
void dcc_zc_get_resolved_services_list(char **listPtr)
{
int len;
int errorVal;
int netfd = open_socket_out(DISTCC_DEFAULT_SCHEDULER_PORT, &errorVal);
if ( netfd == -1 ) {
int maxRetries = 30;
char *path = (char *) "/usr/bin/distccschedd";
int ret;
int retries = 0;
if (dcc_getenv_bool("DISTCC_VERBOSE", 0)) {
char *args[] = { path, (char *) "--daemon", (char *) "--verbose",
(char *) "--log-file=/tmp/distccHelperLog", NULL };
ret = dcc_simple_spawn(path, args);
} else {
char *args[] = { path, (char *) "--daemon", NULL };
ret = dcc_simple_spawn(path, args);
}
if ( ret != 0 ) {
rs_trace("Unable to start distccschedd after failing to contact it once.");
}
rs_trace("Attempting to contact distccschedd again.");
do {
retries++;
rs_trace("Pausing to allow distccschedd to initialize");
sleep(1);
rs_trace("Finished pausing");
netfd = open_socket_out(DISTCC_DEFAULT_SCHEDULER_PORT,
&errorVal);
} while ( netfd == -1 && retries <= maxRetries &&
( errorVal == ETIMEDOUT || errorVal == ECONNREFUSED ) );
}
if ( netfd == -1 ) {
rs_log_error("Unable to open port %u to contact distccschedd",
DISTCC_DEFAULT_SCHEDULER_PORT);
} else {
if ( dcc_r_token_int(netfd, DISTCC_DEFAULT_ZC_LIST_LEN_TOKEN,
&len) == 0 ) {
int exitVal = dcc_r_str_alloc(netfd, len, listPtr);
if ( exitVal == 0 ) {
rs_trace("Read zeroconfig service list: %s", *listPtr);
} else {
rs_log_error("Unable to read zeroconfig service list: (%d) %s",
exitVal, strerror(exitVal));
}
} else {
rs_log_error("Unable to read zeroconfig service list length");
}
close(netfd);
}
}
#endif // DARWIN