blob: f392bd9d2893b90e13a9f4639d37cbee386162c6 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26#include <stdlib.h>
27#include <sys/types.h>
28#include <sys/socket.h>
29#include <netinet/in.h>
30#include <arpa/inet.h>
31#include <unistd.h>
32#include <fcntl.h>
33#include <errno.h>
34#include <string.h>
35#include <sys/time.h>
36#ifdef __solaris__
37#include <thread.h>
38#endif
39#ifdef __linux__
40#include <pthread.h>
41#include <sys/poll.h>
42#endif
43
44#include "socket_md.h"
45#include "sysSocket.h"
46
47int
48dbgsysListen(int fd, INT32 count) {
49 return listen(fd, count);
50}
51
52int
53dbgsysConnect(int fd, struct sockaddr *name, int namelen) {
54 int rv = connect(fd, name, namelen);
55 if (rv < 0 && errno == EINPROGRESS) {
56 return DBG_EINPROGRESS;
57 } else {
58 return rv;
59 }
60}
61
62int
63dbgsysFinishConnect(int fd, long timeout) {
64 int rv = dbgsysPoll(fd, 0, 1, timeout);
65 if (rv == 0) {
66 return DBG_ETIMEOUT;
67 }
68 if (rv > 0) {
69 return 0;
70 }
71 return rv;
72}
73
74int
75dbgsysAccept(int fd, struct sockaddr *name, int *namelen) {
76 int rv;
77 for (;;) {
78 rv = accept(fd, name, namelen);
79 if (rv >= 0) {
80 return rv;
81 }
82 if (errno != ECONNABORTED) {
83 return rv;
84 }
85 }
86}
87
88int
89dbgsysRecvFrom(int fd, char *buf, int nBytes,
90 int flags, struct sockaddr *from, int *fromlen) {
91 return recvfrom(fd, buf, nBytes, flags, from, fromlen);
92}
93
94int
95dbgsysSendTo(int fd, char *buf, int len,
96 int flags, struct sockaddr *to, int tolen) {
97 return sendto(fd, buf, len, flags, to, tolen);
98}
99
100int
101dbgsysRecv(int fd, char *buf, int nBytes, int flags) {
102 return recv(fd, buf, nBytes, flags);
103}
104
105int
106dbgsysSend(int fd, char *buf, int nBytes, int flags) {
107 return send(fd, buf, nBytes, flags);
108}
109
110struct hostent *
111dbgsysGetHostByName(char *hostname) {
112 return gethostbyname(hostname);
113}
114
115unsigned short
116dbgsysHostToNetworkShort(unsigned short hostshort) {
117 return htons(hostshort);
118}
119
120int
121dbgsysSocket(int domain, int type, int protocol) {
122 return socket(domain, type, protocol);
123}
124
125int dbgsysSocketClose(int fd) {
126 return close(fd);
127}
128
129int
130dbgsysBind(int fd, struct sockaddr *name, int namelen) {
131 return bind(fd, name, namelen);
132}
133
134UINT32
135dbgsysInetAddr(const char* cp) {
136 return (UINT32)inet_addr(cp);
137}
138
139UINT32
140dbgsysHostToNetworkLong(UINT32 hostlong) {
141 return htonl(hostlong);
142}
143
144unsigned short
145dbgsysNetworkToHostShort(unsigned short netshort) {
146 return ntohs(netshort);
147}
148
149int
150dbgsysGetSocketName(int fd, struct sockaddr *name, int *namelen) {
151 return getsockname(fd, name, namelen);
152}
153
154UINT32
155dbgsysNetworkToHostLong(UINT32 netlong) {
156 return ntohl(netlong);
157}
158
159
160int
161dbgsysSetSocketOption(int fd, jint cmd, jboolean on, jvalue value)
162{
163 if (cmd == TCP_NODELAY) {
164 struct protoent *proto = getprotobyname("TCP");
165 int tcp_level = (proto == 0 ? IPPROTO_TCP: proto->p_proto);
166 INT32 onl = (INT32)on;
167
168 if (setsockopt(fd, tcp_level, TCP_NODELAY,
169 (char *)&onl, sizeof(INT32)) < 0) {
170 return SYS_ERR;
171 }
172 } else if (cmd == SO_LINGER) {
173 struct linger arg;
174 arg.l_onoff = on;
175
176 if(on) {
177 arg.l_linger = (unsigned short)value.i;
178 if(setsockopt(fd, SOL_SOCKET, SO_LINGER,
179 (char*)&arg, sizeof(arg)) < 0) {
180 return SYS_ERR;
181 }
182 } else {
183 if (setsockopt(fd, SOL_SOCKET, SO_LINGER,
184 (char*)&arg, sizeof(arg)) < 0) {
185 return SYS_ERR;
186 }
187 }
188 } else if (cmd == SO_SNDBUF) {
189 jint buflen = value.i;
190 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF,
191 (char *)&buflen, sizeof(buflen)) < 0) {
192 return SYS_ERR;
193 }
194 } else if (cmd == SO_REUSEADDR) {
195 int oni = (int)on;
196 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
197 (char *)&oni, sizeof(oni)) < 0) {
198 return SYS_ERR;
199
200 }
201 } else {
202 return SYS_ERR;
203 }
204 return SYS_OK;
205}
206
207int
208dbgsysConfigureBlocking(int fd, jboolean blocking) {
209 int flags = fcntl(fd, F_GETFL);
210
211 if ((blocking == JNI_FALSE) && !(flags & O_NONBLOCK)) {
212 return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
213 }
214 if ((blocking == JNI_TRUE) && (flags & O_NONBLOCK)) {
215 return fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
216 }
217 return 0;
218}
219
220int
221dbgsysPoll(int fd, jboolean rd, jboolean wr, long timeout) {
222 struct pollfd fds[1];
223 int rv;
224
225 fds[0].fd = fd;
226 fds[0].events = 0;
227 if (rd) {
228 fds[0].events |= POLLIN;
229 }
230 if (wr) {
231 fds[0].events |= POLLOUT;
232 }
233 fds[0].revents = 0;
234
235 rv = poll(&fds[0], 1, timeout);
236 if (rv >= 0) {
237 rv = 0;
238 if (fds[0].revents & POLLIN) {
239 rv |= DBG_POLLIN;
240 }
241 if (fds[0].revents & POLLOUT) {
242 rv |= DBG_POLLOUT;
243 }
244 }
245 return rv;
246}
247
248int
249dbgsysGetLastIOError(char *buf, jint size) {
250 char *msg = strerror(errno);
251 strncpy(buf, msg, size-1);
252 buf[size-1] = '\0';
253 return 0;
254}
255
256#ifdef __solaris__
257int
258dbgsysTlsAlloc() {
259 thread_key_t tk;
260 if (thr_keycreate(&tk, NULL)) {
261 perror("thr_keycreate");
262 exit(-1);
263 }
264 return (int)tk;
265}
266
267void
268dbgsysTlsFree(int index) {
269 /* no-op */
270}
271
272void
273dbgsysTlsPut(int index, void *value) {
274 thr_setspecific((thread_key_t)index, value) ;
275}
276
277void *
278dbgsysTlsGet(int index) {
279 void* r = NULL;
280 thr_getspecific((thread_key_t)index, &r);
281 return r;
282}
283
284#endif
285
286#ifdef __linux__
287int
288dbgsysTlsAlloc() {
289 pthread_key_t key;
290 if (pthread_key_create(&key, NULL)) {
291 perror("pthread_key_create");
292 exit(-1);
293 }
294 return (int)key;
295}
296
297void
298dbgsysTlsFree(int index) {
299 pthread_key_delete((pthread_key_t)index);
300}
301
302void
303dbgsysTlsPut(int index, void *value) {
304 pthread_setspecific((pthread_key_t)index, value) ;
305}
306
307void *
308dbgsysTlsGet(int index) {
309 return pthread_getspecific((pthread_key_t)index);
310}
311
312#endif
313
314long
315dbgsysCurrentTimeMillis() {
316 struct timeval t;
317 gettimeofday(&t, 0);
318 return ((jlong)t.tv_sec) * 1000 + (jlong)(t.tv_usec/1000);
319}