|
30 | 30 | import com.sun.jna.NativeLong; |
31 | 31 | import com.sun.jna.Pointer; |
32 | 32 | import com.sun.jna.Structure; |
| 33 | +import com.sun.jna.Union; |
33 | 34 | import com.sun.jna.platform.unix.LibCAPI; |
34 | 35 | import com.sun.jna.ptr.IntByReference; |
35 | 36 | import com.sun.jna.ptr.LongByReference; |
@@ -298,6 +299,245 @@ class RUsageInfoV2 extends Structure { |
298 | 299 | public long ri_diskio_byteswritten; |
299 | 300 | } |
300 | 301 |
|
| 302 | + // proc_info.h: Flavors for proc_pidinfo and proc_pidfdinfo |
| 303 | + int PROC_PIDLISTFDS = 1; |
| 304 | + int PROC_PIDFDSOCKETINFO = 3; |
| 305 | + |
| 306 | + // proc_info.h: File descriptor types |
| 307 | + int PROX_FDTYPE_SOCKET = 2; |
| 308 | + |
| 309 | + // proc_info.h: Socket info kinds |
| 310 | + int SOCKINFO_IN = 1; |
| 311 | + int SOCKINFO_TCP = 2; |
| 312 | + |
| 313 | + // proc_info.h: TCP timer count |
| 314 | + int TSI_T_NTIMERS = 4; |
| 315 | + |
| 316 | + // socket.h: Address families |
| 317 | + int AF_INET = 2; |
| 318 | + int AF_INET6 = 30; |
| 319 | + |
| 320 | + /** |
| 321 | + * File descriptor information as returned by {@code proc_pidinfo} with |
| 322 | + * {@link #PROC_PIDLISTFDS}. |
| 323 | + * <p> |
| 324 | + * Corresponds to {@code struct proc_fdinfo} in {@code <sys/proc_info.h>}. |
| 325 | + */ |
| 326 | + @Structure.FieldOrder({ "proc_fd", "proc_fdtype" }) |
| 327 | + class ProcFdInfo extends Structure { |
| 328 | + public int proc_fd; |
| 329 | + public int proc_fdtype; |
| 330 | + } |
| 331 | + |
| 332 | + /** |
| 333 | + * IPv4 address mapped into IPv6 address space. |
| 334 | + * <p> |
| 335 | + * Corresponds to {@code struct in4in6_addr} in {@code <sys/proc_info.h>}. |
| 336 | + */ |
| 337 | + @Structure.FieldOrder({ "i46a_pad32", "i46a_addr4" }) |
| 338 | + class In4In6Addr extends Structure { |
| 339 | + /** Padding to align IPv4 address at offset 12. */ |
| 340 | + public int[] i46a_pad32 = new int[3]; |
| 341 | + /** IPv4 address (network byte order). */ |
| 342 | + public int i46a_addr4; |
| 343 | + } |
| 344 | + |
| 345 | + /** |
| 346 | + * IPv6 address (128 bits). |
| 347 | + * <p> |
| 348 | + * Corresponds to {@code struct in6_addr} in {@code <netinet/in.h>}. |
| 349 | + */ |
| 350 | + @Structure.FieldOrder({ "__u6_addr" }) |
| 351 | + class In6Addr extends Structure { |
| 352 | + /** 16-byte IPv6 address. */ |
| 353 | + public byte[] __u6_addr = new byte[16]; |
| 354 | + } |
| 355 | + |
| 356 | + /** |
| 357 | + * Union of IPv4-mapped-in-IPv6 and IPv6 addresses, used in |
| 358 | + * {@link InSockInfo}. |
| 359 | + * <p> |
| 360 | + * Corresponds to the anonymous union containing {@code ina_46} and |
| 361 | + * {@code ina_6} in {@code struct in_sockinfo}. |
| 362 | + */ |
| 363 | + class InsiAddr extends Union { |
| 364 | + public In4In6Addr ina_46; |
| 365 | + public In6Addr ina_6; |
| 366 | + } |
| 367 | + |
| 368 | + /** |
| 369 | + * Internet socket information. |
| 370 | + * <p> |
| 371 | + * Corresponds to {@code struct in_sockinfo} in {@code <sys/proc_info.h>}. |
| 372 | + */ |
| 373 | + @Structure.FieldOrder({ "insi_fport", "insi_lport", "insi_gencnt", "insi_flags", "insi_flow", "insi_vflag", |
| 374 | + "insi_ip_ttl", "rfu_1", "insi_faddr", "insi_laddr", "insi_v4", "insi_v6" }) |
| 375 | + class InSockInfo extends Structure { |
| 376 | + /** Foreign port. */ |
| 377 | + public int insi_fport; |
| 378 | + /** Local port. */ |
| 379 | + public int insi_lport; |
| 380 | + /** Generation count of this instance. */ |
| 381 | + public long insi_gencnt; |
| 382 | + /** Generic IP/datagram flags. */ |
| 383 | + public int insi_flags; |
| 384 | + public int insi_flow; |
| 385 | + /** INI_IPV4 or INI_IPV6. */ |
| 386 | + public byte insi_vflag; |
| 387 | + /** Time to live proto. */ |
| 388 | + public byte insi_ip_ttl; |
| 389 | + /** Reserved. */ |
| 390 | + public int rfu_1; |
| 391 | + /** Foreign host table entry. */ |
| 392 | + public InsiAddr insi_faddr; |
| 393 | + /** Local host table entry. */ |
| 394 | + public InsiAddr insi_laddr; |
| 395 | + /** IPv4 type of service. */ |
| 396 | + public byte insi_v4; |
| 397 | + /** IPv6 info (in6_hlim, in6_cksum, in6_ifindex, in6_hops). */ |
| 398 | + public byte[] insi_v6 = new byte[9]; |
| 399 | + |
| 400 | + @Override |
| 401 | + public void read() { |
| 402 | + super.read(); |
| 403 | + if (insi_vflag == 2) { |
| 404 | + insi_faddr.setType("ina_6"); |
| 405 | + insi_laddr.setType("ina_6"); |
| 406 | + } else { |
| 407 | + insi_faddr.setType("ina_46"); |
| 408 | + insi_laddr.setType("ina_46"); |
| 409 | + } |
| 410 | + insi_faddr.read(); |
| 411 | + insi_laddr.read(); |
| 412 | + } |
| 413 | + } |
| 414 | + |
| 415 | + /** |
| 416 | + * TCP socket information. |
| 417 | + * <p> |
| 418 | + * Corresponds to {@code struct tcp_sockinfo} in {@code <sys/proc_info.h>}. |
| 419 | + */ |
| 420 | + @Structure.FieldOrder({ "tcpsi_ini", "tcpsi_state", "tcpsi_timer", "tcpsi_mss", "tcpsi_flags", "rfu_1", |
| 421 | + "tcpsi_tp" }) |
| 422 | + class TcpSockInfo extends Structure { |
| 423 | + public InSockInfo tcpsi_ini; |
| 424 | + public int tcpsi_state; |
| 425 | + public int[] tcpsi_timer = new int[TSI_T_NTIMERS]; |
| 426 | + public int tcpsi_mss; |
| 427 | + public int tcpsi_flags; |
| 428 | + /** Reserved. */ |
| 429 | + public int rfu_1; |
| 430 | + /** Opaque handle of TCP protocol control block. */ |
| 431 | + public long tcpsi_tp; |
| 432 | + } |
| 433 | + |
| 434 | + /** |
| 435 | + * Per-file descriptor information. |
| 436 | + * <p> |
| 437 | + * Corresponds to {@code struct proc_fileinfo} in {@code <sys/proc_info.h>}. |
| 438 | + */ |
| 439 | + @Structure.FieldOrder({ "fi_openflags", "fi_status", "fi_offset", "fi_type", "fi_guardflags" }) |
| 440 | + class ProcFileInfo extends Structure { |
| 441 | + public int fi_openflags; |
| 442 | + public int fi_status; |
| 443 | + public long fi_offset; |
| 444 | + public int fi_type; |
| 445 | + public int fi_guardflags; |
| 446 | + } |
| 447 | + |
| 448 | + /** |
| 449 | + * Socket buffer information. |
| 450 | + * <p> |
| 451 | + * Corresponds to {@code struct sockbuf_info} in {@code <sys/proc_info.h>}. |
| 452 | + */ |
| 453 | + @Structure.FieldOrder({ "sbi_cc", "sbi_hiwat", "sbi_mbcnt", "sbi_mbmax", "sbi_lowat", "sbi_flags", |
| 454 | + "sbi_timeo" }) |
| 455 | + class SockbufInfo extends Structure { |
| 456 | + public int sbi_cc; |
| 457 | + public int sbi_hiwat; |
| 458 | + public int sbi_mbcnt; |
| 459 | + public int sbi_mbmax; |
| 460 | + public int sbi_lowat; |
| 461 | + public short sbi_flags; |
| 462 | + public short sbi_timeo; |
| 463 | + } |
| 464 | + |
| 465 | + /** |
| 466 | + * Union of protocol-specific socket information in {@link SocketInfo}. |
| 467 | + * <p> |
| 468 | + * Corresponds to the {@code soi_proto} union in |
| 469 | + * {@code struct socket_info}. |
| 470 | + */ |
| 471 | + class Pri extends Union { |
| 472 | + public InSockInfo pri_in; |
| 473 | + public TcpSockInfo pri_tcp; |
| 474 | + /** Ensures the union is large enough for all protocol variants. */ |
| 475 | + public byte[] max_size = new byte[524]; |
| 476 | + } |
| 477 | + |
| 478 | + /** |
| 479 | + * Socket information. |
| 480 | + * <p> |
| 481 | + * Corresponds to {@code struct socket_info} in {@code <sys/proc_info.h>}. |
| 482 | + * The {@code soi_stat} field ({@code struct vinfo_stat}) is mapped as a |
| 483 | + * 136-byte opaque region. |
| 484 | + */ |
| 485 | + @Structure.FieldOrder({ "soi_stat", "soi_so", "soi_pcb", "soi_type", "soi_protocol", "soi_family", |
| 486 | + "soi_options", "soi_linger", "soi_state", "soi_qlen", "soi_incqlen", "soi_qlimit", "soi_timeo", |
| 487 | + "soi_error", "soi_oobmark", "soi_rcv", "soi_snd", "soi_kind", "rfu_1", "soi_proto" }) |
| 488 | + class SocketInfo extends Structure { |
| 489 | + /** Opaque {@code vinfo_stat} (136 bytes). */ |
| 490 | + public byte[] soi_stat = new byte[136]; |
| 491 | + /** Opaque handle of socket. */ |
| 492 | + public long soi_so; |
| 493 | + /** Opaque handle of protocol control block. */ |
| 494 | + public long soi_pcb; |
| 495 | + public int soi_type; |
| 496 | + public int soi_protocol; |
| 497 | + public int soi_family; |
| 498 | + public short soi_options; |
| 499 | + public short soi_linger; |
| 500 | + public short soi_state; |
| 501 | + public short soi_qlen; |
| 502 | + public short soi_incqlen; |
| 503 | + public short soi_qlimit; |
| 504 | + public short soi_timeo; |
| 505 | + public short soi_error; |
| 506 | + public int soi_oobmark; |
| 507 | + public SockbufInfo soi_rcv; |
| 508 | + public SockbufInfo soi_snd; |
| 509 | + public int soi_kind; |
| 510 | + /** Reserved. */ |
| 511 | + public int rfu_1; |
| 512 | + public Pri soi_proto; |
| 513 | + |
| 514 | + @Override |
| 515 | + public void read() { |
| 516 | + super.read(); |
| 517 | + if (soi_kind == SOCKINFO_TCP) { |
| 518 | + soi_proto.setType("pri_tcp"); |
| 519 | + } else if (soi_kind == SOCKINFO_IN) { |
| 520 | + soi_proto.setType("pri_in"); |
| 521 | + } else { |
| 522 | + soi_proto.setType("max_size"); |
| 523 | + } |
| 524 | + soi_proto.read(); |
| 525 | + } |
| 526 | + } |
| 527 | + |
| 528 | + /** |
| 529 | + * Socket file descriptor information as returned by |
| 530 | + * {@code proc_pidfdinfo} with {@link #PROC_PIDFDSOCKETINFO}. |
| 531 | + * <p> |
| 532 | + * Corresponds to {@code struct socket_fdinfo} in |
| 533 | + * {@code <sys/proc_info.h>}. |
| 534 | + */ |
| 535 | + @Structure.FieldOrder({ "pfi", "psi" }) |
| 536 | + class SocketFdInfo extends Structure { |
| 537 | + public ProcFileInfo pfi; |
| 538 | + public SocketInfo psi; |
| 539 | + } |
| 540 | + |
301 | 541 | @Structure.FieldOrder({ "vip_vi", "vip_path" }) |
302 | 542 | class VnodeInfoPath extends Structure { |
303 | 543 | public byte[] vip_vi = new byte[152]; // vnode_info but we don't |
@@ -877,4 +1117,51 @@ int host_processor_info(int hostPort, int flavor, IntByReference procCount, Poin |
877 | 1117 | * @return the process ID of the calling process. |
878 | 1118 | */ |
879 | 1119 | int getpid(); |
| 1120 | + |
| 1121 | + /** |
| 1122 | + * Returns information about a file descriptor of a process. |
| 1123 | + * |
| 1124 | + * @param pid |
| 1125 | + * the process identifier |
| 1126 | + * @param fd |
| 1127 | + * the file descriptor |
| 1128 | + * @param flavor |
| 1129 | + * the type of information requested (e.g., |
| 1130 | + * {@link #PROC_PIDFDSOCKETINFO}) |
| 1131 | + * @param buffer |
| 1132 | + * holds results |
| 1133 | + * @param buffersize |
| 1134 | + * size of results |
| 1135 | + * @return the number of bytes of data returned in the provided buffer; -1 if an |
| 1136 | + * error was encountered |
| 1137 | + */ |
| 1138 | + int proc_pidfdinfo(int pid, int fd, int flavor, Structure buffer, int buffersize); |
| 1139 | + |
| 1140 | + /** |
| 1141 | + * The statfs64() routine returns information about a mounted file system. |
| 1142 | + * The {@code path} argument is the path name of any file or directory within |
| 1143 | + * the mounted file system. The {@code buf} argument is a pointer to a |
| 1144 | + * {@code statfs} structure. |
| 1145 | + * |
| 1146 | + * @param path |
| 1147 | + * the path to any file within the mounted filesystem |
| 1148 | + * @param buf |
| 1149 | + * a {@link Statfs} structure |
| 1150 | + * @return 0 on success; -1 on failure (sets errno) |
| 1151 | + */ |
| 1152 | + int statfs64(String path, Statfs buf); |
| 1153 | + |
| 1154 | + /** |
| 1155 | + * Deallocates a region of virtual memory in the specified task. |
| 1156 | + * |
| 1157 | + * @param targetTask |
| 1158 | + * the target task (typically from {@link #mach_task_self()}) |
| 1159 | + * @param address |
| 1160 | + * the starting address of the region to deallocate |
| 1161 | + * @param size |
| 1162 | + * the number of bytes to deallocate |
| 1163 | + * @return 0 ({@code KERN_SUCCESS}) on success; a {@code kern_return_t} error |
| 1164 | + * code otherwise |
| 1165 | + */ |
| 1166 | + int vm_deallocate(int targetTask, long address, long size); |
880 | 1167 | } |
0 commit comments