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

WAIT

Having covered the shutdown script in the last article, we now turn our attention to one of the new CUSPs used therein: WAIT. First, the user documentation, then the source code for the program.

WAIT

WAIT places the process into a wait state for the specified amount of time. It is used to delay execution of a script, or a part thereof.

Format

WAIT time

Parameters

time
This is a delta time, relative to the point at which WAIT is encountered. This can either be a integer number indicating the number of minutes to wait, or a delta time interval with the following format:

hour:minute:second.hundreth

The fields have the following meaning:
FieldMeaning
hourNumber of hours
minuteNumber of minutes
secondNumber of seconds
hundrethNumber of one-hundreth seconds
All values must be integers and the colons (:) and period (.) are required if the respective fields are specified.

Description

If entered interactively, the process will pause until the time interval is over or a Control-C or Control-Y is pressed on that terminal. Wait does not prompt the user under any circumstances. If no time is specified, it does nothing.

Example

$ RUN PREPARE
$ WAIT 0:15
$ RUN COMPLETE

In this example, the script runs the PREPARE program, then waits for 15 seconds, and then runs the COMPLETE program.


function Run : int64 ;

var C : string ;
    E : int64 ;
    OS : POS_UOS ;

begin
    OS := new( POS_UOS, Init ) ;
    E := _Wait( PChar( OS^.Command_Line ), True ) ;
    if( E <> 0 ) then
    begin
        OS^.OutputLn( 0, LIB_Get_Exception_Text( 0, E ) ) ;
    end ;
    OS.Free ;
    SYS_EXIT( 0 ) ;
end ;
This routine is the standard Run routine used in most CUSPs, with the exception that there is no default handling. As you may recall, most CUSPs will use a symbol, if defined, that contains the default qualifiers for runs of that program. However, WAIT has no qualifiers, so a default would be pointless. Hence we don't bother checking. Basically, we pass the command line to the _Wait function and then report any error, if there was one.

function _Wait( Command : PChar ; Standalone : boolean ) : int64 ;

var I : integer ;
    S : string ;
    T : int64 ;

begin
    // Setup...
    Result := 0 ;
    S := trim( Command ) ;
    if( S = '' ) then
    begin
        exit ;
    end ;

    // Parse command...
    if( trystrtoint( S, I ) ) then
    begin
        // A single number is a minute specification
        S := S + ':00.0' ;
    end ;

    // Process command...
    T := BINTIM( S ) ;
    if( T = 0 ) then
    begin
        Result := Last_Error ;
        exit ;
    end ;
    T := T + LIB_Get_Timestamp ;

    SYS_SETIMR( 0, int64( @T ) ) ;
    SYS_WAITFR( 0 ) ;
end ; // Run
This very simple routine executes the wait operation. First, we get the passed command (from the command line if running the program stand-alone). If this is a null string, we immediately exit. As described in the documentation, if no time is specified, the program does nothing.

Otherwise, if this is an integer value, we know that a minute has been specified. Otherwise it is a time specification (or some sort of erroneous input). In the case of a minute specification, we convert it to a time specification by adding ":00.0" to the end. Thus,
WAIT 15
would be interpreted as
WAIT 15:00.0
(either way means 15 minutes).

Now, we take our time specification (modified or not) and use the BINTIM service to convert it to a UOS timestamp. If the specification is invalid, BINTIM returns 0 and we get the error and exit. Otherwise, we now have a delta timestamp, which we add to the current time to get an absolute time that indicates when the wait will be over.

Finally, we call the SETIMR services to set a timer for that time, then we call the WAITFR service to wait until the timer goes off. We will cover these system services in the next article, but I'll make a comment about our use of the timer here. Timers can fire off AST calls back to the application, set event flags, and have other options. We don't specify an event flag (first parameter), so it uses event flag 0. Nor do we want any other behavior, such as callbacks. Timers operate asynchronously, so once we create one, we have to tell UOS that we want to wait until the timer fires. The call to WAITFR doesn't come back to us until the timer fires, or the user interrupts things with a control-C or control-Y. This is the simplest possible use of a timer.

Event Flags

Before we continue on to the new system services, we need to discuss event flags. Several articles in the past have mentioned event flags, but we haven't discussed what they are until now.

Event flags are boolean values (set/clear, 0/1, on/off) maintained by UOS. There are five sets of event flags, called event flag clusters, each containing 32 flags (not to be confused with UOS Clusters). The EF clusters can be either Local or Common. Local EF clusters are process-specific. Common EF clusters are shared between processes in a group. The flags are numbered 0 through 159, though some are reserved for UOS use. Local event flags are all zero when a process begins.

Event flags are used for synchronization when performing asynchronous operations. When an asychronous operation begins, the specified flag is cleared to 0. When the operation completes, the specified flag is set to 1. This allows programs to detect when a specific asynchronous operation completes, especially when multiple asynchronous operations are pending.

Event flag 0 is the default flag used if no event flag is specified in a system service call. Therefore, programs should avoid specifically using this flag since it is likely to be used within called library code. Event flag 128 is for use in certain cases, such as calls to SYS$QIOW, since the completion of those calls is synchronized through the status blocks used with the call. This avoids contention on other event flags and operates with less overhead.

Event flags should be allocated and deallocated (freed) to avoid inadvertant side-effects. The flags can be used as semaphores within a program, but the main use of the flags is to put the process or thread into a wait state until an asynchronous operation completes.

The following table describes the event flags.
Cluster numberFlag numberTypeDescription
00LocalDefault flag.
01 to 23LocalGeneral use.
024 to 31LocalReserved for UOS use.
132 to 63LocalGeneral use.
264 to 95CommonGeneral use.
396 to 127CommonGeneral use.
4128LocalGeneral use without explicit allocation.
4129 to 159LocalReserved for future use.

There are system services that allocate, free, and manipulate event flags. We will discuss these services in the future.

I realize that this is a short article, but - as you have seen - WAIT is one of the simplest of the CUSPs. However, if I were to try to include the documentation and code for either of the new system services, the article would be overlong.

In the next article, we will look at the new system services used above.