duke@435: /* duke@435: * Copyright 1999-2005 Sun Microsystems, Inc. All Rights Reserved. duke@435: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@435: * duke@435: * This code is free software; you can redistribute it and/or modify it duke@435: * under the terms of the GNU General Public License version 2 only, as duke@435: * published by the Free Software Foundation. duke@435: * duke@435: * This code is distributed in the hope that it will be useful, but WITHOUT duke@435: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@435: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@435: * version 2 for more details (a copy is included in the LICENSE file that duke@435: * accompanied this code). duke@435: * duke@435: * You should have received a copy of the GNU General Public License version duke@435: * 2 along with this work; if not, write to the Free Software Foundation, duke@435: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@435: * duke@435: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, duke@435: * CA 95054 USA or visit www.sun.com if you need additional information or duke@435: * have any questions. duke@435: * duke@435: */ duke@435: duke@435: // duke@435: // Because the interruptible IO has been dropped for HotSpot/Linux, duke@435: // the following HPI interface is very different from HotSparc. duke@435: // duke@435: duke@435: #include duke@435: #include duke@435: #include duke@435: #include duke@435: #include duke@435: duke@435: // HPI_FileInterface duke@435: duke@435: inline int hpi::close(int fd) { duke@435: return ::close(fd); duke@435: } duke@435: duke@435: inline size_t hpi::read(int fd, void *buf, unsigned int nBytes) { duke@435: size_t res; duke@435: RESTARTABLE( (size_t) ::read(fd, buf, (size_t) nBytes), res); duke@435: return res; duke@435: } duke@435: duke@435: inline size_t hpi::write(int fd, const void *buf, unsigned int nBytes) { duke@435: size_t res; duke@435: RESTARTABLE((size_t) ::write(fd, buf, (size_t) nBytes), res); duke@435: return res; duke@435: } duke@435: duke@435: duke@435: // HPI_SocketInterface duke@435: duke@435: inline int hpi::socket_close(int fd) { duke@435: return ::close(fd); duke@435: } duke@435: duke@435: inline int hpi::socket(int domain, int type, int protocol) { duke@435: return ::socket(domain, type, protocol); duke@435: } duke@435: duke@435: inline int hpi::recv(int fd, char *buf, int nBytes, int flags) { duke@435: RESTARTABLE_RETURN_INT(::recv(fd, buf, nBytes, (unsigned int) flags)); duke@435: } duke@435: duke@435: inline int hpi::send(int fd, char *buf, int nBytes, int flags) { duke@435: RESTARTABLE_RETURN_INT(::send(fd, buf, nBytes, (unsigned int) flags)); duke@435: } duke@435: never@657: inline int hpi::raw_send(int fd, char *buf, int nBytes, int flags) { never@657: return send(fd, buf, nBytes, flags); never@657: } never@657: duke@435: inline int hpi::timeout(int fd, long timeout) { duke@435: julong prevtime,newtime; duke@435: struct timeval t; duke@435: duke@435: gettimeofday(&t, NULL); duke@435: prevtime = ((julong)t.tv_sec * 1000) + t.tv_usec / 1000; duke@435: duke@435: for(;;) { duke@435: struct pollfd pfd; duke@435: duke@435: pfd.fd = fd; duke@435: pfd.events = POLLIN | POLLERR; duke@435: duke@435: int res = ::poll(&pfd, 1, timeout); duke@435: duke@435: if (res == OS_ERR && errno == EINTR) { duke@435: duke@435: // On Linux any value < 0 means "forever" duke@435: duke@435: if(timeout >= 0) { duke@435: gettimeofday(&t, NULL); duke@435: newtime = ((julong)t.tv_sec * 1000) + t.tv_usec / 1000; duke@435: timeout -= newtime - prevtime; duke@435: if(timeout <= 0) duke@435: return OS_OK; duke@435: prevtime = newtime; duke@435: } duke@435: } else duke@435: return res; duke@435: } duke@435: } duke@435: duke@435: inline int hpi::listen(int fd, int count) { duke@435: return ::listen(fd, count); duke@435: } duke@435: duke@435: inline int hpi::connect(int fd, struct sockaddr *him, int len) { duke@435: RESTARTABLE_RETURN_INT(::connect(fd, him, len)); duke@435: } duke@435: duke@435: inline int hpi::accept(int fd, struct sockaddr *him, int *len) { duke@435: // This cast is from int to unsigned int on linux. Since we duke@435: // only pass the parameter "len" around the vm and don't try to duke@435: // fetch it's value, this cast is safe for now. The java.net group duke@435: // may need and want to change this interface someday if socklen_t goes duke@435: // to 64 bits on some platform that we support. duke@435: // Linux doc says this can't return EINTR, unlike accept() on Solaris duke@435: duke@435: return ::accept(fd, him, (socklen_t *)len); duke@435: } duke@435: duke@435: inline int hpi::recvfrom(int fd, char *buf, int nBytes, int flags, duke@435: sockaddr *from, int *fromlen) { duke@435: RESTARTABLE_RETURN_INT(::recvfrom(fd, buf, nBytes, (unsigned int) flags, from, (socklen_t *)fromlen)); duke@435: } duke@435: duke@435: inline int hpi::sendto(int fd, char *buf, int len, int flags, duke@435: struct sockaddr *to, int tolen) { duke@435: RESTARTABLE_RETURN_INT(::sendto(fd, buf, len, (unsigned int) flags, to, tolen)); duke@435: } duke@435: duke@435: inline int hpi::socket_available(int fd, jint *pbytes) { duke@435: // Linux doc says EINTR not returned, unlike Solaris duke@435: int ret = ::ioctl(fd, FIONREAD, pbytes); duke@435: duke@435: //%% note ioctl can return 0 when successful, JVM_SocketAvailable duke@435: // is expected to return 0 on failure and 1 on success to the jdk. duke@435: return (ret < 0) ? 0 : 1; duke@435: } duke@435: duke@435: duke@435: // following methods have been updated to avoid problems in duke@435: // hpi's sockets calls based on sys_api_td.c (JDK1.3) duke@435: duke@435: /* duke@435: HPIDECL(socket_shutdown, "socket_shutdown", _socket, SocketShutdown, duke@435: int, "%d", duke@435: (int fd, int howto), duke@435: ("fd = %d, howto = %d", fd, howto), duke@435: (fd, howto)); duke@435: */ duke@435: inline int hpi::socket_shutdown(int fd, int howto){ duke@435: return ::shutdown(fd, howto); duke@435: } duke@435: duke@435: /* duke@435: HPIDECL(bind, "bind", _socket, Bind, duke@435: int, "%d", duke@435: (int fd, struct sockaddr *him, int len), duke@435: ("fd = %d, him = %p, len = %d", duke@435: fd, him, len), duke@435: (fd, him, len)); duke@435: */ duke@435: inline int hpi::bind(int fd, struct sockaddr *him, int len){ duke@435: return ::bind(fd, him, len); duke@435: } duke@435: duke@435: /* duke@435: HPIDECL(get_sock_name, "get_sock_name", _socket, GetSocketName, duke@435: int, "%d", duke@435: (int fd, struct sockaddr *him, int *len), duke@435: ("fd = %d, him = %p, len = %p", duke@435: fd, him, len), duke@435: (fd, him, len)); duke@435: */ duke@435: inline int hpi::get_sock_name(int fd, struct sockaddr *him, int *len){ duke@435: return ::getsockname(fd, him, (socklen_t *)len); duke@435: } duke@435: duke@435: /* duke@435: HPIDECL(get_host_name, "get_host_name", _socket, GetHostName, int, "%d", duke@435: (char *hostname, int namelen), duke@435: ("hostname = %p, namelen = %d", duke@435: hostname, namelen), duke@435: (hostname, namelen)); duke@435: */ duke@435: inline int hpi::get_host_name(char* name, int namelen){ duke@435: return ::gethostname(name, namelen); duke@435: } duke@435: duke@435: /* duke@435: HPIDECL(get_sock_opt, "get_sock_opt", _socket, SocketGetOption, int, "%d", duke@435: (int fd, int level, int optname, char *optval, int* optlen), duke@435: ("fd = %d, level = %d, optname = %d, optval = %p, optlen = %p", duke@435: fd, level, optname, optval, optlen), duke@435: (fd, level, optname, optval, optlen)); duke@435: */ duke@435: inline int hpi::get_sock_opt(int fd, int level, int optname, duke@435: char *optval, int* optlen){ duke@435: return ::getsockopt(fd, level, optname, optval, (socklen_t *)optlen); duke@435: } duke@435: duke@435: /* duke@435: HPIDECL(set_sock_opt, "set_sock_opt", _socket, SocketSetOption, int, "%d", duke@435: (int fd, int level, int optname, const char *optval, int optlen), duke@435: ("fd = %d, level = %d, optname = %d, optval = %p, optlen = %d", duke@435: fd, level, optname, optval, optlen), duke@435: (fd, level, optname, optval, optlen)); duke@435: */ duke@435: inline int hpi::set_sock_opt(int fd, int level, int optname, duke@435: const char *optval, int optlen){ duke@435: return ::setsockopt(fd, level, optname, optval, optlen); duke@435: } duke@435: duke@435: duke@435: // Reconciliation History duke@435: // hpi_solaris.hpp 1.9 99/08/30 16:31:23 duke@435: // End