1 Introduction
2 Ground Rules
Building a File System
3 File Systems
4 File Content Data Structure
5 Allocation Cluster Manager
6 Exceptions and Emancipation
7 Base Classes, Testing, and More
8 File Meta Data
9 Native File Class
10 Our File System
11 Allocation Table
12 File System Support Code
13 Initializing the File System
14 Contiguous Files
15 Rebuilding the File System
16 Native File System Support Methods
17 Lookups, Wildcards, and Unicode, Oh My
18 Finishing the File System Class
The Init Program
19 Hardware Abstraction and UOS Architecture
20 Init Command Mode
21 Using Our File System
22 Hardware and Device Lists
23 Fun with Stores: Partitions
24 Fun with Stores: RAID
25 Fun with Stores: RAM Disks
26 Init wrap-up
The Executive
27 Overview of The Executive
28 Starting the Kernel
29 The Kernel
30 Making a Store Bootable
31 The MMC
32 The HMC
33 Loading the components
34 Using the File Processor
35 Symbols and the SSC
36 The File Processor and Device Management
37 The File Processor and File System Management
38 Finishing Executive Startup
Users and Security
39 Introduction to Users and Security
40 More Fun With Stores: File Heaps
41 File Heaps, part 2
42 SysUAF
43 TUser
44 SysUAF API
Terminal I/O
45 Shells and UCL
46 UOS API, the Application Side
47 UOS API, the Executive Side
48 I/O Devices
49 Streams
50 Terminal Output Filters
51 The TTerminal Class
52 Handles
53 Putting it All Together
54 Getting Terminal Input
55 QIO
56 Cooking Terminal Input
57 Putting it all together, part 2
58 Quotas and I/O
UCL
59 UCL Basics
60 Symbol Substitution
61 Command execution
62 Command execution, part 2
63 Command Abbreviation
64 ASTs
65 Expressions, Part 1
66 Expressions, Part 2: Support code
67 Expressions, part 3: Parsing
68 SYS_GETJPIW and SYS_TRNLNM
69 Expressions, part 4: Evaluation
UCL Lexical Functions
70 PROCESS_SCAN
71 PROCESS_SCAN, Part 2
72 TProcess updates
73 Unicode revisted
74 Lexical functions: F$CONTEXT
75 Lexical functions: F$PID
76 Lexical Functions: F$CUNITS
77 Lexical Functions: F$CVSI and F$CVUI
78 UOS Date and Time Formatting
79 Lexical Functions: F$CVTIME
80 LIB_CVTIME
81 Date/Time Contexts
82 SYS_GETTIM, LIB_Get_Timestamp, SYS_ASCTIM, and LIB_SYS_ASCTIM
83 Lexical Functions: F$DELTA_TIME
84 Lexical functions: F$DEVICE
85 SYS_DEVICE_SCAN
86 Lexical functions: F$DIRECTORY
87 Lexical functions: F$EDIT and F$ELEMENT
88 Lexical functions: F$ENVIRONMENT
89 SYS_GETUAI
90 Lexical functions: F$EXTRACT and F$IDENTIFIER
91 LIB_FAO and LIB_FAOL
92 LIB_FAO and LIB_FAOL, part 2
93 Lexical functions: F$FAO
94 File Processing Structures
95 Lexical functions: F$FILE_ATTRIBUTES
96 SYS_DISPLAY
97 Lexical functions: F$GETDVI
98 Parse_GetDVI
99 GetDVI
100 GetDVI, part 2
101 GetDVI, part 3
102 Lexical functions: F$GETJPI
103 GETJPI
104 Lexical functions: F$GETSYI
105 GETSYI
106 Lexical functions: F$INTEGER, F$LENGTH, F$LOCATE, and F$MATCH_WILD
107 Lexical function: F$PARSE
108 FILESCAN
109 SYS_PARSE
110 Lexical Functions: F$MODE, F$PRIVILEGE, and F$PROCESS
111 File Lookup Service
112 Lexical Functions: F$SEARCH
113 SYS_SEARCH
114 F$SETPRV and SYS_SETPRV
115 Lexical Functions: F$STRING, F$TIME, and F$TYPE
116 More on symbols
117 Lexical Functions: F$TRNLNM
118 SYS_TRNLNM, Part 2
119 Lexical functions: F$UNIQUE, F$USER, and F$VERIFY
120 Lexical functions: F$MESSAGE
121 TUOS_File_Wrapper
122 OPEN, CLOSE, and READ system services
UCL Commands
123 WRITE
124 Symbol assignment
125 The @ command
126 @ and EXIT
127 CRELNT system service
128 DELLNT system service
129 IF...THEN...ELSE
130 Comments, labels, and GOTO
131 GOSUB and RETURN
132 CALL, SUBROUTINE, and ENDSUBROUTINE
133 ON, SET {NO}ON, and error handling
134 INQUIRE
135 SYS_WRITE Service
136 OPEN
137 CLOSE
138 DELLNM system service
139 READ
140 Command Recall
141 RECALL
142 RUN
143 LIB_RUN
144 The Data Stream Interface
145 Preparing for execution
146 EOJ and LOGOUT
147 SYS_DELPROC and LIB_GET_FOREIGN
CUSPs and utilities
148 The I/O Queue
149 Timers
150 Logging in, part one
151 Logging in, part 2
152 System configuration
153 SET NODE utility
154 UUI
155 SETTERM utility
156 SETTERM utility, part 2
157 SETTERM utility, part 3
158 AUTHORIZE utility
159 AUTHORIZE utility, UI
160 AUTHORIZE utility, Access Restrictions
161 AUTHORIZE utility, Part 4
162 AUTHORIZE utility, Reporting
163 AUTHORIZE utility, Part 6
164 Authentication
165 Hashlib
166 Authenticate, Part 7
167 Logging in, part 3
168 DAY_OF_WEEK, CVT_FROM_INTERNAL_TIME, and SPAWN
169 DAY_OF_WEEK and CVT_FROM_INTERNAL_TIME
170 LIB_SPAWN
171 CREPRC
172 CREPRC, Part 2
173 COPY
174 COPY, part 2
175 COPY, part 3
176 COPY, part 4
177 LIB_Get_Default_File_Protection and LIB_Substitute_Wildcards
178 CREATESTREAM, STREAMNAME, and Set_Contiguous
179 Help Files
180 LBR Services
181 LBR Services, Part 2
182 LIBRARY utility
183 LIBRARY utility, Part 2
184 FS Services
185 FS Services, Part 2
186 Implementing Help
187 HELP
188 HELP, Part 2
189 DMG_Get_Key and LIB_Put_Formatted_Output
190 LIBRARY utility, Part 3
191 Shutting Down UOS
192 SHUTDOWN
193 WAIT
194 SETIMR
195 WAITFR and Scheduling
196 REPLY, OPCOM, and Mailboxes
197 REPLY utility
198 Mailboxes
199 BRKTHRU
200 OPCOM
201 Mailbox Services
202 Mailboxes, Part 2
203 DEFINE
204 CRELNM
205 DISABLE
206 STOP
207 OPCCRASH and SHUTDOWN
208 APPEND
Glossary/Index
Downloads
|
GETJPI
As mentioned in the last article, we briefly introduced this
system call back in article 68, but we have extended
it to handle more than the three items previously supported. Some of the items
have to do with features we will not be introducing until sometime in the future.
Here is the definition of the system call:
GETJPI returns information about one or more processes on the system or cluster.
Format
GETJPI( efn, pidadr, prcnam, itemlst, iosb, astadr, astprm )
Return Value
Either an integer or a string, depending upon the item requested. The table below
indicates the valid items and the corresponding return values.
Arguments
efn
Event flag to set upon completion.
pidadr
Address of PID of the process to return information about. If pidadr is -1, GETJPI
assumes a wildcard operation and returns the requested information for each process
on the system that the calling process has privilege to access. Each call will
return information about the next process.
If used with PROCESS_SCAN, you can search for specific processes by passing the
process scan context instead of the address of a process ID.
If pidadr is 0 and prcnam is not null, prcnam is used to identify the target process.
If pidadr is 0 and prcnam is null, the current process is used as the target process.
If pidadr is a valid address, and the value in the memory pointed to by pidadr is 0,
the current process is used as the target process. In this case, the current process'
ID is written back to that memory location.
prcnam
An SRB pointing to a string containing the process name. If pidadr is non-zero, this
parameter is ignored.
itmlst
Pointer to a list of descriptors which indicate what information to return. The
valid item codes are listed below.
iosb
I/O status block to receive the final completion status.
astadr
Address of AST routine to execute when GETJPI completed. If this is 0, no AST routine
is called.
astprm
AST parameter to be passed to the AST service routine specified by the astadr parameter.
Description
The Get Job/Process Information service returns information about one or more processes
on the system or cluster. Using this service along with PROCESS_SCAN allows you to
perform selective process searches.
The calling process must have GROUP privilege to obtain information about processes
belonging to one of the groups to which the caller belongs. The calling process
must have WORLD privilege to obtain information about other processes on the system
that do not belong to one of the groups to which the caller belongs.
If both pidadr and prcnam are specified, pidadr is used and prcnam is ignored. If
neither is provided, the current process is the target process. Generally it is
preferable to use pidadr instead of prcnam as there is less overhead in passing
parameters as well as avoiding the overhead in searching the process tables for the
specified name.
The following item codes are valid for the passed descriptor list:
Item | Information returned. |
JPI_ACCOUNT | The account name. |
JPI_APTCNT | Active page table count. |
JPI_ASTACT | Access modes with active ASTs. Bitmask indicating ring of ASTs: bit 0 = ring 0, bit 1 = ring 1, etc. |
JPI_ASTCNT | Remaining AST quota. |
JPI_ASTEN | Access modes with ASTs enabled. Bitmask indicating ring of ASTs: bit 0 = ring 0, bit 1 = ring 1, etc. |
JPI_ASTLM | AST limit quota. |
JPI_AUTHPRI | Maximum authorized priority. |
JPI_AUTHPRIV | Authorized privileges. 64-bit privilege mask. |
JPI_BIOCNT | Remaining buffered I/O quota. |
JPI_BIOLM | Buffered I/O limit quota. |
JPI_BUFIO | Count of buffered I/O operations. |
JPI_BYTCNT | Remaining buffered I/O byte count quota. |
JPI_BYTLM | Buffered I/O byte count quota. |
JPI_CASE_LOOKUP_IMAGE | Information about the file name lookup case sensitivity for the life of the currently running image: BLIND or SENSITIVE. |
JPI_CASE_LOOKUP_PERM | Information about the file name lookup case sensitivity for the life of the process: BLIND or SENSITIVE. |
JPI_CLASSIFICATION | Current MAC classification |
JPI_CHAIN | UOS ignores this item and moves to the next one. |
JPI_CLINAME | Current command language interpreter (shell). |
JPI_CPULIM | CPU time limit. |
JPI_CPUTIM | CPU time used, in nanoseconds. |
JPI_CREPRC_FLAGS | Flags specified by the stsflg argument in the CREPRC system call that created the process. |
JPI_CURPRIV | Current process privileges. |
JPI_CURRENT_CAP_MASK | Current capabilities mask. 64-bit privilege mask. |
JPI_DFPFC | Default page fault cluster size. |
JPI_DFWSCNT | Default working set size. |
JPI_DIOCNT | Remaining direct I/O count. |
JPI_DIOLM | Direct I/O limit. |
JPI_DIRIO | Count of direct I/O operations. |
JPI_EFCS | Local event flags 0-31. |
JPI_EFCU | Local event flags 32-63. |
JPI_EFWM | Event flag wait mask. |
JPI_ENQCNT | Lock request quota remaining. |
JPI_ENQLM | Lock request quota limit. |
JPI_EXCVEC | Address of a list of exception vectors. |
JPI_FAST_VP_SWITCH | Number of times process has issued vector processor that enabled an inactive vector processor without the expense of a vector context switch. |
JPI_FILCNT | Remaining open file quota. |
JPI_FILLM | Open file quota. |
JPI_FINALEXC | Address of a list of final exception vectors. There are four vectors in the list: one for each ring, from 0 to 3. Each vector is 64-bits. |
JPI_FREP0VA | First free page at end of executable/data address space. |
JPI_FREP1VA | Last free page before start of stack space. |
JPI_FREPTECNT | Number of pages available for virtual memory expansion. |
JPI_GPGCNT | Global page count in working set. |
JPI_GRP | Group(s) the process user belongs to. An array of group IDs. |
JPI_HOME_RAD | Home resource affinity domain (RAD). |
JPI_IMAGECOUNT | Number of image rundowns. |
JPI_IMAGE_AUTHPRIV | Authorized privilege for running image. A 64-bit privilege mask. |
JPI_IMAGE_PERMPRIV | Default privilege for running image. A 64-bit privilege mask. |
JPI_IMAGE_WORKPRIV | Current (working) privilege for running image. A 64-bit privilege mask. |
JPI_IMAGNAME | File name and path of current image. |
JPI_IMAGPRIV | Privileges current image was installed with. A 64-bit privilege mask. |
JPI_INSTALL_RIGHTS | Binary content of the install rights list. |
JPI_INSTALL_RIGHTS_SIZE | Number of bytes needed to store the install rights. |
JPI_JOBPRCCNT | Number of subprocesses owned by job. |
JPI_JOBTYPE | Execution mode of the process at the root of the job tree:
JPI_K_DETACHED
JPI_K_NETWORK
JPI_K_BATCH
JPI_K_LOCAL
JPI_K_DIALUP
JPI_K_REMOTE |
JPI_LAST_LOGIN_I | Date/Time of last interactive login. |
JPI_LAST_LOGIN_N | Date/Time of last noninteractive login. |
JPI_LOGIN_FAILURES | Number of login failures prior to the start of the current session. |
JPI_LOGIN_FLAGS | Bitmask containing additional information relating to the login sequence. |
JPI_LOGINTIM | Process creation time. |
JPI_MASTER_PID | PID of the top of the job's process tree. |
JPI_MAXDETACH | Maximum number of detached processes allowed for the user who owns the process. |
JPI_MAXJOBS | Maximum number of active processes allowed for user who owns the process. |
JPI_MODE | Current process mode:
JPI_K_OTHER
JPI_K_NETWORK
JPI_K_BATCH
JPI_K_INTERACTIVE |
JPI_MSGMASK | Current message mask. |
JPI_MULTITHREAD | Current multuthread limit. |
JPI_NODENAME | Name of the cluster node on which the process is running. |
JPI_NODE_CSID | Cluster ID of the cluster node on which the process is running. |
JPI_NODE_VERSION | UOS version number of the cluster node on which the process is running. |
JPI_OWNER | PID of process' owner. |
JPI_PAGEFLTS | Page fault count. |
JPI_PAGFILCNT | Remaining page file quota. |
JPI_PAGFILLOC | Location of the page file. |
JPI_PARSE_STYLE_PERM | Values set by the SET_PROCESS_PROPERTIESW. |
JPI_PARSE_STYLE_IMAGE | Values set by the SET_PROCESS_PROPERTIESW. |
JPI_PERMANENT_CAP_MASK | Permanent capabilities mask. |
JPI_PERSONA_AUTHPRIV | Authorized privilege mask of the persona. |
JPI_PERSONA_ID | The ID of the persona. |
JPI_PERSONA_PERMPRIV | Default privilege mask of the persona. |
JPI_PERSONA_RIGHTS | Binary content of the persona rights list. |
JPI_PERSONA_RIGHTS_SIZE | Number of bytes needed to store the persona rights. |
JPI_PERSONA_WORKPRIV | Current privilege mask of the active persona. |
JPI_PGFLQUOTA | Page file quota. |
JPI_PHDFLAGS | Flags word. |
JPI_PID | Process ID. |
JPI_PPGCNT | Process page count. |
JPI_PRCCNT | Number of subprocesses owned by process. This does not include subprocesses owned by any subprocesses of the process. |
JPI_PRCLM | Subprocess quota. |
JPI_PRCNAM | Process name. Because this can be up to 16 characters long, the return buffer should be large enough to hold 16 bytes. |
JPI_PRI | Current priority. |
JPI_PRIB | Base priority. |
JPI_PROC_INDEX | Same as JPI_PID. |
JPI_PROCESS_RIGHTS | Contents of the process local rights list. |
JPI_PROCPRIV | Default privileges. |
JPI_RIGHTSLIST | Contents of all process rights lists. |
JPI_RIGHTS_SIZE | Number of bytes required for the rights list. |
JPI_SCHED_CLASS_NAME | Name of the scheduling class if process is class scheduled. Null otherwise. |
JPI_SHRFILLM | Maximum number of open shared files for the job to which the process belongs. |
JPI_SITESPEC | Per-process site-specific integer. |
JPI_SLOW_VP_SWITCH | Number of times process has issued a vector instruction that enabled a inactive vector processor with a fill vector context switch. |
JPI_STATE | Process state:
SCH_C_CEF | Common event flag wait |
SCH_C_COLPG | Collided page wait |
SCH_C_COM | Computable (Idle) |
SCH_C_COMO | Computable, outswapped |
SCH_C_CUR | Current process |
SCH_C_FPG | Free page wait |
SCH_C_HIB | Hibernate wait |
SCH_C_HIBO | Hibernate wait, outswapped |
SCH_C_IOR | Blocked for I/O read |
SCH_C_IOW | Blocked for I/O write |
SCH_C_LEF | Local event flag wait |
SCH_C_LEFO | Local event flag wait, outswapped |
SCH_C_MWAIT | Mutex and miscellaneous resource wait |
SCH_C_PFW | Page fault wait |
SCH_C_RUN | Running, but not current process (on multi-processor systems) |
SCH_C_SUSP | Suspended |
SCH_C_SUSPO | Suspended, outswapped |
|
JPI_STS | First 32-bits of process status flags, A bitmask containing zero or more of the following:
PCB_V_ASTPEN | AST pending |
PCB_V_BATCH | Process is a batch job |
PCB_V_DELPEN | Delete pending |
PCB_V_DISAWS | Disable automatic working set adjustment |
PCB_V_FORCPEN | Force exit pending |
PCB_V_HARDAFF | Process bound to a particular CPU |
PCB_V_HIBER | Hibernate after initial image activate |
PCB_V_INQUAN | Initial quantum in progress |
PCB_V_INTER | Process is an interactive job |
PCB_V_LOGIN | Log in without reading authorization file |
PCB_V_NETWRK | Process is a network connect object |
PCB_V_NOACNT | No accounting for process |
PCB_V_NODELET | No delete |
PCB_V_PHDRES | Process header resident |
PCB_V_PREEMPTED | Kernel mode suspend has overridden supervisor mode suspend |
PCB_V_PSWAPM | Process swap mode (1=noswap) |
PCB_V_PWRAST | Power fail AST |
PCB_V_RECOVER | Process can recover locks |
PCB_V_RES | Resident, in balance set |
PCB_V_RESPEN | Resume pending, skip suspend |
PCB_V_SECAUDIT | Mandatory security auditing |
PCB_V_SOFTSUSP | Process is in supervisor mode suspend |
PCB_V_SSFEXC | System service exception enable (kernel) |
PCB_V_SSFEXCE | System service exception enable (exec) |
PCB_V_SSFEXCS | System service exception enable (super) |
PCB_V_SSFEXCU | System service exception enable (user) |
PCB_V_SSRWAIT | System service resource wait disable |
PCB_V_SUSPEN | Suspend pending |
PCB_V_WAKEPEN | Wake pending, skip hibernate |
PCB_V_WALL | Wait for all events in mask |
|
JPI_STS2 | Second 32-bits of process status flags. A bitmask containing zero of more of the following:
PCB_V_NOUNSHELVE | Process does not automatically unshelve files |
|
JPI_SUBSYSTEM_RIGHTS | Binary content of the subsystem rights lists. |
JPI_SUBSYSTEM_RIGHTS_SIZE | Number of bytes needed to store the system rights. |
JPI_SWPFILLOC | Swap file location. |
JPI_SYSTEM_RIGHTS | Contents of system rights list for the process, including identifier names. |
JPI_SYSTEM_RIGHTS_SIZE | Number of bytes needed to store the system rights. |
JPI_TABLENAME | File specification of process CLI table containing valid UCL commands. |
JPI_TERMINAL | Login terminal name for interactive users. |
JPI_TMBU | Termination mailbox unit number. |
JPI_TOKEN | Token size (TRADITIONAL or EXPANDED). |
JPI_TQCNT | Remaining timer queue entry quota/ |
JPI_TQLM | Timer queue quota. |
JPI_TT_ACCPORNAM | Access port name for terminal associated with process. |
JPI_TT_PHYDEVNAM | Physical device name of the terminal asssociated with process. |
JPI_UAF_FLAGS | User authorization file (UAF) flags for user who owns process. |
JPI_UIC | User ID code. |
JPI_USERNAME | User name of process. |
JPI_VIRTPEAK | Peak virtual address size, in bytes. |
JPI_VOLUMES | Count of current privately mounted volumes. |
JPI_VP_CONSUMER | Flag indicating if the process is a vector consumer. |
JPI_VP_CPUTIM | Total amount of time, in nanoseconds, process has accumulated as a vector consumer. |
JPI_WSAUTH | Maximum authorized working set size. |
JPI_WSAUTHEXT | Maximum authorized working set extent. |
JPI_WSEXTENT | Current working set extent. |
JPI_WSPEAK | Working set peak. |
JPI_WSQUOTA | Working set size quota. |
JPI_WSSIZE | Current working set limit. |
The items that return rights lists return an array of int64 values.
procedure TUSC.Get_Job_Process_Info( pidadr : int64 ; prcnam : string ;
itmlst : int64 ; var IOSB : TIOSB ) ;
var Buff : PAnsiChar ;
Context : TContext ;
Descriptor : TSYS_Descriptor ;
I : integer ;
Len : int64 ;
Offset : int64 ;
PID : TPID ;
_Process, Process : TProcess ;
Res : int64 ;
S : string ;
Status : longint ;
Target_PID : TPID ;
Process_Context : TProcess_Scan_Context ;
Value : cardinal ;
begin // TUSC.Get_Job_Process_Info
PID := Kernel.PID ;
Target_PID := PID ;
Process_Context := nil ;
Process := Get_Process( PID ) ;
if( pidadr = -1 ) then
begin
if( Process.Wildcard_Context = nil ) then
begin
Process.Wildcard_Context := TProcess_Scan_Context.Create ;
end ;
Process_Context := Process.Wildcard_Context ;
end else
if( pidadr <> 0 ) then
begin
if( ( pidadr and 1 ) <> 0 ) then // A context
begin
Context := Process.Get_Context( pidadr and ( not 1 ) ) ;
if( Context.Context_Type <> CT_Process ) then
begin
Context := nil ; // Wrong context type
end ;
if( Context = nil ) then
begin
Generate_Exception( UOSErr_Invalid_Context ) ;
exit ;
end ;
Process_Context := TProcess_Scan_Context( Context ) ;
end else
begin
Target_PID := Get_User_Integer( Kernel, PID, pidadr, Status ) ;
if( Status = UE_Error ) then
begin
IOSB.r_io_64.w_status := Status ;
if( MMC.Last_Error = nil ) then
begin
Generate_Exception( UOSErr_Memory_Address_Error ) ;
end ;
exit ;
end ;
if( Target_PID = 0 ) then
begin
Target_PID := PID ;
Status := Write_User_int64( Kernel, PID, pidadr, PID ) ;
if( Status = UE_Error ) then
begin
IOSB.r_io_64.w_status := Status ;
if( MMC.Last_Error = nil ) then
begin
Generate_Exception( UOSErr_Memory_Address_Error ) ;
end ;
exit ;
end ;
end ;
end ;
end else
if( prcnam <> '' ) then
begin
//TODO:Handle process names with node prefix on clusters
prcnam := lowercase( prcnam ) ;
for I := 0 to Processes.Count - 1 do
begin
Process := TProcess( Processes[ I ] ) ;
if( Process <> nil ) then
begin
if( prcnam = lowercase( Process.Name ) ) then
begin
Target_PID := Process._PID ;
break ;
end ; // if( prcnam = lowercase( Process.Name ) )
end ; // if( Process <> nil )
end ; // for I := 0 to Processes.Count - 1
end ;
if( Process_Context <> nil ) then
begin
Target_PID := Process_Context.Next_PID ;
if( Target_PID = 0 ) then
begin
if( Process_Context = Process.Wildcard_Context ) then
begin
Process.Wildcard_Context.Free ;
Process.Wildcard_Context := nil ;
end ;
Generate_Exception( UOSErr_Nonexistent_Process ) ;
exit ;
end ;
end ; // if( Process_Context <> nil )
Process := Get_Process( Target_PID ) ;
if( Process = nil ) then // Process doesn't exist
begin
Generate_Exception( UOSErr_Nonexistent_Process ) ;
exit ;
end ;
We made changes to this code, which we first covered in article 68
and then revised in article 72. The basic behavior is
the same but we've fleshed out some of the context handling. Further, we've checked
for a non-existent process (Process=nil) and exit with an error in that case.
while( true ) do
begin
// Map item and process descriptor...
Offset := MMC.Lock_Pages( PID, itmlst, sizeof( Descriptor ) ) ;
try
Buff := PAnsiChar( MMC.Map_Pages( PID, 0, itmlst, sizeof( Descriptor ),
MAM_Read or MAM_Lock ) ) ;
if( Buff = nil ) then
begin
if( MMC.Last_Error = nil ) then
begin
Generate_Exception( UOSErr_Memory_Address_Error ) ;
end ;
exit ;
end ;
try
move( Buff[ Offset ], Descriptor, sizeof( Descriptor ) ) ;
if(
( Descriptor.Buffer_Length = 0 )
or
( Descriptor.Buffer_Address = 0 )
or
( Descriptor.Return_Length_Address = 0 )
) then // End of list
begin
exit ;
end ;
Len := Descriptor.Buffer_Length ;
if( Descriptor.Buffer_Address = 0 ) then
begin
Generate_Exception( UOSErr_Memory_Address_Error ) ;
exit ;
end ;
case Descriptor.Item_Code of
Again, this code has been covered before. We obtain the next descriptor in the
list and exit when we hit the end.
As with GETDVI, there are several item codes that have to do with features that we
haven't yet addressed. For now we return either 0 or null strings for these codes.
We'll address them in future articles.
JPI_INSTALL_RIGHTS:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_INSTALL_RIGHTS_SIZE:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_RIGHTSLIST:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_RIGHTS_SIZE:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_SUBSYSTEM_RIGHTS:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_SUBSYSTEM_RIGHTS_SIZE:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_SYSTEM_RIGHTS:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_SYSTEM_RIGHTS_SIZE:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
These item codes have to so with rights lists. We will cover these in the future.
JPI_EFCS:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_EFCU:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_EFWM:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
These items have to do with event flags, which we will cover in the future.
JPI_FREP0VA:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_FREP1VA:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_FREPTECNT:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_P0_FIRST_FREE_VA_64:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_P1_FIRST_FREE_VA_64:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_P2_FIRST_FREE_VA_64:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_WSEXTENT:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_WSQUOTA:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
These items concern the process' virtual address space. We will cover this in the future.
JPI_FAST_VP_SWITCH:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_SLOW_VP_SWITCH:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_VP_CONSUMER:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_VP_CPUTIM:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
These items have to do with vector processing. Again, a topic for the future.
JPI_PERSONA_AUTHPRIV:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_PERSONA_ID:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_PERSONA_PERMPRIV:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_PERSONA_RIGHTS:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_PERSONA_RIGHTS_SIZE:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_PERSONA_WORKPRIV:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
These items have to do with personas, which is a topic for future articles.
JPI_RMS_DFMBC:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_RMS_DFMBFIDX:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_RMS_DFMBFREL:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_RMS_DFMBFSDK:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_RMS_DFMBFSMT:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_RMS_DFMBFSUR:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_RMS_DFNBC:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_RMS_EXTEND_SIZE:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_RMS_PROLOGUE:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
These items have to do with RMS, which we will cover in the future.
JPI_ASTACT:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_ASTEN:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_CASE_LOOKUP_PERM:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_CASE_LOOKUP_TEMP:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_CLASSIFICATION:
begin
Write_String_Value( Len, ' ' ) ; //TODO
end ;
JPI_CURRENT_AFFINITY_MASK:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_CURRENT_USERCAP_MASK:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_DFMBC:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_DFPFC:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_EXCVEC:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_FINALEXC:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_GRP:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_HOME_RAD:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_IMAGE_RIGHTS:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_KT_COUNT:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_MSGMASK:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_PAGEFLTS:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_PAGFILLOC:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_PARSE_STYLE_IMAGE:
begin
Write_Value( Len, PARSE_STYLE_C_TRADITIONAL ) ; //TODO
end ;
JPI_PARSE_STYLE_PERM:
begin
Write_Value( Len, PARSE_STYLE_C_TRADITIONAL ) ; //TODO
end ;
JPI_PERMANENT_AFFINITY_MASK:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_PERMANENT_USERCAP_MASK:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_PHDFLAGS:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_PROCESS_RIGHTS:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_SCHED_CLASS_NAME:
begin
Write_String_Value( Len, '' ) ; //TODO
end ;
JPI_SCHED_POLICY:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_SITESPEC:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_SWPFILLOC:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_TABLENAME:
begin
Write_String_Value( Len, '' ) ; //TODO
end ;
JPI_THREAD_INDEX:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_TMBU:
begin
Write_Value( Len, 0 ) ; //TODO
end ;
JPI_TT_ACCPORNAM:
begin
Write_String_Value( Len, '' ) ; //TODO
end ;
These various items are all related to features we will address in the future.
JPI_OWNER : // Get owner (parent) of process
begin
Write_Value( Len, Process._Parent ) ;
end ;
JPI_PID, // Get PID
JPI_INITIAL_THREAD_PID,
JPI_PROC_INDEX :
begin
Write_Value( Len, Target_PID ) ;
end ;
JPI_RMS_FILEPROT: // RMS File Protection
begin
Write_Value( Len, Process.Protection ) ;
end ;
These codes were covered in previous articles, but we've simplified them by using
the new Write_Value procedure, which writes an integer to the user's
memory space.
JPI_ACCOUNT:
begin
Write_String_Value( Len, Process.Account ) ;
end ;
This works similarly to the previous items, except this writes a string via the
Write_String_Value procedure.
JPI_ASTCNT:
begin
Res := Process.User.Quotas.ASTLM ;
if( Res <> 0 ) then
begin
Res := Res - Process.Usage.ASTLM ;
end ;
Write_Value( Len, Res ) ;
end ;
Some of the GETJPI items return the remaining amount of some quota. For instance,
this item returns the remaining ASTLM quota. This will be the authorized quota minus
the used amount. First we get the authorized quota for the user. If it is 0, there
is no limit and we return that. Otherwise, we get the usage value from the process
and subtract it from the quota. The result is returned.
JPI_CHAIN:
begin
// Intentionally ignored
end ;
This special case is used on VMS to pass multiple lists of different sized descriptors. Since
UOS only uses a single descriptor type, this is simply ignored.
JPI_JOBPRCCNT:
begin
_Process := Process.Job ;
if( _Process = nil ) then
begin
_Process := Process ;
end ;
Write_Value( Len, _Process.Child_Count ) ;
end ;
Some items return information from the job rather than the process. The job is
the topmost process in the tree in which the process is located. So we get the
job process for the target process. If it is nil, then the target process is
the job. Either way, _Process is the appropriate job process. Then
we return the value.
JPI_MODE:
begin
I := Process.Job_Type ;
case I of
JPI_K_LOCAL, JPI_K_DIALUP, JPI_K_REMOTE: I := JPI_K_INTERACTIVE ;
end ;
Write_Value( Len, I ) ;
end ;
The process mode is similar to the job type, except that several types are combined
into the JPI_K_INTERACTIVE value.
JPI_APTCNT:
begin
Write_Value( Len, Process._Pages.Count ) ;
end ;
JPI_ASTLM:
begin
Write_Value( Len, Process.User.Quotas.ASTLM ) ;
end ;
JPI_AUTHPRI:
begin
Write_Value( Len, Process.User.Priority ) ;
end ;
JPI_AUTHPRIV:
begin
Write_Value( Len, Process.User.Privileges ) ;
end ;
JPI_BIOCNT:
begin
Res := Process.User.Quotas.BIOLM ;
if( Res <> 0 ) then
begin
Res := Res - Process.Usage.BIOLM ;
end ;
Write_Value( Len, Res ) ;
end ;
JPI_BIOLM:
begin
Write_Value( Len, Process.User.Quotas.BIOLM ) ;
end ;
JPI_BUFIO:
begin
Write_Value( Len, Process.Usage.BIOLM ) ;
end ;
JPI_BYTCNT:
begin
Write_Value( Len, Process.Usage.BYTLM ) ;
end ;
JPI_BYTLM:
begin
Write_Value( Len, Process.User.Quotas.BYTLM ) ;
end ;
JPI_CLINAME:
begin
Write_String_Value( Len, Process.Shell ) ;
end ;
JPI_CPU_ID:
begin
Write_Value( Len, Process.CPUID ) ;
end ;
JPI_CPULIM:
begin
Write_Value( Len, Process.User.Quotas.CPUTIM ) ;
end ;
JPI_CPUTIM:
begin
Write_Value( Len, Process.Usage.CPUTIM ) ;
end ;
JPI_CREPRC_FLAGS:
begin
Write_Value( Len, Process.Creation_Flags ) ;
end ;
JPI_CURPRIV:
begin
Write_Value( Len, Process.Current_Privileges ) ;
end ;
JPI_DEADLOCK_WAIT:
begin
Write_Value( Len, Process.Deadlock_Time ) ;
end ;
JPI_DFWSCNT:
begin
Write_Value( Len, Process.User.Quotas.WSDEFAULT ) ;
end ;
JPI_DIOCNT:
begin
Res := Process.User.Quotas.DIOLM ;
if( Res <> 0 ) then
begin
Res := Res - Process.Usage.DIOLM ;
end ;
Write_Value( Len, Res ) ;
end ;
JPI_DIOLM:
begin
Write_Value( Len, Process.User.Quotas.DIOLM ) ;
end ;
JPI_DIRIO:
begin
Write_Value( Len, Process.Usage.DIOLM ) ;
end ;
JPI_ENQCNT:
begin
Res := Process.User.Quotas.ENQLM ;
if( Res <> 0 ) then
begin
Res := Res - Process.Usage.ENQLM ;
end ;
Write_Value( Len, Res ) ;
end ;
JPI_ENQLM:
begin
Write_Value( Len, Process.User.Quotas.ENQLM ) ;
end ;
JPI_FILCNT:
begin
Res := Process.User.Quotas.FILLM ;
if( Res <> 0 ) then
begin
Res := Res - Process.Usage.FILLM ;
end ;
Write_Value( Len, Res ) ;
end ;
JPI_FILLM:
begin
Write_Value( Len, Process.User.Quotas.FILLM ) ;
end ;
JPI_GETJPI_CONTROL_FLAGS:
begin
Write_Value( Len, 0 ) ; // Doesn't apply to UOS
end ;
JPI_GPGCNT:
begin
Write_Value( Len, Process._Pages.Count ) ;
end ;
JPI_IMAGECOUNT:
begin
Write_Value( Len, Process.Image_Count ) ;
end ;
JPI_IMAGE_AUTHPRIV:
begin
Write_Value( Len, Process.Image_Auth_Priv ) ;
end ;
JPI_IMAGE_PERMPRIV:
begin
Write_Value( Len, Process.Image_Perm_Priv ) ;
end ;
JPI_IMAGPRIV:
begin
Write_Value( Len, Process.Image_Priv ) ;
end ;
JPI_JOBTYPE:
begin
_Process := Process.Job ;
if( _Process = nil ) then
begin
_Process := Process ;
end ;
Write_Value( Len, _Process.Job_Type ) ;
end ;
JPI_LAST_LOGIN_I:
begin
Write_Value( Len, Process.User.Last_Interactive_Login ) ;
end ;
JPI_LAST_LOGIN_N:
begin
Write_Value( Len, Process.User.Last_NonInteractive_Login ) ;
end ;
JPI_LOGIN_FAILURES:
begin
Write_Value( Len, Process.User.Login_Failures ) ;
end ;
JPI_LOGIN_FLAGS:
begin
Write_Value( Len, Process.Login_Flags ) ;
end ;
JPI_LOGINTIM:
begin
Write_Value( Len, Process.Time ) ;
end ;
JPI_MASTER_PID:
begin
_Process := Process.Job ;
if( _Process = nil ) then
begin
_Process := Process ;
end ;
Write_Value( Len, _Process._PID ) ;
end ;
JPI_MAXDETACH:
begin
Write_Value( Len, Process.User.Quotas.MAXDETJOBS ) ;
end ;
JPI_MAXJOBS:
begin
Write_Value( Len, Process.User.Quotas.MAXJOBS ) ;
end ;
JPI_MULTITHREAD:
begin
Write_Value( Len, Process.User.Quotas.THREADLM ) ;
end ;
JPI_NODENAME:
begin
S := Process.NodeName ;
Write_String_Value( Len, S ) ;
end ;
JPI_NODE_CSID:
begin
Write_Value( Len, Process.CSID ) ;
end ;
JPI_NODE_VERSION:
begin
Write_Value( Len, Process.Version ) ;
end ;
JPI_PAGFILCNT:
begin
Res := Process.User.Quotas.PGFLQUOTA ;
if( Res <> 0 ) then
begin
Res := Res - Process.Usage.PGFLQUOTA ;
end ;
Write_Value( Len, Res ) ;
end ;
JPI_PGFLQUOTA:
begin
Write_Value( Len, Process.User.Quotas.PGFLQUOTA ) ;
end ;
JPI_PPGCNT:
begin
Write_Value( Len, Process._Pages.Count ) ;
end ;
JPI_PRCCNT:
begin
Write_Value( Len, Process._Children.Count ) ;
end ;
JPI_PRCLM:
begin
Write_Value( Len, Process.User.Quotas.PRCLM ) ;
end ;
JPI_PRCNAM:
begin
Write_String_Value( Len, Process.Name ) ;
end ;
JPI_PRI:
begin
Write_Value( Len, Process.Priority ) ;
end ;
JPI_PRIB:
begin
Write_Value( Len, Process.Base_Priority ) ;
end ;
JPI_PROCPRIV:
begin
Write_Value( Len, Process.User.Privileges ) ;
end ;
JPI_SHRFILLM:
begin
Write_Value( Len, Process.User.Quotas.SFILLM ) ;
end ;
JPI_STATE:
begin
Write_Value( Len, Process.State ) ;
end ;
JPI_STS:
begin
Write_Value( Len, Process.Status and $FFFFFFFF ) ;
end ;
JPI_STS2:
begin
Write_Value( Len, Process.Status and ( not $FFFFFFFF ) ) ;
end ;
JPI_TERMINAL:
begin
Write_String_Value( Len, Kernel.FIP.Device_Name( Process.Attached_Device ) ) ;
end ;
JPI_TQCNT:
begin
Res := Process.User.Quotas.TQELM ;
if( Res <> 0 ) then
begin
Res := Res - Process.Usage.TQELM ;
end ;
Write_Value( Len, Res ) ;
end ;
JPI_TQLM:
begin
Write_Value( Len, Process.User.Quotas.TQELM ) ;
end ;
JPI_TT_PHYDEVNAM:
begin
Write_String_Value( Len, Kernel.FIP.Device_Name( Process.Attached_Device ) ) ;
//TODO: Remote terminals
end ;
JPI_UAF_FLAGS:
begin
Write_Value( Len, Process.User.Flags ) ;
end ;
JPI_UIC:
begin
Write_Value( Len, Process._User ) ;
end ;
JPI_USERNAME:
begin
Write_String_Value( Len, Process.User.Name ) ;
end ;
JPI_VIRTPEAK:
begin
Write_Value( Len, Process.Peak_Memory ) ;
end ;
JPI_VOLUMES:
begin
Write_Value( Len, Process._Mounts.Count ) ;
end ;
JPI_WSAUTH:
begin
Write_Value( Len, Process.User.Quotas.WSDEFAULT ) ;
end ;
JPI_WSAUTHEXT:
begin
Write_Value( Len, Process.User.Quotas.WSEXTENT ) ;
end ;
JPI_WSPEAK:
begin
Write_Value( Len, Process.Peak_Memory div HAL.RAM_Page_Size ) ;
end ;
JPI_WSSIZE:
begin
Write_Value( Len, Process._Pages.Count ) ;
end ;
The remaining items use one of the previous "templates". Of note is the JPI_TT_PHYDEVNAM
item. For remote terminals, as an example, the physical device is the network device
used to communicate with those terminals. Remote terminals is a topic for the future,
so for now we simply return the device name. The remainder of the function
is unchanged from before.
procedure Write_Value( Len, V : int64 ) ;
begin
if( Len > sizeof( V ) ) then
begin
Len := sizeof( V ) ;
end ;
Write_User( Kernel, PID, Descriptor.Buffer_Address, Len, V ) ;
if( Descriptor.Return_Length_Address <> 0 ) then
begin
Write_User( Kernel, PID, Descriptor.Return_Length_Address, Len, V ) ;
end ;
end ;
This local procedure writes an integer to the user's address space. First we make
sure the result buffer length isn't smaller than the integer. If so, we reduce the
length. Otherwise, when we copy the data, we would copy past the end of the integer
value and possible generate a memory access error. Then we write the result, and
if a return length address is specified, we write the actual length there.
function Write_String_Value( Len : int64 ; V : string ) : integer ;
var SRB : TSRB ;
begin
if( Len > length( V ) ) then
begin
Len := length( V ) ;
end ;
SRB.Buffer := Descriptor.Buffer_Address ;
SRB.Length := Descriptor.Buffer_Length ;
Set_User_String( Kernel, PID, SRB, V ) ;
if( Descriptor.Return_Length_Address <> 0 ) then
begin
Result := Write_User( Kernel, PID, Descriptor.Return_Length_Address, sizeof( Len ), Len ) ;
end ;
end ;
This local procedure writes a string to the user's address space. We make sure the
target buffer length isn't smaller than the string lengh and then create a TSRB
structure. Finally we use Set_User_String to write it to the user's
memory space. If a return length address was specified, we write the length as well.
// SYS JPI descriptor codes...
const JPI_ACCOUNT = 1 ;
JPI_APTCNT = 2 ;
JPI_ASTACT = 3 ;
JPI_ASTCNT = 4 ;
JPI_ASTEN = 5 ;
JPI_ASTLM = 6 ;
JPI_AUTHPRI = 7 ;
JPI_AUTHPRIV = 8 ;
JPI_BIOCNT = 9 ;
JPI_BIOLM = 10 ;
JPI_BUFIO = 11 ;
JPI_BYTCNT = 12 ;
JPI_BYTLM = 13 ;
JPI_CASE_LOOKUP_PERM = 14 ;
JPI_CASE_LOOKUP_TEMP = 15 ;
JPI_CHAIN = 16 ;
JPI_CLASSIFICATION = 17 ;
JPI_CLINAME = 18 ;
JPI_CPU_ID = 19 ;
JPI_CPULIM = 20 ;
JPI_CPUTIM = 21 ;
JPI_CREPRC_FLAGS = 22 ;
JPI_CURPRIV = 23 ;
JPI_CURRENT_AFFINITY_MASK = 24 ;
JPI_CURRENT_USERCAP_MASK = 25 ;
JPI_DEADLOCK_WAIT = 26 ;
JPI_DFMBC = 27 ;
JPI_DFPFC = 28 ;
JPI_DFWSCNT = 29 ;
JPI_DIOCNT = 30 ;
JPI_DIOLM = 31 ;
JPI_DIRIO = 32 ;
JPI_EFCS = 33 ;
JPI_EFCU = 34 ;
JPI_EFWM = 35 ;
JPI_ENQCNT = 36 ;
JPI_ENQLM = 37 ;
JPI_EXCVEC = 38 ;
JPI_FAST_VP_SWITCH = 39 ;
JPI_FILCNT = 40 ;
JPI_FILLM = 41 ;
JPI_FINALEXC = 42 ;
JPI_FREP0VA = 43 ;
JPI_FREP1VA = 44 ;
JPI_FREPTECNT = 45 ;
JPI_GETJPI_CONTROL_FLAGS = 46 ;
JPI_GPGCNT = 47 ;
JPI_HOME_RAD = 48 ;
JPI_IMAGECOUNT = 49 ;
JPI_IMAGE_AUTHPRIV = 50 ;
JPI_IMAGE_PERMPRIV = 51 ;
JPI_IMAGE_RIGHTS = 52 ;
JPI_IMAGPRIV = 53 ;
JPI_INITIAL_THREAD_PID = 54 ;
JPI_INSTALL_RIGHTS = 55 ;
JPI_INSTALL_RIGHTS_SIZE = 56 ;
JPI_JOBPRCCNT = 57 ;
JPI_JOBTYPE = 58 ;
JPI_KT_COUNT = 59 ;
JPI_LAST_LOGIN_I = 60 ;
JPI_LAST_LOGIN_N = 61 ;
JPI_LOGIN_FAILURES = 62 ;
JPI_LOGIN_FLAGS = 63 ;
JPI_LOGINTIM = 64 ;
JPI_MASTER_PID = 65 ;
JPI_MAXDETACH = 66 ;
JPI_MAXJOBS = 67 ;
JPI_GRP = 68 ;
JPI_MODE = 69 ;
JPI_MSGMASK = 70 ;
JPI_MULTITHREAD = 71 ;
JPI_NODENAME = 72 ;
JPI_NODE_CSID = 73 ;
JPI_NODE_VERSION = 74 ;
JPI_OWNER = 75 ; // Get owner (parent) of process
JPI_PAGEFLTS = 76 ;
JPI_PAGFILCNT = 77 ;
JPI_PAGFILLOC = 78 ;
JPI_PARSE_STYLE_IMAGE = 79 ;
JPI_PARSE_STYLE_PERM = 80 ;
JPI_PERMANENT_AFFINITY_MASK = 81 ;
JPI_PERMANENT_USERCAP_MASK = 82 ;
JPI_PERSONA_AUTHPRIV = 83 ;
JPI_PERSONA_ID = 84 ;
JPI_PERSONA_PERMPRIV = 85 ;
JPI_PERSONA_RIGHTS = 86 ;
JPI_PERSONA_RIGHTS_SIZE = 87 ;
JPI_PERSONA_WORKPRIV = 88 ;
JPI_PGFLQUOTA = 89 ;
JPI_PHDFLAGS = 90 ;
JPI_PID = 91 ; // Get PID
JPI_P0_FIRST_FREE_VA_64 = 92 ;
JPI_P1_FIRST_FREE_VA_64 = 93 ;
JPI_P2_FIRST_FREE_VA_64 = 94 ;
JPI_PPGCNT = 95 ;
JPI_PRCCNT = 96 ;
JPI_PRCLM = 97 ;
JPI_PRCNAM = 98 ;
JPI_PRI = 99 ;
JPI_PRIB = 100 ;
JPI_PROCESS_RIGHTS = 101 ;
JPI_PROC_INDEX = 102 ;
JPI_PROCPRIV = 103 ;
JPI_RIGHTSLIST = 104 ;
JPI_RIGHTS_SIZE = 105 ;
JPI_RMS_DFMBC = 106 ;
JPI_RMS_DFMBFIDX = 107 ;
JPI_RMS_DFMBFREL = 108 ;
JPI_RMS_DFMBFSDK = 109 ;
JPI_RMS_DFMBFSMT = 110 ;
JPI_RMS_DFMBFSUR = 111 ;
JPI_RMS_DFNBC = 112 ;
JPI_RMS_EXTEND_SIZE = 113 ;
JPI_RMS_FILEPROT = 114 ; // Get RMS file protection
JPI_RMS_PROLOGUE = 115 ;
JPI_SCHED_CLASS_NAME = 116 ;
JPI_SCHED_POLICY = 117 ;
JPI_SHRFILLM = 118 ;
JPI_SITESPEC = 119 ;
JPI_SLOW_VP_SWITCH = 120 ;
JPI_STATE = 121 ;
JPI_STS = 122 ;
JPI_STS2 = 123 ;
JPI_SUBSYSTEM_RIGHTS = 124 ;
JPI_SUBSYSTEM_RIGHTS_SIZE = 125 ;
JPI_SWPFILLOC = 126 ;
JPI_SYSTEM_RIGHTS = 127 ;
JPI_SYSTEM_RIGHTS_SIZE = 128 ;
JPI_TABLENAME = 129 ;
JPI_TERMINAL = 130 ;
JPI_THREAD_INDEX = 131 ;
JPI_TMBU = 132 ;
JPI_TQCNT = 133 ;
JPI_TQLM = 134 ;
JPI_TT_ACCPORNAM = 135 ;
JPI_TT_PHYDEVNAM = 136 ;
JPI_IMAGE_WORKPRIV = 137 ;
JPI_UAF_FLAGS = 138 ;
JPI_UIC = 139 ;
JPI_USERNAME = 140 ;
JPI_VIRTPEAK = 141 ;
JPI_VOLUMES = 142 ;
JPI_VP_CONSUMER = 143 ;
JPI_VP_CPUTIM = 144 ;
JPI_WSAUTH = 145 ;
JPI_WSAUTHEXT = 146 ;
JPI_WSEXTENT = 147 ;
JPI_WSPEAK = 148 ;
JPI_WSQUOTA = 149 ;
JPI_WSSIZE = 150 ;
JPI_IMAGNAME = 151 ;
And finally, here is the complete set of JPI_* constants.
In the next article, we will look at the next lexical function.
Copyright © 2020 by Alan Conroy. This article may be copied
in whole or in part as long as this copyright is included.
|