Skip to content

Commit 4cd4d97

Browse files
committed
Add proc_info structs and methods to mac SystemB
- Add ProcFdInfo, InSockInfo, TcpSockInfo structs to c.s.j.p.mac.SystemB - Add proc_pidfdinfo(), statfs64(), vm_deallocate() methods - Add PROC_PIDLISTFDS, PROC_PIDFDSOCKETINFO, PROX_FDTYPE_SOCKET, SOCKINFO_IN, SOCKINFO_TCP, TSI_T_NTIMERS, AF_INET, AF_INET6 constants - Add SystemBTest additions (testProcPidFdInfo, testStatfs64) All struct mappings verified against Apple XNU headers: - sys/proc_info.h (struct proc_fdinfo, struct in_sockinfo, struct tcp_sockinfo)
1 parent 08f9e8d commit 4cd4d97

3 files changed

Lines changed: 167 additions & 0 deletions

File tree

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Features
1111
* [#1697](https://github.com/java-native-access/jna/pull/1697): Add WlanApi module - [@eranl](https://github.com/eranl).
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).
14+
* [#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).
1415

1516
Bug Fixes
1617
---------

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

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,91 @@ class RUsageInfoV2 extends Structure {
298298
public long ri_diskio_byteswritten;
299299
}
300300

301+
// proc_info.h: Flavors for proc_pidinfo and proc_pidfdinfo
302+
int PROC_PIDLISTFDS = 1;
303+
int PROC_PIDFDSOCKETINFO = 3;
304+
305+
// proc_info.h: File descriptor types
306+
int PROX_FDTYPE_SOCKET = 2;
307+
308+
// proc_info.h: Socket info kinds
309+
int SOCKINFO_IN = 1;
310+
int SOCKINFO_TCP = 2;
311+
312+
// proc_info.h: TCP timer count
313+
int TSI_T_NTIMERS = 4;
314+
315+
// socket.h: Address families
316+
int AF_INET = 2;
317+
int AF_INET6 = 30;
318+
319+
/**
320+
* File descriptor information as returned by {@code proc_pidinfo} with
321+
* {@link #PROC_PIDLISTFDS}.
322+
* <p>
323+
* Corresponds to {@code struct proc_fdinfo} in {@code <sys/proc_info.h>}.
324+
*/
325+
@Structure.FieldOrder({ "proc_fd", "proc_fdtype" })
326+
class ProcFdInfo extends Structure {
327+
public int proc_fd;
328+
public int proc_fdtype;
329+
}
330+
331+
/**
332+
* Internet socket information.
333+
* <p>
334+
* Corresponds to {@code struct in_sockinfo} in {@code <sys/proc_info.h>}.
335+
* The {@code insi_faddr} and {@code insi_laddr} fields are unions of
336+
* {@code in4in6_addr} and {@code in6_addr}, both 16 bytes, mapped as
337+
* {@code int[4]}.
338+
*/
339+
@Structure.FieldOrder({ "insi_fport", "insi_lport", "insi_gencnt", "insi_flags", "insi_flow", "insi_vflag",
340+
"insi_ip_ttl", "rfu_1", "insi_faddr", "insi_laddr", "insi_v4", "insi_v6" })
341+
class InSockInfo extends Structure {
342+
/** Foreign port. */
343+
public int insi_fport;
344+
/** Local port. */
345+
public int insi_lport;
346+
/** Generation count of this instance. */
347+
public long insi_gencnt;
348+
/** Generic IP/datagram flags. */
349+
public int insi_flags;
350+
public int insi_flow;
351+
/** INI_IPV4 or INI_IPV6. */
352+
public byte insi_vflag;
353+
/** Time to live proto. */
354+
public byte insi_ip_ttl;
355+
/** Reserved. */
356+
public int rfu_1;
357+
/** Foreign host table entry (union of in4in6_addr/in6_addr, 16 bytes). */
358+
public int[] insi_faddr = new int[4];
359+
/** Local host table entry (union of in4in6_addr/in6_addr, 16 bytes). */
360+
public int[] insi_laddr = new int[4];
361+
/** IPv4 type of service. */
362+
public byte insi_v4;
363+
/** IPv6 info (in6_hlim, in6_cksum, in6_ifindex, in6_hops). */
364+
public byte[] insi_v6 = new byte[9];
365+
}
366+
367+
/**
368+
* TCP socket information.
369+
* <p>
370+
* Corresponds to {@code struct tcp_sockinfo} in {@code <sys/proc_info.h>}.
371+
*/
372+
@Structure.FieldOrder({ "tcpsi_ini", "tcpsi_state", "tcpsi_timer", "tcpsi_mss", "tcpsi_flags", "rfu_1",
373+
"tcpsi_tp" })
374+
class TcpSockInfo extends Structure {
375+
public InSockInfo tcpsi_ini;
376+
public int tcpsi_state;
377+
public int[] tcpsi_timer = new int[TSI_T_NTIMERS];
378+
public int tcpsi_mss;
379+
public int tcpsi_flags;
380+
/** Reserved. */
381+
public int rfu_1;
382+
/** Opaque handle of TCP protocol control block. */
383+
public long tcpsi_tp;
384+
}
385+
301386
@Structure.FieldOrder({ "vip_vi", "vip_path" })
302387
class VnodeInfoPath extends Structure {
303388
public byte[] vip_vi = new byte[152]; // vnode_info but we don't
@@ -877,4 +962,51 @@ int host_processor_info(int hostPort, int flavor, IntByReference procCount, Poin
877962
* @return the process ID of the calling process.
878963
*/
879964
int getpid();
965+
966+
/**
967+
* Returns information about a file descriptor of a process.
968+
*
969+
* @param pid
970+
* the process identifier
971+
* @param fd
972+
* the file descriptor
973+
* @param flavor
974+
* the type of information requested (e.g.,
975+
* {@link #PROC_PIDFDSOCKETINFO})
976+
* @param buffer
977+
* holds results
978+
* @param buffersize
979+
* size of results
980+
* @return the number of bytes of data returned in the provided buffer; -1 if an
981+
* error was encountered
982+
*/
983+
int proc_pidfdinfo(int pid, int fd, int flavor, Structure buffer, int buffersize);
984+
985+
/**
986+
* The statfs64() routine returns information about a mounted file system.
987+
* The {@code path} argument is the path name of any file or directory within
988+
* the mounted file system. The {@code buf} argument is a pointer to a
989+
* {@code statfs} structure.
990+
*
991+
* @param path
992+
* the path to any file within the mounted filesystem
993+
* @param buf
994+
* a {@link Statfs} structure
995+
* @return 0 on success; -1 on failure (sets errno)
996+
*/
997+
int statfs64(String path, Statfs buf);
998+
999+
/**
1000+
* Deallocates a region of virtual memory in the specified task.
1001+
*
1002+
* @param targetTask
1003+
* the target task (typically from {@link #mach_task_self()})
1004+
* @param address
1005+
* the starting address of the region to deallocate
1006+
* @param size
1007+
* the number of bytes to deallocate
1008+
* @return 0 ({@code KERN_SUCCESS}) on success; a {@code kern_return_t} error
1009+
* code otherwise
1010+
*/
1011+
int vm_deallocate(int targetTask, long address, long size);
8801012
}

contrib/platform/test/com/sun/jna/platform/mac/SystemBTest.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import com.sun.jna.platform.mac.SystemB.IFmsgHdr;
3939
import com.sun.jna.platform.mac.SystemB.IFmsgHdr2;
4040
import com.sun.jna.platform.mac.SystemB.Passwd;
41+
import com.sun.jna.platform.mac.SystemB.ProcFdInfo;
4142
import com.sun.jna.platform.mac.SystemB.ProcTaskAllInfo;
4243
import com.sun.jna.platform.mac.SystemB.RUsageInfoV2;
4344
import com.sun.jna.platform.mac.SystemB.Statfs;
@@ -171,6 +172,12 @@ public void testHostProcessorInfo() {
171172
assertTrue(procCount.getValue() > 0);
172173
assertEquals(procCpuLoadInfo.getValue().getIntArray(0, procInfoCount.getValue()).length,
173174
procInfoCount.getValue());
175+
176+
// Deallocate the memory allocated by host_processor_info
177+
int taskSelf = SystemB.INSTANCE.mach_task_self();
178+
ret = SystemB.INSTANCE.vm_deallocate(taskSelf, Pointer.nativeValue(procCpuLoadInfo.getValue()),
179+
(long) procInfoCount.getValue() * SystemB.INT_SIZE);
180+
assertEquals(0, ret);
174181
}
175182

176183
// From Unix LibCAPI
@@ -366,6 +373,33 @@ public void testIFs() {
366373
}
367374
}
368375

376+
public void testProcPidFdInfo() {
377+
int pid = SystemB.INSTANCE.getpid();
378+
379+
// Get the list of open file descriptors for this process
380+
int bufferSize = SystemB.INSTANCE.proc_pidinfo(pid, SystemB.PROC_PIDLISTFDS, 0, null, 0);
381+
assertTrue(bufferSize > 0);
382+
383+
int numFds = bufferSize / new ProcFdInfo().size();
384+
assertTrue(numFds > 0);
385+
386+
ProcFdInfo[] fdInfoArray = (ProcFdInfo[]) new ProcFdInfo().toArray(numFds);
387+
int ret = SystemB.INSTANCE.proc_pidinfo(pid, SystemB.PROC_PIDLISTFDS, 0, fdInfoArray[0],
388+
bufferSize);
389+
assertTrue(ret > 0);
390+
391+
// Verify we got valid fd entries
392+
assertTrue(fdInfoArray[0].proc_fd >= 0);
393+
assertTrue(fdInfoArray[0].proc_fdtype >= 0);
394+
}
395+
396+
public void testStatfs64() {
397+
Statfs buf = new Statfs();
398+
assertEquals(0, SystemB.INSTANCE.statfs64("/", buf));
399+
assertTrue(buf.f_blocks > 0);
400+
assertTrue(buf.f_bsize > 0);
401+
}
402+
369403
public static void main(java.lang.String[] argList) {
370404
junit.textui.TestRunner.run(SystemBTest.class);
371405
}

0 commit comments

Comments
 (0)