This section describes the following GT.M I/O commands:

The OPEN command establishes a connection from a GT.M process to a device.

The format of the OPEN command is:

O[PEN][:tvexpr] expr[:[(keyword[=expr][:...])][:numexpr][:expr]][,...]

By default, when a device is unavailable, GT.M retries the OPEN indefinitely at approximately one second intervals. A device is unavailable when another process is using it exclusively, or when the OPENing process does not have the resources left to open the device.

All other errors on OPEN raise an error condition and interrupt program flow. A timeout is a tool that lets a GT.M routine regain program control when a device remains unavailable. When the OPEN specifies a timeout, GT.M keeps retrying until either the OPEN succeeds or the timeout expires.

If OPEN establishes a connection with a device before the timeout expires, GT.M sets $TEST to TRUE (1). If the timeout expires, GT.M sets $TEST to FALSE (0). If an OPEN command does not specify a timeout, the execution of the command does not affect $TEST.

If a process has not previously OPENed a device, any deviceparameters not supplied on the OPEN take their default values. When reOPENing a device that it previously closed, a GT.M process restores all characteristics not specified on the OPEN to the values the device had when it was last CLOSEd, except with SD, FIFO, and PIPE. GT.M treats sequential disk files differently and uses defaults for unspecified sequential disk file characteristics on every OPEN; in other words, by default CLOSE of a sequential disk file acts as if DESTROY were specified and it requires an explicit NODESTROY to retain sequential disk file characteristics on a CLOSE.

For a sequential disk device CLOSEd with the NODESTROY deviceparameter, a subsequent OPEN of the device with no deviceparameters restores the device state including its file position; or to the file position specified by a SEEK deviceparameter. Note that when $ZCHSET specifies a UTF character set in FIXED format, the device must have done at least one READ prior to its close. An OPEN with additional deviceparameters positions the device to the beginning of the file or to the end of file if APPEND is specified. Any SEEK specified as a deviceparameter is then applied.

If you have a menu-driven application that OPENs and CLOSEs devices based on user selections, take care that every OPEN explicitly includes all deviceparameters important to the application.

If a process OPENs an already OPEN device, GT.M modifies any characteristics that accept changes when a device is OPEN to reflect any new deviceparameter specifications.

In UTF-8 mode, the OPEN command recognizes ICHSET, OCHSET, and CHSET as three additional deviceparameters to determine the encoding of the the input / output devices.

In M mode, the OPEN command ignores ICHSET, OCHSET, CHSET, and PAD device parameters.

If an I/O device uses a multi-byte character encoding, every READ and WRITE operation of that device checks for well-formed characters according to the specified character encoding with ICHSET or OCHSET. If the I/O commands encounter an illegal sequence of bytes, they always trigger a run-time error; a VIEW "NOBADCHAR" does not prevent such errors. Strings created by $ZCHAR() and other Z equivalent functions may contain illegal sequences. The only way to input or output such illegal sequences is to specify character set "M" with one of these deviceparameters.

ATTACH=expr Applies to: SOC

ATTACH assigns expr as the handle name to the newly created socket. When ATTACH is used and one of LISTEN or CONNECT is specified on the same OPEN, the value of expr becomes the identifier of the newly created socket. If neither LISTEN nor CONNECT is specified, ATTACH is ignored.

For information on using the ATTACH with USE, refer to “ATTACH” in the USE Deviceparameters section.

Example:

open tcpdev:(ichset="M":connect=hostname_":"_portno_":TCP":attach="client"):timeout:"SOCKET"

This example uses the ATTACH deviceparameter to specify "client" as the identifier of the newly created socket. Note that GT.M recognizes ICHSET only in UTF-8 mode.

CONNECT=expr Applies to: SOC

Creates a client connection with a server, which is located by the information provided by expr. A new socket is allocated for the client connection and is made the current socket for the device, if the operation is successful.

expr specifies the protocol and the protocol-specific information. Currently, GT.M supports TCP/IP and LOCAL (also known as UNIX domain) socket protocols. For TCP/IP sockets, specify expr in the form of "<host>:<port>:TCP", where host is an IPv4 or IPv6 address optionally encapsulated by square-brackets ([]) like "127.0.0.1", "::1", "[127.0.0.1]", or "[::1]" or a IPv4 or IPv6 hostname like server.fis-gtm.com. When a hostname is specified, GT.M uses the IP version of the first address returned by DNS:

For LOCAL sockets, specify expr in the form of "<pathname>:LOCAL", where <pathname> is the name of the file to be used for communication. <pathname> may contain a dollar sign ($) followed by the name of an environment variable which GT.M expands in the same way as the device name for a sequential file. The maximum allowed length of the expanded path name depends on the OS.

For LOCAL sockets, CONNECT attempts to open the specified file. If it doesn't exist or there is no listener, CONNECT retries until it succeeds or a specified timeout expires.

[Note]Note

CONNECT is not compatible with LISTEN.

If the OPEN does not specify a timeout, a SOCKET OPEN waits for the connection to complete or an event that terminates the attempt.

Example:

open tcpdev:(connect=hostname_":"_portno_":TCP":attach="client":ioerror="TRAP"):timeout:"SOCKET" 

This example establishes a client connect with the server using the connection string in the format of "hostname:port:TCP".

EXCEPTION=expr Applies to: All devices

Defines an error handler for an I/O device. The expression must contain a fragment of GT.M code (for example, GOTO ERRFILE) that GT.M XECUTEs when GT.M detects an error, or an entryref to which GT.M transfers control, as appropriate for the current gtm_ztrap_form, setting except that there is never any implicit popping with EXCEPTION action.

A device EXCEPTION gets control after a non-fatal device error and $ETRAP/$ZTRAP get control after other non-fatal errors.

Example:

GTM>do ^FREAD
FREAD;
 zprint ^FREAD 
 read "File > ",sd
 set retry=0
 set $ztrap="BADAGAIN"
 open sd:(readonly:exception="do BADOPEN")
 use sd:exception="goto EOF"
 for  use sd read x use $principal write x,!
EOF;
 if '$zeof zmessage +$zstatus
 close sd
 quit
BADOPEN;
 set retry=retry+1 
 if retry=2 open sd
 if retry=4 halt
 if $piece($zstatus,",",1)=2 do  
 . write !,"The file ",sd," does not exist. Retrying in about 2 seconds ..."
 . hang 2.1
 . quit 
 if $piece($zstatus,",",1)=13 do  
 . write !,"The file ",sd," is not accessible. Retrying in about 3 seconds ..."
 . hang 3.1
 . quit
 quit
BADAGAIN;
 w !,"BADAGAIN",!
 
File >

This example asks for the name of the file and displays its contents. It OPENs that file as READONLY and specifies an EXCEPTION. The exception handler for the OPEN deals with file-not-found and file-access errors and retries the OPEN command on error. The first USE sets the EXCEPTION to handle end-of-file. The FOR loop reads the file one record at a time and transfers each record to the principal device. The GOTO in the EXCEPTION terminates the FOR loop. At label EOF, if $ZEOF is false, the code reissues the error that triggered the exception. Otherwise, the CLOSE releases the file.

[NO]FIXED Applies to: SD FIFO PIPE

Selects a fixed-length record format for sequential disk files. FIXED does not specify the actual length of a record. Use RECORDSIZE to specify the record length.

NOFIXED specifies a variable-length record format for sequential disk files. NOFIXED is a synonym for VARIABLE. FIXED is incompatible with STREAM and VARIABLE. By default, records have VARIABLE length record format.

[Note]Note

FIXED length records do not implicitly use embedded record terminators such as line feeds.

In UTF-8 mode, GT.M I/O enforces a more record-oriented view of the file, treating each record as RECORDSIZE bytes long. Note that a UTF-8 code-point never splits across records. If a multi-byte character (when CHSET is UTF-8) or a surrogate pair (when CHSET is UTF-16) does not fit into the record (either logical as given by WIDTH or physical as given by RECORDSIZE), the WRITE command uses the byte values as specified by the PAD deviceparameter to fill the physical record. A combining character may end up in the subsequent record if it does not fit in the current record.

[Note]Note

PAD is effective only for devices opened with a CHSET related to Unicode® characters. In M mode PAD is always <SP>

Example:

GTM>do ^fixedex
fixedex;
  zprint ^fixedex
  set file="fix.txt"
  open file:(newversion:fixed:recordsize=4)
  use file
  write "Hello, World",!
  close file
  set file="fixnowrap.txt"
  open file:(newversion:fixed:recordsize=4:nowrap)
  use file
  write "Hel",!
  write "lo, World",! ; This writes only 'lo, '
  close file
  zsystem ("more fix*.txt")
  zsystem ("od -cb fix.txt")
  zsystem ("od -cb fixnowrap.txt")
  quit
::::::::::::::
fix.txt
::::::::::::::
Hello, World
::::::::::::::
fixnowrap.txt
::::::::::::::
Hel lo,
0000000   H   e   l   l   o   ,       W   o   r   l   d
        110 145 154 154 157 054 040 127 157 162 154 144
0000014
0000000   H   e   l       l   o   ,
        110 145 154 040 154 157 054 040
0000010

Example:

GTM>zprint ^gtmcp
gtmcp ; Copy a binary file using GT.M
  new dest,line,max,src
  if 2>$length($zcmdline," ") write "$gtm_dist/mumps -r source target",!
  set dest=$piece($zcmdline," ",2)
  set src=$piece($zcmdline," ",1)
  set max=1024*1024 ; the maximum GT.M string size
  open src:(readonly:FIXED:WRAP:CHSET="M") ;
  open dest:(newversion:FIXED:WRAP:CHSET="M") ; use FIXED format because it does not insert carriage control characters after $X reaches its maximum value.
  for  use src read line#max quit:$zeof  use dest write line
  close src
  use dest
  set $x=0
  close dest
  quit

This example copies a binary file using GT.M.

IOERROR=expr Applies to: SOC

Enables exception handling in socket devices. expr specifies the I/O error trapping mode. A value equal to "TRAP" specifies that I/O errors on a device raise error conditions. A value equal to "NOTRAP", or when IOERROR is not specified, indicates that I/O error on a device does not raise error conditions.

[Note]Note

The IOERROR setting is associated with sockets while EXCEPTION is associated with the SOCKET device. In other words, IOERROR can be turned on or off for each of the sockets associated with a SOCKET device but there is only one EXCEPTION value which is used for all the sockets.

Example:

open sock:(connect=host_":"_port_":TCP":delim=$char(13,10):ioerror="TRAP")::"SOCKET" 

This example opens a socket connection and specifies that I/O errors on the device raises error conditions.

If $LENGTH(expr)&("Tt"[$EXTRACT(expr)) then Error Trapping is enabled; otherwise the application must check $DEVICE and other ISVs for errors.

Note that an OPEN command does not change the current device. Therefore, $DEVICE does not have the status information when an error occurs on OPEN. An application should check $TEST and other ISVs for errors on OPEN.

$DEVICE holds status information for a socket device. To properly trap IOERRORs related to connection handling, it is best to create an empty SOCKET device (with something like open tcpdev::timeout:"SOCKET") before opening a socket connection with the OPEN (with LISTEN or CONNECT deviceparameters) command. Then, use "USE tcpdev" to bring it to the current device. This method ensures that a device exists that would update $DEVICE with status information.

Applies to: SD, PIPE, and FIFO

Specifies information about the key file to use for reading and writing encrypted data. The syntax of the KEY deviceparameter is as follows:

KEY="key_name [IV]"

key_name is case-sensitive and must match a key name in the "files" section of the gtmcrypt_config file. The optional IV specifies an initialization vector to use for encryption and decryption.

To perform encryption and description, GT.M calls an encryption plugin using the GT.M encryption API and can use any library that conforms to the API. The encryption plugin in turn can call user-selected cryptographic libraries for cryptographic functionality. The key name and IV are passed as binary sequences of bytes to the reference implementation plugin. Because GT.M only uses the first space in the deviceparameter to delimit the end of the key, the IV can include any content, including spaces. The GT.M runtime system uses the plugin to pass the IV to the cryptographic libraries used, which use the length of the IV, to determine whether an IV less than the required size it is zero padded, and whether an IV that is longer than the required length generates an error. FIS suggests using $ZCHAR() in preference to $CHAR() when building IV byte sequences, and to make sure that IV sequences are not unintentionally subjected to numeric conversion.

A USE command with a KEY/IKEY/OKEY deviceparameter that attempts to change the cipher key or IV, including disabling encryption (by specifying an empty key), only succeeds prior to the first WRITE or READ, or after the encryption or decryption state has been reset, such as after a REWIND (only for READ) or a TRUNCATE at the start of a file (for both READ and WRITE).

Separate IKEY and OKEY deviceparameters allow different keys for READ from and WRITE to a device; for example, when a GT.M process is an element of a UNIX pipe. Because encryption ciphers use state machines (which are initialized with the IV at the beginning of the file), GT.M permits READ and WRITE operations only either starting at the beginning of a file, or at the position at which the last READ or WRITE operation completed. In particular, non-empty files cannot be opened in APPEND mode; the SEEK deviceparameter is prohibited; and the TRUNCATE is only permitted at the beginning of a file or at the end, the former deleting the contents, and the latter effectively a no-op.

[Note]Note

Encrypted files must be written and read sequentially from the beginning (including the Byte Order Marker for UTF files); GT.M supports READ and WRITE operations at arbitrary locations in a file only for unencrypted files.

Example:

The basic steps to use a key and IV to create an encrypted file and decrypt its data in a testing environment are as follows. These steps are solely for demonstration purposes. You must understand and appropriately adjust the steps before using them in a production environment. For example, in a production environment you should keep the key files in a secure location, protected with appropriate permissions from unauthorized access (such as 0500 for directories and 0400 for individual files). File encryption is just one of many components of a comprehensive security plan.

export LD_LIBRARY_PATH=/usr/local/lib
export GNUPGHOME=$PWD/mygnupg
$gtm_dist/plugin/gtmcrypt/gen_keypair.sh mykeypair@gtm Keymaster
$gtm_dist/plugin/gtmcrypt/gen_sym_key.sh 0 Sunday.key
$gtm_dist/plugin/gtmcrypt/gen_sym_key.sh 0 Monday.key
$gtm_dist/plugin/gtmcrypt/gen_sym_key.sh 0 Tuesday.key
$gtm_dist/plugin/gtmcrypt/gen_sym_key.sh 0 Wednesday.key
$gtm_dist/plugin/gtmcrypt/gen_sym_key.sh 0 Thursday.key
$gtm_dist/plugin/gtmcrypt/gen_sym_key.sh 0 Friday.key
$gtm_dist/plugin/gtmcrypt/gen_sym_key.sh 0 Saturday.key
echo -n "Enter password for gtm_passwd";export gtm_passwd="`$gtm_dist/plugin/gtmcrypt/maskpass|cut -f 3 -d " "`"
export gtmcrypt_config=mygtmcryptfile
cat mygtmcryptfile
 files: {
 CustomerReportKey1: "Sunday.key";
 CustomerReportKey2: "Monday.key";
 CustomerReportKey3: "Tuesday.key";
 CustomerReportKey4: "Wednesday.key";
 CustomerReportKey5: "Thursday.key";
 CustomerReportKey6: "Friday.key";
 CustomerReportKey7: "Saturday.key";
};
$gtm_dist/mumps -dir
GTM>zprint ^encrfile
encrfile
 set now=$horolog
 set timestamp=$zdate(now,"YYYYMMDDAM1260SS")
 set dayofweek=$zdate(now,"DAY","","1,2,3,4,5,6,7")
 set file="Customers"_timestamp_".log"
 open file:(newversion:key="CustomerReportKey"_dayofweek_" "_timestamp)
 use file
 write "Customer Report - Page 1",!
 close file
 write "IV : ",timestamp,!,"Key : CustomerReportKey"_dayofweek
GTM>do ^encrfile
IV : 20140911AM042419
Key : CustomerReportKey5
GTM>zprint ^readencrfile
readencrfile(key,iv)
 set file="Customers"_iv_".log"
 open file:(key=key_" "_iv)
 use file
 for read data use $principal write data,! use file quit:$zeof
 close file
GTM>do ^readencrfile("CustomerReportKey5","20140911AM042419")
Customer Report - Page 1
GTM>

In this example, the key name is CustomerReportKey followed by the number representing the day of the week, and IV is a timestamp, which is also a part of the file name. Although all reports start with the same string "Customer Report - Page 1", using a different IV for each file ensures that encrypted data begins with a different sequence of bytes, and making that IV a part of the file name ensures that the recipient of a report (who would have access to the key) can easily deduce the IV needed to decrypt the contents.

MOREREADTIME=intexpr Applies to: SOC

MOREREADTIME specifies the polling interval (in milliseconds) that a SOCKET device uses to check for arriving packets.

With no MOREREADTIME specified, SOCKET READ implements a dynamic approach of using a longer first interval of 200 ms when it finds no data, then shortening the interval to 10 ms when data starts to arrive.

If an interval is specified, the SOCKET device always uses the specified interval and doesn't adjust dynamically. This applies to any SOCKET READ. For more information on implementing SOCKET READ, refer to “Socket Read Operation”.

If a SOCKET READ is not subject to any of the defined terminating conditions, it terminates either after it has at least one character followed by an interval with no new packets, or reading 1,048,576 bytes.

If you use the MOREREADTIME behavior, bear in mind that:

  • Usually, it is more efficient and responsive for an application to wait and process input in larger chunks. Therefore, a larger value for MOREREADTIME can bring larger chunks of input to the application. However, large values may make for sluggish response.

  • A short value for MOREREADTIME may consume considerable CPU cycles, especially on a lightly loaded system.

  • The maximum value of MORETREADTIME is 999 (basically 1 second). Never set MOREREADTIME to 0 as it causes excessive CPU "spinning".

Example:

Use tcpdev:morereadtime=200 

This example specifies that all READs for socket device tcpdev must wait for 200 milliseconds for input.

PAD=expr Applies to: SD FIFO PIPE

For FIXED format sequential files when the character set is not M, if a multi-byte character (when CHSET is UTF-8) or a surrogate pair (when CHSET is UTF-16) does not fit into the record (either logical as given by WIDTH or physical as given by RECORDSIZE) the WRITE command uses bytes with the value specified by the PAD deviceparameter to fill out the physical record. READ ignores the pad bytes when found at the end of the record. The value for PAD is given as an integer in the range 0-127 (the ASCII characters). PAD is always a byte value and the default is $ZCHAR(32) or [SPACE].

In UTF-8 mode, there are three cases that cause GT.M to insert PAD characters when WRITEing. When READing GT.M attempts to strip any PAD characters. This stripping only works properly if the RECORDSIZE and PAD are the same for the READ as when the WRITEs occurred. WRITE inserts PAD characters when:

[Note]Note

In all UTF-16 character sets, RECORDSIZE must be even and PAD bytes occupy two bytes with the high order byte zero.

Example:

GTM>do ^padexample
padexample 
 zprint ^padexample
 set a="主要雨在西班牙停留在平原"
 set encoding="UTF-8"
 set filename="bom"_encoding_".txt"
 open filename:(newversion:fixed:record=8:pad=66:chset=encoding)
 use filename
 write a
 close filename
 halt
$ cat bomUTF-8.txt 
主要BB雨在BB西班BB牙停BB留在BB平原
$ od -tcd1 bomUTF-8.txt 
0000000  344  270  273  350  246  201    B    B  351  233  250  345  234  250    B    B
         -28  -72  -69  -24  -90 -127   66   66  -23 -101  -88  -27 -100  -88   66   66
0000020  350  245  277  347  217  255    B    B  347  211  231  345  201  234    B    B
         -24  -91  -65  -25 -113  -83   66   66  -25 -119 -103  -27 -127 -100   66   66
0000040  347  225  231  345  234  250    B    B  345  271  263  345  216  237
         -25 -107 -103  -27 -100  -88   66   66  -27  -71  -77  -27 -114  -97   32   32

In this example, the local variable a is set to a string of three-byte characters. PAD=66 sets padding byte value to $CHAR(66)

PARSE Applies to: PIPE

The PARSE deviceparameter invokes preliminary validation of the COMMAND value. When debugging, PARSE provides more accessible diagnosis for COMMAND values. By default, OPEN does not validate command values before passing them to the newly created process. PARSE has certain limitations, which may, or may not map to, those of the shell.

SEEK Applies to: SD

Positions the current file pointer to the location specified in strexpr. The format of strexpr is a string of the form "[+|-]integer" where unsigned value specifies an offset from the beginning of the file, and an explicitly signed value specifies an offset relative to the current file position. For STREAM or VARIABLE format, the positive intexpr after any sign is a byte offset, while for a FIXED format, it is a record offset. In order to deal with the possible presence of a Byte Order Marker (BOM), SEEK for a FIXED format file written in a UTF character set must follow at least one prior READ since the device was created.

[Note]Note

If an APPEND is combined with a SEEK deviceparameter the APPEND is done first - regardless of deviceparameter order.

Example:

GTM>zprint ^seekdemo
seekdemo
  new x,p
  set p="seekfixed"
  open p:(newversion:fixed:recordsize=60)
  use p
  ; create file with 9 records of length 60 bytes each
  ; number from 0 to correspond to record offset
 
  for i=0:1:8 write $justify(i_" - [-05-|-10-|-15-|-20-|-25-|-30-|-35-|-40-|-45-|-50-|-55-|",60)
  use p:rewind
  for i=0:1:8 read x set zk=$zkey use $p write "x= ",x," $zkey= ",zk,! use p
  close p
  write !!,"** OPEN with FIXED:RECORDSIZE=60:seek=""5""",!
  open p:(fixed:recordsize=60:seek="5")
  use p
  read x set ZKEY=$zkey
  ;expect: $ZKEY= 6,0
  use $p write "x= ",x," $zkey= ",ZKEY,!
  write !,"** use with SEEK=""-3""",!
  use p:seek="-3"
  read x set ZKEY=$zkey
  ;expect: $ZKEY= 4,0
  use $p write "x= ",x," $zkey= ",ZKEY,!
  write !,"** use with SEEK=""-1"" to read from the same record. read x#20 to read a partial record",!
  use p:seek="-1"
  read x#20 set ZKEY=$zkey
  ;expect: $ZKEY= 3,20
  use $p write "x= ",x," $zkey= ",ZKEY,!
  write !,"** read x#40 to finish reading the record",!
  use p
  read x#40 set ZKEY=$zkey
  ;expect: $ZKEY= 4,0
  use $p write "x= ",x," $zkey= ",ZKEY,!
  write !,"** CLOSE NODESTROY and reOPEN with no deviceparameters",!
  close p:nodestroy
  open p
  use p
  read x set ZKEY=$zkey
  ;expect: $ZKEY= 5,0
  use $p write "x= ",x," $zkey= ",ZKEY,!
  write !,"** CLOSE NODESTROY and reOPEN with SEEK=""+2""",!
  close p:nodestroy
  open p:seek="+2"
  use p
  read x set ZKEY=$zkey
  ;expect: $ZKEY= 8,0
  use $p write "x= ",x," $zkey= ",ZKEY,!
  write !,"** CLOSE NODESTROY and reOPEN with M:SEEK=""+3""",!
  close p:nodestroy
  open p:(M:seek="+3")
  use p
  read x set ZKEY=$zkey
  ;expect: $ZKEY= 4,0
  use $p write "x= ",x," $zkey= ",ZKEY,!
  write !,"** CLOSE NODESTROY and reOPEN with APPEND:SEEK=""-1""",!
  close p:nodestroy
  open p:(append:seek="-1")
  use p
  read x set ZKEY=$zkey
  ;expect: $ZKEY= 9,0
  use $p write "x= ",x," $zkey= ",ZKEY,!
  close p
  write !,"** CLOSE DESTROY and OPEN non-fixed with SEEK=""120"" and read 60 bytes",!
  open p:seek="120"
  use p
  read x#60 set ZKEY=$zkey
  ;expect: $ZKEY= 180
  use $p write "x= ",x," $zkey= ",ZKEY,!
  write !,"** CLOSE NODESTROY and reOPEN with append:SEEK=""-60"" and read last 60 bytes",!
  close p:nodestroy
  open p:(append:seek="-60")
  use p
  read x#60 set ZKEY=$zkey
  ;expect: $ZKEY= 540
  use $p write "x= ",x," $zkey= ",ZKEY,!
  close p
  quit
 
 
 
GTM>do ^seekdemo
x= 0 - [-05-|-10-|-15-|-20-|-25-|-30-|-35-|-40-|-45-|-50-|-55-| $zkey= 1,0
x= 1 - [-05-|-10-|-15-|-20-|-25-|-30-|-35-|-40-|-45-|-50-|-55-| $zkey= 2,0
x= 2 - [-05-|-10-|-15-|-20-|-25-|-30-|-35-|-40-|-45-|-50-|-55-| $zkey= 3,0
x= 3 - [-05-|-10-|-15-|-20-|-25-|-30-|-35-|-40-|-45-|-50-|-55-| $zkey= 4,0
x= 4 - [-05-|-10-|-15-|-20-|-25-|-30-|-35-|-40-|-45-|-50-|-55-| $zkey= 5,0
x= 5 - [-05-|-10-|-15-|-20-|-25-|-30-|-35-|-40-|-45-|-50-|-55-| $zkey= 6,0
x= 6 - [-05-|-10-|-15-|-20-|-25-|-30-|-35-|-40-|-45-|-50-|-55-| $zkey= 7,0
x= 7 - [-05-|-10-|-15-|-20-|-25-|-30-|-35-|-40-|-45-|-50-|-55-| $zkey= 8,0
x= 8 - [-05-|-10-|-15-|-20-|-25-|-30-|-35-|-40-|-45-|-50-|-55-| $zkey= 9,0
** OPEN with FIXED:RECORDSIZE=60:seek="5"
x= 5 - [-05-|-10-|-15-|-20-|-25-|-30-|-35-|-40-|-45-|-50-|-55-| $zkey= 6,0
** use with SEEK="-3"
x= 3 - [-05-|-10-|-15-|-20-|-25-|-30-|-35-|-40-|-45-|-50-|-55-| $zkey= 4,0
** use with SEEK="-1" to read from the same record. read x#20 to read a partial record
x= 3 - [-05-|-10-|-15-| $zkey= 3,20
** read x#40 to finish reading the record
x= -20-|-25-|-30-|-35-|-40-|-45-|-50-|-55-| $zkey= 4,0
** CLOSE NODESTROY and reOPEN with no deviceparameters
x= 4 - [-05-|-10-|-15-|-20-|-25-|-30-|-35-|-40-|-45-|-50-|-55-| $zkey= 5,0
** CLOSE NODESTROY and reOPEN with SEEK="+2"
x= 7 - [-05-|-10-|-15-|-20-|-25-|-30-|-35-|-40-|-45-|-50-|-55-| $zkey= 8,0
** CLOSE NODESTROY and reOPEN with M:SEEK="+3"
x= 3 - [-05-|-10-|-15-|-20-|-25-|-30-|-35-|-40-|-45-|-50-|-55-| $zkey= 4,0
** CLOSE NODESTROY and reOPEN with APPEND:SEEK="-1"
x= 8 - [-05-|-10-|-15-|-20-|-25-|-30-|-35-|-40-|-45-|-50-|-55-| $zkey= 9,0
** CLOSE DESTROY and OPEN non-fixed with SEEK="120" and read 60 bytes
x= 2 - [-05-|-10-|-15-|-20-|-25-|-30-|-35-|-40-|-45-|-50-|-55-| $zkey= 180
** CLOSE NODESTROY and reOPEN with append:SEEK="-60" and read last 60 bytes
x= 8 - [-05-|-10-|-15-|-20-|-25-|-30-|-35-|-40-|-45-|-50-|-55-| $zkey= 540
 
GTM>

This program demonstrates the use of the SEEK deviceparameter on OPEN and USE and reOPEN after CLOSE NODESTROY. This test is shown as an M program which may be executed, followed by the expected test output. First the test creates the file called "seekfixed" with 9, 60-byte records and then REWINDs and reads each record and outputs the record followed by $ZKEY which is a record,byte pair. Note that the records are numbered from 0 to match the SEEK record offset. Later in the test the same file is OPENed VARIABLE so $ZKEY will be a byte offset in that case. Details are given after the file output.

The first OPEN has deviceparameters set to (FIXED:RECORDSIZE=60:SEEK="5") which SEEKs to record offset 5 or physical record 6. Note, FIXED length records and RECORDSIZE remain in effect after a CLOSE NODESTROY unless changed on a reOPEN. Record offset 5 is read and output along with $ZKEY= 6,0 which points to the beginning of record offset 6. Next, a USE with SEEK="-3" is done to move back 3 records to read and output record followed by $ZKEY= 4,0. A USE with SEEK="-1" moves back one record to the beginning of the record just processed. A partial read of 20 bytes is done to show a record offset 3 with a byte offset of 20 or $ZKEY= 3,20. A read of 40 bytes is then done to finish processing that record for a $ZKEY= 4,0. Next a sequence of CLOSE NODESTROY and reOPENs are done. After the first CLOSE NODESTROY a reOPEN is done with no deviceparameters. The state of the file device, including file position, is restored and a read is done of record offset 4 which is output followed by $ZKEY= 5,0. The file device is then CLOSEd NODESTROY and a reOPEN is done with the only deviceparameter being SEEK="+2". The state of the file device is restored and a relative SEEK is done 2 records later in the file with a read which outputs record offset 7 followed by $ZKEY= 8,0. The file device is then CLOSEd NODESTORY and a reOPEN is done with deviceparameters (M:SEEK="+3"). The file device is OPENed at the beginning of the file due to the presence of a deviceparameter (M) other than SEEK on reOPEN. A relative SEEK forward of 3 records is then done from the beginning of the file and record offset 3 is read and output followed by $ZKEY= 4,0. The file device is then CLOSEd NODESTORY and a reOPEN is done with the (APPEND:SEEK="-1"). APPEND moves the file position to the EOF and then the SEEK="-1" moves the file position to the beginning of record 8 - the final record in the file. Note, the APPEND is applied prior to the SEEK - regardless of deviceparameter order. The file device is then CLOSEd (DESTROY is the default) and OPENed with the only deviceparameter being absolute SEEK="120" to byte offset 120. This processing is NOFIXED by default and a read of x#60 is done and output followed by $ZKEY= 180. The output is the same as record 2 in FIXED format. Finally, the file device is then CLOSEd NODESTROY and a reOPEN is done with deviceparameters (APPEND:SEEK="-60"). This will move the file position to the EOF and go back 60 bytes which is the starting offset to the final record in the file. Another read of x#60 and is done and output followed by $ZKEY= 540 - which is the size of the file.

[NO]STREAM Applies to: SD FIFO PIPE

STREAM and VARIABLE are semantically equivalent unless WRAP is disabled. As long as records do not exceed the WIDTH, they are also equivalent.

When WRAP is disabled and a WRITE exceeds the WIDTH, VARIABLE format truncates the line at the WIDTH, however in STREAM format, each WRITE argument is output without truncation or line terminator and the total record can be of arbitrary length.

For STREAM or VARIABLE record format files, a READ returns when it encounters an EOL, or has read #length characters for a READ #(fixed length READ), or WIDTH characters if #length is not specified, whichever occurs first.

By default, records are VARIABLE, NOSTREAM.

Example:

set sd="foo.txt"
open sd:(newversion:stream)
use sd:(width=20:nowrap)
for i=1:1:10 write " the quick brown fox jumped over the lazy dog ",$x,!
use sd:(rewind:width=100)
for i=1:1 use sd read x quit:$zeof use $principal write !,i,?5,x
close sd
quit 

The output of this example is as follows:

1     the quick brown fox jumped over the lazy dog 46
2     the quick brown fox jumped over the lazy dog 46
3     the quick brown fox jumped over the lazy dog 46
4     the quick brown fox jumped over the lazy dog 46
5     the quick brown fox jumped over the lazy dog 46
6     the quick brown fox jumped over the lazy dog 46
7     the quick brown fox jumped over the lazy dog 46
8     the quick brown fox jumped over the lazy dog 46
9     the quick brown fox jumped over the lazy dog 46
10    the quick brown fox jumped over the lazy dog 46

If you change the FORMAT to VARIABLE, the same example produces the following output.

1     the quick brown fox 
2     the quick brown fox 
3     the quick brown fox 
4     the quick brown fox 
5     the quick brown fox 
6     the quick brown fox 
7     the quick brown fox 
8     the quick brown fox 
9     the quick brown fox 
10    the quick brown fox 

If you remove the "!" format from the WRITE sequence for VARIABLE, the same example produces the following output:

1     the quick brown fox 

With STREAM, the same example produces the following output:

1     the quick brown fox jumped over the lazy dog 46 the quick brown fox jumped over the lazy dog 94 the
2     quick brown fox jumped over the lazy dog 142 the quick brown fox jumped over the lazy dog 191 the q
3    uick brown fox jumped over the lazy dog 240 the quick brown fox jumped over the lazy dog 289 the qui
4    ck brown fox jumped over the lazy dog 338 the quick brown fox jumped over the lazy dog 387 the quick
5     brown fox jumped over the lazy dog 436 the quick brown fox jumped over the lazy dog 485

The USE command selects the current device for READs (input) and WRITEs (output).

The format of the USE command is:

U[SE][:tvexpr] expr[:(keyword[=expr][:...])][,...]

The intrinsic special variable $IO identifies the current device, so GT.M directs all READs and WRITEs to $IO. When a GT.M image starts, $PRINCIPAL is implicitly OPENed and USEd. Once the GT.M image USEs a device, $IO holds the name of that device until the next USE command.

A USE command modifies the device in accordance with the deviceparameters that apply to the device type and ignores those that do not apply. Characteristics set with USE deviceparameters persist until another USE for the same device with the corresponding deviceparameter. Characteristics persist through USEs of other devices and, except for SD, FIFO, and PIPE, through a subsequent CLOSE and re-OPEN.

Example:

USE $P:(X=0:Y=$Y-1:NOECHO)

This example USEs the principal device. If that device is a terminal, the deviceparameters turn off echo and position the cursor to the beginning of the previous line.

ATTACH=expr Applies to: SOC

expr specifies the handle for a socket in the socketpool. ATTACH looks up expr in the socketpool's collection of sockets and brings the one found to the current SOCKET device. If an ATTACH operation is successful, the attached socket becomes the current socket for the device.

ATTACH is not compatible with any other device parameters in the USE command.A socket can move from one device to another using DETACH/ATTACH.

[Note]Note

A socket does not carry [I|O]CHSET with it while being moved. Such a socket uses the [I|O]CHSET of the device it is ATTACHed to. If there is input still buffered, this may cause unintentional consequences in the application if [I|O]CHSET changes. GT.M does not detect (or report) a change in [I|O]CHSET due to DETACH/ATTACH.

For information on using the ATTACH with OPEN, refer to “ATTACH” in the OPEN Deviceparameters section.

CONNECT=expr Applies to: SOC

Enables a client connection with a server, which is located by the information provided by expr. A new socket is allocated for the client connection and is made the current socket for the device, if the operation is successful.

expr specifies the protocol and the protocol-specific information. Currently, GT.M supports TCP/IP and LOCAL (also known as UNIX domain) socket protocols.

For more information, refer to “CONNECT”.

[Note]Note

CONNECT is not compatible with LISTEN.

Although CONNECT can be used with USE command, FIS recommends not to use it that way, because unlike the OPEN command, there is no way to specify a timeout to the USE command. CONNECT in the USE command take a default timeout value of 0.

Example:

Refer to the "CONNECT" examples in “Examples of OPEN”.

CTRAP=$CHAR(intexpr[,...]) Applies to: TRM

Establishes a trap facility for <CTRL> characters for the current device. The expression is a comma seperated list of ASCII characters where 0<=intexpr<=31. Other than <CTRL_C>, GT.M recognizes <CTRL> characters only when reading them from $IO. The behavior for <CTRL-C> is different in the sense that the OS recognizes it as an out-of-band interrupt including when it occurs on $PRINCIPAL when $IO'=$PRINCIPAL and delivers it immediately; When the device receives a <CTRL-n>, GT.M interrupts process execution.

Other than the <CTRL> characters (ASCII 0 through 31), terminal configuration may cause some <CTRL> characters to be seen as causing an OS action and also prevent them from ever reaching GT.M's CTRAP facility.

For example, the command USE $PRINCIPAL:CTRAP=$C(26,30,7,19) sets a trap for the ASCII characters <SUB>, <RS>, <BEL> and <DC3>.

Specifying CTRAP completely replaces the previous CTRAP list. Setting CTRAP to the empty string ("") disables character trapping.

A <CTRL-n> enabled by CTRAP produces one of the following actions:

For more information on error handling, refer to Chapter 13: “Error Processing.

When CTRAP includes <CTRL-C>, [NO]CENABLE has no effect. CTRAPping <CTRL-C> also takes precedence over CENABLE.

DETACH=expr Applies to: SOC

Removes the socket identified by expr from the current socket device, without affecting any existing connection of that socket. The removed socket is placed in the socketpool (which has the reserved name "YGTMSOCKETSPOOL") and may be attached to another socket device. If the socket being removed is the current socket, then GT.M does the following:

[Note]Note

A socket can move from one device to another using DETACH/ATTACH. A socket does not carry [I|O]CHSET with it while being moved. Such a socket uses the [I|O]CHSET of the device it is ATTACHed to. If there is input still buffered, this may cause unintentional consequences in the application if [I|O]CHSET changes. GT.M does not detect (or report) a change in [I|O]CHSET due to DETACH/ATTACH.

DETACH is not compatible with any other device parameters in the USE command.

Example:

GTM>set tcp="seerv" open tcp:(listen="6321:TCP":attach="serv")::"SOCKET"
GTM>zshow "D"
/dev/pts/9 OPEN TERMINAL NOPAST NOESCA NOREADS TYPE WIDTH=80 LENG=24
seerv OPEN SOCKET TOTAL=1 CURRENT=0
    SOCKET[0]=serv DESC=3 LISTENING PASSIVE NOTRAP PORT=6321
         ZDELAY ZBFSIZE=1024 ZIBFSIZE=87380 NODELIMITER
GTM>set tcp="seerv" o tcp:(listen="6322:TCP":attach="serv2")::"SOCKET"
GTM>zshow "D"
/dev/pts/9 OPEN TERMINAL NOPAST NOESCA NOREADS TYPE WIDTH=80 LENG=24
seerv OPEN SOCKET TOTAL=2 CURRENT=1
    SOCKET[0]=serv DESC=3 LISTENING PASSIVE NOTRAP PORT=6321
         ZDELAY ZBFSIZE=1024 ZIBFSIZE=87380 NODELIMITER
    SOCKET[1]=serv2 DESC=4 LISTENING PASSIVE NOTRAP PORT=6322
         ZDELAY ZBFSIZE=1024 ZIBFSIZE=87380 NODELIMITER

At this point, the socket device "seerv" has two sockets associated with it.

The following command moves the "serv" socket to the "YGTMSOCKETPOOL" device.

GTM>use tcp:detach="serv"
GTM>use 0 zshow "D"
/dev/pts/9 OPEN TERMINAL NOPAST NOESCA NOREADS TYPE WIDTH=80 LENG=24
seerv OPEN SOCKET TOTAL=1 CURRENT=0
    SOCKET[0]=serv2 DESC=4 LISTENING PASSIVE NOTRAP PORT=6322
         ZDELAY ZBFSIZE=1024 ZIBFSIZE=87380 NODELIMITER
YGTMSOCKETPOOL OPEN SOCKET TOTAL=1 CURRENT=0
    SOCKET[0]=serv DESC=3 LISTENING PASSIVE NOTRAP PORT=6321
         ZDELAY ZBFSIZE=1024 ZIBFSIZE=87380 NODELIMITER

Notice how socket "serv" is now associated with the pseudo socket device "YGTMSOCKETPOOL". Its only purpose is to hold detached sockets.

GTM>set tcp2="s2" o tcp2:::"SOCKET"

This creates a new socket device.

GTM>zshow "D"
/dev/pts/9 OPEN TERMINAL NOPAST NOESCA NOREADS TYPE WIDTH=80 LENG=24
 s2 OPEN SOCKET TOTAL=0 CURRENT=0
seerv OPEN SOCKET TOTAL=1 CURRENT=0
    SOCKET[0]=serv2 DESC=4 LISTENING PASSIVE NOTRAP PORT=6322
        ZDELAY ZBFSIZE=1024 ZIBFSIZE=87380 NODELIMITER
YGTMSOCKETPOOL OPEN SOCKET TOTAL=1 CURRENT=0
    SOCKET[0]=serv DESC=3 LISTENING PASSIVE NOTRAP PORT=6321
        ZDELAY ZBFSIZE=1024 ZIBFSIZE=87380 NODELIMITER

The following command moves the serv socket from the socketpool to the tcp2 device.

GTM>use tcp2:attach="serv"
GTM>use 0 zshow "D"
/dev/pts/9 OPEN TERMINAL NOPAST NOESCA NOREADS TYPE WIDTH=80 LENG=24
s2 OPEN SOCKET TOTAL=1 CURRENT=0
   SOCKET[0]=serv DESC=3 LISTENING PASSIVE NOTRAP PORT=6321
       ZDELAY ZBFSIZE=1024 ZIBFSIZE=87380 NODELIMITER
seerv OPEN SOCKET TOTAL=1 CURRENT=0
   SOCKET[0]=serv2 DESC=4 LISTENING PASSIVE NOTRAP PORT=6322
       ZDELAY ZBFSIZE=1024 ZIBFSIZE=87380 NODELIMITER
YGTMSOCKETPOOL OPEN SOCKET TOTAL=0 CURRENT=-1

[NO]EDITING Applies to: TRM

Enables the EDITING mode for the $PRINCIPAL device. If you enable EDITING, GT.M allows the use of the left and right cursor movement keys and certain <CTRL> characters within the current input line. You can recall the last input line using the up or down arrow key. The editing functions are the same as during direct mode command input as described in the "Line Editing" section of the "Operating & Debugging in Direct Mode" chapter except that backspace is not treated the same as the erase character from terminfo which is usually delete (ASCII 127). NOECHO disables EDITING mode.

Set the environment variable gtm_principal_editing to specify the mode for EDITING. For example, gtm_principal_editing="EDITING" enables EDITING mode at GT.M startup. You can also specify the mode for INSERT. For example, gtm_principal_editing="NOINSERT:EDITING". If you specify both modes then separate them with a colon (":") and put them in any order.

By default, EDITING mode is disabled.

If you enable the EDITING mode, escape sequences do not terminate READs.

Enabling PASTHRU mode supersedes EDITING mode.

If any of the EDITING <CTRL> characters are in the CTRAP list, their editing functions are not available since CTRAP takes precedence. However, EDITING <CTRL> characters take precedence over the TERMINATOR list.

[Note]Note

M READ EDITING depends on the values of $X and $Y being correct. If the application sends its own escape sequences or control characters, which change the cursor position, it must properly update $X and $Y before doing a M READ with EDITING enabled to ensure correct formatting during input.

[NO]FILTER[=expr] Applies to: TRM SOC NULL

Specifies character filtering for specified cursor movement sequences. Filtering requires character by character examination of all output and reduces I/O performance.

Each FILTER deviceparameter can have only one argument. However, multiple FILTER deviceparameters can appear in a single USE command, each with different arguments.

The valid values for expr:

By default, GT.M does not perform output filtering. For GT.M to maintain $X for non-graphic characters as described by the standard, FILTER="CHARACTERS" must be enabled. Output filtering adds additional overhead to I/O processing.

Example:

use tcpdev:filter="NOESCAPE" 

This example removes the effect of escape sequences on the maintenance $X and $Y.

LISTEN=expr Applies to: SOC

A new socket is allocated to listen for a connection. It is made the current socket for the device, if the operation is successful.

expr specifies the protocol and the protocol-specific information. Currently, GT.M supports TCP/IP and LOCAL (also known as UNIX domain) socket protocols.

For more information, refer to “LISTEN”.

Example:

GTM>set tcp="seerv" open tcp:(listen="6321:TCP":attach="serv")::"SOCKET"
GTM>use tcp:listen="6322:TCP"
GTM>use 0 zshow "D"
/dev/pts/9 OPEN TERMINAL NOPAST NOESCA NOREADS TYPE WIDTH=80 LENG=24
seerv OPEN SOCKET TOTAL=2 CURRENT=1
SOCKET[0]=serv DESC=3 LISTENING PASSIVE NOTRAP PORT=6321
     ZDELAY ZBFSIZE=1024 ZIBFSIZE=87380 NODELIMITER
SOCKET[1]=h12185825450 DESC=4 LISTENING PASSIVE NOTRAP PORT=6322
     ZDELAY ZBFSIZE=1024 ZIBFSIZE=87380 NODELIMITER

[NO]TERMINATOR[=expr] Applies to: TRM

Specifies which of the 256 ASCII characters terminate a READ. For example, TERMINATOR=$C(0) makes <NUL> the terminator.

When NOESCAPE is in effect, TERMINATOR controls whether or not <ESC> or <CSI> are treated as terminators, however, when ESCAPE processing is enabled, the entire escape sequence is treated as a terminator regardless of the TERMINATOR specification.

When EDITING is enabled, the control characters used for editing are not treated as terminators even if they are in the TERMINATOR list.

You can define any control character as a terminator, but they are all single character.

When the terminal is in UTF-8 mode (chset=utf8,) GT.M limits the terminator characters to the first 127 which are common between ASCII and UTF-8 encodng. In M mode, any of the 256 characters may be specified a terminator.

In UTF-8 mode, if CR is in the terminator list (either by default or explicitly,) GT.M ignore the following LF to keep with the standard Unicode® line terminator definitions.

NOTERMINATOR eliminates all terminators. When a terminal has all terminators disabled, fixed length READ and READ * terminate on receipt of some number of characters, and a timed READ terminates on timeout, but any other READ only terminates when the input fills the terminal read buffer.

By default, terminals recognize <CR>, <LF>, and <ESC> as terminators (that is, TERMINATOR=$C(10, 13,27)). TERMINATOR="" restores the default. In UTF-8 mode, the usual UTF-8 line terminators are also included in the default set of terminators.

Example:

GTM> USE $P:TERM=$C(26,13,11,7)

This example enables the ASCII characters <SUB>, <CR>, <VT> and <BEL> as READ terminators.

[NO]TTSYNC Applies to: TRM

Enables or disables recognition of XON/XOFF for terminal output.

[Note]Note

A terminal may have its own handling of XON/XOFF, controlled by a set-up mode or by switches. If an application requires program recognition of <CTRL-S> and <CTRL-Q>, the terminals may require reconfiguration.

The READ command transfers input from the current device to a global or local variable specified as a READ argument. For convenience, READ also accepts arguments that perform limited output to the current device.

The format of the READ command is:

R[EAD][:tvexpr] glvn|*glvn|glvn#intexpr|strlit|fcc[,...]

The maximum length of the input string is the smaller of the device buffer size limitation or the GT.M maximum string size (1,048,576 bytes). If a record is longer than the maximum record length, GT.M returns the record piece by piece during sequential reads, for devices that allow it.

When a string literal appears as an argument to a READ, M writes the literal to the current device. String literals appear as READ arguments to serve as prompts for input. GT.M does not permit expression arguments on a READ to act as prompts. Variable prompts must appear as arguments to a WRITE. If a variable appears as an argument to a READ, GT.M always interprets it as input, never as output. This facility is used mostly with terminal I/O.

The READ commands adjust $X and $Y, based on the length of the input read.

In UTF-8 mode, the READ command uses the character set value specified on the device OPEN as the character encoding of the input device. If character set "M" or "UTF-8" is specified, the data is read with no transformation. If character set is "UTF-16", "UTF-16LE", or "UTF-16BE", the data is read with the specified encoding and transformed to UTF-8. If the READ command encounters an illegal character or a character outside the selected representation, it produces a run-time error. The READ command recognizes all Unicode® line terminators for non-FIXED devices. See "Line Terminators" section for more details. In M mode, characters and bytes have a one-to-one relationship and therefore READ can be used to read bit-streams of non-character data.

The READ * command reads one character from the current device and returns the decimal ASCII representation of that character into the variable specified for the READ * command. READ * appears most frequently in communication protocols, or in interactive programs where single character answers are appropriate.

In UTF-8 mode, the READ * command accepts one Unicode® character input and puts the numeric code-point value for that character into the variable. The READ * command reads one to four bytes, depending on the encoding and returns the numeric code-point value of the character. If ICHSET specifies "UTF-16", "UTF-16LE" or "UTF-16BE", the READ * command reads a byte pair or two byte pairs (if it is a surrogate pair) and returns the numeric code-point value. If ICHSET is M, the READ * command reads a single byte and returns the numeric byte value just like in M mode.

The following example reads the value "A", and returns the decimal ASCII representation of "A" in the variable X.

Example:

GTM> READ *X
A
GTM> WRITE X
65

If a timeout occurs before GT.M reads a character, the READ * returns a negative one (-1) in the variable.

GTM>Set filename="mydata.out"; assume that mydata.out contains "主要雨在西班牙停留在平原".
GTM>Open filename:(readonly:ichset="UTF-16LE")
GTM>Use filename
GTM>Read *x
GTM>Close filename
GTM>Write $char(x)
主

In this example, the READ * command reads the first character of the file mydata.out according to the encoding specified by ICHSET.

The WRITE command transfers a character stream specified by its arguments to the current device.

The format of the WRITE command is:

W[RITE][:tvexpr] expr|*intexpr|fcc[,...]

GT.M can write up to 1,048,576 bytes (the GT.M maximum string size) as a result of a single WRITE argument. GT.M buffers output into a "logical record" for all devices except sockets without DELIMITERs and sequential devices with STREAM enabled. The WRITE command appends a string to the current record of the current device. GT.M does not write to the output device until the buffer is full, a GT.M format control character forces a write, a USE command, a CLOSE command, or, for terminals, the buffer becomes stale. The GT.M compiler breaks a concatenated WRITE argument into a series of WRITE arguments to eliminate the overhead of the concatentation. If circumstances provide a reason for a single WRITE, perform the concatenation prior to the WRITE.

Each device has a WIDTH and a LENGTH that define the virtual "page". The WIDTH determines the maximum size of a record for a device, while the LENGTH determines how many records fit on a page. When the current record size ($X) reaches the maximum WIDTH and the device has WRAP enabled, GT.M starts a new record. When the current line ($Y) reaches the maximum LENGTH, GT.M starts a new page.

For devices OPENed with a CHSET supported in UTF-8 mode, WRITE * takes intexpr as a code-point and writes the associated Unicode® character in the encoding specified by CHSET. For devices OPENed in M mode, WRITE * takes intexpr as an ASCII value and writes the associated ASCII character.

The WRITE command also has several format control characters that allow the manipulation of the virtual cursor. For all I/O devices, the GT.M format control characters do the following:

[Note]Note

If $X is less than WIDTH, WRITE ! writes WIDTH - $X spaces.

For devices OPENed with a CHSET supported in UTF-8 mode, WRITE * takes intexpr as a code-point and writes the associated Unicode character in the encoding specified by CHSET. For devices OPENed in M mode, WRITE * takes intexpr as an ASCII value and writes the associated ASCII character.

In UTF-8 mode, if a WRITE command encounters an illegal character, it produces a run-time error irrespective of the setting of VIEW "BADCHAR".

For more information, see the sections on specific I/O devices.

The CLOSE command breaks the connection between a process and a device.

The format of the CLOSE command is:

C[LOSE][:tvexpr] expr[:(keyword[=expr][:...])][,...]

When a CLOSE is issued, GT.M flushes all pending output to the device, and processes any deviceparameters. CLOSEing a device not currently OPEN has no effect.

If a partial record has been output, a WRITE ! is done to complete it. To suppress this action, set $X to zero before the CLOSE.

GT.M retains the characteristics of all device types, except a sequential file, for use in case of subsequent re-OPENs. If the device is a sequential file, characteristics controlled by deviceparameters are lost after the CLOSE.

If the device being CLOSEd is $IO, GT.M implicitly USEs $PRINCIPAL. GT.M ignores CLOSE $PRINCIPAL.

Example:

CLOSE SD:RENAME=SD_".SAV"

This closes the device and, if it is a disk file, renames it to have the type .SAV.

Example:

CLOSE SOCKDEV:(SOCKET="LOCALSOCK1":DELETE)

This deletes the socket file associated with LOCALSOCK1 if it is a LOCAL socket and closes only the named socket on the socket device.

loading table of contents...