| 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
 209 APPEND and CONTINUE
 
 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.
 
FormatF$GETSYI( item {,name {,id}} )
 
Return ValueEither an integer or a string, depending upon the item requested.  The table below 
indicates the valid items and the corresponding return values.
 
Argumentsitem
 
 
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.
 
DescriptionF$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:
 
| Item | Information returned. | 
|---|
 | ACTIVE_CPU_MASK | A number representing a bitmask indexed by CPU
number.  If a given bit is set, that CPU is in the active set. |  | ACTIVECPU_CNT | The count of active CPUs. |  | ARCHFLAG | Architecture flags for the system. |  | ARCH_NAME | Name of the CPU architecture. |  | ARCH_TYPE | Type of CPU architecture. |  | AVAIL_CPU_MASK | A 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_CNT | The count of CPUs recognized by the system. |  | BOOT_DEVICE | Name of the device that UOS was booted from. |  | BOOTTIME | Date/time that UOS was booted. |  | CHARACTER_EMULATED | TRUE if this is a VAX with character instruction set emulation. |  | CLUSTER_EVOTES | Total number of votes in the cluster. |  | CLUSTER_FSYSID | System ID for the first node to boot in the cluster (the 
founding node).  This is a character string containing a hexadecimal value. |  | CLUSTER_FTIME | Time when the first node in the cluster was booted. |  | CLUSTER_MEMBER | TRUE or FALSE if the node is the member of a cluster. |  | CLUSTER_NODES | Total number of nodes in the cluster. |  | CLUSTER_QUORUM | Total quorum for the cluster. |  | CLUSTER_VOTES | Total number of votes in the cluster. |  | COMMUNITY_ID | AlphaServer system hardware community ID. |  | CONSOLE_VERSION | Console firmware version. |  | CONTIG_GBLPAGES | Total number of free, contiguous global pages. |  | CPU | Processor type. |  | CPU_AUTOSTART | A 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_FAILOVER | Destinations for crashed Alpha CPUs.  A list
delimited by commas, indexed by CPU. |  | CPUCAP_MASK | List of hexadecimal values, delimited by commas, indexed
by CPU.  Each value is a bitmask indicating CPU capabilities. |  | CPUTYPE | The processor type. |  | CWLOGICALS | Flag indicating that the clusterwide logical name database 
has been initialized on the system. |  | DECIMAL_EMULATED | TRUE if this is a VAX CPU with decimal instruction 
set emulation. |  | DECNET_FULLNAME | Node name. |  | DECNET_VERSION | Network version. |  | D_FLOAT_EMULATED | TRUE if this is a VAX with D Float instruction emulation. |  | ERLBUFFERPAG_S2 | Number of system pages used for each S2 errorlog buffer. |  | ERRORLOGBUF_S2 | Number of S2 errorlog buffers. |  | ERLBUFFERPAGES | Number of system pages used for each S0 errorlog buffer. |  | ERRORLOGBUFFERS | Number of S0 errorlog buffers. |  | F_FLOAT_EMULATED | TRUE if this is a VAX with F Float instruction emulation. |  | FREE_GBLPAGES | Current count of free global pages. |  | FREE_GBLSECTS | Current count of free global section table entries. |  | FREE_PAGES | Total number of free pages. |  | G_FLOAT_EMULATED | TRUE if this is a VAX with G Float instruction emulation. |  | GALAXY_ID | 128-bit Galaxy ID for AlphaServer GS systems. |  | GALAXY_MEMBER | 1 if member of a Galaxy ID for AlphaServer GS systems, 0 if not. |  | GALAXY_PLATFORM | 1 if running on a Galaxy platform for AlphaServer GS systems, 0 if not. |  | GALAXY_SHMEMSIZE | Number of shared memory pages for AlphaServer GS systems. |  | GH_RSRVPGCNT | Number of pages covered by granularity hints for AlphaServer GS systems. |  | GLX_FORMATION | Time when galaxy configuration was created. |  | GLX_MAX_MEMBERS | Maximum count of instances that may join the galaxy
configuration for AlphaServer GS systems. |  | GLX_MBR_MEMBER | A 64-byte integer.  Each 8 bytes represents a galaxy instance from 7 to 9.  Value is 1 if instance is a member. |  | GLX_MBR_NAME | A string indicating the names which are known in the Galaxy membership. |  | GLX_TERMINATION | The time when the galaxy configuration was terminated for AlphaServer GS systems. |  | H_FLOAT_EMULATED | TRUE if this is a VAX with H Float instruction emulation. |  | HP_ACTIVE_CPU_CNT | The count of CPUs in the hard partition that are not in firmware console mode. |  | HP_ACTIVE_SP_CNT | The count of active UOS instances currently executing within the hard partition. |  | HP_CONFIG_SBB_CNT | The count of existing system building blocks within the current hard partition. |  | HP_CONFIG_SP_CNT | The maximum count of soft partitions within the current hard partition. |  | HW_MODEL | System model type. |  | HW_NAME | System model name. |  | ITB_ENTRIES | On alpha, number of I-stream translation buffer entries that support granularity hints. |  | MAX_CPUS | The maximum number of CPUs that can be recognized by the system. |  | MEMSIZE | Number of pages of memory available to UOS. |  | MODIFIED_PAGES | Number of modified pages. |  | MULTITHREAD | Value of the MULTITHREAD system parameter. |  | NODE_AREA | Network area for the node. |  | NODE_CSID | Cluster ID of the node in the form of a string containing a hexadecimal value. |  | NODE_EVOTES | Number of votes alloted to the node. |  | NODE_HWVERS | Hardware version of the specified node. |  | NODE_NUMBER | Network number for the specified node. |  | NODE_QUORUM | Node's quorum. |  | NODE_SWINCARN | Software incarnation number for the node in the form 
of a string containing a hexadecimal value. |  | NODE_SWTYPE | Type of UOS software for the node. |  | NODE_SWVERS | Software version of the specified node. |  | NODE_SYSTEMID | System ID of the node as a hexadecimal string. |  | NODE_VOTES | Number of votes alloted to the node. |  | NODENAME | Node name (not including double colon). |  | NPAGED_FREE | Number of free bytes in the non-paged pool. |  | NPAGED_LARGEST | Size of largest contiguous area of free memory in the non-paged pool. |  | NPAGED_TOTAL | Total size (in bytes) of non-paged pool. |  | NPAGED_INUSE | Total number of bytes currently used in the non-paged pool. |  | PAGED_FREE | Number of free bytes in the paged pool. |  | PAGED_INUSE | Total number of bytes currently used in the paged pool. |  | PAGED_LARGEST | Size of largest contiguous area of free memory in the paged pool. |  | PAGED_TOTAL | Total size (in bytes) of non-paged pool. |  | PAGEFILE_FREE | Number of free pages in the currently installed paging files. |  | PAGEFILE_PAGE | Total number of pages in the currently installed paging files. |  | PAGE_SIZE | Number of bytes in a physical page of memory. |  | PALCODE_VERSION | Version of PALCODE on an Alpha system. |  | PARTITION_ID | Soft partition ID for AlphaServer systems that support partitioning. |  | POTENTIAL_CPU_MASK | A number representing a bitmask indexed by CPU
number.  If a given bit is set, that CPU is in the potential set. |  | POTENTIALCPU_CNT | The count of the CPUs in the hard partition that are in the potential set. |  | POWERED_CPU_MASK | A number representing a bitmask indexed by CPU
number.  If a given bit is set, that CPU is powered up. |  | POWEREDCPU_CNT | The count of CPUs in the hard partition that are physically powered up. |  | PRESENT_CPU_MASK | A number representing a bitmask indexed by CPU
number.  If a given bit is set, that CPU is in the present set. |  | PRESENTCPU_CNT | The count of CPUs in the hard partition that physically reside in a hardware slot. |  | PRIMARY_CPUID | The ID of the primary processor for the node. |  | QUANTUM | Maximum amount of processor time a process can receive while 
other processes are waiting. |  | RAD_CPUS | List of RAD,CPU pairs, delimited by commas on AlphaServer GS systems. |  | RAD_MAX_RAD | The maximum number of RADs possible on this platform on AlphaServer GS systems. |  | RAD_MEMSIZE | List of RAD,PAGES pairs, delimited by commas  on AlphaServer GS systems. |  | RAD_SHMEMSIZE | List of shared RAD,PAGES pairs, delimited by commas on AlphaServer GS systems. |  | REAL_CPUTYPE | Actual CPU type of the primary CPU on the node. |  | SCSNODE | Galaxy instance name on AlphaServer GS systems that support partitioning. |  | SCS_EXISTS | TRUE or FALSE to indicate whether the system communication subsystem (SCS) is currently loaded on the node. |  | SID | System ID. |  | SWAPFILE_FREE | Number of free pages in currently installed swap files. |  | SWAPFILE_PAGE | Number of pages in the currently installed swap files. |  | SYSTEM_RIGHTS | Contents of system rights list on the local node.  Always null for a remote node. |  | SYSTEM_UUID | The 128-bit Universal Unique Identifier for the node. |  | SYSTYPE | The family or system hardware platform. |  | TOTAL_PAGES | Total number of physical memory pages. |  | USED_GBLPAGCNT | Number of pages currently in use in the global page table. |  | USED_GBLPAGMAX | Maximum number of pages ever in use in the global page table. |  | USED_PAGES | Total number of used pages. |  | VERSION | UOS version. |  | VECTOR_EMULATOR | Flag indicating presence of vector instruction emulator facility (VVIEF) on the node. |  | VP_MASK | Mask indicating which processors have vector coprocessors. |  | VP_NUMBER | Number of vector processors in the sytem. |  
The items that return rights lists return an array of int64 values.
 
 
We add the hook to the UCL        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 ;
 Function_Referencefunction.
 
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.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 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( 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 ;
 
 
    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_MASKis 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.
 
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.    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
 
 
This function obtains a single item from GETSYI, much likefunction 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 ;
 Get_DVIandGet_JPI.
 
These are the constants for the GETSYI system service, most of which are used in
the above code.// 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
 
 
Finally, here is thefunction 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 ;
 Get_SYIfunction 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. |