Create a TCP socket and connect it to the specified address. * On success the socket descriptor is returned, otherwise -1. * * If 'nonblock' is non-zero, the socket is put in nonblocking state * and the connect() attempt will not block as well, but the socket * may not be immediately ready for writing. */
| 63 | * and the connect() attempt will not block as well, but the socket |
| 64 | * may not be immediately ready for writing. */ |
| 65 | int TCPConnect(char *addr, int port, int nonblock) { |
| 66 | int s, retval = -1; |
| 67 | struct addrinfo hints, *servinfo, *p; |
| 68 | |
| 69 | char portstr[6]; /* Max 16 bit number string length. */ |
| 70 | snprintf(portstr,sizeof(portstr),"%d",port); |
| 71 | memset(&hints,0,sizeof(hints)); |
| 72 | hints.ai_family = AF_UNSPEC; |
| 73 | hints.ai_socktype = SOCK_STREAM; |
| 74 | |
| 75 | if (getaddrinfo(addr,portstr,&hints,&servinfo) != 0) return -1; |
| 76 | |
| 77 | for (p = servinfo; p != NULL; p = p->ai_next) { |
| 78 | /* Try to create the socket and to connect it. |
| 79 | * If we fail in the socket() call, or on connect(), we retry with |
| 80 | * the next entry in servinfo. */ |
| 81 | if ((s = socket(p->ai_family,p->ai_socktype,p->ai_protocol)) == -1) |
| 82 | continue; |
| 83 | |
| 84 | /* Put in non blocking state if needed. */ |
| 85 | if (nonblock && socketSetNonBlockNoDelay(s) == -1) { |
| 86 | close(s); |
| 87 | break; |
| 88 | } |
| 89 | |
| 90 | /* Try to connect. */ |
| 91 | if (connect(s,p->ai_addr,p->ai_addrlen) == -1) { |
| 92 | /* If the socket is non-blocking, it is ok for connect() to |
| 93 | * return an EINPROGRESS error here. */ |
| 94 | if (errno == EINPROGRESS && nonblock) return s; |
| 95 | |
| 96 | /* Otherwise it's an error. */ |
| 97 | close(s); |
| 98 | break; |
| 99 | } |
| 100 | |
| 101 | /* If we ended an iteration of the for loop without errors, we |
| 102 | * have a connected socket. Let's return to the caller. */ |
| 103 | retval = s; |
| 104 | break; |
| 105 | } |
| 106 | |
| 107 | freeaddrinfo(servinfo); |
| 108 | return retval; /* Will be -1 if no connection succeded. */ |
| 109 | } |
| 110 | |
| 111 | /* If the listening socket signaled there is a new connection ready to |
| 112 | * be accepted, we accept(2) it and return -1 on error or the new client |
no test coverage detected