VMS / OpenVMS DCL command shell for x86 Linux and Windows


Migate and run DCL scripgts and commands on x86 Intel Linux.

VMS / OpenVMS DCL Command Line Interpreter Shell for Linux and Windows. VX/DCL is an implementation of DEC's VMS Digital Command Language for Linux/Windows. VX/DCL allows you to use the VMS commands that you are familiar with on Linux/Windows systems. Your command scripts (. COM files) will run on the new platform. VX/DCL supports VMS / OpenVMS LOGICALS, SYMBOLS, LEXICALS, COMMANDS, with a complete API set.

VX/DCL lets you migrate the .COM files that your programs need to run. VX/DCL will execute your VMS / OpenVMS .COM files without any changes.

VX/RT and VX/DCL include a full logical name handler and supports a configurable VMS device table. As such you can use your VMS / OpenVMS .COM DCL scripts on Linux unchanged. VX/DCL supports the full VMS file specification. DIR DUA0:[a.c.b]TEXT.TXT will covert DUA0 to the value set in the global device table, for example, DUA0 equated to /vms_disk. The directory specification clearly can be translated almost "one for one". The specification DUA0:[a.c.b]TEXT.TXT becomes /vms_disk/a/b/c/TEXT.TXT.

To allow VX/DCL to also access regular Linux files VX/DCL has extended the lexical functions. f$vms_to_Linux("DUA0:[a.c.b]TEXT.TXT") returns (as expected) /vms_disk/a/b/c/TEXT.TXT. f$_Linux_to_vms("/vms_disk/a/b/c/TEXT.TXT") will do the reverse translation and also scan the device table for the correct VMS device substitution. So, f$_Linux_to_vms("/vms_disk/a/b/c/TEXT.TXT") will actually return DUA0:[a.c.b]TEXT.TXT.

VX/RT also allows global file spec translation rules - Directory and file specifications can be translated to upper case, lower case, or left "as is". VX/RT will apply smart mapping to the results from SYS$PARSE() and SYS$SEARCH() .

VX/DCL supports all the DCL command that your program need to execute exactly as it did on VMS / OpenVMS. VX/DCL scripts and commands can be invoked from the application via LIB$DO_COMMAND() and LIB$SPAWN().

VX/DCL, like VMS / OpenVMS DCL, uses a CLD (Command Line Definition) specification to parse command line arguments. The CLD file for VX/DCL can be extended so that, if you have added your own applicaiton invocation CLD to VMS / OpenVMS DCL, the same CLD will run under VX/DCL.


Learn More

INTRODUCTION

VX/DCL is an implementation of DEC's VMS Digital Command Language for Linux. Written entirely in C for portability, it provides DEC VMS DCL functionality for most Linux based platforms. One of the most important aspects to be considered when migrating from DEC VMS to Linux is the provision of a command line interface which is familiar to the users. Starting with the $ prompt, VX/DCL provides a fully interactive environment that appears and behaves in a manner that is almost identical to HP VMS / OpenVMS DCL, whilst running under Linux. By providing the user with identical command procedure capabilities, the same programming enhancements, and simplification of system level interaction available to DEC VMS users.

VX/DCL can be used in place of the various shells provided by Linux and Windows,

DCL LOGICALS AND SYMBOLS

VX/DCL provides Linux/Windows users with VMS-compatible logical name capabilities. Each of the four main logical name tables is fully implemented, as are standard access modes and table creation. Support is provided for system-created logical names (process-permanent, system-permanent). Redefining capabilities have been implemented to provide identical functionality. The creation, display and deletion of logical names behave as under VMS, and all VMS programming conventions are preserved and supported. VX/DCL also implements the LNM$PROCESS and LNM$SYSTEM directory tables, create your own tables and logical name translation priorities.

In addition to supporting all Lexicals, VX/DCL includes all underlying DEC VMS system service routines called by the Lexicals VX/DCL provides the user with the capability to obtain system-wide information such as processes, files and devices, and then directly manipulate the data with relevant system services or command procedures. VX/DCL also supports DEC VMS string and number manipulation. VX/DCL will act as a parser, performing all scripts, calls, gosub and symbol expansion or data conversion routines.

VX/DCL supports the standard use and manipulation of symbols. Symbol substitution is also supported. Symbol names can be 1 to 255 characters in length. Legal symbol names can begin with "A-Z", "a-z", "_" . Two "=" signs define that the symbol is to be placed into the global symbol table (CLI$K_GLOBAL_SYM). One "=" places the symbol in the local symbol table (CLI$K_LOCAL_SYM). The symbol tables are searched locally and then globally.

FUNCTION

VX/DCL supports most standard commands available to DEC VMS users. Expressions and lexical functions may be used with existing DCL command procedures, which are inclusive of in-line data and will perform the same as under VMS. File manipulation capabilities including specification (name, type, version), directory organization (directory or sub-directory designations), and operations (creation, use, deletion of files) that are fully supported. By using VX/RMS, VX/DCL is able to extend Linux file handling capabilities to a level DEC VMS users have always enjoyed.

VX/DCL significantly eases the impact of a new operating environment by providing a familiar user interface and enabling the use of existing DEC VMS command procedures. Supported features include but are not limited to:

Support for over 130 commands

Captive Accounts
INPUT and OUTPUT Redirect
Line editing & command history
Fully integrated lexical functionality
Symbol & logical expressions
Powerful Parser
User-defined commands
Integration with VX/RMS for file (OPEN/CLOSE) functions
Integration with VX/JSP for SYS$BATCH & SYS$PRINT
Integration with VX/SORT for SORT/MERGE
Use of Linux commands from the $ prompt
Automatic VMS filespec to Linux/Windows filespec
Additional lexcials for Linux (F$$VMS_TO_Linux)
Run Linux Commands from the DCL Prompt

DCL PRINT AND BATCH Queue's

As an extension to VX/DCL, Sector7 can also supply a fully integrated job spooler system, VX/JSP. The job spooler environment includes support for both batch execution and printer queues with the necessary commands to SUBMIT and PRINT

If you make use of VMS's extensive batch and print queue facilities, VX/JSP can be fully integrated with VX/DCL to provide a rich set of extended functions. The job spooler environment includes support for both batch execution and printer queues, with the necessary commands to START and STOP the queues, SUBMIT and PRINT. By providing users with identical command procedure capabilities, and the same programming enhancements and system-level interaction available to VMS users.

DCL & CAPTIVE ACCOUNTS

It is possible to invoke VX/DCL instead of your normal Linux shell from the Linux command line or from within a Linux shell script. For interactive use, invoking VX/DCL instead of your normal Linux shell provides a captive environment for the user. It means that upon login, the user is placed directly into the VX/DCL environment. Upon typing LOGOUT at the VX/DCL prompt, the user is then returned to the login screen, much like VMS. The major difference between VMS DCL and VX/DCL is that SYLOGIN.COM resides in SYS$MANAGER on VMS and in SYS$LIBRARY under VX/DCL. SYS$LOGIN is normally set to the users HOME directory, which is where VX/DCL will look for LOGIN.COM. If using VX/DCL to run a command file at system startup, you may find the '-n' option useful. This informs VX/DCL to ignore

SYS$LIBRARY:SYLOGIN.COM
and

SYS$LOGIN:LOGIN.COM

Examples of DCL on LINUX

LOGIN.COM

Note: UNIX is a Sector7 extension to the VMS DCL syntax to allow Unix/Linux commands to be used from DCL

Sector7 has also added f$vms_to_unix() and f$_unix_to_vms() to convert between VMS and Linux file specifications

$! write sys$output "SYS$LOGIN:LOGIN.COM executing..."
$ say :=="write sys$output"
$ ARGC :=="unix argc"
$ BASH :=="unix bash"
$ BIG :=="unix figlet"
$ CLEAR :=="unix clear"
$ DATE :=="unix date"
$ GDB :=="unix gdb"
$ MAKE :=="unix make"
$ MAN :=="unix man"
$ QDBG :=="unix qdebug"
$ FIND :=="$find.exe"
$ VALUE :=="unix value"
$ MENU :=="@sys$login:[.src.vxtools85.testsuite.dcl]jspmenu.com"
$! MENU :=="@[.testsuite.dcl]jspmenu.com"
$ SBM :== "SUBMIT/NOPRINTER/NONOTIFY"
$ cli :=="unix echo $PPID"
$! BIG "VMS -or- Linux?"
$! BIG 'f$getjpi("","username")
$ vdb:=="unix gdb -x scan.gdb vxscan.exe"
$! say "active cpus.: ",f$getsyi("activecpu_cnt")
$! say "architecture: ",f$getsyi("arch_name")
$! say "arch flag...: ",f$getsyi("archflag")
$!
$! UAF = F$PARSE("SYSUAF","SYS$SYSTEM:.DAT")
$!
$! CLS :== TYPE/PAGE NL:
$! set prompt="''f$environment("default")' $ "
$! PIPE CC/VERSION | (READ SYS$PIPE hdr ; DEFINE/JOB/NOLOG hdr &hdr )
$!
$! pipe show system | search sys$input opcom | (read sys$input pid ;
$! pid=f$element(0," ",pid) ; define/system opcom_pid &pid)
$! show log opcom_pid
$! "OPCOM_PID" = "0000020B" (LNM$SYSTEM_TABLE)
$!
$ time_stamp = f$time()
$ current_date = f$cvtime("''time_stamp'","absolute","date")
$ current_day = f$cvtime("''current_date'",,"weekday")
$ off_set = 1
$ if current_day .eqs. "Friday" then off_set = 3
$ next_day = f$cvtime("''current_date'+''off_set'-",,"weekday")
$ write sys$output "Enjoying ''current_day' ... can it wait until ''next_day'?"

#4 ..32.. IntegrationServer::/Users/jameshale: DCL

Sector7 VX/DCL 8.5-7 (Feb 25 2020 12:35:54)
Copyright (C) 1985-2020 Sector 7 USA LLC.
All Rights Reserved
Default Release Configuration

RUN LOGIN.COM



Enjoying Tuesday ... can it wait until Wednesday?

$ say "active cpus.: ",f$getsyi("activecpu_cnt")

active cpus.: 8

$ say "architecture: ",f$getsyi("arch_name")
architecture: IA64

$ date (Symbol for "UNIX DATE")
Tue Feb 25 14:12:35 CST 2020 

$ show time
25-FEB-2020 16:12:48.69

VMS PRINT And BATCH Queue Management

$ start/queue/manager

$ show queue/full/all

Generic batch queue FEED_0001, stopped
    /BASE_PRIORITY=4 /GENERIC=(GRID_0001,GRID_0002,GRID_0003,GRID_0004,GRID_0005,
    GRID_0006,GRID_0007,GRID_0008,GRID_0009,GRID_0010) /OWNER=[SYSTEM]
    /PROTECTION=(S:M,O:D,G:R,W:S)
    
Generic batch queue FEED_0002, stopped
    /BASE_PRIORITY=4 /GENERIC=(GRID_0011,GRID_0012,GRID_0013,GRID_0014,GRID_0015,
    GRID_0016,GRID_0017,GRID_0018,GRID_0019,GRID_0020) /OWNER=[SYSTEM]
    /PROTECTION=(S:M,O:D,G:R,W:S)
    
Batch queue GRID_0001, stopped
    /BASE_PRIORITY=4 /NOENABLE_GENERIC /JOB_LIMIT=2 /OWNER=[SYSTEM]
    /PROTECTION=(S:M,O:D,G:R,W:S)
    
Batch queue SYS$BATCH, idle
    /BASE_PRIORITY=4 /NOENABLE_GENERIC /JOB_LIMIT=1 /OWNER=[SYSTEM]
    /PROTECTION=(S:M,O:D,G:R,W:S)
    [Cropped]

$ START/QUEUE SYS$BATCH
$ START/QUEUE GRID_0001
$ SHOW QUEUE/FULL/ALL

Generic batch queue FEED_0001, stopped
    /BASE_PRIORITY=4 /GENERIC=(GRID_0001,GRID_0002,GRID_0003,GRID_0004,GRID_0005,
    GRID_0006,GRID_0007,GRID_0008,GRID_0009,GRID_0010) /OWNER=[SYSTEM]
    /PROTECTION=(S:M,O:D,G:R,W:S)
          
Generic batch queue FEED_0002, stopped
    /BASE_PRIORITY=4 /GENERIC=(GRID_0011,GRID_0012,GRID_0013,GRID_0014,GRID_0015,
    GRID_0016,GRID_0017,GRID_0018,GRID_0019,GRID_0020) /OWNER=[SYSTEM]
    /PROTECTION=(S:M,O:D,G:R,W:S) 
          
Batch queue GRID_0001, idle
    /BASE_PRIORITY=4 /NOENABLE_GENERIC /JOB_LIMIT=2 /OWNER=[SYSTEM]
    /PROTECTION=(S:M,O:D,G:R,W:S)
          
Batch queue SYS$BATCH, idle
    /BASE_PRIORITY=4 /NOENABLE_GENERIC /JOB_LIMIT=1 /OWNER=[SYSTEM]
    /PROTECTION=(S:M,O:D,G:R,W:S)
    [CROPPED]



$ show system

VX/RT v8.5-7  on node INTEGRATIO

Pid      Name            UIC           Mode        TTY          User     Image Name
00009b6d JAMESHALE       [   20,  502] INTERACTIVE LTA9:        JAMESHAL dcl
00009d08 LCKMGR_SERVER   [   20,  502] INTERACTIVE              JAMESHAL lckmgr
0000a028 JSPCTL          [    1,    4] BATCH                    ROOT     jspctl
0000a028 SYS$BATCH       [    1,    4] BATCH                    ROOT     qmgr
0000a028 GRID_0020       [    1,    4] BATCH                    ROOT     qmgr

 

VMS Device Table Compatibility

$ show device/all

Device           ALLOC   ASSIGN  ATTACH  DMT  Type
SYS0            000000       N       N    N  DISK /SYS0
SYS1            000000       N       N    N  DISK /SYS1
BIGDISK         000000       N       N    N  DISK /Volumes/s7
$1$DIA0         000000       N       N    N  DISK /
$1$DIA1         000000       N       N    N  DISK /shared
$1$DIA2         000000       N       N    N  DISK /var/spool/vxrt
H               000000       N       N    N  DISK /home
S7              000000       N       N    N  DISK /Volumes/s7
USERS           000000       N       N    N  DISK /Volumes/s7/Users
T               000000       N       N    N  DISK /Volumes/CaseSensitive
U               000000       N       N    N  DISK /Users
V               000000       N       N    N  DISK /Volumes
X               000000       N       N    N  DISK /opt
SCRATCH         000000       N       N    N  DISK /var/spool/vxrt/tmp
NL              000000       N       N    N    NL /dev/null
NLA0            000000       N       N    N    NL /dev/null
LP              000000       N       N    N    LP /dev/lp0
OPER            000000       N       N    N    LP /dev/log
LTA9            039789       Y       Y    N  TERM /dev/ttys006  (This TTY)

$ write sys$output F$GETDVI("TT","FULLDEVNAM")

_LTA9:

$ write sys$output F$GETDVI("TT","DEVNAM")

LTA9:

$ write sys$output F$GETDVI("TT","TT_PHYDEVNAM")

/dev/ttys006

$ write sys$output f$getdvi("TT","TT_PAGE")

24

$ write sys$output f$getdvi("TT","DEVBUFSIZ")

80
Notice that VX/DCL has translated /Users to U: by indexing in the device table)

VMS / Linux filespec Conversion

$ show def

U:[jameshale]
$ say f$vms_to_unix("U:[jameshale]")
/Users/jameshale/

Notice that the device U has been expandxed to [USERS] and merged (as VMS) to [Users.JAMESHALE] WHich translates to a Linux file spec /Users/jamshale

$ say f$unix_to_vms("/Users/jameshale/")

U:[jameshale]

VMS Lexicals

$ say f$setprv("ALL")

PALL = "NOCMKRNL,NOCMEXEC,NOSYSNAM,NOGRPNAM,NOALLSPOOL,NODETACH,NODIAGNOSE,NOLOG_IO,NOGROUP,NOACNT,NOPRMCEB,NOPRMMBX,NOPSWAPM,NOALTPRI,NOSETPRV,NOTMPMBX,NOWORLD,NOMOUNT,NOOPER,NOEXQUOTA,NONETMBX,NOVOLPRO,NOPHY_IO,NOBUGCHK,NOPRMGBL,NOSYSGBL,NOPFNMAP,NOSHMEM,NOSYSPRV,NOBYPASS,NOSYSLCK,NOSHARE,NOUPGRADE,NODOWNGRADE,NOGRPPRV,NOREADALL,NOIMPORT,NOAUDIT,NOSECURITY"

 

 

$type test_search_lists.com

$ CHARS="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
$ LMAX=f$length(CHARS)
$ write sys$output "list ''CHARS' ... max == ''LMAX'"
$ on error then goto FIRSTDIR
$ cre/dir sys$login:[.FILES]
$FIRSTDIR:
$ on error then goto NEXTDIR
$ LNUM=0
$NEWDIR:
$ LNAM=f$fao("!AS!AS", "REP", f$extract( LNUM, 1, CHARS ))
$ LDIR=f$fao("!AS!AS", "REPORT", f$extract( LNUM, 1, CHARS ))
$ NDIR="sys$login:[.FILES.''LDIR']"
$! write sys$output NDIR
$! write sys$output "define ''LNAM' ''NDIR'"
$ define 'LNAM 'NDIR
$ cre/dir 'NDIR
$ FNAM=f$fao("!AS!AS!AS", NDIR, f$extract( LNUM, 1, CHARS ), "FILE.TXT")
$ open/write FD 'FNAM
$ write FD "Hello World"
$ close FD
$NEXTDIR:
$ if LNUM .EQ. LMAX-1 then goto SETUP
$ LNUM = LNUM + 1
$ goto NEWDIR
$SETUP:
$ on error then goto EXITING
$ write sys$output "dir sys$login:[.FILES...]"
$ dir sys$login:[.FILES...]
$ def REP0 SYS$LOGIN:[.FILES],REPA,REPB,REPC,REPD,REPE,REPF,REPG,REPH,REPI,REPJ, -
           REPK,REPL,REPM,REPN,REPO,REPP,REPQ,REPR,REPS,REPT, -
           REPU,REPV,REPW,REPX,REPY,REPZ
$ write sys$output ""
$ write sys$output "dir REP0"
$ dir rep0
$ write sys$output ""
$ write sys$output "dir REP0:*.TXT"
$ dir REP0:*.TXT
$ LNUM=0
$NEXTCHAR:
$ CHAR=f$extract( LNUM, 1, CHARS )
$ write sys$output ""
$ write sys$output "dir REP0:''CHAR'*.TXT"
$ dir REP0:''CHAR'*.TXT
$ if LNUM .EQ. LMAX-1 then goto EXITING
$ LNUM = LNUM + 1
$ goto NEXTCHAR
$EXITING:
$ write sys$output ""
$ write sys$output "EXITING..."

$ @test_search_lists.com

list ABCDEFGHIJKLMNOPQRSTUVWXYZ ... max == 26
DCL$CREATE: sys$login:[.FILES] already exists
DCL$CREATE: sys$login:[.FILES.REPORTA] already exists
DCL$CREATE: sys$login:[.FILES.REPORTB] already exists
DCL$CREATE: sys$login:[.FILES.REPORTC] already exists
DCL$CREATE: sys$login:[.FILES.REPORTD] already exists
DCL$CREATE: sys$login:[.FILES.REPORTE] already exists
DCL$CREATE: sys$login:[.FILES.REPORTF] already exists
DCL$CREATE: sys$login:[.FILES.REPORTG] already exists
DCL$CREATE: sys$login:[.FILES.REPORTH] already exists

[ TURNCATED ]

dir sys$login:[.FILES...]

Directory U:[jameshale.FILES.REPORTA]

AFILE.TXT;1

[ TRUNCATED ]

Directory U:[jameshale.FILES]

REPORTA.DIR;1       REPORTB.DIR;1       REPORTC.DIR;1       REPORTD.DIR;1
REPORTE.DIR;1       REPORTF.DIR;1       REPORTG.DIR;1       REPORTH.DIR;1
REPORTI.DIR;1       REPORTJ.DIR;1       REPORTK.DIR;1       REPORTL.DIR;1
REPORTM.DIR;1       REPORTN.DIR;1       REPORTO.DIR;1       REPORTP.DIR;1
REPORTQ.DIR;1       REPORTR.DIR;1       REPORTS.DIR;1       REPORTT.DIR;1
REPORTU.DIR;1       REPORTV.DIR;1       REPORTW.DIR;1       REPORTX.DIR;1
REPORTY.DIR;1       REPORTZ.DIR;1

[ TRUNCATED ]


DCL CONTROL

$ TYPE GOSUB.COM

$ GOSUB LABEL1
$ EXIT
$ LABEL1:
$   write sys$output "Im here LABEL 1"
$   gosub LABEL2
$ return
$ LABEL2:
$   write sys$output "Im here LABEL 2"
$   gosub LABEL3
$ return
$ LABEL3:
$   write sys$output "Im here LABEL 3"
$   return

$ @GOSUB

Im here LABEL 1
Im here LABEL 2
Im here LABEL 3

Calling Linux utilities via DCL symbols

$ BIG "Linux or VMS"

 _     _                                __     ____  __ ____
| |   (_)_ __  _   ___  __   ___  _ __  \ \   / /  \/  / ___|
| |   | | '_ \| | | \ \/ /  / _ \| '__|  \ \ / /| |\/| \___ \
| |___| | | | | |_| |\>  \<  | (_) | |      \ V / | |  | |___) |
|_____|_|_| |_|\__,_/_/\_\  \___/|_|       \_/  |_|  |_|____/

DCL API's
CLI$
DCL_PARSE
DISPATCH
GET_VALUE
PRESENT
LIB$
DELETE_SYMBOL
GET_SYMBOL
SET_SYMBOL
DO_COMMAND
GET_COMMAND
SPAWN
GET_LOGICAL
DELETE_LOGICAL
SET_LOGICAL
SET_COMMON
GET_COMMON
SYS$
CRELNM
CRELNT
CRELOG
DELLNM
GETQUI(W)
SNDJBC(W)
TRNLNM
TRNLOG
DCL LEXICALS
F$ADDTIME
F$CONTEXT
F$CSID
F$CVSI
F$CVTIME
F$CVUI
F$DEVICE
F$DIRECTORY
F$EDIT
F$ELEMENT
F$ENVIRONMENT
F$EXTRACT
F$FAO
F$FILE_ATTRIBUTES
F$GETDVI
F$GETJPI
F$GETQUI
F$GETSYI
F$IDENTIFIER
F$INTEGER
F$LENGTH
F$LOCATE
F$LOGICAL
F$MESSAGE
F$MODE
F$PARSE
F$PID
F$PRIVILEGE
F$PROCESS
F$RELEASE
F$SEARCH
F$SETPRV
F$SHELLVAR
F$STRING
F$TIME
F$TRNLNM
F$TYPE
F$Linux_TO_VMS
F$USER
F$VERIFY
F$VMS_TO_Linux
COMMAND
ALLOCATE
ANALYZE
APPEND
ASSIGN
ATTACH
BASIC
C
CALL
CLOSE
COBOL
CONTINUE
CONVERT
COPY
CREATE
DEALLOCATE
DEASSIGN
DECK
DEFINE
/CHARA
/FORM
/KEY
DELETE
/ENTRY
/FORM
/KEY
/QUEUE
/SYMBOL
DIFF
DIR
EDIT
ELSE

COMMAND
ENDIF
ENDSUBROUTINE
EOD
EXIT
FDL
Fortran
GOSUB
GOTO
HELP
IF
INITIALIZE
INIT QUEUE
INQUIRE
LIBRARY
LINK
LOGOUT
ON
OPEN
PASCAL
PRINT
PURGE
READ
RECALL
RECALL/ALL
RENAME
REPLY
RETURN
RUN
RUN/DETACHED
RUN/PROCESS
SEARCH
SET CONTROL
SET DEFAULT
COMMAND
SET DIRECTORY
SET ENTRY
SET FILE
SET KEY
SET MESSAGE
SET ON
SET OUTPUT
SET PROCESS
SET PROMPT
SET PROT
SET QUEUE
RESTART
SET RMS DEF
SET SYMBOL
SET TERMINAL
SET TRACE
SET UIC
SET VERIFY
SHOW SYMBOLS
SHOW TIME
SHOW DEFAULT
COMMAND
SHOW DEVICE
SHOW ENTRY
SHOW ERROR
SHOW KEY
SHOW LOGICAL
SHOW PROCESS
SHOW PROT
SHOW QUEUE
SHOW QUOTA
SHOW SYMBOL
SHOW SYSTEM
SHOW TERMINAL
SHOW TRANSL
SHOW USER
SORT
SPAWN
START
STOP
STOP
SUBMIT
SUBROUTINE
THEN
TYPE
Linux
WAIT
WRITE