1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package libcore.io; 18 19 import android.system.ErrnoException; 20 import android.system.GaiException; 21 import android.system.StructAddrinfo; 22 import android.system.StructCapUserData; 23 import android.system.StructCapUserHeader; 24 import android.system.StructFlock; 25 import android.system.StructGroupReq; 26 import android.system.StructGroupSourceReq; 27 import android.system.StructIfaddrs; 28 import android.system.StructLinger; 29 import android.system.StructPasswd; 30 import android.system.StructPollfd; 31 import android.system.StructStat; 32 import android.system.StructStatVfs; 33 import android.system.StructTimeval; 34 import android.system.StructUcred; 35 import android.system.StructUtsname; 36 import android.util.MutableInt; 37 import android.util.MutableLong; 38 import java.io.FileDescriptor; 39 import java.io.InterruptedIOException; 40 import java.net.InetAddress; 41 import java.net.InetSocketAddress; 42 import java.net.SocketAddress; 43 import java.net.SocketException; 44 import java.nio.ByteBuffer; 45 import java.nio.NioUtils; 46 47 public final class Linux implements Os { Linux()48 Linux() { } 49 accept(FileDescriptor fd, SocketAddress peerAddress)50 public native FileDescriptor accept(FileDescriptor fd, SocketAddress peerAddress) throws ErrnoException, SocketException; access(String path, int mode)51 public native boolean access(String path, int mode) throws ErrnoException; android_getaddrinfo(String node, StructAddrinfo hints, int netId)52 public native InetAddress[] android_getaddrinfo(String node, StructAddrinfo hints, int netId) throws GaiException; bind(FileDescriptor fd, InetAddress address, int port)53 public native void bind(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException; bind(FileDescriptor fd, SocketAddress address)54 public native void bind(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException; 55 @Override capget(StructCapUserHeader hdr)56 public native StructCapUserData[] capget(StructCapUserHeader hdr) throws ErrnoException; 57 @Override capset(StructCapUserHeader hdr, StructCapUserData[] data)58 public native void capset(StructCapUserHeader hdr, StructCapUserData[] data) 59 throws ErrnoException; chmod(String path, int mode)60 public native void chmod(String path, int mode) throws ErrnoException; chown(String path, int uid, int gid)61 public native void chown(String path, int uid, int gid) throws ErrnoException; close(FileDescriptor fd)62 public native void close(FileDescriptor fd) throws ErrnoException; connect(FileDescriptor fd, InetAddress address, int port)63 public native void connect(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException; connect(FileDescriptor fd, SocketAddress address)64 public native void connect(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException; dup(FileDescriptor oldFd)65 public native FileDescriptor dup(FileDescriptor oldFd) throws ErrnoException; dup2(FileDescriptor oldFd, int newFd)66 public native FileDescriptor dup2(FileDescriptor oldFd, int newFd) throws ErrnoException; environ()67 public native String[] environ(); execv(String filename, String[] argv)68 public native void execv(String filename, String[] argv) throws ErrnoException; execve(String filename, String[] argv, String[] envp)69 public native void execve(String filename, String[] argv, String[] envp) throws ErrnoException; fchmod(FileDescriptor fd, int mode)70 public native void fchmod(FileDescriptor fd, int mode) throws ErrnoException; fchown(FileDescriptor fd, int uid, int gid)71 public native void fchown(FileDescriptor fd, int uid, int gid) throws ErrnoException; fcntlFlock(FileDescriptor fd, int cmd, StructFlock arg)72 public native int fcntlFlock(FileDescriptor fd, int cmd, StructFlock arg) throws ErrnoException, InterruptedIOException; fcntlInt(FileDescriptor fd, int cmd, int arg)73 public native int fcntlInt(FileDescriptor fd, int cmd, int arg) throws ErrnoException; fcntlVoid(FileDescriptor fd, int cmd)74 public native int fcntlVoid(FileDescriptor fd, int cmd) throws ErrnoException; fdatasync(FileDescriptor fd)75 public native void fdatasync(FileDescriptor fd) throws ErrnoException; fstat(FileDescriptor fd)76 public native StructStat fstat(FileDescriptor fd) throws ErrnoException; fstatvfs(FileDescriptor fd)77 public native StructStatVfs fstatvfs(FileDescriptor fd) throws ErrnoException; fsync(FileDescriptor fd)78 public native void fsync(FileDescriptor fd) throws ErrnoException; ftruncate(FileDescriptor fd, long length)79 public native void ftruncate(FileDescriptor fd, long length) throws ErrnoException; gai_strerror(int error)80 public native String gai_strerror(int error); getegid()81 public native int getegid(); geteuid()82 public native int geteuid(); getgid()83 public native int getgid(); getenv(String name)84 public native String getenv(String name); getnameinfo(InetAddress address, int flags)85 public native String getnameinfo(InetAddress address, int flags) throws GaiException; getpeername(FileDescriptor fd)86 public native SocketAddress getpeername(FileDescriptor fd) throws ErrnoException; getpgid(int pid)87 public native int getpgid(int pid); getpid()88 public native int getpid(); getppid()89 public native int getppid(); getpwnam(String name)90 public native StructPasswd getpwnam(String name) throws ErrnoException; getpwuid(int uid)91 public native StructPasswd getpwuid(int uid) throws ErrnoException; getsockname(FileDescriptor fd)92 public native SocketAddress getsockname(FileDescriptor fd) throws ErrnoException; getsockoptByte(FileDescriptor fd, int level, int option)93 public native int getsockoptByte(FileDescriptor fd, int level, int option) throws ErrnoException; getsockoptInAddr(FileDescriptor fd, int level, int option)94 public native InetAddress getsockoptInAddr(FileDescriptor fd, int level, int option) throws ErrnoException; getsockoptInt(FileDescriptor fd, int level, int option)95 public native int getsockoptInt(FileDescriptor fd, int level, int option) throws ErrnoException; getsockoptLinger(FileDescriptor fd, int level, int option)96 public native StructLinger getsockoptLinger(FileDescriptor fd, int level, int option) throws ErrnoException; getsockoptTimeval(FileDescriptor fd, int level, int option)97 public native StructTimeval getsockoptTimeval(FileDescriptor fd, int level, int option) throws ErrnoException; getsockoptUcred(FileDescriptor fd, int level, int option)98 public native StructUcred getsockoptUcred(FileDescriptor fd, int level, int option) throws ErrnoException; gettid()99 public native int gettid(); getuid()100 public native int getuid(); getxattr(String path, String name)101 public native byte[] getxattr(String path, String name) throws ErrnoException; getifaddrs()102 public native StructIfaddrs[] getifaddrs() throws ErrnoException; if_indextoname(int index)103 public native String if_indextoname(int index); if_nametoindex(String name)104 public native int if_nametoindex(String name); inet_pton(int family, String address)105 public native InetAddress inet_pton(int family, String address); ioctlFlags(FileDescriptor fd, String interfaceName)106 public native int ioctlFlags(FileDescriptor fd, String interfaceName) throws ErrnoException; ioctlInetAddress(FileDescriptor fd, int cmd, String interfaceName)107 public native InetAddress ioctlInetAddress(FileDescriptor fd, int cmd, String interfaceName) throws ErrnoException; ioctlInt(FileDescriptor fd, int cmd, MutableInt arg)108 public native int ioctlInt(FileDescriptor fd, int cmd, MutableInt arg) throws ErrnoException; ioctlMTU(FileDescriptor fd, String interfaceName)109 public native int ioctlMTU(FileDescriptor fd, String interfaceName) throws ErrnoException; isatty(FileDescriptor fd)110 public native boolean isatty(FileDescriptor fd); kill(int pid, int signal)111 public native void kill(int pid, int signal) throws ErrnoException; lchown(String path, int uid, int gid)112 public native void lchown(String path, int uid, int gid) throws ErrnoException; link(String oldPath, String newPath)113 public native void link(String oldPath, String newPath) throws ErrnoException; listen(FileDescriptor fd, int backlog)114 public native void listen(FileDescriptor fd, int backlog) throws ErrnoException; listxattr(String path)115 public native String[] listxattr(String path) throws ErrnoException; lseek(FileDescriptor fd, long offset, int whence)116 public native long lseek(FileDescriptor fd, long offset, int whence) throws ErrnoException; lstat(String path)117 public native StructStat lstat(String path) throws ErrnoException; mincore(long address, long byteCount, byte[] vector)118 public native void mincore(long address, long byteCount, byte[] vector) throws ErrnoException; mkdir(String path, int mode)119 public native void mkdir(String path, int mode) throws ErrnoException; mkfifo(String path, int mode)120 public native void mkfifo(String path, int mode) throws ErrnoException; mlock(long address, long byteCount)121 public native void mlock(long address, long byteCount) throws ErrnoException; mmap(long address, long byteCount, int prot, int flags, FileDescriptor fd, long offset)122 public native long mmap(long address, long byteCount, int prot, int flags, FileDescriptor fd, long offset) throws ErrnoException; msync(long address, long byteCount, int flags)123 public native void msync(long address, long byteCount, int flags) throws ErrnoException; munlock(long address, long byteCount)124 public native void munlock(long address, long byteCount) throws ErrnoException; munmap(long address, long byteCount)125 public native void munmap(long address, long byteCount) throws ErrnoException; open(String path, int flags, int mode)126 public native FileDescriptor open(String path, int flags, int mode) throws ErrnoException; pipe2(int flags)127 public native FileDescriptor[] pipe2(int flags) throws ErrnoException; poll(StructPollfd[] fds, int timeoutMs)128 public native int poll(StructPollfd[] fds, int timeoutMs) throws ErrnoException; posix_fallocate(FileDescriptor fd, long offset, long length)129 public native void posix_fallocate(FileDescriptor fd, long offset, long length) throws ErrnoException; prctl(int option, long arg2, long arg3, long arg4, long arg5)130 public native int prctl(int option, long arg2, long arg3, long arg4, long arg5) throws ErrnoException; pread(FileDescriptor fd, ByteBuffer buffer, long offset)131 public int pread(FileDescriptor fd, ByteBuffer buffer, long offset) throws ErrnoException, InterruptedIOException { 132 final int bytesRead; 133 final int position = buffer.position(); 134 135 if (buffer.isDirect()) { 136 bytesRead = preadBytes(fd, buffer, position, buffer.remaining(), offset); 137 } else { 138 bytesRead = preadBytes(fd, NioUtils.unsafeArray(buffer), NioUtils.unsafeArrayOffset(buffer) + position, buffer.remaining(), offset); 139 } 140 141 maybeUpdateBufferPosition(buffer, position, bytesRead); 142 return bytesRead; 143 } pread(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, long offset)144 public int pread(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, long offset) throws ErrnoException, InterruptedIOException { 145 // This indirection isn't strictly necessary, but ensures that our public interface is type safe. 146 return preadBytes(fd, bytes, byteOffset, byteCount, offset); 147 } preadBytes(FileDescriptor fd, Object buffer, int bufferOffset, int byteCount, long offset)148 private native int preadBytes(FileDescriptor fd, Object buffer, int bufferOffset, int byteCount, long offset) throws ErrnoException, InterruptedIOException; pwrite(FileDescriptor fd, ByteBuffer buffer, long offset)149 public int pwrite(FileDescriptor fd, ByteBuffer buffer, long offset) throws ErrnoException, InterruptedIOException { 150 final int bytesWritten; 151 final int position = buffer.position(); 152 153 if (buffer.isDirect()) { 154 bytesWritten = pwriteBytes(fd, buffer, position, buffer.remaining(), offset); 155 } else { 156 bytesWritten = pwriteBytes(fd, NioUtils.unsafeArray(buffer), NioUtils.unsafeArrayOffset(buffer) + position, buffer.remaining(), offset); 157 } 158 159 maybeUpdateBufferPosition(buffer, position, bytesWritten); 160 return bytesWritten; 161 } pwrite(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, long offset)162 public int pwrite(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, long offset) throws ErrnoException, InterruptedIOException { 163 // This indirection isn't strictly necessary, but ensures that our public interface is type safe. 164 return pwriteBytes(fd, bytes, byteOffset, byteCount, offset); 165 } pwriteBytes(FileDescriptor fd, Object buffer, int bufferOffset, int byteCount, long offset)166 private native int pwriteBytes(FileDescriptor fd, Object buffer, int bufferOffset, int byteCount, long offset) throws ErrnoException, InterruptedIOException; read(FileDescriptor fd, ByteBuffer buffer)167 public int read(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException, InterruptedIOException { 168 final int bytesRead; 169 final int position = buffer.position(); 170 171 if (buffer.isDirect()) { 172 bytesRead = readBytes(fd, buffer, position, buffer.remaining()); 173 } else { 174 bytesRead = readBytes(fd, NioUtils.unsafeArray(buffer), NioUtils.unsafeArrayOffset(buffer) + position, buffer.remaining()); 175 } 176 177 maybeUpdateBufferPosition(buffer, position, bytesRead); 178 return bytesRead; 179 } read(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount)180 public int read(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws ErrnoException, InterruptedIOException { 181 // This indirection isn't strictly necessary, but ensures that our public interface is type safe. 182 return readBytes(fd, bytes, byteOffset, byteCount); 183 } readBytes(FileDescriptor fd, Object buffer, int offset, int byteCount)184 private native int readBytes(FileDescriptor fd, Object buffer, int offset, int byteCount) throws ErrnoException, InterruptedIOException; readlink(String path)185 public native String readlink(String path) throws ErrnoException; realpath(String path)186 public native String realpath(String path) throws ErrnoException; readv(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts)187 public native int readv(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts) throws ErrnoException, InterruptedIOException; recvfrom(FileDescriptor fd, ByteBuffer buffer, int flags, InetSocketAddress srcAddress)188 public int recvfrom(FileDescriptor fd, ByteBuffer buffer, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException { 189 final int bytesReceived; 190 final int position = buffer.position(); 191 192 if (buffer.isDirect()) { 193 bytesReceived = recvfromBytes(fd, buffer, position, buffer.remaining(), flags, srcAddress); 194 } else { 195 bytesReceived = recvfromBytes(fd, NioUtils.unsafeArray(buffer), NioUtils.unsafeArrayOffset(buffer) + position, buffer.remaining(), flags, srcAddress); 196 } 197 198 maybeUpdateBufferPosition(buffer, position, bytesReceived); 199 return bytesReceived; 200 } recvfrom(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetSocketAddress srcAddress)201 public int recvfrom(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException { 202 // This indirection isn't strictly necessary, but ensures that our public interface is type safe. 203 return recvfromBytes(fd, bytes, byteOffset, byteCount, flags, srcAddress); 204 } recvfromBytes(FileDescriptor fd, Object buffer, int byteOffset, int byteCount, int flags, InetSocketAddress srcAddress)205 private native int recvfromBytes(FileDescriptor fd, Object buffer, int byteOffset, int byteCount, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException; remove(String path)206 public native void remove(String path) throws ErrnoException; removexattr(String path, String name)207 public native void removexattr(String path, String name) throws ErrnoException; rename(String oldPath, String newPath)208 public native void rename(String oldPath, String newPath) throws ErrnoException; sendfile(FileDescriptor outFd, FileDescriptor inFd, MutableLong inOffset, long byteCount)209 public native long sendfile(FileDescriptor outFd, FileDescriptor inFd, MutableLong inOffset, long byteCount) throws ErrnoException; sendto(FileDescriptor fd, ByteBuffer buffer, int flags, InetAddress inetAddress, int port)210 public int sendto(FileDescriptor fd, ByteBuffer buffer, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException { 211 final int bytesSent; 212 final int position = buffer.position(); 213 214 if (buffer.isDirect()) { 215 bytesSent = sendtoBytes(fd, buffer, position, buffer.remaining(), flags, inetAddress, port); 216 } else { 217 bytesSent = sendtoBytes(fd, NioUtils.unsafeArray(buffer), NioUtils.unsafeArrayOffset(buffer) + position, buffer.remaining(), flags, inetAddress, port); 218 } 219 220 maybeUpdateBufferPosition(buffer, position, bytesSent); 221 return bytesSent; 222 } sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetAddress inetAddress, int port)223 public int sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException { 224 // This indirection isn't strictly necessary, but ensures that our public interface is type safe. 225 return sendtoBytes(fd, bytes, byteOffset, byteCount, flags, inetAddress, port); 226 } sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, SocketAddress address)227 public int sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, SocketAddress address) throws ErrnoException, SocketException { 228 return sendtoBytes(fd, bytes, byteOffset, byteCount, flags, address); 229 } sendtoBytes(FileDescriptor fd, Object buffer, int byteOffset, int byteCount, int flags, InetAddress inetAddress, int port)230 private native int sendtoBytes(FileDescriptor fd, Object buffer, int byteOffset, int byteCount, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException; sendtoBytes(FileDescriptor fd, Object buffer, int byteOffset, int byteCount, int flags, SocketAddress address)231 private native int sendtoBytes(FileDescriptor fd, Object buffer, int byteOffset, int byteCount, int flags, SocketAddress address) throws ErrnoException, SocketException; setegid(int egid)232 public native void setegid(int egid) throws ErrnoException; setenv(String name, String value, boolean overwrite)233 public native void setenv(String name, String value, boolean overwrite) throws ErrnoException; seteuid(int euid)234 public native void seteuid(int euid) throws ErrnoException; setgid(int gid)235 public native void setgid(int gid) throws ErrnoException; setpgid(int pid, int pgid)236 public native void setpgid(int pid, int pgid) throws ErrnoException; setregid(int rgid, int egid)237 public native void setregid(int rgid, int egid) throws ErrnoException; setreuid(int ruid, int euid)238 public native void setreuid(int ruid, int euid) throws ErrnoException; setsid()239 public native int setsid() throws ErrnoException; setsockoptByte(FileDescriptor fd, int level, int option, int value)240 public native void setsockoptByte(FileDescriptor fd, int level, int option, int value) throws ErrnoException; setsockoptIfreq(FileDescriptor fd, int level, int option, String value)241 public native void setsockoptIfreq(FileDescriptor fd, int level, int option, String value) throws ErrnoException; setsockoptInt(FileDescriptor fd, int level, int option, int value)242 public native void setsockoptInt(FileDescriptor fd, int level, int option, int value) throws ErrnoException; setsockoptIpMreqn(FileDescriptor fd, int level, int option, int value)243 public native void setsockoptIpMreqn(FileDescriptor fd, int level, int option, int value) throws ErrnoException; setsockoptGroupReq(FileDescriptor fd, int level, int option, StructGroupReq value)244 public native void setsockoptGroupReq(FileDescriptor fd, int level, int option, StructGroupReq value) throws ErrnoException; setsockoptGroupSourceReq(FileDescriptor fd, int level, int option, StructGroupSourceReq value)245 public native void setsockoptGroupSourceReq(FileDescriptor fd, int level, int option, StructGroupSourceReq value) throws ErrnoException; setsockoptLinger(FileDescriptor fd, int level, int option, StructLinger value)246 public native void setsockoptLinger(FileDescriptor fd, int level, int option, StructLinger value) throws ErrnoException; setsockoptTimeval(FileDescriptor fd, int level, int option, StructTimeval value)247 public native void setsockoptTimeval(FileDescriptor fd, int level, int option, StructTimeval value) throws ErrnoException; setuid(int uid)248 public native void setuid(int uid) throws ErrnoException; setxattr(String path, String name, byte[] value, int flags)249 public native void setxattr(String path, String name, byte[] value, int flags) throws ErrnoException; shutdown(FileDescriptor fd, int how)250 public native void shutdown(FileDescriptor fd, int how) throws ErrnoException; socket(int domain, int type, int protocol)251 public native FileDescriptor socket(int domain, int type, int protocol) throws ErrnoException; socketpair(int domain, int type, int protocol, FileDescriptor fd1, FileDescriptor fd2)252 public native void socketpair(int domain, int type, int protocol, FileDescriptor fd1, FileDescriptor fd2) throws ErrnoException; stat(String path)253 public native StructStat stat(String path) throws ErrnoException; statvfs(String path)254 public native StructStatVfs statvfs(String path) throws ErrnoException; strerror(int errno)255 public native String strerror(int errno); strsignal(int signal)256 public native String strsignal(int signal); symlink(String oldPath, String newPath)257 public native void symlink(String oldPath, String newPath) throws ErrnoException; sysconf(int name)258 public native long sysconf(int name); tcdrain(FileDescriptor fd)259 public native void tcdrain(FileDescriptor fd) throws ErrnoException; tcsendbreak(FileDescriptor fd, int duration)260 public native void tcsendbreak(FileDescriptor fd, int duration) throws ErrnoException; umask(int mask)261 public int umask(int mask) { 262 if ((mask & 0777) != mask) { 263 throw new IllegalArgumentException("Invalid umask: " + mask); 264 } 265 return umaskImpl(mask); 266 } umaskImpl(int mask)267 private native int umaskImpl(int mask); uname()268 public native StructUtsname uname(); unlink(String pathname)269 public native void unlink(String pathname) throws ErrnoException; unsetenv(String name)270 public native void unsetenv(String name) throws ErrnoException; waitpid(int pid, MutableInt status, int options)271 public native int waitpid(int pid, MutableInt status, int options) throws ErrnoException; write(FileDescriptor fd, ByteBuffer buffer)272 public int write(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException, InterruptedIOException { 273 final int bytesWritten; 274 final int position = buffer.position(); 275 if (buffer.isDirect()) { 276 bytesWritten = writeBytes(fd, buffer, position, buffer.remaining()); 277 } else { 278 bytesWritten = writeBytes(fd, NioUtils.unsafeArray(buffer), NioUtils.unsafeArrayOffset(buffer) + position, buffer.remaining()); 279 } 280 281 maybeUpdateBufferPosition(buffer, position, bytesWritten); 282 return bytesWritten; 283 } write(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount)284 public int write(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws ErrnoException, InterruptedIOException { 285 // This indirection isn't strictly necessary, but ensures that our public interface is type safe. 286 return writeBytes(fd, bytes, byteOffset, byteCount); 287 } writeBytes(FileDescriptor fd, Object buffer, int offset, int byteCount)288 private native int writeBytes(FileDescriptor fd, Object buffer, int offset, int byteCount) throws ErrnoException, InterruptedIOException; writev(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts)289 public native int writev(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts) throws ErrnoException, InterruptedIOException; 290 maybeUpdateBufferPosition(ByteBuffer buffer, int originalPosition, int bytesReadOrWritten)291 private static void maybeUpdateBufferPosition(ByteBuffer buffer, int originalPosition, int bytesReadOrWritten) { 292 if (bytesReadOrWritten > 0) { 293 buffer.position(bytesReadOrWritten + originalPosition); 294 } 295 } 296 } 297