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.compat.annotation.UnsupportedAppUsage; 20 import android.system.ErrnoException; 21 import android.system.GaiException; 22 import android.system.Int64Ref; 23 import android.system.OsConstants; 24 import android.system.StructAddrinfo; 25 import android.system.StructLinger; 26 import android.system.StructMsghdr; 27 import android.system.StructPollfd; 28 import android.system.StructStat; 29 import android.system.StructStatVfs; 30 31 import java.io.FileDescriptor; 32 import java.io.InterruptedIOException; 33 import java.net.InetAddress; 34 import java.net.InetSocketAddress; 35 import java.net.SocketAddress; 36 import java.net.SocketException; 37 import java.nio.ByteBuffer; 38 39 import dalvik.system.BlockGuard; 40 import dalvik.system.SocketTagger; 41 42 import static android.system.OsConstants.*; 43 44 /** 45 * Informs BlockGuard of any activity it should be aware of. 46 */ 47 public class BlockGuardOs extends ForwardingOs { 48 @UnsupportedAppUsage BlockGuardOs(Os os)49 public BlockGuardOs(Os os) { 50 super(os); 51 } 52 tagSocket(FileDescriptor fd)53 private FileDescriptor tagSocket(FileDescriptor fd) throws ErrnoException { 54 try { 55 SocketTagger.get().tag(fd); 56 return fd; 57 } catch (SocketException e) { 58 throw new ErrnoException("socket", EINVAL, e); 59 } 60 } 61 accept(FileDescriptor fd, SocketAddress peerAddress)62 @Override public FileDescriptor accept(FileDescriptor fd, SocketAddress peerAddress) throws ErrnoException, SocketException { 63 if (!(isUnixSocket(fd) && isNonBlockingFile(fd))) { 64 BlockGuard.getThreadPolicy().onNetwork(); 65 } 66 final FileDescriptor acceptFd = super.accept(fd, peerAddress); 67 if (acceptFd != null && isInetSocket(acceptFd)) { 68 tagSocket(acceptFd); 69 } 70 return acceptFd; 71 } 72 access(String path, int mode)73 @Override public boolean access(String path, int mode) throws ErrnoException { 74 BlockGuard.getThreadPolicy().onReadFromDisk(); 75 BlockGuard.getVmPolicy().onPathAccess(path); 76 return super.access(path, mode); 77 } 78 79 @UnsupportedAppUsage chmod(String path, int mode)80 @Override public void chmod(String path, int mode) throws ErrnoException { 81 BlockGuard.getThreadPolicy().onWriteToDisk(); 82 BlockGuard.getVmPolicy().onPathAccess(path); 83 super.chmod(path, mode); 84 } 85 86 @UnsupportedAppUsage chown(String path, int uid, int gid)87 @Override public void chown(String path, int uid, int gid) throws ErrnoException { 88 BlockGuard.getThreadPolicy().onWriteToDisk(); 89 BlockGuard.getVmPolicy().onPathAccess(path); 90 super.chown(path, uid, gid); 91 } 92 93 @UnsupportedAppUsage close(FileDescriptor fd)94 @Override public void close(FileDescriptor fd) throws ErrnoException { 95 try { 96 // The usual case is that this _isn't_ a socket, so the getsockopt(2) call in 97 // isLingerSocket will throw, and that's really expensive. Try to avoid asking 98 // if we don't care. 99 if (fd.isSocket$()) { 100 if (isLingerSocket(fd)) { 101 // If the fd is a socket with SO_LINGER set, we might block indefinitely. 102 // We allow non-linger sockets so that apps can close their network 103 // connections in methods like onDestroy which will run on the UI thread. 104 BlockGuard.getThreadPolicy().onNetwork(); 105 } 106 } 107 } catch (ErrnoException ignored) { 108 // We're called via Socket.close (which doesn't ask for us to be called), so we 109 // must not throw here, because Socket.close must not throw if asked to close an 110 // already-closed socket. Also, the passed-in FileDescriptor isn't necessarily 111 // a socket at all. 112 } 113 super.close(fd); 114 } 115 isNonBlockingFile(FileDescriptor fd)116 public static boolean isNonBlockingFile(FileDescriptor fd) throws ErrnoException { 117 int flag = android.system.Os.fcntlInt(fd, F_GETFL, 0); 118 if ((flag & O_NONBLOCK) != 0) { 119 return true; 120 } 121 return false; 122 } 123 isUnixSocket(FileDescriptor fd)124 public static boolean isUnixSocket(FileDescriptor fd) throws ErrnoException { 125 return isUnixDomain(Libcore.os.getsockoptInt(fd, SOL_SOCKET, SO_DOMAIN)); 126 } 127 isUnixDomain(int domain)128 private static boolean isUnixDomain(int domain) { 129 return (domain == AF_UNIX); 130 } 131 isInetSocket(FileDescriptor fd)132 private static boolean isInetSocket(FileDescriptor fd) throws ErrnoException{ 133 return isInetDomain(Libcore.os.getsockoptInt(fd, SOL_SOCKET, SO_DOMAIN)); 134 } 135 isInetDomain(int domain)136 private static boolean isInetDomain(int domain) { 137 return (domain == AF_INET) || (domain == AF_INET6); 138 } 139 140 @SuppressWarnings("NewApi") // False positive lint limitation, see b/177434707. isLingerSocket(FileDescriptor fd)141 private static boolean isLingerSocket(FileDescriptor fd) throws ErrnoException { 142 StructLinger linger = Libcore.os.getsockoptLinger(fd, SOL_SOCKET, SO_LINGER); 143 return linger.isOn() && linger.l_linger > 0; 144 } 145 isUdpSocket(FileDescriptor fd)146 private static boolean isUdpSocket(FileDescriptor fd) throws ErrnoException { 147 return Libcore.os.getsockoptInt(fd, SOL_SOCKET, SO_PROTOCOL) == IPPROTO_UDP; 148 } 149 connect(FileDescriptor fd, InetAddress address, int port)150 @Override public void connect(FileDescriptor fd, InetAddress address, int port) 151 throws ErrnoException, SocketException { 152 boolean skipGuard = false; 153 try { 154 skipGuard = isUdpSocket(fd); 155 } catch (ErrnoException ignored) { 156 } 157 if (!skipGuard) BlockGuard.getThreadPolicy().onNetwork(); 158 super.connect(fd, address, port); 159 } 160 connect(FileDescriptor fd, SocketAddress address)161 @Override public void connect(FileDescriptor fd, SocketAddress address) throws ErrnoException, 162 SocketException { 163 boolean skipGuard = false; 164 try { 165 skipGuard = isUdpSocket(fd); 166 } catch (ErrnoException ignored) { 167 } 168 if (!skipGuard) BlockGuard.getThreadPolicy().onNetwork(); 169 super.connect(fd, address); 170 } 171 172 @UnsupportedAppUsage fchmod(FileDescriptor fd, int mode)173 @Override public void fchmod(FileDescriptor fd, int mode) throws ErrnoException { 174 BlockGuard.getThreadPolicy().onWriteToDisk(); 175 super.fchmod(fd, mode); 176 } 177 178 @UnsupportedAppUsage fchown(FileDescriptor fd, int uid, int gid)179 @Override public void fchown(FileDescriptor fd, int uid, int gid) throws ErrnoException { 180 BlockGuard.getThreadPolicy().onWriteToDisk(); 181 super.fchown(fd, uid, gid); 182 } 183 184 // TODO: Untag newFd when needed for dup2(FileDescriptor oldFd, int newFd) 185 186 @UnsupportedAppUsage fdatasync(FileDescriptor fd)187 @Override public void fdatasync(FileDescriptor fd) throws ErrnoException { 188 BlockGuard.getThreadPolicy().onWriteToDisk(); 189 super.fdatasync(fd); 190 } 191 192 @UnsupportedAppUsage fstat(FileDescriptor fd)193 @Override public StructStat fstat(FileDescriptor fd) throws ErrnoException { 194 BlockGuard.getThreadPolicy().onReadFromDisk(); 195 return super.fstat(fd); 196 } 197 198 @UnsupportedAppUsage fstatvfs(FileDescriptor fd)199 @Override public StructStatVfs fstatvfs(FileDescriptor fd) throws ErrnoException { 200 BlockGuard.getThreadPolicy().onReadFromDisk(); 201 return super.fstatvfs(fd); 202 } 203 fsync(FileDescriptor fd)204 @Override public void fsync(FileDescriptor fd) throws ErrnoException { 205 BlockGuard.getThreadPolicy().onWriteToDisk(); 206 super.fsync(fd); 207 } 208 ftruncate(FileDescriptor fd, long length)209 @Override public void ftruncate(FileDescriptor fd, long length) throws ErrnoException { 210 BlockGuard.getThreadPolicy().onWriteToDisk(); 211 super.ftruncate(fd, length); 212 } 213 android_getaddrinfo(String node, StructAddrinfo hints, int netId)214 @Override public InetAddress[] android_getaddrinfo(String node, StructAddrinfo hints, int netId) throws GaiException { 215 // With AI_NUMERICHOST flag set, the node must a numerical network address, therefore no 216 // host address lookups will be performed. In this case, it is fine to perform on main 217 // thread. 218 boolean isNumericHost = (hints.ai_flags & AI_NUMERICHOST) != 0; 219 if (!isNumericHost) { 220 BlockGuard.getThreadPolicy().onNetwork(); 221 } 222 return super.android_getaddrinfo(node, hints, netId); 223 } 224 225 @UnsupportedAppUsage lchown(String path, int uid, int gid)226 @Override public void lchown(String path, int uid, int gid) throws ErrnoException { 227 BlockGuard.getThreadPolicy().onWriteToDisk(); 228 BlockGuard.getVmPolicy().onPathAccess(path); 229 super.lchown(path, uid, gid); 230 } 231 232 @UnsupportedAppUsage link(String oldPath, String newPath)233 @Override public void link(String oldPath, String newPath) throws ErrnoException { 234 BlockGuard.getThreadPolicy().onWriteToDisk(); 235 BlockGuard.getVmPolicy().onPathAccess(oldPath); 236 BlockGuard.getVmPolicy().onPathAccess(newPath); 237 super.link(oldPath, newPath); 238 } 239 240 @UnsupportedAppUsage lseek(FileDescriptor fd, long offset, int whence)241 @Override public long lseek(FileDescriptor fd, long offset, int whence) throws ErrnoException { 242 BlockGuard.getThreadPolicy().onReadFromDisk(); 243 return super.lseek(fd, offset, whence); 244 } 245 246 @UnsupportedAppUsage lstat(String path)247 @Override public StructStat lstat(String path) throws ErrnoException { 248 BlockGuard.getThreadPolicy().onReadFromDisk(); 249 BlockGuard.getVmPolicy().onPathAccess(path); 250 return super.lstat(path); 251 } 252 253 @UnsupportedAppUsage mkdir(String path, int mode)254 @Override public void mkdir(String path, int mode) throws ErrnoException { 255 BlockGuard.getThreadPolicy().onWriteToDisk(); 256 BlockGuard.getVmPolicy().onPathAccess(path); 257 super.mkdir(path, mode); 258 } 259 260 @UnsupportedAppUsage mkfifo(String path, int mode)261 @Override public void mkfifo(String path, int mode) throws ErrnoException { 262 BlockGuard.getThreadPolicy().onWriteToDisk(); 263 BlockGuard.getVmPolicy().onPathAccess(path); 264 super.mkfifo(path, mode); 265 } 266 267 @UnsupportedAppUsage open(String path, int flags, int mode)268 @Override public FileDescriptor open(String path, int flags, int mode) throws ErrnoException { 269 BlockGuard.getThreadPolicy().onReadFromDisk(); 270 BlockGuard.getVmPolicy().onPathAccess(path); 271 if ((flags & O_ACCMODE) != O_RDONLY) { 272 BlockGuard.getThreadPolicy().onWriteToDisk(); 273 } 274 return super.open(path, flags, mode); 275 } 276 poll(StructPollfd[] fds, int timeoutMs)277 @Override public int poll(StructPollfd[] fds, int timeoutMs) throws ErrnoException { 278 // Greater than 0 is a timeout in milliseconds and -1 means "block forever", 279 // but 0 means "poll and return immediately", which shouldn't be subject to BlockGuard. 280 if (timeoutMs != 0) { 281 BlockGuard.getThreadPolicy().onNetwork(); 282 } 283 return super.poll(fds, timeoutMs); 284 } 285 286 @UnsupportedAppUsage posix_fallocate(FileDescriptor fd, long offset, long length)287 @Override public void posix_fallocate(FileDescriptor fd, long offset, long length) throws ErrnoException { 288 BlockGuard.getThreadPolicy().onWriteToDisk(); 289 super.posix_fallocate(fd, offset, length); 290 } 291 292 @UnsupportedAppUsage pread(FileDescriptor fd, ByteBuffer buffer, long offset)293 @Override public int pread(FileDescriptor fd, ByteBuffer buffer, long offset) throws ErrnoException, InterruptedIOException { 294 BlockGuard.getThreadPolicy().onReadFromDisk(); 295 return super.pread(fd, buffer, offset); 296 } 297 298 @UnsupportedAppUsage pread(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, long offset)299 @Override public int pread(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, long offset) throws ErrnoException, InterruptedIOException { 300 BlockGuard.getThreadPolicy().onReadFromDisk(); 301 return super.pread(fd, bytes, byteOffset, byteCount, offset); 302 } 303 304 @UnsupportedAppUsage pwrite(FileDescriptor fd, ByteBuffer buffer, long offset)305 @Override public int pwrite(FileDescriptor fd, ByteBuffer buffer, long offset) throws ErrnoException, InterruptedIOException { 306 BlockGuard.getThreadPolicy().onWriteToDisk(); 307 return super.pwrite(fd, buffer, offset); 308 } 309 310 @UnsupportedAppUsage pwrite(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, long offset)311 @Override public int pwrite(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, long offset) throws ErrnoException, InterruptedIOException { 312 BlockGuard.getThreadPolicy().onWriteToDisk(); 313 return super.pwrite(fd, bytes, byteOffset, byteCount, offset); 314 } 315 316 @UnsupportedAppUsage read(FileDescriptor fd, ByteBuffer buffer)317 @Override public int read(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException, InterruptedIOException { 318 BlockGuard.getThreadPolicy().onReadFromDisk(); 319 return super.read(fd, buffer); 320 } 321 322 @UnsupportedAppUsage read(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount)323 @Override public int read(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws ErrnoException, InterruptedIOException { 324 BlockGuard.getThreadPolicy().onReadFromDisk(); 325 return super.read(fd, bytes, byteOffset, byteCount); 326 } 327 328 @UnsupportedAppUsage readlink(String path)329 @Override public String readlink(String path) throws ErrnoException { 330 BlockGuard.getThreadPolicy().onReadFromDisk(); 331 BlockGuard.getVmPolicy().onPathAccess(path); 332 return super.readlink(path); 333 } 334 335 @UnsupportedAppUsage realpath(String path)336 @Override public String realpath(String path) throws ErrnoException { 337 BlockGuard.getThreadPolicy().onReadFromDisk(); 338 BlockGuard.getVmPolicy().onPathAccess(path); 339 return super.realpath(path); 340 } 341 342 @UnsupportedAppUsage readv(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts)343 @Override public int readv(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts) throws ErrnoException, InterruptedIOException { 344 BlockGuard.getThreadPolicy().onReadFromDisk(); 345 return super.readv(fd, buffers, offsets, byteCounts); 346 } 347 recvfrom(FileDescriptor fd, ByteBuffer buffer, int flags, InetSocketAddress srcAddress)348 @Override public int recvfrom(FileDescriptor fd, ByteBuffer buffer, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException { 349 BlockGuard.getThreadPolicy().onNetwork(); 350 return super.recvfrom(fd, buffer, flags, srcAddress); 351 } 352 recvfrom(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetSocketAddress srcAddress)353 @Override public int recvfrom(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException { 354 BlockGuard.getThreadPolicy().onNetwork(); 355 return super.recvfrom(fd, bytes, byteOffset, byteCount, flags, srcAddress); 356 } 357 recvmsg(FileDescriptor fd, StructMsghdr msg, int flags)358 @Override public int recvmsg(FileDescriptor fd, StructMsghdr msg, int flags) throws ErrnoException, SocketException { 359 BlockGuard.getThreadPolicy().onNetwork(); 360 return super.recvmsg(fd, msg, flags); 361 } 362 363 @UnsupportedAppUsage remove(String path)364 @Override public void remove(String path) throws ErrnoException { 365 BlockGuard.getThreadPolicy().onWriteToDisk(); 366 BlockGuard.getVmPolicy().onPathAccess(path); 367 super.remove(path); 368 } 369 370 @UnsupportedAppUsage rename(String oldPath, String newPath)371 @Override public void rename(String oldPath, String newPath) throws ErrnoException { 372 BlockGuard.getThreadPolicy().onWriteToDisk(); 373 BlockGuard.getVmPolicy().onPathAccess(oldPath); 374 BlockGuard.getVmPolicy().onPathAccess(newPath); 375 super.rename(oldPath, newPath); 376 } 377 sendfile(FileDescriptor outFd, FileDescriptor inFd, Int64Ref offset, long byteCount)378 @Override public long sendfile(FileDescriptor outFd, FileDescriptor inFd, Int64Ref offset, long byteCount) throws ErrnoException { 379 BlockGuard.getThreadPolicy().onWriteToDisk(); 380 return super.sendfile(outFd, inFd, offset, byteCount); 381 } 382 sendmsg(FileDescriptor fd, StructMsghdr msg, int flags)383 @Override public int sendmsg(FileDescriptor fd, StructMsghdr msg, int flags) throws ErrnoException, SocketException { 384 BlockGuard.getThreadPolicy().onNetwork(); 385 return super.sendmsg(fd, msg, flags); 386 } 387 sendto(FileDescriptor fd, ByteBuffer buffer, int flags, InetAddress inetAddress, int port)388 @Override public int sendto(FileDescriptor fd, ByteBuffer buffer, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException { 389 BlockGuard.getThreadPolicy().onNetwork(); 390 return super.sendto(fd, buffer, flags, inetAddress, port); 391 } 392 sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetAddress inetAddress, int port)393 @Override public int sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException { 394 // We permit datagrams without hostname lookups. 395 if (inetAddress != null) { 396 BlockGuard.getThreadPolicy().onNetwork(); 397 } 398 return super.sendto(fd, bytes, byteOffset, byteCount, flags, inetAddress, port); 399 } 400 socket(int domain, int type, int protocol)401 @Override public FileDescriptor socket(int domain, int type, int protocol) throws ErrnoException { 402 final FileDescriptor fd = super.socket(domain, type, protocol); 403 if (isInetDomain(domain)) { 404 tagSocket(fd); 405 } 406 return fd; 407 } 408 socketpair(int domain, int type, int protocol, FileDescriptor fd1, FileDescriptor fd2)409 @Override public void socketpair(int domain, int type, int protocol, FileDescriptor fd1, FileDescriptor fd2) throws ErrnoException { 410 super.socketpair(domain, type, protocol, fd1, fd2); 411 if (isInetDomain(domain)) { 412 tagSocket(fd1); 413 tagSocket(fd2); 414 } 415 } 416 417 @UnsupportedAppUsage stat(String path)418 @Override public StructStat stat(String path) throws ErrnoException { 419 BlockGuard.getThreadPolicy().onReadFromDisk(); 420 BlockGuard.getVmPolicy().onPathAccess(path); 421 return super.stat(path); 422 } 423 424 @UnsupportedAppUsage statvfs(String path)425 @Override public StructStatVfs statvfs(String path) throws ErrnoException { 426 BlockGuard.getThreadPolicy().onReadFromDisk(); 427 BlockGuard.getVmPolicy().onPathAccess(path); 428 return super.statvfs(path); 429 } 430 431 @UnsupportedAppUsage symlink(String oldPath, String newPath)432 @Override public void symlink(String oldPath, String newPath) throws ErrnoException { 433 BlockGuard.getThreadPolicy().onWriteToDisk(); 434 BlockGuard.getVmPolicy().onPathAccess(oldPath); 435 BlockGuard.getVmPolicy().onPathAccess(newPath); 436 super.symlink(oldPath, newPath); 437 } 438 439 @UnsupportedAppUsage write(FileDescriptor fd, ByteBuffer buffer)440 @Override public int write(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException, InterruptedIOException { 441 BlockGuard.getThreadPolicy().onWriteToDisk(); 442 return super.write(fd, buffer); 443 } 444 445 @UnsupportedAppUsage write(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount)446 @Override public int write(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws ErrnoException, InterruptedIOException { 447 BlockGuard.getThreadPolicy().onWriteToDisk(); 448 return super.write(fd, bytes, byteOffset, byteCount); 449 } 450 451 @UnsupportedAppUsage writev(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts)452 @Override public int writev(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts) throws ErrnoException, InterruptedIOException { 453 BlockGuard.getThreadPolicy().onWriteToDisk(); 454 return super.writev(fd, buffers, offsets, byteCounts); 455 } 456 execv(String filename, String[] argv)457 @Override public void execv(String filename, String[] argv) throws ErrnoException { 458 BlockGuard.getThreadPolicy().onReadFromDisk(); 459 BlockGuard.getVmPolicy().onPathAccess(filename); 460 super.execv(filename, argv); 461 } 462 execve(String filename, String[] argv, String[] envp)463 @Override public void execve(String filename, String[] argv, String[] envp) 464 throws ErrnoException { 465 BlockGuard.getThreadPolicy().onReadFromDisk(); 466 BlockGuard.getVmPolicy().onPathAccess(filename); 467 super.execve(filename, argv, envp); 468 } 469 getxattr(String path, String name)470 @Override public byte[] getxattr(String path, String name) throws ErrnoException { 471 BlockGuard.getThreadPolicy().onReadFromDisk(); 472 BlockGuard.getVmPolicy().onPathAccess(path); 473 return super.getxattr(path, name); 474 } 475 msync(long address, long byteCount, int flags)476 @Override public void msync(long address, long byteCount, int flags) throws ErrnoException { 477 if ((flags & OsConstants.MS_SYNC) != 0) { 478 BlockGuard.getThreadPolicy().onWriteToDisk(); 479 } 480 super.msync(address, byteCount, flags); 481 } 482 removexattr(String path, String name)483 @Override public void removexattr(String path, String name) throws ErrnoException { 484 BlockGuard.getThreadPolicy().onWriteToDisk(); 485 BlockGuard.getVmPolicy().onPathAccess(path); 486 super.removexattr(path, name); 487 } 488 setxattr(String path, String name, byte[] value, int flags)489 @Override public void setxattr(String path, String name, byte[] value, int flags) 490 throws ErrnoException { 491 BlockGuard.getThreadPolicy().onWriteToDisk(); 492 BlockGuard.getVmPolicy().onPathAccess(path); 493 super.setxattr(path, name, value, flags); 494 } 495 sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, SocketAddress address)496 @Override public int sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, 497 int flags, SocketAddress address) throws ErrnoException, SocketException { 498 BlockGuard.getThreadPolicy().onNetwork(); 499 return super.sendto(fd, bytes, byteOffset, byteCount, flags, address); 500 } 501 unlink(String pathname)502 @Override public void unlink(String pathname) throws ErrnoException { 503 BlockGuard.getThreadPolicy().onWriteToDisk(); 504 BlockGuard.getVmPolicy().onPathAccess(pathname); 505 super.unlink(pathname); 506 } 507 splice(FileDescriptor fdIn, Int64Ref offIn, FileDescriptor fdOut, Int64Ref offOut, long len, int flags)508 @Override public long splice(FileDescriptor fdIn, Int64Ref offIn, FileDescriptor fdOut, Int64Ref offOut, long len, int flags) throws ErrnoException { 509 // It's infeasible to figure out if splice will result in read or write (would require fstat to figure out which fd is pipe). 510 // So, signal both read and write. 511 BlockGuard.getThreadPolicy().onWriteToDisk(); 512 BlockGuard.getThreadPolicy().onReadFromDisk(); 513 return super.splice(fdIn, offIn, fdOut, offOut, len, flags); 514 } 515 } 516