Skip to content

Commit 70db423

Browse files
committed
Add proc_info structs and methods to mac SystemB
Add In4In6Addr, In6Addr, InsiAddr union for proper address mapping in InSockInfo. Add ProcFileInfo, SockbufInfo, SocketInfo, Pri union, and SocketFdInfo structures for proc_pidfdinfo support. InSockInfo.read() and SocketInfo.read() automatically select the correct union type based on insi_vflag and soi_kind respectively. Add testProcPidFdSocketInfo test exercising proc_pidfdinfo with PROC_PIDFDSOCKETINFO.
1 parent 1e2075a commit 70db423

3 files changed

Lines changed: 372 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: 287 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;
@@ -298,6 +299,245 @@ class RUsageInfoV2 extends Structure {
298299
public long ri_diskio_byteswritten;
299300
}
300301

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+
301541
@Structure.FieldOrder({ "vip_vi", "vip_path" })
302542
class VnodeInfoPath extends Structure {
303543
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
8771117
* @return the process ID of the calling process.
8781118
*/
8791119
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);
8801167
}

0 commit comments

Comments
 (0)