src/jdk.jdwp.agent/unix/native/libdt_socket/socket_md.c
changeset 47216 71c04702a3d5
parent 46862 cb4b080576fa
child 48767 0c6ce8fdb50a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jdwp.agent/unix/native/libdt_socket/socket_md.c	Tue Sep 12 19:03:39 2017 +0200
@@ -0,0 +1,333 @@
+/*
+ * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/time.h>
+#ifdef __solaris__
+#include <thread.h>
+#else
+#include <pthread.h>
+#include <poll.h>
+#endif
+
+#include "socket_md.h"
+#include "sysSocket.h"
+
+int
+dbgsysListen(int fd, int backlog) {
+    return listen(fd, backlog);
+}
+
+int
+dbgsysConnect(int fd, struct sockaddr *name, socklen_t namelen) {
+    int rv = connect(fd, name, namelen);
+    if (rv < 0 && (errno == EINPROGRESS || errno == EINTR)) {
+        return DBG_EINPROGRESS;
+    } else {
+        return rv;
+    }
+}
+
+int
+dbgsysFinishConnect(int fd, int timeout) {
+    int rv = dbgsysPoll(fd, 0, 1, timeout);
+    if (rv == 0) {
+        return DBG_ETIMEOUT;
+    }
+    if (rv > 0) {
+        return 0;
+    }
+    return rv;
+}
+
+int
+dbgsysAccept(int fd, struct sockaddr *name, socklen_t *namelen) {
+    int rv;
+    for (;;) {
+        rv = accept(fd, name, namelen);
+        if (rv >= 0) {
+            return rv;
+        }
+        if (errno != ECONNABORTED && errno != EINTR) {
+            return rv;
+        }
+    }
+}
+
+int
+dbgsysRecvFrom(int fd, char *buf, size_t nBytes,
+                  int flags, struct sockaddr *from, socklen_t *fromlen) {
+    int rv;
+    do {
+        rv = recvfrom(fd, buf, nBytes, flags, from, fromlen);
+    } while (rv == -1 && errno == EINTR);
+
+    return rv;
+}
+
+int
+dbgsysSendTo(int fd, char *buf, size_t len,
+                int flags, struct sockaddr *to, socklen_t tolen) {
+    int rv;
+    do {
+        rv = sendto(fd, buf, len, flags, to, tolen);
+    } while (rv == -1 && errno == EINTR);
+
+    return rv;
+}
+
+int
+dbgsysRecv(int fd, char *buf, size_t nBytes, int flags) {
+    int rv;
+    do {
+        rv = recv(fd, buf, nBytes, flags);
+    } while (rv == -1 && errno == EINTR);
+
+    return rv;
+}
+
+int
+dbgsysSend(int fd, char *buf, size_t nBytes, int flags) {
+    int rv;
+    do {
+        rv = send(fd, buf, nBytes, flags);
+    } while (rv == -1 && errno == EINTR);
+
+    return rv;
+}
+
+struct hostent *
+dbgsysGetHostByName(char *hostname) {
+    return gethostbyname(hostname);
+}
+
+unsigned short
+dbgsysHostToNetworkShort(unsigned short hostshort) {
+    return htons(hostshort);
+}
+
+int
+dbgsysSocket(int domain, int type, int protocol) {
+    return socket(domain, type, protocol);
+}
+
+int dbgsysSocketClose(int fd) {
+    int rv;
+    do {
+        rv = close(fd);
+    } while (rv == -1 && errno == EINTR);
+
+    return rv;
+}
+
+int
+dbgsysBind(int fd, struct sockaddr *name, socklen_t namelen) {
+    return bind(fd, name, namelen);
+}
+
+uint32_t
+dbgsysInetAddr(const char* cp) {
+    return (uint32_t)inet_addr(cp);
+}
+
+uint32_t
+dbgsysHostToNetworkLong(uint32_t hostlong) {
+    return htonl(hostlong);
+}
+
+unsigned short
+dbgsysNetworkToHostShort(unsigned short netshort) {
+    return ntohs(netshort);
+}
+
+int
+dbgsysGetSocketName(int fd, struct sockaddr *name, socklen_t *namelen) {
+    return getsockname(fd, name, namelen);
+}
+
+uint32_t
+dbgsysNetworkToHostLong(uint32_t netlong) {
+    return ntohl(netlong);
+}
+
+
+int
+dbgsysSetSocketOption(int fd, jint cmd, jboolean on, jvalue value)
+{
+    if (cmd == TCP_NODELAY) {
+        struct protoent *proto = getprotobyname("TCP");
+        int tcp_level = (proto == 0 ? IPPROTO_TCP: proto->p_proto);
+        uint32_t onl = (uint32_t)on;
+
+        if (setsockopt(fd, tcp_level, TCP_NODELAY,
+                       (char *)&onl, sizeof(uint32_t)) < 0) {
+                return SYS_ERR;
+        }
+    } else if (cmd == SO_LINGER) {
+        struct linger arg;
+        arg.l_onoff = on;
+        arg.l_linger = (on) ? (unsigned short)value.i : 0;
+        if (setsockopt(fd, SOL_SOCKET, SO_LINGER,
+                       (char*)&arg, sizeof(arg)) < 0) {
+          return SYS_ERR;
+        }
+    } else if (cmd == SO_SNDBUF) {
+        jint buflen = value.i;
+        if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF,
+                       (char *)&buflen, sizeof(buflen)) < 0) {
+            return SYS_ERR;
+        }
+    } else if (cmd == SO_REUSEADDR) {
+        int oni = (int)on;
+        if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
+                       (char *)&oni, sizeof(oni)) < 0) {
+            return SYS_ERR;
+
+        }
+    } else {
+        return SYS_ERR;
+    }
+    return SYS_OK;
+}
+
+int
+dbgsysConfigureBlocking(int fd, jboolean blocking) {
+    int flags = fcntl(fd, F_GETFL);
+
+    if ((blocking == JNI_FALSE) && !(flags & O_NONBLOCK)) {
+        return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
+    }
+    if ((blocking == JNI_TRUE) && (flags & O_NONBLOCK)) {
+        return fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
+    }
+    return 0;
+}
+
+int
+dbgsysPoll(int fd, jboolean rd, jboolean wr, long timeout) {
+    struct pollfd fds[1];
+    int rv;
+
+    fds[0].fd = fd;
+    fds[0].events = 0;
+    if (rd) {
+        fds[0].events |= POLLIN;
+    }
+    if (wr) {
+        fds[0].events |= POLLOUT;
+    }
+    fds[0].revents = 0;
+
+    rv = poll(&fds[0], 1, timeout);
+    if (rv >= 0) {
+        rv = 0;
+        if (fds[0].revents & POLLIN) {
+            rv |= DBG_POLLIN;
+        }
+        if (fds[0].revents & POLLOUT) {
+            rv |= DBG_POLLOUT;
+        }
+    }
+    return rv;
+}
+
+int
+dbgsysGetLastIOError(char *buf, jint size) {
+    char *msg = strerror(errno);
+    strncpy(buf, msg, size-1);
+    buf[size-1] = '\0';
+    return 0;
+}
+
+#ifdef __solaris__
+int
+dbgsysTlsAlloc() {
+    thread_key_t tk;
+    if (thr_keycreate(&tk, NULL)) {
+        perror("thr_keycreate");
+        exit(-1);
+    }
+    return (int)tk;
+}
+
+void
+dbgsysTlsFree(int index) {
+   /* no-op */
+}
+
+void
+dbgsysTlsPut(int index, void *value) {
+    thr_setspecific((thread_key_t)index, value) ;
+}
+
+void *
+dbgsysTlsGet(int index) {
+    void* r = NULL;
+    thr_getspecific((thread_key_t)index, &r);
+    return r;
+}
+
+#else
+int
+dbgsysTlsAlloc() {
+    pthread_key_t key;
+    if (pthread_key_create(&key, NULL)) {
+        perror("pthread_key_create");
+        exit(-1);
+    }
+    return (int)key;
+}
+
+void
+dbgsysTlsFree(int index) {
+    pthread_key_delete((pthread_key_t)index);
+}
+
+void
+dbgsysTlsPut(int index, void *value) {
+    pthread_setspecific((pthread_key_t)index, value) ;
+}
+
+void *
+dbgsysTlsGet(int index) {
+    return pthread_getspecific((pthread_key_t)index);
+}
+
+#endif
+
+long
+dbgsysCurrentTimeMillis() {
+    struct timeval t;
+    gettimeofday(&t, 0);
+    return ((jlong)t.tv_sec) * 1000 + (jlong)(t.tv_usec/1000);
+}