Skip to content

Commit 5c421d7

Browse files
authored
Merge pull request #1723 from dbwiddis/add-resource-usage-and-proc-info
Add proc_info structs and methods to macOS SystemB
2 parents 7897cc7 + abfd400 commit 5c421d7

3 files changed

Lines changed: 410 additions & 0 deletions

File tree

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Features
1212
* [#1718](https://github.com/java-native-access/jna/pull/1718): Add `Cups` to `c.s.j.p.unix` providing CUPS printing system bindings for destinations, jobs, options, and server configuration - [@dbwiddis](https://github.com/dbwiddis).
1313
* [#1720](https://github.com/java-native-access/jna/pull/1720): Add `groupCount` and `groupMasks` fields to `CACHE_RELATIONSHIP` in `c.s.j.p.win32.WinNT`, matching the updated Windows struct layout - [@dbwiddis](https://github.com/dbwiddis).
1414
* [#1719](https://github.com/java-native-access/jna/pull/1719): Add `CoreGraphics` to `c.s.j.p.mac` with Quartz Window Services and Display Services bindings; implement `getAllWindows()` in `MacWindowUtils` - [@dbwiddis](https://github.com/dbwiddis).
15+
* [#1723](https://github.com/java-native-access/jna/pull/1723): Add `ProcFdInfo`, `InSockInfo`, `TcpSockInfo`, `proc_pidfdinfo`, `statfs64`, and `vm_deallocate` to `c.s.j.p.mac.SystemB` - [@dbwiddis](https://github.com/dbwiddis).
1516

1617
Bug Fixes
1718
---------

contrib/platform/src/com/sun/jna/platform/mac/SystemB.java

Lines changed: 318 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import com.sun.jna.NativeLong;
3131
import com.sun.jna.Pointer;
3232
import com.sun.jna.Structure;
33+
import com.sun.jna.Union;
3334
import com.sun.jna.platform.unix.LibCAPI;
3435
import com.sun.jna.ptr.IntByReference;
3536
import com.sun.jna.ptr.LongByReference;
@@ -299,6 +300,276 @@ class RUsageInfoV2 extends Structure {
299300
public long ri_diskio_byteswritten;
300301
}
301302

303+
// proc_info.h: Flavors for proc_pidinfo and proc_pidfdinfo
304+
int PROC_PIDLISTFDS = 1;
305+
int PROC_PIDFDSOCKETINFO = 3;
306+
307+
// proc_info.h: File descriptor types
308+
int PROX_FDTYPE_SOCKET = 2;
309+
310+
// proc_info.h: Socket info kinds
311+
int SOCKINFO_IN = 1;
312+
int SOCKINFO_TCP = 2;
313+
314+
// proc_info.h: TCP timer count
315+
int TSI_T_NTIMERS = 4;
316+
317+
// socket.h: Address families
318+
int AF_INET = 2;
319+
int AF_INET6 = 30;
320+
321+
/**
322+
* File descriptor information as returned by {@code proc_pidinfo} with
323+
* {@link #PROC_PIDLISTFDS}.
324+
* <p>
325+
* Corresponds to {@code struct proc_fdinfo} in {@code <sys/proc_info.h>}.
326+
*/
327+
@Structure.FieldOrder({ "proc_fd", "proc_fdtype" })
328+
class ProcFdInfo extends Structure {
329+
public int proc_fd;
330+
public int proc_fdtype;
331+
}
332+
333+
/**
334+
* IPv4 address mapped into IPv6 address space.
335+
* <p>
336+
* Corresponds to {@code struct in4in6_addr} in {@code <sys/proc_info.h>}.
337+
*/
338+
@Structure.FieldOrder({ "i46a_pad32", "i46a_addr4" })
339+
class In4In6Addr extends Structure {
340+
/** Padding to align IPv4 address at offset 12. */
341+
public int[] i46a_pad32 = new int[3];
342+
/** IPv4 address (network byte order). */
343+
public int i46a_addr4;
344+
}
345+
346+
/**
347+
* IPv6 address (128 bits).
348+
* <p>
349+
* Corresponds to {@code struct in6_addr} in {@code <netinet/in.h>}.
350+
*/
351+
@Structure.FieldOrder({ "__u6_addr" })
352+
class In6Addr extends Structure {
353+
/** 16-byte IPv6 address. */
354+
public byte[] __u6_addr = new byte[16];
355+
}
356+
357+
/**
358+
* Union of IPv4-mapped-in-IPv6 and IPv6 addresses, used in
359+
* {@link InSockInfo}.
360+
* <p>
361+
* Corresponds to the anonymous union containing {@code ina_46} and
362+
* {@code ina_6} in {@code struct in_sockinfo}.
363+
*/
364+
class InsiAddr extends Union {
365+
public In4In6Addr ina_46;
366+
public In6Addr ina_6;
367+
}
368+
369+
/**
370+
* Internet socket information.
371+
* <p>
372+
* Corresponds to {@code struct in_sockinfo} in {@code <sys/proc_info.h>}.
373+
*/
374+
@Structure.FieldOrder({ "insi_fport", "insi_lport", "insi_gencnt", "insi_flags", "insi_flow", "insi_vflag",
375+
"insi_ip_ttl", "rfu_1", "insi_faddr", "insi_laddr", "insi_v4", "insi_v6" })
376+
class InSockInfo extends Structure {
377+
/** Foreign port. */
378+
public int insi_fport;
379+
/** Local port. */
380+
public int insi_lport;
381+
/** Generation count of this instance. */
382+
public long insi_gencnt;
383+
/** Generic IP/datagram flags. */
384+
public int insi_flags;
385+
public int insi_flow;
386+
/** INI_IPV4 or INI_IPV6. */
387+
public byte insi_vflag;
388+
/** Time to live proto. */
389+
public byte insi_ip_ttl;
390+
/** Reserved. */
391+
public int rfu_1;
392+
/** Foreign host table entry. */
393+
public InsiAddr insi_faddr;
394+
/** Local host table entry. */
395+
public InsiAddr insi_laddr;
396+
/** IPv4 type of service. */
397+
public byte insi_v4;
398+
/** IPv6 info (in6_hlim, in6_cksum, in6_ifindex, in6_hops). */
399+
public byte[] insi_v6 = new byte[9];
400+
401+
@Override
402+
public void read() {
403+
super.read();
404+
if (insi_vflag == 2) {
405+
insi_faddr.setType("ina_6");
406+
insi_laddr.setType("ina_6");
407+
} else {
408+
insi_faddr.setType("ina_46");
409+
insi_laddr.setType("ina_46");
410+
}
411+
insi_faddr.read();
412+
insi_laddr.read();
413+
}
414+
}
415+
416+
/**
417+
* TCP socket information.
418+
* <p>
419+
* Corresponds to {@code struct tcp_sockinfo} in {@code <sys/proc_info.h>}.
420+
*/
421+
@Structure.FieldOrder({ "tcpsi_ini", "tcpsi_state", "tcpsi_timer", "tcpsi_mss", "tcpsi_flags", "rfu_1",
422+
"tcpsi_tp" })
423+
class TcpSockInfo extends Structure {
424+
public InSockInfo tcpsi_ini;
425+
public int tcpsi_state;
426+
public int[] tcpsi_timer = new int[TSI_T_NTIMERS];
427+
public int tcpsi_mss;
428+
public int tcpsi_flags;
429+
/** Reserved. */
430+
public int rfu_1;
431+
/** Opaque handle of TCP protocol control block. */
432+
public long tcpsi_tp;
433+
}
434+
435+
/**
436+
* Per-file descriptor information.
437+
* <p>
438+
* Corresponds to {@code struct proc_fileinfo} in {@code <sys/proc_info.h>}.
439+
*/
440+
@Structure.FieldOrder({ "fi_openflags", "fi_status", "fi_offset", "fi_type", "fi_guardflags" })
441+
class ProcFileInfo extends Structure {
442+
public int fi_openflags;
443+
public int fi_status;
444+
public long fi_offset;
445+
public int fi_type;
446+
public int fi_guardflags;
447+
}
448+
449+
/**
450+
* Socket buffer information.
451+
* <p>
452+
* Corresponds to {@code struct sockbuf_info} in {@code <sys/proc_info.h>}.
453+
*/
454+
@Structure.FieldOrder({ "sbi_cc", "sbi_hiwat", "sbi_mbcnt", "sbi_mbmax", "sbi_lowat", "sbi_flags",
455+
"sbi_timeo" })
456+
class SockbufInfo extends Structure {
457+
public int sbi_cc;
458+
public int sbi_hiwat;
459+
public int sbi_mbcnt;
460+
public int sbi_mbmax;
461+
public int sbi_lowat;
462+
public short sbi_flags;
463+
public short sbi_timeo;
464+
}
465+
466+
/**
467+
* Union of protocol-specific socket information in {@link SocketInfo}.
468+
* <p>
469+
* Corresponds to the {@code soi_proto} union in
470+
* {@code struct socket_info}.
471+
*/
472+
class Pri extends Union {
473+
public InSockInfo pri_in;
474+
public TcpSockInfo pri_tcp;
475+
/** Ensures the union is large enough for all protocol variants. */
476+
public byte[] max_size = new byte[524];
477+
}
478+
479+
/**
480+
* File status information.
481+
* <p>
482+
* Corresponds to {@code struct vinfo_stat} in {@code <sys/proc_info.h>}. A copy of {@code stat64} with
483+
* statically-sized fields.
484+
*/
485+
@Structure.FieldOrder({ "vst_dev", "vst_mode", "vst_nlink", "vst_ino", "vst_uid", "vst_gid", "vst_atime",
486+
"vst_atimensec", "vst_mtime", "vst_mtimensec", "vst_ctime", "vst_ctimensec", "vst_birthtime",
487+
"vst_birthtimensec", "vst_size", "vst_blocks", "vst_blksize", "vst_flags", "vst_gen", "vst_rdev",
488+
"vst_qspare" })
489+
class VinfoStat extends Structure {
490+
public int vst_dev;
491+
public short vst_mode;
492+
public short vst_nlink;
493+
public long vst_ino;
494+
public int vst_uid;
495+
public int vst_gid;
496+
public long vst_atime;
497+
public long vst_atimensec;
498+
public long vst_mtime;
499+
public long vst_mtimensec;
500+
public long vst_ctime;
501+
public long vst_ctimensec;
502+
public long vst_birthtime;
503+
public long vst_birthtimensec;
504+
public long vst_size;
505+
public long vst_blocks;
506+
public int vst_blksize;
507+
public int vst_flags;
508+
public int vst_gen;
509+
public int vst_rdev;
510+
public long[] vst_qspare = new long[2];
511+
}
512+
513+
/**
514+
* Socket information.
515+
* <p>
516+
* Corresponds to {@code struct socket_info} in {@code <sys/proc_info.h>}.
517+
*/
518+
@Structure.FieldOrder({ "soi_stat", "soi_so", "soi_pcb", "soi_type", "soi_protocol", "soi_family",
519+
"soi_options", "soi_linger", "soi_state", "soi_qlen", "soi_incqlen", "soi_qlimit", "soi_timeo",
520+
"soi_error", "soi_oobmark", "soi_rcv", "soi_snd", "soi_kind", "rfu_1", "soi_proto" })
521+
class SocketInfo extends Structure {
522+
public VinfoStat soi_stat;
523+
/** Opaque handle of socket. */
524+
public long soi_so;
525+
/** Opaque handle of protocol control block. */
526+
public long soi_pcb;
527+
public int soi_type;
528+
public int soi_protocol;
529+
public int soi_family;
530+
public short soi_options;
531+
public short soi_linger;
532+
public short soi_state;
533+
public short soi_qlen;
534+
public short soi_incqlen;
535+
public short soi_qlimit;
536+
public short soi_timeo;
537+
public short soi_error;
538+
public int soi_oobmark;
539+
public SockbufInfo soi_rcv;
540+
public SockbufInfo soi_snd;
541+
public int soi_kind;
542+
/** Reserved. */
543+
public int rfu_1;
544+
public Pri soi_proto;
545+
546+
@Override
547+
public void read() {
548+
super.read();
549+
if (soi_kind == SOCKINFO_TCP) {
550+
soi_proto.setType("pri_tcp");
551+
} else if (soi_kind == SOCKINFO_IN) {
552+
soi_proto.setType("pri_in");
553+
} else {
554+
soi_proto.setType("max_size");
555+
}
556+
soi_proto.read();
557+
}
558+
}
559+
560+
/**
561+
* Socket file descriptor information as returned by
562+
* {@code proc_pidfdinfo} with {@link #PROC_PIDFDSOCKETINFO}.
563+
* <p>
564+
* Corresponds to {@code struct socket_fdinfo} in
565+
* {@code <sys/proc_info.h>}.
566+
*/
567+
@Structure.FieldOrder({ "pfi", "psi" })
568+
class SocketFdInfo extends Structure {
569+
public ProcFileInfo pfi;
570+
public SocketInfo psi;
571+
}
572+
302573
@Structure.FieldOrder({ "vip_vi", "vip_path" })
303574
class VnodeInfoPath extends Structure {
304575
public byte[] vip_vi = new byte[152]; // vnode_info but we don't
@@ -885,4 +1156,51 @@ int host_processor_info(int hostPort, int flavor, IntByReference procCount, Poin
8851156
* @return the process ID of the calling process.
8861157
*/
8871158
int getpid();
1159+
1160+
/**
1161+
* Returns information about a file descriptor of a process.
1162+
*
1163+
* @param pid
1164+
* the process identifier
1165+
* @param fd
1166+
* the file descriptor
1167+
* @param flavor
1168+
* the type of information requested (e.g.,
1169+
* {@link #PROC_PIDFDSOCKETINFO})
1170+
* @param buffer
1171+
* holds results
1172+
* @param buffersize
1173+
* size of results
1174+
* @return the number of bytes of data returned in the provided buffer; -1 if an
1175+
* error was encountered
1176+
*/
1177+
int proc_pidfdinfo(int pid, int fd, int flavor, Structure buffer, int buffersize);
1178+
1179+
/**
1180+
* The statfs64() routine returns information about a mounted file system.
1181+
* The {@code path} argument is the path name of any file or directory within
1182+
* the mounted file system. The {@code buf} argument is a pointer to a
1183+
* {@code statfs} structure.
1184+
*
1185+
* @param path
1186+
* the path to any file within the mounted filesystem
1187+
* @param buf
1188+
* a {@link Statfs} structure
1189+
* @return 0 on success; -1 on failure (sets errno)
1190+
*/
1191+
int statfs64(String path, Statfs buf);
1192+
1193+
/**
1194+
* Deallocates a region of virtual memory in the specified task.
1195+
*
1196+
* @param targetTask
1197+
* the target task (typically from {@link #mach_task_self()})
1198+
* @param address
1199+
* the starting address of the region to deallocate
1200+
* @param size
1201+
* the number of bytes to deallocate
1202+
* @return 0 ({@code KERN_SUCCESS}) on success; a {@code kern_return_t} error
1203+
* code otherwise
1204+
*/
1205+
int vm_deallocate(int targetTask, long address, long size);
8881206
}

0 commit comments

Comments
 (0)