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

Glossary/Index


Downloads

Lexical functions - F$GETSYI

Our next lexical function is used to obtain system hardware, processor, and UOS information. Here is the definition:

F$GETSYI returns information about the local system or about a node within a cluster.

Format
F$GETSYI( item {,name {,id}} )

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
item

Indicates the type of information to be reported about the local, or specified, node. The valid codes are listed in the table below.

name

Optional name of the node for which to obtain information. For the local system, this should be null.

id

The cluster ID of the cluster node to return information for. If 0 is specified, the local system is assumed.

Description
F$GETSYI invokes the GETSYI system service to return status and identification on the local system or another node in a cluster. The table below lists the valid item codes and describes what information is returned. If a specific node is provided, it can be specified by name or cluster ID. By using F$CSID to obtain each cluster node, information can be returned for all nodes in the cluster.

The following are the valid item codes:
ItemInformation returned.
ACTIVE_CPU_MASKA number representing a bitmask indexed by CPU number. If a given bit is set, that CPU is in the active set.
ACTIVECPU_CNTThe count of active CPUs.
ARCHFLAGArchitecture flags for the system.
ARCH_NAMEName of the CPU architecture.
ARCH_TYPEType of CPU architecture.
AVAIL_CPU_MASKA number representing a bitmask indexed by CPU number. If a given bit is set, that CPU is in the active set and participating in scheduling activities.
AVAILCPU_CNTThe count of CPUs recognized by the system.
BOOT_DEVICEName of the device that UOS was booted from.
BOOTTIMEDate/time that UOS was booted.
CHARACTER_EMULATEDTRUE if this is a VAX with character instruction set emulation.
CLUSTER_EVOTESTotal number of votes in the cluster.
CLUSTER_FSYSIDSystem ID for the first node to boot in the cluster (the founding node). This is a character string containing a hexadecimal value.
CLUSTER_FTIMETime when the first node in the cluster was booted.
CLUSTER_MEMBERTRUE or FALSE if the node is the member of a cluster.
CLUSTER_NODESTotal number of nodes in the cluster.
CLUSTER_QUORUMTotal quorum for the cluster.
CLUSTER_VOTESTotal number of votes in the cluster.
COMMUNITY_IDAlphaServer system hardware community ID.
CONSOLE_VERSIONConsole firmware version.
CONTIG_GBLPAGESTotal number of free, contiguous global pages.
CPUProcessor type.
CPU_AUTOSTARTA list of CPUs that will brought into the active set if it transitions into the current instance from outside or is powered up while owned. A list of zeros and ones, delimited by commas, indexed by CPU. Any entry with a 1 indicates the CPU will be brought into the active set.
CPU_FAILOVERDestinations for crashed Alpha CPUs. A list delimited by commas, indexed by CPU.
CPUCAP_MASKList of hexadecimal values, delimited by commas, indexed by CPU. Each value is a bitmask indicating CPU capabilities.
CPUTYPEThe processor type.
CWLOGICALSFlag indicating that the clusterwide logical name database has been initialized on the system.
DECIMAL_EMULATEDTRUE if this is a VAX CPU with decimal instruction set emulation.
DECNET_FULLNAMENode name.
DECNET_VERSIONNetwork version.
D_FLOAT_EMULATEDTRUE if this is a VAX with D Float instruction emulation.
ERLBUFFERPAG_S2Number of system pages used for each S2 errorlog buffer.
ERRORLOGBUF_S2Number of S2 errorlog buffers.
ERLBUFFERPAGESNumber of system pages used for each S0 errorlog buffer.
ERRORLOGBUFFERSNumber of S0 errorlog buffers.
F_FLOAT_EMULATEDTRUE if this is a VAX with F Float instruction emulation.
FREE_GBLPAGESCurrent count of free global pages.
FREE_GBLSECTSCurrent count of free global section table entries.
FREE_PAGESTotal number of free pages.
G_FLOAT_EMULATEDTRUE if this is a VAX with G Float instruction emulation.
GALAXY_ID128-bit Galaxy ID for AlphaServer GS systems.
GALAXY_MEMBER1 if member of a Galaxy ID for AlphaServer GS systems, 0 if not.
GALAXY_PLATFORM1 if running on a Galaxy platform for AlphaServer GS systems, 0 if not.
GALAXY_SHMEMSIZENumber of shared memory pages for AlphaServer GS systems.
GH_RSRVPGCNTNumber of pages covered by granularity hints for AlphaServer GS systems.
GLX_FORMATIONTime when galaxy configuration was created.
GLX_MAX_MEMBERSMaximum count of instances that may join the galaxy configuration for AlphaServer GS systems.
GLX_MBR_MEMBERA 64-byte integer. Each 8 bytes represents a galaxy instance from 7 to 9. Value is 1 if instance is a member.
GLX_MBR_NAMEA string indicating the names which are known in the Galaxy membership.
GLX_TERMINATIONThe time when the galaxy configuration was terminated for AlphaServer GS systems.
H_FLOAT_EMULATEDTRUE if this is a VAX with H Float instruction emulation.
HP_ACTIVE_CPU_CNTThe count of CPUs in the hard partition that are not in firmware console mode.
HP_ACTIVE_SP_CNTThe count of active UOS instances currently executing within the hard partition.
HP_CONFIG_SBB_CNTThe count of existing system building blocks within the current hard partition.
HP_CONFIG_SP_CNTThe maximum count of soft partitions within the current hard partition.
HW_MODELSystem model type.
HW_NAMESystem model name.
ITB_ENTRIESOn alpha, number of I-stream translation buffer entries that support granularity hints.
MAX_CPUSThe maximum number of CPUs that can be recognized by the system.
MEMSIZENumber of pages of memory available to UOS.
MODIFIED_PAGESNumber of modified pages.
MULTITHREADValue of the MULTITHREAD system parameter.
NODE_AREANetwork area for the node.
NODE_CSIDCluster ID of the node in the form of a string containing a hexadecimal value.
NODE_EVOTESNumber of votes alloted to the node.
NODE_HWVERSHardware version of the specified node.
NODE_NUMBERNetwork number for the specified node.
NODE_QUORUMNode's quorum.
NODE_SWINCARNSoftware incarnation number for the node in the form of a string containing a hexadecimal value.
NODE_SWTYPEType of UOS software for the node.
NODE_SWVERSSoftware version of the specified node.
NODE_SYSTEMIDSystem ID of the node as a hexadecimal string.
NODE_VOTESNumber of votes alloted to the node.
NODENAMENode name (not including double colon).
NPAGED_FREENumber of free bytes in the non-paged pool.
NPAGED_LARGESTSize of largest contiguous area of free memory in the non-paged pool.
NPAGED_TOTALTotal size (in bytes) of non-paged pool.
NPAGED_INUSETotal number of bytes currently used in the non-paged pool.
PAGED_FREENumber of free bytes in the paged pool.
PAGED_INUSETotal number of bytes currently used in the paged pool.
PAGED_LARGESTSize of largest contiguous area of free memory in the paged pool.
PAGED_TOTALTotal size (in bytes) of non-paged pool.
PAGEFILE_FREENumber of free pages in the currently installed paging files.
PAGEFILE_PAGETotal number of pages in the currently installed paging files.
PAGE_SIZENumber of bytes in a physical page of memory.
PALCODE_VERSIONVersion of PALCODE on an Alpha system.
PARTITION_IDSoft partition ID for AlphaServer systems that support partitioning.
POTENTIAL_CPU_MASKA number representing a bitmask indexed by CPU number. If a given bit is set, that CPU is in the potential set.
POTENTIALCPU_CNTThe count of the CPUs in the hard partition that are in the potential set.
POWERED_CPU_MASKA number representing a bitmask indexed by CPU number. If a given bit is set, that CPU is powered up.
POWEREDCPU_CNTThe count of CPUs in the hard partition that are physically powered up.
PRESENT_CPU_MASKA number representing a bitmask indexed by CPU number. If a given bit is set, that CPU is in the present set.
PRESENTCPU_CNTThe count of CPUs in the hard partition that physically reside in a hardware slot.
PRIMARY_CPUIDThe ID of the primary processor for the node.
QUANTUMMaximum amount of processor time a process can receive while other processes are waiting.
RAD_CPUSList of RAD,CPU pairs, delimited by commas on AlphaServer GS systems.
RAD_MAX_RADThe maximum number of RADs possible on this platform on AlphaServer GS systems.
RAD_MEMSIZEList of RAD,PAGES pairs, delimited by commas on AlphaServer GS systems.
RAD_SHMEMSIZEList of shared RAD,PAGES pairs, delimited by commas on AlphaServer GS systems.
REAL_CPUTYPEActual CPU type of the primary CPU on the node.
SCSNODEGalaxy instance name on AlphaServer GS systems that support partitioning.
SCS_EXISTSTRUE or FALSE to indicate whether the system communication subsystem (SCS) is currently loaded on the node.
SIDSystem ID.
SWAPFILE_FREENumber of free pages in currently installed swap files.
SWAPFILE_PAGENumber of pages in the currently installed swap files.
SYSTEM_RIGHTSContents of system rights list on the local node. Always null for a remote node.
SYSTEM_UUIDThe 128-bit Universal Unique Identifier for the node.
SYSTYPEThe family or system hardware platform.
TOTAL_PAGESTotal number of physical memory pages.
USED_GBLPAGCNTNumber of pages currently in use in the global page table.
USED_GBLPAGMAXMaximum number of pages ever in use in the global page table.
USED_PAGESTotal number of used pages.
VERSIONUOS version.
VECTOR_EMULATORFlag indicating presence of vector instruction emulator facility (VVIEF) on the node.
VP_MASKMask indicating which processors have vector coprocessors.
VP_NUMBERNumber of vector processors in the sytem.

The items that return rights lists return an array of int64 values.

        Function_GETSYI : begin
                              if( Missing_Parentheses( '(' ) ) then
                              begin
                                  exit ;
                              end ;
                              if( Parse_GetSYI( Err, Context ) ) then
                              begin
                                  exit ;
                              end ;
                              if( Missing_Parentheses( ')' ) ) then
                              begin
                                  exit ;
                              end ;
                              S := Context ;
                          end ;
We add the hook to the UCL Function_Reference function.

function Parse_GetSYI( var Err : integer ; var Context : string ) : boolean ;

var Code, CID : integer ;
    ItemType : TItemType ;
    I : int64 ;
    Itm, Node : string ;
    PP_SYS_Descriptor : array[ 0..1 ] of TSYS_Descriptor ;
    Buff : array of int64 ;
    BufLen : int64 ;

begin
    // Setup...
    Result := False ; // Assume no problems
    Context := '' ;
    ItemType := IT_Integer ;
    CID := 0 ;
    Node := '' ;

    // Get item....
    Itm := trim( lowercase( Get_Parameter( Err, Context ) ) ) ;
    if( Err <> 0 ) then
    begin
        exit ;
    end ;
    if( Parser.Peek <> ')' ) then
    begin
        if( Missing_Comma( Err ) ) then
        begin
            exit ;
        end ;

        // Get node name....
        Node := Get_Parameter( Err, Context ) ;
        if( Err <> 0 ) then
        begin
            exit ;
        end ;
        if( Parser.Peek <> ')' ) then
        begin
            if( Missing_Comma( Err ) ) then
            begin
                exit ;
            end ;

            // Get node name....
            CID := Get_Numeric_Parameter( Err, Context ) ;
            if( Err <> 0 ) then
            begin
                exit ;
            end ;
        end ;
    end ;
This new function first obtains the item code. Because the next paramters are optional, we only look for them if the next token isn't the closing parenthesis. If not, we verify the presence of a comma, then get the next parameter. We do this for the node name and CID.

    if( Itm = 'active_cpu_mask' ) then
    begin
        Code := SYI_ACTIVE_CPU_MASK ;
    end else
    if( Itm = 'activecpu_cnt' ) then
    begin
        Code := SYI_ACTIVECPU_CNT ;
    end else
    if( Itm = 'archflag' ) then
    begin
        Code := SYI_ARCHFLAG ;
    end else
    if( Itm = 'arch_name' ) then
    begin
        Code := SYI_ARCH_NAME ;
        ItemType := IT_String ;
    end else
    if( Itm = 'arch_type' ) then
    begin
        Code := SYI_ARCH_TYPE ;
    end else
    if( Itm = 'avail_cpu_mask' ) then
    begin
        Code := SYI_AVAIL_CPU_MASK ;
    end else
    if( Itm = 'availcpu_cnt' ) then
    begin
        Code := SYI_AVAILCPU_CNT ;
    end else
    if( Itm = 'boot_device' ) then
    begin
        Code := SYI_BOOT_DEVICE ;
        ItemType := IT_String ;
    end else
    if( Itm = 'boottime' ) then
    begin
        Code := SYI_BOOTTIME ;
        ItemType := IT_Time ;
    end else
    if( Itm = 'character_emulated' ) then
    begin
        Code := SYI_CHARACTER_EMULATED ;
        ItemType := IT_Boolean ;
    end else
    if( Itm = 'cluster_evotes' ) then
    begin
        Code := SYI_CLUSTER_EVOTES ;
    end else
    if( Itm = 'cluster_fsysid' ) then
    begin
        Code := SYI_CLUSTER_FSYSID ;
    end else
    if( Itm = 'cluster_ftime' ) then
    begin
        Code := SYI_CLUSTER_FTIME ;
        ItemType := IT_Time ;
    end else
    if( Itm = 'cluster_member' ) then
    begin
        Code := SYI_CLUSTER_MEMBER ;
        ItemType := IT_Boolean ;
    end else
    if( Itm = 'cluster_nodes' ) then
    begin
        Code := SYI_CLUSTER_NODES ;
    end else
    if( Itm = 'cluster_quorum' ) then
    begin
        Code := SYI_CLUSTER_QUORUM ;
    end else
    if( Itm = 'cluster_votes' ) then
    begin
        Code := SYI_CLUSTER_VOTES ;
    end else
    if( Itm = 'console_version' ) then
    begin
        Code := SYI_CONSOLE_VERSION ;
    end else
    if( Itm = 'contig_gblpages' ) then
    begin
        Code := SYI_CONTIG_GBLPAGES ;
    end else
    if( Itm = 'community_id' ) then
    begin
        Code := SYI_COMMUNITY_ID ;
    end else
    if( Itm = 'cpu' ) then
    begin
        Code := SYI_CPU ;
    end else
    if( Itm = 'cpu_autostart' ) then
    begin
        Code := SYI_CPU_AUTOSTART ;
        ItemType := IT_CPU ;
    end else
    if( Itm = 'cpu_failover' ) then
    begin
        Code := SYI_CPU_FAILOVER ;
        ItemType := IT_CPU ;
    end else
    if( Itm = 'cpucap_mask' ) then
    begin
        Code := SYI_CPUCAP_MASK ;
    end else
    if( Itm = 'cputype' ) then
    begin
        Code := SYI_CPUTYPE ;
    end else
    if( Itm = 'cwlogicals' ) then
    begin
        Code := SYI_CWLOGICALS ;
        ItemType := IT_Boolean ;
    end else
    if( Itm = 'decimal_emulated' ) then
    begin
        Code := SYI_DECIMAL_EMULATED ;
        ItemType := IT_String ;
    end else
    if( Itm = 'decnet_fullname' ) then
    begin
        Code := SYI_DECNET_FULLNAME ;
        ItemType := IT_String ;
    end else
    if( Itm = 'decnet_version' ) then
    begin
        Code := SYI_DECNET_VERSION ;
    end else
    if( Itm = 'd_float_emulated' ) then
    begin
        Code := SYI_D_FLOAT_EMULATED ;
        ItemType := IT_String ;
    end else
    if( Itm = 'erlbufferpages' ) then
    begin
        Code := SYI_ERLBUFFERPAGES ;
    end else
    if( Itm = 'erlbufferpag_s2' ) then
    begin
        Code := SYI_ERLBUFFERPAG_S2 ;
    end else
    if( Itm = 'errorlogbuff_s2' ) then
    begin
        Code := SYI_ERRORLOGBUF_S2 ;
    end else
    if( Itm = 'errorlogbuffers' ) then
    begin
        Code := SYI_ERRORLOGBUFFERS ;
    end else
    if( Itm = 'f_float_emulated' ) then
    begin
        Code := SYI_F_FLOAT_EMULATED ;
        ItemType := IT_String ;
    end else
    if( Itm = 'free_gblpages' ) then
    begin
        Code := SYI_FREE_GBLPAGES ;
    end else
    if( Itm = 'free_gblsects' ) then
    begin
        Code := SYI_FREE_GBLSECTS ;
    end else
    if( Itm = 'free_pages' ) then
    begin
        Code := SYI_FREE_PAGES ;
    end else
    if( Itm = 'g_float_emulated' ) then
    begin
        Code := SYI_G_FLOAT_EMULATED ;
        ItemType := IT_Boolean ;
    end else
    if( Itm = 'galaxy_id' ) then
    begin
        Code := SYI_GALAXY_ID ;
    end else
    if( Itm = 'galaxy_member' ) then
    begin
        Code := SYI_GALAXY_MEMBER ;
    end else
    if( Itm = 'galaxy_platform' ) then
    begin
        Code := SYI_GALAXY_PLATFORM ;
    end else
    if( Itm = 'galaxy_shmemsize' ) then
    begin
        Code := SYI_GALAXY_SHMEMSIZE ;
    end else
    if( Itm = 'gh_rsrvpgcnt' ) then
    begin
        Code := SYI_GH_RSRVPGCNT ;
    end else
    if( Itm = 'glx_formation' ) then
    begin
        Code := SYI_GLX_FORMATION ;
        ItemType := IT_Time ;
    end else
    if( Itm = 'glx_max_members' ) then
    begin
        Code := SYI_GLX_MAX_MEMBERS ;
    end else
    if( Itm = 'glx_mbr_member' ) then
    begin
        Code := SYI_GLX_MBR_MEMBER ;
    end else
    if( Itm = 'glx_mbr_name' ) then
    begin
        Code := SYI_GLX_MBR_NAME ;
    end else
    if( Itm = 'glx_termination' ) then
    begin
        Code := SYI_GLX_TERMINATION ;
        ItemType := IT_Time ;
    end else
    if( Itm = 'hp_active_cpu_cnt' ) then
    begin
        Code := SYI_HP_ACTIVE_CPU_CNT ;
    end else
    if( Itm = 'hp_active_sp_cnt' ) then
    begin
        Code := SYI_HP_ACTIVE_SP_CNT ;
    end else
    if( Itm = 'hp_config_sbb_cnt' ) then
    begin
        Code := SYI_HP_CONFIG_SBB_CNT ;
    end else
    if( Itm = 'hp_config_sp_cnt' ) then
    begin
        Code := SYI_HP_CONFIG_SP_CNT ;
    end else
    if( Itm = 'hw_model' ) then
    begin
        Code := SYI_HW_MODEL ;
    end else
    if( Itm = 'hw_name' ) then
    begin
        Code := SYI_HW_NAME ;
    end else
    if( Itm = 'itb_entries' ) then
    begin
        Code := SYI_ITB_ENTRIES ;
    end else
    if( Itm = 'max_cpus' ) then
    begin
        Code := SYI_MAX_CPUS ;
    end else
    if( Itm = 'memsize' ) then
    begin
        Code := SYI_MEMSIZE ;
    end else
    if( Itm = 'modified_pages' ) then
    begin
        Code := SYI_MODIFIED_PAGES ;
    end else
    if( Itm = 'multithread' ) then
    begin
        Code := SYI_MULTITHREAD ;
    end else
    if( Itm = 'nodename' ) then
    begin
        Code := SYI_NODENAME ;
        ItemType := IT_String ;
    end else
    if( Itm = 'node_area' ) then
    begin
        Code := SYI_NODE_AREA ;
    end else
    if( Itm = 'node_csid' ) then
    begin
        Code := SYI_NODE_CSID ;
    end else
    if( Itm = 'node_evotes' ) then
    begin
        Code := SYI_NODE_EVOTES ;
    end else
    if( Itm = 'node_hwvers' ) then
    begin
        Code := SYI_NODE_HWVERS ;
    end else
    if( Itm = 'node_number' ) then
    begin
        Code := SYI_NODE_NUMBER ;
    end else
    if( Itm = 'node_quorum' ) then
    begin
        Code := SYI_NODE_QUORUM ;
    end else
    if( Itm = 'node_swincarn' ) then
    begin
        Code := SYI_NODE_SWINCARN ;
    end else
    if( Itm = 'node_swtype' ) then
    begin
        Code := SYI_NODE_SWTYPE ;
    end else
    if( Itm = 'node_swvers' ) then
    begin
        Code := SYI_NODE_SWVERS ;
    end else
    if( Itm = 'node_systemid' ) then
    begin
        Code := SYI_NODE_SYSTEMID ;
    end else
    if( Itm = 'node_votes' ) then
    begin
        Code := SYI_NODE_VOTES ;
    end else
    if( Itm = 'npaged_free' ) then
    begin
        Code := SYI_NPAGED_FREE ;
    end else
    if( Itm = 'npaged_inuse' ) then
    begin
        Code := SYI_NPAGED_INUSE ;
    end else
    if( Itm = 'npaged_largest' ) then
    begin
        Code := SYI_NPAGED_LARGEST ;
    end else
    if( Itm = 'npaged_total' ) then
    begin
        Code := SYI_NPAGED_TOTAL ;
    end else
    if( Itm = 'paged_free' ) then
    begin
        Code := SYI_PAGED_FREE ;
    end else
    if( Itm = 'paged_inuse' ) then
    begin
        Code := SYI_PAGED_INUSE ;
    end else
    if( Itm = 'paged_largest' ) then
    begin
        Code := SYI_PAGED_LARGEST ;
    end else
    if( Itm = 'paged_total' ) then
    begin
        Code := SYI_PAGED_TOTAL ;
    end else
    if( Itm = 'pagefile_free' ) then
    begin
        Code := SYI_PAGEFILE_FREE ;
    end else
    if( Itm = 'pagefile_page' ) then
    begin
        Code := SYI_PAGEFILE_PAGE ;
    end else
    if( Itm = 'page_size' ) then
    begin
        Code := SYI_PAGE_SIZE ;
    end else
    if( Itm = 'palcode_version' ) then
    begin
        Code := SYI_PALCODE_VERSION ;
    end else
    if( Itm = 'partition_id' ) then
    begin
        Code := SYI_PARTITION_ID ;
    end else
    if( Itm = 'potential_cpu_mask' ) then
    begin
        Code := SYI_POTENTIAL_CPU_MASK ;
    end else
    if( Itm = 'potentialcpu_cnt' ) then
    begin
        Code := SYI_POTENTIALCPU_CNT ;
    end else
    if( Itm = 'powered_cpu_mask' ) then
    begin
        Code := SYI_POWERED_CPU_MASK ;
    end else
    if( Itm = 'poweredcpu_cnt' ) then
    begin
        Code := SYI_POWEREDCPU_CNT ;
    end else
    if( Itm = 'present_cpu_mask' ) then
    begin
        Code := SYI_PRESENT_CPU_MASK ;
    end else
    if( Itm = 'presentcpu_cnt' ) then
    begin
        Code := SYI_PRESENTCPU_CNT ;
    end else
    if( Itm = 'primary_cpuid' ) then
    begin
        Code := SYI_PRIMARY_CPUID ;
    end else
    if( Itm = 'quantum' ) then
    begin
        Code := SYI_QUANTUM ;
    end else
    if( Itm = 'rad_cpus' ) then
    begin
        Code := SYI_RAD_CPUS ;
    end else
    if( Itm = 'rad_max_rads' ) then
    begin
        Code := SYI_RAD_MAX_RAD ;
    end else
    if( Itm = 'rad_memsize' ) then
    begin
        Code := SYI_RAD_MEMSIZE ;
    end else
    if( Itm = 'rad_shmemsize' ) then
    begin
        Code := SYI_RAD_SHMEMSIZE ;
    end else
    if( Itm = 'real_cputype' ) then
    begin
        Code := SYI_REAL_CPUTYPE ;
    end else
    if( Itm = 'scs_exists' ) then
    begin
        Code := SYI_SCS_EXISTS ;
        ItemType := IT_Boolean ;
    end else
    if( Itm = 'scsnode' ) then
    begin
        Code := SYI_SCSNODE ;
        ItemType := IT_String ;
    end else
    if( Itm = 'sid' ) then
    begin
        Code := SYI_SID ;
    end else
    if( Itm = 'swapfile_free' ) then
    begin
        Code := SYI_SWAPFILE_FREE ;
    end else
    if( Itm = 'swapfile_page' ) then
    begin
        Code := SYI_SWAPFILE_PAGE ;
    end else
    if( Itm = 'system_rights' ) then
    begin
        Code := SYI_SYSTEM_RIGHTS ;
    end else
    if( Itm = 'system_uuid' ) then
    begin
        Code := SYI_SYSTEM_UUID ;
    end else
    if( Itm = 'systype' ) then
    begin
        Code := SYI_SYSTYPE ;
    end else
    if( Itm = 'total_pages' ) then
    begin
        Code := SYI_TOTAL_PAGES ;
    end else
    if( Itm = 'used_gblpagcnt' ) then
    begin
        Code := SYI_USED_GBLPAGCNT ;
    end else
    if( Itm = 'used_gblpagmax' ) then
    begin
        Code := SYI_USED_GBLPAGMAX ;
    end else
    if( Itm = 'used_pages' ) then
    begin
        Code := SYI_USED_PAGES ;
    end else
    if( Itm = 'vector_emulator' ) then
    begin
        Code := SYI_VECTOR_EMULATOR ;
    end else
    if( Itm = 'version' ) then
    begin
        Code := SYI_VERSION ;
        ItemType := IT_String ;
    end else
    if( Itm = 'vp_mask' ) then
    begin
        Code := SYI_VP_MASK ;
    end else
    if( Itm = 'vp_number' ) then
    begin
        Code := SYI_VP_NUMBER ;
    end else
    begin
        Err := UCL_IVKEYW ; // Unrecognized keyword
        Context := Itm ;
        exit ;
    end ;
This code is similar to what we've seen before: we convert from an item code to the corresponding constant. We default to integer return values.

    if( Code = SYI_CPUCAP_MASK ) then
    begin
        Context := Get_SYI( SYI_MAX_CPUS, Node, CID ) ;
        I := Get_Integer_From_String( Context ) ; // Number of CPUs
        BufLen := I * sizeof( int64 ) ;
        fillchar( PP_SYS_Descriptor, sizeof( PP_SYS_Descriptor ), 0 ) ;
        PP_SYS_Descriptor[ 0 ].MBO := $FFFF ;
        PP_SYS_Descriptor[ 0 ].MBMO := -1 ;
        PP_SYS_Descriptor[ 0 ].Buffer_Length := sizeof( Buf ) ;
        PP_SYS_Descriptor[ 0 ].Item_Code := Code ;
        PP_SYS_Descriptor[ 0 ].Buffer_Address := integer( @Buf ) ;
        PP_SYS_Descriptor[ 0 ].Return_Length_Address := integer( @BufLen ) ;
        GETSYIW( 0, int64( @CID ), Node, integer( @PP_SYS_Descriptor ), integer( @IOSB ), 0, 0 ) ;
        setlength( Context, BufLen ) ;
        move( Buf[ 0 ], PChar( Context )[ 0 ], BufLen ) ;
        Itm := '' ;
        for Code := 0 to I - 1 do
        begin
            move( Buf[ Code * 8 ], CID, 8 ) ;
            if( Code > 0 ) then
            begin
                Itm := Itm + ',' ;
            end ;
            Itm := Itm + CVTB( 10, 16, inttostr( CID ) ) ;
        end ;
        exit ;
    end ;
SYI_CPUCAP_MASK is a special case. First we obtain the number of CPUs and then set up a result buffer of the appropriate size. Then we make the call to GETSYI to fill it with data. Then we iterate through the returned int64 values to construct the comma-delimited, hexadecimal values.

    Context := Get_SYI( Code, Node, CID ) ;
    if( ItemType <> IT_String ) then
    begin
        I := Get_Integer_From_String( Context ) ;
        if( ItemType = IT_Time ) then
        begin
            Context := ASCTIM( I ) ;
        end else
        begin
            Context := inttostr( I ) ;
        end ;
    end ;
    if( ( Code = SYI_CLUSTER_FSYSID ) or ( Code = SYI_NODE_CSID ) or
        ( Code = SYI_NODE_SWINCARN ) or ( Code = SYI_NODE_SYSTEMID ) ) then
    begin
        Context := CVTB( 10, 16, Context ) ;
        exit ;
    end ;
    if( ItemType = IT_Boolean ) then
    begin
        if( Context = '0' ) then
        begin
            Context := 'FALSE' ;
        end else
        begin
            Context := 'TRUE' ;
        end ;
    end ;
end ; // Parse_GetSYI
In all other cases, we proceed pretty much like we did for GetDVI and GetJPI handling in previous articles. The only new thing here are the few special cases where we convert the integer value into a hexadecimal representation.

function Get_SYI( Code : integer ; Name : string ; CID : integer ) : string ;

var PP_SYS_Descriptor : array[ 0..1 ] of TSYS_Descriptor ;

begin
    BufLen := sizeof( Buf ) ;
    fillchar( PP_SYS_Descriptor, sizeof( PP_SYS_Descriptor ), 0 ) ;
    PP_SYS_Descriptor[ 0 ].MBO := $FFFF ;
    PP_SYS_Descriptor[ 0 ].MBMO := -1 ;
    PP_SYS_Descriptor[ 0 ].Buffer_Length := sizeof( Buf ) ;
    PP_SYS_Descriptor[ 0 ].Item_Code := Code ;
    PP_SYS_Descriptor[ 0 ].Buffer_Address := integer( @Buf ) ;
    PP_SYS_Descriptor[ 0 ].Return_Length_Address := integer( @BufLen ) ;
    GETSYIW( 0, int64( @CID ), Name, integer( @PP_SYS_Descriptor ), integer( @IOSB ), 0, 0 ) ;
    setlength( Result, BufLen ) ;
    move( Buf[ 0 ], PChar( Result )[ 0 ], BufLen ) ;
end ;
This function obtains a single item from GETSYI, much like Get_DVI and Get_JPI.

// SYS SYI descriptor codes...
const SYI_ACTIVE_CPU_BITMAP = 1 ;
      SYI_ACTIVE_CPU_MASK = 2 ;
      SYI_ACTIVECPU_CNT = 3 ;
      SYI_ARCHFLAG = 4 ;
      SYI_ARCH_NAME = 5 ;
      SYI_ARCH_TYPE = 6 ;
      SYI_AVAIL_CPU_BITMAP = 7 ;
      SYI_AVAIL_CPU_MASK = 8 ;
      SYI_AVAILCPU_CNT = 9 ;
      SYI_BOOT_DEVICE = 10 ;
      SYI_BOOTTIME = 11 ;
      SYI_CHARACTER_EMULATED = 12 ;
      SYI_CLUSTER_EVOTES = 13 ;
      SYI_CLUSTER_FSYSID = 14 ;
      SYI_CLUSTER_FTIME = 15 ;
      SYI_CLUSTER_MEMBER = 16 ;
      SYI_CLUSTER_NODES = 17 ;
      SYI_CLUSTER_QUORUM = 18 ;
      SYI_CLUSTER_VOTES = 19 ;
      SYI_COMMUNITY_ID = 20 ;
      SYI_CONTIG_GBLPAGES = 21 ;
      SYI_CPU = 22 ;
      SYI_CPU_AUTOSTART = 23 ;
      SYI_CPU_FAILOVER = 24 ;
      SYI_CPUCAP_MASK = 25 ;
      SYI_CPUCONF = 26 ;
      SYI_CPUTYPE = 27 ;
      SYI_CWLOGICALS = 28 ;
      SYI_DAY_OVERRIDE = 29 ;
      SYI_DAY_SECONDARY = 30 ;
      SYI_DECIMAL_EMULATED = 31 ;
      SYI_DECNET_FULLNAME = 32 ;
      SYI_D_FLOAT_EMULATED = 33 ;
      SYI_DEF_PRIO_MAX = 34 ;
      SYI_DEF_PRIO_MIN = 35 ;
      SYI_ERLBUFFERPAGES = 36 ;
      SYI_ERRORLOGBUFFERS = 37 ;
      SYI_F_FLOAT_EMULATED = 38 ;
      SYI_FREE_GBLPAGES = 39 ;
      SYI_FREE_GBLSECTS = 40 ;
      SYI_G_FLOAT_EMULATED = 41 ;
      SYI_GALAXY_ID = 42 ;
      SYI_GALAXY_MEMBER = 43 ;
      SYI_GALAXY_PLATFORM = 44 ;
      SYI_GALAXY_SHMEMSIZE = 45 ;
      SYI_GH_RSRVPGCNT = 46 ;
      SYI_GLX_FORMATION = 47 ;
      SYI_GLX_MAX_MEMBERS = 48 ;
      SYI_GLX_MBR_MEMBER = 49 ;
      SYI_GLX_MBR_NAME = 50 ;
      SYI_GLX_TERMINATION = 51 ;
      SYI_H_FLOAT_EMULATED = 52 ;
      SYI_HP_ACTIVE_CPU_CNT = 53 ;
      SYI_HP_ACTIVE_SP_CNT = 54 ;
      SYI_HP_CONFIG_SBB_CNT = 55 ;
      SYI_HP_CONFIG_SP_CNT = 56 ;
      SYI_HW_MODEL = 57 ;
      SYI_HW_NAME = 58 ;
      SYI_IO_PRCPU_BITMAP = 59 ;
      SYI_IO_PREFER_CPU = 60 ;
      SYI_ITB_ENTRIES = 61 ;
      SYI_MAX_CPUS = 62 ;
      SYI_MAX_PFN = 63 ;
      SYI_MEMSIZE = 64 ;
      SYI_NODE_AREA = 65 ;
      SYI_NODE_CSID = 66 ;
      SYI_NODE_EVOTES = 67 ;
      SYI_NODE_HWVERS = 68 ;
      SYI_NODE_NUMBER = 69 ;
      SYI_NODE_QUORUM = 70 ;
      SYI_NODE_SWINCARN = 71 ;
      SYI_NODE_SWTYPE = 72 ;
      SYI_NODE_SWVERS = 73 ;
      SYI_NODE_SYSTEMID = 74 ;
      SYI_NODE_VOTES = 75 ;
      SYI_NODENAME = 76 ;
      SYI_PAGEFILE_FREE = 77 ;
      SYI_PAGEFILE_PAGE = 78 ;
      SYI_PAGE_SIZE = 79 ;
      SYI_PARTITION_ID = 80 ;
      SYI_PFN_MEMORY_MAP = 81 ;
      SYI_PFN_MEMORY_MAP_64 = 82 ;
      SYI_PHYSICALPAGES = 83 ;
      SYI_PMD_COUNT = 84 ;
      SYI_POTENTIAL_CPU_BITMAP = 85 ;
      SYI_POTENTIAL_CPU_MASK = 86 ;
      SYI_POTENTIALCPU_CNT = 87 ;
      SYI_POWERED_CPU_BITMAP = 88 ;
      SYI_POWERED_CPU_MASK = 89 ;
      SYI_POWEREDCPU_CNT = 90 ;
      SYI_PRESENT_CPU_BITMAP = 91 ;
      SYI_PRESENT_CPU_MASK = 92 ;
      SYI_PRESENTCPU_CNT = 93 ;
      SYI_PRIMARY_CPUID = 94 ;
      SYI_PROCESS_SPACE_LIMIT = 95 ;
      SYI_PSXFIFO_PRIO_MAX = 96 ;
      SYI_PSXFIFO_PRIO_MIN = 97 ;
      SYI_PSXRR_PRIO_MAX = 98 ;
      SYI_PSXRR_PRIO_MIN = 99 ;
      SYI_PT_BASE = 100 ;
      SYI_PTES_PER_PAGE = 101 ;
      SYI_RAD_CPUS = 102 ;
      SYI_RAD_MEMSIZE = 103 ;
      SYI_RAD_MAX_RAD = 104 ;
      SYI_RAD_SHMEMSIZE = 105 ;
      SYI_REAL_CPUTYPE = 106 ;
      SYI_SCSNODE = 107 ;
      SYI_SCS_EXISTS = 108 ;
      SYI_SERIAL_NUMBER = 109 ;
      SYI_SHARED_VA_PTES = 110 ;
      SYI_SID = 111 ;
      SYI_SWAPFILE_FREE = 112 ;
      SYI_SWAPFILE_PAGE = 113 ;
      SYI_SYSTEM_RIGHTS = 114 ;
      SYI_SYSTEM_UUID = 115 ;
      SYI_SYSTYPE = 116 ;
      SYI_VERSION = 117 ;
      SYI_VECTOR_EMULATOR = 118 ;
      SYI_VP_MASK = 119 ;
      SYI_VP_NUMBER = 120 ;
      SYI_XCPU = 121 ;
      SYI_XSID = 122 ;
      SYI_CONSOLE_VERSION = 123 ;
      SYI_DECNET_VERSION = 124 ;
      SYI_ERLBUFFERPAG_S2 = 125 ;
      SYI_ERRORLOGBUF_S2 = 126 ;
      SYI_FREE_PAGES = 127 ;
      SYI_MODIFIED_PAGES = 128 ;
      SYI_MULTITHREAD = 129 ;
      SYI_NPAGED_FREE = 130 ;
      SYI_NPAGED_LARGEST = 131 ;
      SYI_NPAGED_TOTAL = 132 ;
      SYI_NPAGED_INUSE = 133 ;
      SYI_PAGED_FREE = 134 ;
      SYI_PAGED_INUSE = 135 ;
      SYI_PAGED_LARGEST = 136 ;
      SYI_PAGED_TOTAL = 137 ;
      SYI_PALCODE_VERSION = 138 ;
      SYI_QUANTUM = 139 ;
      SYI_TOTAL_PAGES = 140 ;
      SYI_USED_GBLPAGCNT = 141 ;
      SYI_USED_GBLPAGMAX = 142 ;
      SYI_USED_PAGES = 143 ;
      SYI_xxxx = 144 ; // Base of system paramteres
These are the constants for the GETSYI system service, most of which are used in the above code.

function Get_SYI( Code : integer ; Name : string ; CID : integer ) : string ;

var PP_SYS_Descriptor : array[ 0..1 ] of TSYS_Descriptor ;

begin
    BufLen := sizeof( Buf ) ;
    fillchar( PP_SYS_Descriptor, sizeof( PP_SYS_Descriptor ), 0 ) ;
    PP_SYS_Descriptor[ 0 ].MBO := $FFFF ;
    PP_SYS_Descriptor[ 0 ].MBMO := -1 ;
    PP_SYS_Descriptor[ 0 ].Buffer_Length := sizeof( Buf ) ;
    PP_SYS_Descriptor[ 0 ].Item_Code := Code ;
    PP_SYS_Descriptor[ 0 ].Buffer_Address := integer( @Buf ) ;
    PP_SYS_Descriptor[ 0 ].Return_Length_Address := integer( @BufLen ) ;
    GETSYIW( 0, int64( @CID ), Name, integer( @PP_SYS_Descriptor ), integer( @IOSB ), 0, 0 ) ;
    setlength( Result, BufLen ) ;
    move( Buf[ 0 ], PChar( Result )[ 0 ], BufLen ) ;
end ;
Finally, here is the Get_SYI function which obtains a single item from the GETSYI system call by setting up the descriptor array and making the call.

In the next article, we will look at the GETSYI system service.

 

Copyright © 2020 by Alan Conroy. This article may be copied in whole or in part as long as this copyright is included.