+int population_add_peer (population_t *p, const char *node, /* {{{ */
+ const char *port)
+{
+ struct addrinfo ai_hints;
+ struct addrinfo *ai_list;
+ struct addrinfo *ai_ptr;
+ int status;
+
+ if (p == NULL)
+ return (-1);
+
+ if (node == NULL)
+ return (-1);
+
+ if (port == NULL)
+ port = POPULATION_DEFAULT_PORT;
+
+ ai_list = NULL;
+
+ memset (&ai_hints, 0, sizeof (ai_hints));
+ ai_hints.ai_flags = 0;
+#ifdef AI_ADDRCONFIG
+ ai_hints.ai_flags |= AI_ADDRCONFIG;
+#endif
+ ai_hints.ai_family = AF_UNSPEC;
+ ai_hints.ai_socktype = SOCK_DGRAM;
+ ai_hints.ai_protocol = 0;
+
+ status = getaddrinfo (node, port, &ai_hints, &ai_list);
+ if (status != 0)
+ {
+ fprintf (stderr, "population_add_peer: getaddrinfo (%s) failed: %s\n",
+ node, gai_strerror (status));
+ return (-1);
+ }
+
+ pthread_mutex_lock (&p->lock);
+
+ for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+ {
+ int *temp;
+
+ temp = (int *) realloc (p->peers, sizeof (int) * (p->peers_num + 1));
+ if (temp == NULL)
+ {
+ fprintf (stderr, "population_add_peer: realloc failed.\n");
+ continue;
+ }
+ p->peers = temp;
+
+ p->peers[p->peers_num] = socket (ai_ptr->ai_family, ai_ptr->ai_socktype,
+ ai_ptr->ai_protocol);
+ if (p->peers[p->peers_num] < 0)
+ continue;
+
+ status = connect (p->peers[p->peers_num],
+ ai_ptr->ai_addr, ai_ptr->ai_addrlen);
+ if (status != 0)
+ {
+ fprintf (stderr, "population_add_peer: connect(2) failed.\n");
+ close (p->peers[p->peers_num]);
+ continue;
+ }
+
+ status = fcntl (p->peers[p->peers_num], F_SETFL, O_NONBLOCK);
+ if (status != 0)
+ {
+ fprintf (stderr, "population_add_peer: fcntl (F_SETFL, O_NONBLOCK) "
+ "failed. Will use the socket with blocking.\n");
+ }
+
+ p->peers_num++;
+ }
+ pthread_mutex_unlock (&p->lock);
+
+ freeaddrinfo (ai_list);
+
+ return (0);
+} /* }}} int population_add_peer */
+