0N/A/*
2362N/A * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/A#include <stdlib.h>
0N/A#include <sys/types.h>
0N/A#include <sys/socket.h>
0N/A#include <netinet/in.h>
0N/A#include <arpa/inet.h>
0N/A#include <unistd.h>
0N/A#include <fcntl.h>
0N/A#include <errno.h>
0N/A#include <string.h>
0N/A#include <sys/time.h>
0N/A#ifdef __solaris__
0N/A#include <thread.h>
5241N/A#else
0N/A#include <pthread.h>
0N/A#include <sys/poll.h>
0N/A#endif
0N/A
0N/A#include "socket_md.h"
0N/A#include "sysSocket.h"
0N/A
0N/Aint
439N/AdbgsysListen(int fd, int backlog) {
439N/A return listen(fd, backlog);
0N/A}
0N/A
0N/Aint
0N/AdbgsysConnect(int fd, struct sockaddr *name, int namelen) {
0N/A int rv = connect(fd, name, namelen);
4632N/A if (rv < 0 && (errno == EINPROGRESS || errno == EINTR)) {
0N/A return DBG_EINPROGRESS;
0N/A } else {
0N/A return rv;
0N/A }
0N/A}
0N/A
0N/Aint
0N/AdbgsysFinishConnect(int fd, long timeout) {
0N/A int rv = dbgsysPoll(fd, 0, 1, timeout);
0N/A if (rv == 0) {
0N/A return DBG_ETIMEOUT;
0N/A }
0N/A if (rv > 0) {
0N/A return 0;
0N/A }
0N/A return rv;
0N/A}
0N/A
0N/Aint
0N/AdbgsysAccept(int fd, struct sockaddr *name, int *namelen) {
0N/A int rv;
0N/A for (;;) {
0N/A rv = accept(fd, name, namelen);
0N/A if (rv >= 0) {
0N/A return rv;
0N/A }
4632N/A if (errno != ECONNABORTED && errno != EINTR) {
0N/A return rv;
0N/A }
0N/A }
0N/A}
0N/A
0N/Aint
0N/AdbgsysRecvFrom(int fd, char *buf, int nBytes,
0N/A int flags, struct sockaddr *from, int *fromlen) {
4632N/A int rv;
4632N/A do {
4632N/A rv = recvfrom(fd, buf, nBytes, flags, from, fromlen);
4632N/A } while (rv == -1 && errno == EINTR);
4632N/A
4632N/A return rv;
0N/A}
0N/A
0N/Aint
0N/AdbgsysSendTo(int fd, char *buf, int len,
0N/A int flags, struct sockaddr *to, int tolen) {
4632N/A int rv;
4632N/A do {
4632N/A rv = sendto(fd, buf, len, flags, to, tolen);
4632N/A } while (rv == -1 && errno == EINTR);
4632N/A
4632N/A return rv;
0N/A}
0N/A
0N/Aint
0N/AdbgsysRecv(int fd, char *buf, int nBytes, int flags) {
4632N/A int rv;
4632N/A do {
4632N/A rv = recv(fd, buf, nBytes, flags);
4632N/A } while (rv == -1 && errno == EINTR);
4632N/A
4632N/A return rv;
0N/A}
0N/A
0N/Aint
0N/AdbgsysSend(int fd, char *buf, int nBytes, int flags) {
4632N/A int rv;
4632N/A do {
4632N/A rv = send(fd, buf, nBytes, flags);
4632N/A } while (rv == -1 && errno == EINTR);
4632N/A
4632N/A return rv;
0N/A}
0N/A
0N/Astruct hostent *
0N/AdbgsysGetHostByName(char *hostname) {
0N/A return gethostbyname(hostname);
0N/A}
0N/A
0N/Aunsigned short
0N/AdbgsysHostToNetworkShort(unsigned short hostshort) {
0N/A return htons(hostshort);
0N/A}
0N/A
0N/Aint
0N/AdbgsysSocket(int domain, int type, int protocol) {
0N/A return socket(domain, type, protocol);
0N/A}
0N/A
0N/Aint dbgsysSocketClose(int fd) {
4632N/A int rv;
4632N/A do {
4632N/A rv = close(fd);
4632N/A } while (rv == -1 && errno == EINTR);
4632N/A
4632N/A return rv;
0N/A}
0N/A
0N/Aint
0N/AdbgsysBind(int fd, struct sockaddr *name, int namelen) {
0N/A return bind(fd, name, namelen);
0N/A}
0N/A
439N/Auint32_t
0N/AdbgsysInetAddr(const char* cp) {
439N/A return (uint32_t)inet_addr(cp);
0N/A}
0N/A
439N/Auint32_t
439N/AdbgsysHostToNetworkLong(uint32_t hostlong) {
0N/A return htonl(hostlong);
0N/A}
0N/A
0N/Aunsigned short
0N/AdbgsysNetworkToHostShort(unsigned short netshort) {
0N/A return ntohs(netshort);
0N/A}
0N/A
0N/Aint
0N/AdbgsysGetSocketName(int fd, struct sockaddr *name, int *namelen) {
0N/A return getsockname(fd, name, namelen);
0N/A}
0N/A
439N/Auint32_t
439N/AdbgsysNetworkToHostLong(uint32_t netlong) {
0N/A return ntohl(netlong);
0N/A}
0N/A
0N/A
0N/Aint
0N/AdbgsysSetSocketOption(int fd, jint cmd, jboolean on, jvalue value)
0N/A{
0N/A if (cmd == TCP_NODELAY) {
0N/A struct protoent *proto = getprotobyname("TCP");
0N/A int tcp_level = (proto == 0 ? IPPROTO_TCP: proto->p_proto);
439N/A uint32_t onl = (uint32_t)on;
0N/A
0N/A if (setsockopt(fd, tcp_level, TCP_NODELAY,
439N/A (char *)&onl, sizeof(uint32_t)) < 0) {
0N/A return SYS_ERR;
0N/A }
0N/A } else if (cmd == SO_LINGER) {
0N/A struct linger arg;
0N/A arg.l_onoff = on;
0N/A
0N/A if(on) {
0N/A arg.l_linger = (unsigned short)value.i;
0N/A if(setsockopt(fd, SOL_SOCKET, SO_LINGER,
0N/A (char*)&arg, sizeof(arg)) < 0) {
0N/A return SYS_ERR;
0N/A }
0N/A } else {
0N/A if (setsockopt(fd, SOL_SOCKET, SO_LINGER,
0N/A (char*)&arg, sizeof(arg)) < 0) {
0N/A return SYS_ERR;
0N/A }
0N/A }
0N/A } else if (cmd == SO_SNDBUF) {
0N/A jint buflen = value.i;
0N/A if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF,
0N/A (char *)&buflen, sizeof(buflen)) < 0) {
0N/A return SYS_ERR;
0N/A }
0N/A } else if (cmd == SO_REUSEADDR) {
0N/A int oni = (int)on;
0N/A if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
0N/A (char *)&oni, sizeof(oni)) < 0) {
0N/A return SYS_ERR;
0N/A
0N/A }
0N/A } else {
0N/A return SYS_ERR;
0N/A }
0N/A return SYS_OK;
0N/A}
0N/A
0N/Aint
0N/AdbgsysConfigureBlocking(int fd, jboolean blocking) {
0N/A int flags = fcntl(fd, F_GETFL);
0N/A
0N/A if ((blocking == JNI_FALSE) && !(flags & O_NONBLOCK)) {
0N/A return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
0N/A }
0N/A if ((blocking == JNI_TRUE) && (flags & O_NONBLOCK)) {
0N/A return fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
0N/A }
0N/A return 0;
0N/A}
0N/A
0N/Aint
0N/AdbgsysPoll(int fd, jboolean rd, jboolean wr, long timeout) {
0N/A struct pollfd fds[1];
0N/A int rv;
0N/A
0N/A fds[0].fd = fd;
0N/A fds[0].events = 0;
0N/A if (rd) {
0N/A fds[0].events |= POLLIN;
0N/A }
0N/A if (wr) {
0N/A fds[0].events |= POLLOUT;
0N/A }
0N/A fds[0].revents = 0;
0N/A
0N/A rv = poll(&fds[0], 1, timeout);
0N/A if (rv >= 0) {
0N/A rv = 0;
0N/A if (fds[0].revents & POLLIN) {
0N/A rv |= DBG_POLLIN;
0N/A }
0N/A if (fds[0].revents & POLLOUT) {
0N/A rv |= DBG_POLLOUT;
0N/A }
0N/A }
0N/A return rv;
0N/A}
0N/A
0N/Aint
0N/AdbgsysGetLastIOError(char *buf, jint size) {
0N/A char *msg = strerror(errno);
0N/A strncpy(buf, msg, size-1);
0N/A buf[size-1] = '\0';
0N/A return 0;
0N/A}
0N/A
0N/A#ifdef __solaris__
0N/Aint
0N/AdbgsysTlsAlloc() {
0N/A thread_key_t tk;
0N/A if (thr_keycreate(&tk, NULL)) {
0N/A perror("thr_keycreate");
0N/A exit(-1);
0N/A }
0N/A return (int)tk;
0N/A}
0N/A
0N/Avoid
0N/AdbgsysTlsFree(int index) {
0N/A /* no-op */
0N/A}
0N/A
0N/Avoid
0N/AdbgsysTlsPut(int index, void *value) {
0N/A thr_setspecific((thread_key_t)index, value) ;
0N/A}
0N/A
0N/Avoid *
0N/AdbgsysTlsGet(int index) {
0N/A void* r = NULL;
0N/A thr_getspecific((thread_key_t)index, &r);
0N/A return r;
0N/A}
0N/A
5241N/A#else
0N/Aint
0N/AdbgsysTlsAlloc() {
0N/A pthread_key_t key;
0N/A if (pthread_key_create(&key, NULL)) {
0N/A perror("pthread_key_create");
0N/A exit(-1);
0N/A }
0N/A return (int)key;
0N/A}
0N/A
0N/Avoid
0N/AdbgsysTlsFree(int index) {
0N/A pthread_key_delete((pthread_key_t)index);
0N/A}
0N/A
0N/Avoid
0N/AdbgsysTlsPut(int index, void *value) {
0N/A pthread_setspecific((pthread_key_t)index, value) ;
0N/A}
0N/A
0N/Avoid *
0N/AdbgsysTlsGet(int index) {
0N/A return pthread_getspecific((pthread_key_t)index);
0N/A}
0N/A
0N/A#endif
0N/A
0N/Along
0N/AdbgsysCurrentTimeMillis() {
0N/A struct timeval t;
0N/A gettimeofday(&t, 0);
0N/A return ((jlong)t.tv_sec) * 1000 + (jlong)(t.tv_usec/1000);
0N/A}