See changes in changelog, but...
[awesomized/libmemcached] / lib / memcached_connect.c
1 #include "common.h"
2
3 #include <fcntl.h>
4 #include <sys/types.h>
5 #include <sys/socket.h>
6 #include <netinet/tcp.h>
7
8 memcached_return memcached_connect(memcached_st *ptr)
9 {
10 unsigned int x;
11 struct sockaddr_in localAddr, servAddr;
12 struct hostent *h;
13
14 LIBMEMCACHED_MEMCACHED_CONNECT_START();
15
16 if (ptr->connected == ptr->number_of_hosts)
17 return MEMCACHED_SUCCESS;
18
19 if (!ptr->hosts)
20 return MEMCACHED_NO_SERVERS;
21
22 for (x= 0; x < ptr->number_of_hosts; x++)
23 {
24 if (ptr->hosts[x].fd == -1)
25 {
26 if ((h= gethostbyname(ptr->hosts[x].hostname)) == NULL)
27 return MEMCACHED_HOST_LOCKUP_FAILURE;
28
29 servAddr.sin_family= h->h_addrtype;
30 memcpy((char *) &servAddr.sin_addr.s_addr, h->h_addr_list[0], h->h_length);
31 servAddr.sin_port = htons(ptr->hosts[x].port);
32
33 /* Create the socket */
34 if ((ptr->hosts[x].fd= socket(AF_INET, SOCK_STREAM, 0)) < 0)
35 {
36 ptr->my_errno= errno;
37 return MEMCACHED_CONNECTION_SOCKET_CREATE_FAILURE;
38 }
39
40
41 /* bind any port number */
42 localAddr.sin_family = AF_INET;
43 localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
44 localAddr.sin_port = htons(0);
45
46 /* For the moment, not getting a nonblocking mode will note be fatal */
47 if (ptr->flags & MEM_NO_BLOCK)
48 {
49 int flags;
50
51 flags= fcntl(ptr->hosts[x].fd, F_GETFL, 0);
52 if (flags != -1)
53 (void)fcntl(ptr->hosts[x].fd, F_SETFL, flags | O_NONBLOCK);
54 }
55
56 if (ptr->flags & MEM_TCP_NODELAY)
57 {
58 int flag= 1;
59
60 setsockopt(ptr->hosts[x].fd, IPPROTO_TCP, TCP_NODELAY,
61 &flag, (socklen_t)sizeof(int));
62 }
63
64 /* connect to server */
65 test_connect:
66 if (connect(ptr->hosts[x].fd, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0)
67 {
68 switch (errno) {
69 /* We are spinning waiting on connect */
70 case EINPROGRESS:
71 case EINTR:
72 goto test_connect;
73 case EISCONN: /* We were spinning waiting on connect */
74 break;
75 default:
76 ptr->my_errno= errno;
77 return MEMCACHED_HOST_LOCKUP_FAILURE;
78 }
79
80 ptr->connected++;
81 }
82 }
83 }
84 LIBMEMCACHED_MEMCACHED_CONNECT_END();
85
86 return MEMCACHED_SUCCESS;
87 }