Local Interprocess Communication (Pipes)
This page describes how to set up communication with processes outside of InterSystems IRIS® data platform via pipes.
Introduction
You can communicate between your InterSystems IRIS processes and external UNIX® or Windows processes through a pipe, just as at the UNIX® or Windows operating system level. You can send output to or receive input from the pipe. The pipe is one-way; you cannot read from and write to the same program at the same time.
When you open a pipe to another program for output, you can write to it as if it were a sequential file. The program then uses what you have written as its input stream. This capability is especially helpful when you want InterSystems IRIS processes to share resources with external processes.
Opening Pipes to InterSystems IRIS Utilities
You can open a pipe to an InterSystems IRIS utility as well as to UNIX® or Windows processes. Before you can use a pipe for utility I/O, your system manager must define the pipe device on your InterSystems IRIS system.
After the system manager defines the pipe device, when you run a utility (such as ^%RD), you answer the Device: prompt with the mnemonic the system manager defined. Your output goes automatically to that device.
Pipes and Command Pipes
InterSystems IRIS supports both standard pipes and command pipes (CPIPE). Standard pipes are used for relative short command strings, in which the command name and its arguments are less than 256 characters. Command pipes are used when the command string is 256 characters or more in length. In both cases, pipes can only be used on UNIX® and Windows systems.
Standard Pipe OPEN
The following is the OPEN command syntax for standard pipes:
OPEN program:(parameters):timeout
Because program is the first argument (the device argument), it must follow the OPEN command device name limitation of 256 characters.
If an OPEN command is issued for a standard pipe that is already open, the second OPEN is ignored. No error is issued.
Command Pipe OPEN
The following is the OPEN command syntax for command pipes:
OPEN cpipename:program:timeout
OPEN cpipename:(program:parameters:::closetimeout):timeout
The cpipename argument can take the value "|CPIPE|" if there is only command pipe open concurrently. To open multiple concurrent pipes, specify "|CPIPE|xxxxxx", where xxxxxx represents a user-specified unique identifier. This cpipename argument is the argument specified for subsequent USE and CLOSE commands.
Because program is the second argument, it is not limited to 256 characters. The maximum length of program is platform dependent.
If an OPEN command is issued for a command pipe that is already open, the second OPEN is ignored. No error is issued.
OPEN Command for Interprocess Communication
The OPEN command allows your program to communicate with processes external to InterSystems IRIS.
OPEN Arguments
Command Pipes Only — either "|CPIPE|" or "|CPIPE|xxxxxx", where xxxxxx represents a user-specified unique identifier.
A command pipe can execute a program with a command shell, or without a command shell (directly). Executing without a command shell is preferred in most situations. A standard pipe executes a program with a command shell.
Command Pipes Only — To execute without a command shell, specify /COMMAND=program. If program has arguments, you must specify them using the /ARGS keyword. If you specify either the /COMMAND or /ARGS keyword, the program is executed without a command shell: (/COMMAND=program), (/COMMAND=program:/ARGS=arg1) and (program:/ARGS=arg1) are all valid syntax. /ARGS can take a single argument, a comma-separated list of arguments, or an array. For example, (/COMMAND=program:/ARGS=arg1,arg2). You can specify a variable number of arguments using an array:
SET array(1)=arg1, array(2)=arg2, array=2
OPEN device:(/COMMAND=cmd:/ARGS=array...)
To execute using a command shell, specify program, omitting both the /COMMAND and /ARGS keywords.
The program string contains the full pathname of a program installed on your system. It contains the command name and its arguments (if any) to be executed on the host system. For a standard pipe, limited to <256 characters. For command pipe, the maximum length is platform dependent, but substantially more than 256 characters.
Read. For a standard pipe specify Q or QR to open a queue or pipe to accept input from another process. For a command pipe: because a command pipe is unambiguously a pipe, the Q letter code is not required; specify R.
Write. For a standard pipe specify QW to open a queue to send input to another process. For a command pipe: because a command pipe is unambiguously a pipe, the Q letter code is not required; specify W.
Read and Write. For a standard pipe that can be either a read or write pipe specify QRW to open a queue or pipe to accept input from and send input to another process. For a command pipe: because a command pipe is unambiguously a pipe, the Q letter code is not required; specify RW.
You can specify these and other parameters using the /keyword parameters, separated by colons. For example, OPEN "|CPIPE|":(cmd:/READ:/IOTABLE="UTF8"). The following optional keyword parameters are commonly used with pipes:
-
K/name/ (or Knum ) to enable I/O translation, if translation has been enabled system-wide. You identify the previously defined table on which the translation is based by specifying the table's name. The + and - options for turning protocols on and off are not available with the K protocol.
-
Y/name/ (or Ynum) to tell the system to use the named $X/$Y Action Table. You identify the previously defined $X/$Y Action Table on which translation is based by specifying the table's name. $X/$Y action is always enabled. If Y is not specified and a system default $X/$Y is not defined, a built in $X/$Y action table is used. The + and - options for turning protocols on and off are not available with the Y protocol.
You can specify the S (stream), F (fixed length), or U (undefined length) mode parameters with the above parameters. You cannot specify the V (variable length) mode parameter.
For a complete list of letter code and keyword parameters, refer to OPEN Mode Parameters.
Optional — UNIX® only: You can specify the number of seconds the CLOSE command will wait for the command process to exit when closing a piped command device. The default is 30 seconds. You can override this closetimeout by specifying an “I” (immediate) argument on the CLOSE command for interprocess communication.
Optional — A positive integer whose value in seconds is the longest time InterSystems IRIS waits for an OPEN to successfully finish. If InterSystems IRIS is able to open interprocess communication before the timeout expires, it sets $TEST to 1. If InterSystems IRIS is not able to open interprocess communication before the timeout expires, it sets $TEST to 0. If you omit the timeout or specify 0, the OPEN returns control to the process immediately.
OPEN Command Pipe Examples
The following are valid command pipe OPEN statements. Each example specifies a timeout of 10 seconds:
OPEN "|CPIPE|1":"/nethome/myprog":10 // using shell, no args
OPEN "|CPIPE|1":("/nethome/myprog":/WRITE):10 // using shell, no args, WRITE
OPEN "|CPIPE|2":/COMMAND="/nethome/myprog":10 // no shell, no args
OPEN "|CPIPE|3":("":/COMMAND="/nethome/myprog"):10 // no shell, no args
OPEN "|CPIPE|4":(/COMMAND="/nethome/myprog":/ARGS=arg1):10 // no shell, 1 arg
OPEN "|CPIPE|5":("/nethome/myprog":/ARGS=arg1):10 // no shell, 1 arg
OPEN "|CPIPE|6":("/nethome/myprog":/ARGS=arg1:/WRITE):10 // no shell, 1 arg, WRITE
OPEN "|CPIPE|7":(/COMMAND="/nethome/myprog":/ARGS=arg1,arg2):10 // no shell, 2 args
OPEN "|CPIPE|8":(/COMMAND="/nethome/myprog":/ARGS=args...:/WRITE):10 // no shell, args array, WRITE
On a Windows system, an argument can include a blank space or a double quote (") character. In these cases, the argument can be quoted, and a literal double quote character can be escaped by doubling it:
OPEN "|CPIPE|9":("/nethome/myprog":/ARGS="string with blanks"):10
OPEN "|CPIPE|10":("/nethome/myprog":/ARGS="string with literal "" character"):10
OPEN Errors
If you issue an OPEN command with the QW parameter for a non-IPC device, a <WRITE> error occurs when you try to write to this device.
The following UNIX® example opens an output pipe to the lp program, whose pathname in this case is /usr/bin/lp. Then it sends output from the global ^TEXT to the printer through this pipe.
print ; Send the first layer of global ^TEXT to the printer.
SET IO="/usr/bin/lp"
OPEN IO:"QW" ; Open the pipe to lp
USE IO WRITE "The first layer of ^TEXT",! ; Print the title
; . . .
; Print each line, using $ORDER on the global ^TEXT
USE IO WRITE !,"The End.",#
CLOSE IO ; close the pipe, spooling the file to lpsched
QUIT
You can alter this example so that the OPEN command passes arguments to the lp program. For example, to specify that lp should send the output to the printer device named laserjet, you could replace the SET command with the following:
SET IO="/usr/bin/lp -dlaserjet"
The following example shows how to read from an external program. Here the process opens an input pipe to the UNIX® program who, so that it can read the IDs of all users who are currently logged in to UNIX®.
getids ; read the login IDs of everybody currently on
SET IO="/usr/bin/who"
SET $ZTRAP="EOT"
KILL LOGINS
OPEN IO:"Q"
; note that "R" (the default) is understood
SET users=0
FOR I=0:0 {
USE IO
READ USER
SET users=users+1
SET LOGINS(USER)=""
}
QUIT
EOT SET $ZTRAP=""
USE 0
WRITE !,USERS," is/are currently logged on.",!
CLOSE IO
QUIT
On a Windows system, when a CPIPE OPEN program argument specifies /COMMAND or /ARGS, the system uses CreateProcess() to run the command. If the CreateProcess() fails, the OPEN will fail with a <NOTOPEN> error. The GetLastError() value is available via $SYSTEM.Process.OSError()Opens in a new tab.
On a UNIX® system, when a CPIPE OPEN program argument specifies /COMMAND or /ARGS, the system creates a new process which issues an exec() to run the command. If the exec() fails, the OPEN will fail with a <NOTOPEN> error. The exec() errno is available via $SYSTEM.Process.OSError()Opens in a new tab.
OPEN and USE Command Keywords
The following list describes the keywords for controlling interprocess communications pipes with both OPEN and USE commands.
Or:
/IOT[=name]
Default: If name is not specified, the default I/O translation table for the device is used.
Corresponds to the K\name\ parameter code, which establishes an I/O translation table for the device.
Or:
/TRA[=n]
Default: 1
Associated with the K parameter code. /TRANSLATE or /TRANSLATE=n for nonzero values of n enable I/O translation for the device. /TRANSLATE=n for a zero value of n disables I/O translation for the device.
Or:
/XYT[=name]
Default: If name is not specified, the default $X/$Y action table for the device is used.
Corresponds to the Y\name\ parameter code, which establishes a $X/$Y action table for the device.
OPEN-only Keywords
The following list describes the keywords for controlling interprocess communications pipes with only the OPEN command.
Specifies environment variables to be set in the new process. There are two ways to specify the values:
-
Explicitly. For example:
/ENV=(name1:value1,name2:value2)
-
Via a multidimensional array. For example:
Set arr(name1)=value1 Set arr(name2)=value2 // then later use the following in the OPEN command: /ENV=arr...
The examples show two environment variables but there can be any number. The explicit list must be enclosed in parentheses.
Or:
/IGN[=n]
Default: 0
Corresponds to the I parameter code, which specifies that a READ operation should be retried (ignoring any EOF condition) indefinitely or until the specified timeout expires. /IGNOREEOF or /IGNOREEOF=n for nonzero values of n enable the parameter code and /IGNOREEOF=n for a zero value of n disables the parameter code.
Or:
/PAR=str
No default.
Corresponds to the parameter codes positional parameter. (It provides a way to specify a parameter code string in a position independent way.)
Or:
/QUE
Default: The device is not recognized as an interprocess communications pipe.
Corresponds to the Q parameter code, which specifies that an interprocess communications pipe should be opened. Note that using this command requires Use permission on the %System_Callout resource.
Default: Read is the default if neither /Read nor /Write is specified.
Corresponds to the R parameter code, which specifies that a queue or pipe should be opened to accept data from another process.
Or:
/WRI
Default: Read is the default if neither /Read nor /Write is specified.
Corresponds to the W parameter code, which specifies that a queue or pipe should be opened to send data to another process.
READ Command for Interprocess Communication
Syntax
READ:pc readargument,...
READ reads data from a pipe.
where readargument can be:
formatting-mode
string
variable:timeout
*variable:timeout
variable#n:timeout
Use the I formatting-mode parameter with pipes. The I parameter lets you issue a timed READ for a named pipe without losing any data that can occur in a partial record that follows an <ENDOFFILE> error. When you use this parameter on a READ, the READ ignores <ENDOFFILE> messages.
The value of the I formatting-mode is off by default. If you include this parameter in a READ command without a timeout, your process hangs until there is data to process.
CPIPE Exit Codes
You can retrieve the exit code of a command pipe (|CPIPE|) process. This exit code must be retrieved before the |CPIPE| device is closed. It is obtained with the PipeExitCodeOpens in a new tab method of the %SYSTEM.ProcessOpens in a new tab class. Exit codes are always integer values. If the exit code is not available, the method returns a null string and sets the status argument with an explanation, as shown in the following example:
SET exitcode=$SYSTEM.Process.PipeExitCode(device, .status)
IF exitcode="" {DO $SYSTEM.OBJ.DisplayError(status)}
ELSE {WRITE "CPIPE exit code is ",exitcode }
On a UNIX® system, an exit code is available only for non-shell commands; that is, CPIPE devices opened with /COMMAND or /ARGS.
CLOSE Command for Interprocess Communication
If you create a child process using OPEN with a Q (/QUEUE) parameter code, the child process may survive a CLOSE operation on the device. Survivability of a queued interprocess communications pipe is platform-dependent. On UNIX® systems the child process always survives the CLOSE. On Windows systems the survival of the process depends upon how old the process is. A child process that has just been initiated does not survive a CLOSE operation, but once a child process is fully established it survives a CLOSE.
On UNIX® systems, you can specify the how long the CLOSE command should wait when closing a piped command device. The timeout default is 30 seconds. You can modify this default by specifying the OPEN command closetimeout positional argument. You can override the default or specified timeout for a CLOSE command by specifying the optional “I” positional argument. The “I” argument specifies immediate close (close after 1 second). The CLOSE syntax is as follows:
CLOSE cpipename:"I"
Using Named Pipes to Communicate with Visual Basic
On Windows, use named pipes in InterSystems IRIS as you would use TCP devices, but use the device name |NPIPE|nnn instead of |TCP|nnn. The OPEN arguments are as follows:
OPEN "|NPIPE|3":(server:pipename)
where server is the machine name, and pipename is the name of the pipe that it is to be connected to.
To connect to a local pipename, use "." (a quoted period) as a server. To create a pipe (as a server), use "" (quotes without content) as the server name. The following are all valid server names:
OPEN "|NPIPE|3":(".":"localpipe")
OPEN "|NPIPE|3":("mother":"test")
OPEN "|NPIPE|3":("":"info")
A server can open a named pipe and immediately issue a write before the client side has opened the same named pipe. The write operation will hang until the client side opens the named pipe. A user can interrupt the hang by issuing a Control-C.
Once open, a pipe acts like an ordinary device. On the server side, clients can be disconnected as in TCP with:
USE "|NPIPE|3":"DISCONNECT"
Alternatively:
USE "|NPIPE|3" WRITE *-2
OPEN Command Keywords
The following list describes the keywords for controlling named pipes with only the OPEN command.
Or:
/HOS=str
Default: The default is "" (empty string) which opens the pipe as a server.
Corresponds to the server positional parameter, which specifies the Windows computer. It is not necessary to specify this keyword when opening the pipe as a server. Use "." (a quoted period) to connect to a local pipename.
Or:
/IBU=n
Default: 2048
Specifies the size of the named pipe input buffer that holds data received from the pipe but not yet delivered to the application.
Or:
/INS=n
Default: 1
Specifies the maximum number of instances allowed for the named pipe. A value greater than 1 allows more than one server to open an instance of the named pipe, so that more than one client at a time can be served.
Or:
/OBU=n
Default: 2048
Specifies the size of the output buffer used by the operating system. This buffer size is advisory, since the operating system sizes the buffer according to system-imposed constraints.
Or:
/PIP=str
No default.
Corresponds to the pipename positional parameter which specifies the name of the pipe.