View Javadoc
1   /*
2    * Copyright 2021-2022 The OSHI Project Contributors
3    * SPDX-License-Identifier: MIT
4    */
5   package oshi.jna.platform.unix;
6   
7   import java.nio.ByteBuffer;
8   
9   import com.sun.jna.Native;
10  import com.sun.jna.NativeLong;
11  import com.sun.jna.Pointer;
12  import com.sun.jna.Structure;
13  import com.sun.jna.Structure.FieldOrder;
14  
15  import oshi.util.FileUtil;
16  
17  /**
18   * C library. This class should be considered non-API as it may be removed if/when its code is incorporated into the JNA
19   * project.
20   */
21  public interface SolarisLibc extends CLibrary {
22  
23      SolarisLibc INSTANCE = Native.load("c", SolarisLibc.class);
24  
25      int UTX_USERSIZE = 32;
26      int UTX_LINESIZE = 32;
27      int UTX_IDSIZE = 4;
28      int UTX_HOSTSIZE = 257;
29  
30      int PRCLSZ = 8;
31      int PRFNSZ = 16;
32      int PRLNSZ = 32;
33      int PRARGSZ = 80;
34  
35      /**
36       * Connection info
37       */
38      @FieldOrder({ "ut_user", "ut_id", "ut_line", "ut_pid", "ut_type", "ut_exit", "ut_tv", "ut_session", "pad",
39              "ut_syslen", "ut_host" })
40      class SolarisUtmpx extends Structure {
41          public byte[] ut_user = new byte[UTX_USERSIZE]; // user login name
42          public byte[] ut_id = new byte[UTX_IDSIZE]; // etc/inittab id (usually line #)
43          public byte[] ut_line = new byte[UTX_LINESIZE]; // device name
44          public int ut_pid; // process id
45          public short ut_type; // type of entry
46          public Exit_status ut_exit; // process termination/exit status
47          public Timeval ut_tv; // time entry was made
48          public int ut_session; // session ID, used for windowing
49          public int[] pad = new int[5]; // reserved for future use
50          public short ut_syslen; // significant length of ut_host including terminating null
51          public byte[] ut_host = new byte[UTX_HOSTSIZE]; // host name
52      }
53  
54      /**
55       * Part of utmpx structure
56       */
57      @FieldOrder({ "e_termination", "e_exit" })
58      class Exit_status extends Structure {
59          public short e_termination; // Process termination status
60          public short e_exit; // Process exit status
61      }
62  
63      /**
64       * 32/64-bit timeval required for utmpx structure
65       */
66      @FieldOrder({ "tv_sec", "tv_usec" })
67      class Timeval extends Structure {
68          public NativeLong tv_sec; // seconds
69          public NativeLong tv_usec; // microseconds
70      }
71  
72      /**
73       * Reads a line from the current file position in the utmp file. It returns a pointer to a structure containing the
74       * fields of the line.
75       * <p>
76       * Not thread safe
77       *
78       * @return a {@link SolarisUtmpx} on success, and NULL on failure (which includes the "record not found" case)
79       */
80      SolarisUtmpx getutxent();
81  
82      /**
83       * Structure for psinfo file
84       */
85      class SolarisPsInfo {
86          public int pr_flag; // process flags (DEPRECATED; do not use)
87          public int pr_nlwp; // number of active lwps in the process
88          public int pr_pid; // unique process id
89          public int pr_ppid; // process id of parent
90          public int pr_pgid; // pid of process group leader
91          public int pr_sid; // session id
92          public int pr_uid; // real user id
93          public int pr_euid; // effective user id
94          public int pr_gid; // real group id
95          public int pr_egid; // effective group id
96          public Pointer pr_addr; // address of process
97          public size_t pr_size; // size of process image in Kbytes
98          public size_t pr_rssize; // resident set size in Kbytes
99          public size_t pr_rssizepriv; // resident set size of private mappings
100         public NativeLong pr_ttydev; // controlling tty device (or PRNODEV)
101         // The following percent numbers are 16-bit binary
102         // fractions [0 .. 1] with the binary point to the
103         // right of the high-order bit (1.0 == 0x8000)
104         public short pr_pctcpu; // % of recent cpu time used by all lwps
105         public short pr_pctmem; // % of system memory used by process
106         public Timestruc pr_start; // process start time, from the epoch
107         public Timestruc pr_time; // usr+sys cpu time for this process
108         public Timestruc pr_ctime; // usr+sys cpu time for reaped children
109         public byte[] pr_fname = new byte[PRFNSZ]; // name of exec'ed file
110         public byte[] pr_psargs = new byte[PRARGSZ]; // initial characters of arg list
111         public int pr_wstat; // if zombie, the wait() status
112         public int pr_argc; // initial argument count
113         public Pointer pr_argv; // address of initial argument vector
114         public Pointer pr_envp; // address of initial environment vector
115         public byte pr_dmodel; // data model of the process
116         public byte[] pr_pad2 = new byte[3];
117         public int pr_taskid; // task id
118         public int pr_projid; // project id
119         public int pr_nzomb; // number of zombie lwps in the process
120         public int pr_poolid; // pool id
121         public int pr_zoneid; // zone id
122         public int pr_contract; // process contract id
123         public int pr_filler; // 4 bytes reserved for future use
124         public SolarisLwpsInfo pr_lwp; // information for representative lwp
125 
126         public SolarisPsInfo(ByteBuffer buff) {
127             this.pr_flag = FileUtil.readIntFromBuffer(buff);
128             this.pr_nlwp = FileUtil.readIntFromBuffer(buff);
129             this.pr_pid = FileUtil.readIntFromBuffer(buff);
130             this.pr_ppid = FileUtil.readIntFromBuffer(buff);
131             this.pr_pgid = FileUtil.readIntFromBuffer(buff);
132             this.pr_sid = FileUtil.readIntFromBuffer(buff);
133             this.pr_uid = FileUtil.readIntFromBuffer(buff);
134             this.pr_euid = FileUtil.readIntFromBuffer(buff);
135             this.pr_gid = FileUtil.readIntFromBuffer(buff);
136             this.pr_egid = FileUtil.readIntFromBuffer(buff);
137             this.pr_addr = FileUtil.readPointerFromBuffer(buff);
138             this.pr_size = FileUtil.readSizeTFromBuffer(buff);
139             this.pr_rssize = FileUtil.readSizeTFromBuffer(buff);
140             this.pr_rssizepriv = FileUtil.readSizeTFromBuffer(buff);
141             this.pr_ttydev = FileUtil.readNativeLongFromBuffer(buff);
142             this.pr_pctcpu = FileUtil.readShortFromBuffer(buff);
143             this.pr_pctmem = FileUtil.readShortFromBuffer(buff);
144             // Force 8 byte alignment
145             if (Native.LONG_SIZE > 4) {
146                 FileUtil.readIntFromBuffer(buff);
147             }
148             this.pr_start = new Timestruc(buff);
149             this.pr_time = new Timestruc(buff);
150             this.pr_ctime = new Timestruc(buff);
151             FileUtil.readByteArrayFromBuffer(buff, this.pr_fname);
152             FileUtil.readByteArrayFromBuffer(buff, this.pr_psargs);
153             this.pr_wstat = FileUtil.readIntFromBuffer(buff);
154             this.pr_argc = FileUtil.readIntFromBuffer(buff);
155             this.pr_argv = FileUtil.readPointerFromBuffer(buff);
156             this.pr_envp = FileUtil.readPointerFromBuffer(buff);
157             this.pr_dmodel = FileUtil.readByteFromBuffer(buff);
158             FileUtil.readByteArrayFromBuffer(buff, this.pr_pad2);
159             this.pr_taskid = FileUtil.readIntFromBuffer(buff);
160             this.pr_projid = FileUtil.readIntFromBuffer(buff);
161             this.pr_nzomb = FileUtil.readIntFromBuffer(buff);
162             this.pr_poolid = FileUtil.readIntFromBuffer(buff);
163             this.pr_zoneid = FileUtil.readIntFromBuffer(buff);
164             this.pr_contract = FileUtil.readIntFromBuffer(buff);
165             this.pr_filler = FileUtil.readIntFromBuffer(buff);
166             this.pr_lwp = new SolarisLwpsInfo(buff);
167         }
168     }
169 
170     /**
171      * Nested Structure for psinfo file
172      */
173     class SolarisLwpsInfo {
174         public int pr_flag; // lwp flags (DEPRECATED; do not use)
175         public int pr_lwpid; // lwp id
176         public Pointer pr_addr; // DEPRECATED was internal address of lwp
177         public Pointer pr_wchan; // DEPRECATED was wait addr for sleeping lwp
178         public byte pr_stype; // synchronization event type
179         public byte pr_state; // numeric lwp state
180         public byte pr_sname; // printable character for pr_state
181         public byte pr_nice; // nice for cpu usage
182         public short pr_syscall; // system call number (if in syscall)
183         public byte pr_oldpri; // pre-SVR4, low value is high priority
184         public byte pr_cpu; // pre-SVR4, cpu usage for scheduling
185         public int pr_pri; // priority, high value = high priority
186         // The following percent numbers are 16-bit binary
187         // fractions [0 .. 1] with the binary point to the
188         // right of the high-order bit (1.0 == 0x8000)
189         public short pr_pctcpu; // % of recent cpu time used by this lwp
190         public short pr_pad;
191         public Timestruc pr_start; // lwp start time, from the epoch
192         public Timestruc pr_time; // cpu time for this lwp
193         public byte[] pr_clname = new byte[PRCLSZ]; // scheduling class name
194         public byte[] pr_oldname = new byte[PRFNSZ]; // binary compatibility -- unused
195         public int pr_onpro; // processor which last ran this lwp
196         public int pr_bindpro; // processor to which lwp is bound
197         public int pr_bindpset; // processor set to which lwp is bound
198         public int pr_lgrp; // home lgroup
199         public long pr_last_onproc; // Timestamp of when thread last ran on a processor
200         public byte[] pr_name = new byte[PRLNSZ]; // name of system lwp
201 
202         public SolarisLwpsInfo(ByteBuffer buff) {
203             this.pr_flag = FileUtil.readIntFromBuffer(buff);
204             this.pr_lwpid = FileUtil.readIntFromBuffer(buff);
205             this.pr_addr = FileUtil.readPointerFromBuffer(buff);
206             this.pr_wchan = FileUtil.readPointerFromBuffer(buff);
207             this.pr_stype = FileUtil.readByteFromBuffer(buff);
208             this.pr_state = FileUtil.readByteFromBuffer(buff);
209             this.pr_sname = FileUtil.readByteFromBuffer(buff);
210             this.pr_nice = FileUtil.readByteFromBuffer(buff);
211             this.pr_syscall = FileUtil.readShortFromBuffer(buff);
212             this.pr_oldpri = FileUtil.readByteFromBuffer(buff);
213             this.pr_cpu = FileUtil.readByteFromBuffer(buff);
214             this.pr_pri = FileUtil.readIntFromBuffer(buff);
215             this.pr_pctcpu = FileUtil.readShortFromBuffer(buff);
216             this.pr_pad = FileUtil.readShortFromBuffer(buff);
217             this.pr_start = new Timestruc(buff);
218             this.pr_time = new Timestruc(buff);
219             FileUtil.readByteArrayFromBuffer(buff, this.pr_clname);
220             FileUtil.readByteArrayFromBuffer(buff, this.pr_oldname);
221             this.pr_onpro = FileUtil.readIntFromBuffer(buff);
222             this.pr_bindpro = FileUtil.readIntFromBuffer(buff);
223             this.pr_bindpset = FileUtil.readIntFromBuffer(buff);
224             this.pr_lgrp = FileUtil.readIntFromBuffer(buff);
225             this.pr_last_onproc = FileUtil.readLongFromBuffer(buff);
226             FileUtil.readByteArrayFromBuffer(buff, this.pr_name);
227         }
228     }
229 
230     /**
231      * Structure for usage file
232      */
233     class SolarisPrUsage {
234         public int pr_lwpid; // lwp id. 0: process or defunct
235         public int pr_count; // number of contributing lwps
236         public Timestruc pr_tstamp; // current time stamp
237         public Timestruc pr_create; // process/lwp creation time stamp
238         public Timestruc pr_term; // process/lwp termination time stamp
239         public Timestruc pr_rtime; // total lwp real (elapsed) time
240         public Timestruc pr_utime; // user level cpu time
241         public Timestruc pr_stime; // system call cpu time
242         public Timestruc pr_ttime; // other system trap cpu time
243         public Timestruc pr_tftime; // text page fault sleep time
244         public Timestruc pr_dftime; // data page fault sleep time
245         public Timestruc pr_kftime; // kernel page fault sleep time
246         public Timestruc pr_ltime; // user lock wait sleep time
247         public Timestruc pr_slptime; // all other sleep time
248         public Timestruc pr_wtime; // wait-cpu (latency) time
249         public Timestruc pr_stoptime; // stopped time
250         public Timestruc[] filltime = new Timestruc[6]; // filler for future expansion
251         public NativeLong pr_minf; // minor page faults
252         public NativeLong pr_majf; // major page faults
253         public NativeLong pr_nswap; // swaps
254         public NativeLong pr_inblk; // input blocks
255         public NativeLong pr_oublk; // output blocks
256         public NativeLong pr_msnd; // messages sent
257         public NativeLong pr_mrcv; // messages received
258         public NativeLong pr_sigs; // signals received
259         public NativeLong pr_vctx; // voluntary context switches
260         public NativeLong pr_ictx; // involuntary context switches
261         public NativeLong pr_sysc; // system calls
262         public NativeLong pr_ioch; // chars read and written
263         public NativeLong[] filler = new NativeLong[10]; // filler for future expansion
264 
265         public SolarisPrUsage(ByteBuffer buff) {
266             this.pr_lwpid = FileUtil.readIntFromBuffer(buff);
267             this.pr_count = FileUtil.readIntFromBuffer(buff);
268             this.pr_tstamp = new Timestruc(buff);
269             this.pr_create = new Timestruc(buff);
270             this.pr_term = new Timestruc(buff);
271             this.pr_rtime = new Timestruc(buff);
272             this.pr_utime = new Timestruc(buff);
273             this.pr_stime = new Timestruc(buff);
274             this.pr_ttime = new Timestruc(buff);
275             this.pr_tftime = new Timestruc(buff);
276             this.pr_dftime = new Timestruc(buff);
277             this.pr_kftime = new Timestruc(buff);
278             this.pr_ltime = new Timestruc(buff);
279             this.pr_slptime = new Timestruc(buff);
280             this.pr_wtime = new Timestruc(buff);
281             this.pr_stoptime = new Timestruc(buff);
282             for (int i = 0; i < filltime.length; i++) {
283                 this.filltime[i] = new Timestruc(buff);
284             }
285             this.pr_minf = FileUtil.readNativeLongFromBuffer(buff);
286             this.pr_majf = FileUtil.readNativeLongFromBuffer(buff);
287             this.pr_nswap = FileUtil.readNativeLongFromBuffer(buff);
288             this.pr_inblk = FileUtil.readNativeLongFromBuffer(buff);
289             this.pr_oublk = FileUtil.readNativeLongFromBuffer(buff);
290             this.pr_msnd = FileUtil.readNativeLongFromBuffer(buff);
291             this.pr_mrcv = FileUtil.readNativeLongFromBuffer(buff);
292             this.pr_sigs = FileUtil.readNativeLongFromBuffer(buff);
293             this.pr_vctx = FileUtil.readNativeLongFromBuffer(buff);
294             this.pr_ictx = FileUtil.readNativeLongFromBuffer(buff);
295             this.pr_sysc = FileUtil.readNativeLongFromBuffer(buff);
296             this.pr_ioch = FileUtil.readNativeLongFromBuffer(buff);
297             for (int i = 0; i < filler.length; i++) {
298                 this.filler[i] = FileUtil.readNativeLongFromBuffer(buff);
299             }
300         }
301     }
302 
303     /**
304      * 32/64-bit timestruc required for psinfo and lwpsinfo structures
305      */
306     class Timestruc {
307         public NativeLong tv_sec; // seconds
308         public NativeLong tv_nsec; // nanoseconds
309 
310         public Timestruc(ByteBuffer buff) {
311             this.tv_sec = FileUtil.readNativeLongFromBuffer(buff);
312             this.tv_nsec = FileUtil.readNativeLongFromBuffer(buff);
313         }
314     }
315 
316     /**
317      * Returns the thread ID of the calling thread.
318      *
319      * @return the thread ID of the calling thread.
320      */
321     int thr_self();
322 }