/** @inheritDoc */ public int writeBuf(int fd, byte buffer[], int off, int len) throws IOException { int result = 0; byte[] buf = buffer; if (off != 0) { buf = new byte[len]; System.arraycopy(buffer, off, buf, 0, len); } if (DEBUG) { System.err.println("writeBuf(" + fd + ") before write."); } result = libc.write(fd, buf, len); // We rely on open0() for setting the socket to non-blocking if (result < 0) { int err_code = LibCUtil.errno(); if (err_code == LibC.EWOULDBLOCK) { VMThread.getSystemEvents().waitForWriteEvent(fd); if (DEBUG) { System.err.println("writeBuf(" + fd + ") returned from select. retry."); } result = libc.write(fd, buf, len); // We rely on open0() for setting the socket to non-blocking } if (DEBUG) { System.err.println("writeBuf(" + fd + ") error:"); } LibCUtil.errCheckNeg(result); } return result; }
/** @inheritDoc */ public int readBuf(int fd, byte b[], int offset, int length) throws IOException { byte[] buf = b; int result; if (offset != 0) { if (DEBUG) { System.err.println("readBuf() into temp buf"); } buf = new byte[length]; } if (NBIO_WORKS) { result = libc.read(fd, buf, length); // We rely on open0() for setting the socket to non-blocking if (result < 0) { int err_code = LibCUtil.errno(); if (err_code == LibC.EWOULDBLOCK) { if (DEBUG) { System.err.println("Wait for read in select..."); } VMThread.getSystemEvents().waitForReadEvent(fd); result = libc.read( fd, buf, length); // We rely on open0() for setting the socket to non-blocking } LibCUtil.errCheckNeg(result); } } else { // If non-blocking IO doesn't seems to be working, try this hack... int bAvail = available(fd); // may throw IOException if (bAvail == 0) { if (DEBUG) { System.err.println("Wait for read in select..."); } VMThread.getSystemEvents().waitForReadEvent(fd); bAvail = available(fd); if (bAvail == 0) { // woke up because connection is closed if (DEBUG) { System.err.println("readBuf(" + fd + ") signalling EOF."); } return -1; // signal EOF } } if (DEBUG) { System.err.println("readBuf(" + fd + ") returned from select. retry."); } int n = Math.min(bAvail, length); // don't read more than is asked for... result = libc.read(fd, buf, n); // only read what we know is there... LibCUtil.errCheckNeg(result); } if (result == 0) { // If remote side has shut down the connection gracefully, and all // data has been received, recv() will complete immediately with // zero bytes received. // // This is true for Win32/CE and Linux if (DEBUG) { System.err.println("readBuf(" + fd + ") saw remote side shutdown."); } result = -1; } if (offset != 0 && result > 0) { System.arraycopy(buf, 0, b, offset, result); } if (DEBUG) { System.out.println("readBuf(" + fd + ") = " + result); } return result; }