| 140 | } |
| 141 | |
| 142 | void fxConnect(txMachine* the) |
| 143 | { |
| 144 | struct hostent *host; |
| 145 | struct sockaddr_in address; |
| 146 | int fd = -1; |
| 147 | int flag; |
| 148 | char *hostname = "localhost"; |
| 149 | if (getenv("XSBUG_HOST")) |
| 150 | hostname = getenv("XSBUG_HOST"); |
| 151 | host = gethostbyname(hostname); |
| 152 | if (!host) |
| 153 | goto bail; |
| 154 | memset(&address, 0, sizeof(address)); |
| 155 | address.sin_family = AF_INET; |
| 156 | memcpy(&(address.sin_addr), host->h_addr, host->h_length); |
| 157 | if (strstr(program_invocation_name, "xsbug")) |
| 158 | address.sin_port = htons(5003); |
| 159 | else { |
| 160 | int port = 5002; |
| 161 | char *portStr = getenv("XSBUG_PORT"); |
| 162 | if (portStr) |
| 163 | port = atoi(portStr); |
| 164 | address.sin_port = htons(port); |
| 165 | } |
| 166 | fd = socket(AF_INET, SOCK_STREAM, 0); |
| 167 | if (fd < 0) |
| 168 | return; |
| 169 | signal(SIGPIPE, SIG_IGN); |
| 170 | flag = fcntl(fd, F_GETFL, 0); |
| 171 | fcntl(fd, F_SETFL, flag | O_NONBLOCK); |
| 172 | if (connect(fd, (struct sockaddr*)&address, sizeof(address)) < 0) { |
| 173 | if (errno == EINPROGRESS) { |
| 174 | fd_set fds; |
| 175 | struct timeval timeout = { 2, 0 }; // 2 seconds, 0 micro-seconds |
| 176 | int error = 0; |
| 177 | unsigned int length = sizeof(error); |
| 178 | FD_ZERO(&fds); |
| 179 | FD_SET(fd, &fds); |
| 180 | if (select(fd + 1, NULL, &fds, NULL, &timeout) == 0) |
| 181 | goto bail; |
| 182 | if (!FD_ISSET(fd, &fds)) |
| 183 | goto bail; |
| 184 | if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &length) < 0) |
| 185 | goto bail; |
| 186 | if (error) |
| 187 | goto bail; |
| 188 | } |
| 189 | else |
| 190 | goto bail; |
| 191 | } |
| 192 | fcntl(fd, F_SETFL, flag); |
| 193 | signal(SIGPIPE, SIG_DFL); |
| 194 | the->socket = g_socket_new_from_fd(fd, NULL); |
| 195 | if (!the->socket) |
| 196 | goto bail; |
| 197 | g_socket_set_blocking(the->socket, FALSE); |
| 198 | the->source = g_socket_create_source(the->socket, G_IO_IN, NULL); |
| 199 | g_source_set_callback(the->source, (void*)fxReadableCallback, the, NULL); |