2 * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
6 * This file may be distributed and/or modified under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation and appearing in the file LICENSE.GPL included in the
9 * packaging of this file.
11 * Licensees holding valid libFirm Professional Edition licenses may use
12 * this file in accordance with the libFirm Commercial License.
13 * Agreement provided with the Software.
15 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * @brief TCP/IP handling (Windows and Unix like systems)
23 * @author Christian Wuerdig, implementation copied from liblpp created by Sebastian Hack
30 #endif /* HAVE_CONFIG_H */
32 #include "firmnet_t.h"
35 static int winsock_init(void) {
36 WORD wVersionRequested;
40 wVersionRequested = MAKEWORD( 2, 2 );
42 err = WSAStartup( wVersionRequested, &wsaData );
44 /* Tell the user that we could not find a usable */
49 /* Confirm that the WinSock DLL supports 2.2.*/
50 /* Note that if the DLL supports versions greater */
51 /* than 2.2 in addition to 2.2, it will still return */
52 /* 2.2 in wVersion since that is the version we */
55 if ( LOBYTE( wsaData.wVersion ) != 2 ||
56 HIBYTE( wsaData.wVersion ) != 2 ) {
57 /* Tell the user that we could not find a usable */
66 int firmnet_connect_tcp(const char *host, uint16_t port)
70 struct sockaddr_in sin;
77 memset(&sin, 0, sizeof(sin));
78 sin.sin_family = AF_INET;
79 sin.sin_port = htons(port);
81 if ((phe = gethostbyname(host)))
82 memcpy(&sin.sin_addr, phe->h_addr, phe->h_length);
83 else if((sin.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE) {
84 fprintf(stderr, "cannot get host entry for %s", host);
88 ppe = getprotobyname("tcp");
89 ERRNO_CHECK_RETURN(s = socket(PF_INET, SOCK_STREAM, ppe->p_proto), <, 0, -1);
90 ERRNO_CHECK_RETURN(connect(s, (struct sockaddr *) &sin, sizeof(sin)), <, 0, -1);
95 void firmnet_close_socket(int fd) {
104 * Send message of size @p n from buffer @p buf to file descriptor @p fd.
105 * @param fd The file descriptor, the message should be send to.
106 * @param buf The buffer containing the message
107 * @param n The length of the message.
108 * @return Number of bytes written or -1 on failure.
110 ssize_t firmnet_send(int fd, const void *buf, size_t n)
113 size_t bytes_written = 0;
114 const char *data = buf;
117 res = send(fd, &data[bytes_written], n - bytes_written, 0);
124 bytes_written += res;
126 } while (bytes_written < n);
132 * Try to read some bytes but block until a certain amount is read.
133 * @param fd The file descriptor.
134 * @param buf The buffer to read into.
135 * @param try The amount of bytes to try to read.
136 * @param at_least block until this many bytes are read.
137 * @return The number of bytes read or -1 on error.
139 ssize_t firmnet_recv(int fd, void *buf, size_t try, size_t at_least)
142 size_t bytes_read = 0;
146 res = recv(fd, &data[bytes_read], try - bytes_read, 0);
148 if (res == 0 || errno != EAGAIN)
155 } while (bytes_read < at_least);