The server process creates a named pipe by using DosCreateNPipe.
To create a named pipe, specify on the DosCreateNPipe function:
DosCreateNPipe returns a pipe handle that can be used in subsequent pipe operations.
Each named pipe must have a unique name of the following form:
\PIPE\PipeName
The "\PIPE\" in the name above is required, but need not be uppercase. It is not the name of a subdirectory.
To open a pipe on a remote computer, the client process must specify the name of the server process that opened the pipe as part of the pipe name, as follows:
\\Server\PIPE\PipeName
"\\Server" in the name above is the name of the remote computer; again, "\PIPE\" is required.
The name parameter must conform to the rules for OS/2 file names, but no actual file is created for the pipe.
Named pipes created with certain access modes prevent the named pipes' clients from using certain functions. If the named pipe is created with access mode NP_ACCESS_INBOUND, the named pipe's client cannot use these functions:
If the named pipe is created with access mode NP_ACCESS_OUTBOUND, the named pipe's client cannot use these functions:
If the named pipe's client uses an incorrect function, the function returns error code 5 (ERROR_ACCESS_DENIED).
In the following code fragment, DosCreateNPipe creates a pipe named \pipe\pipe1 and supplies a unique handle identifying the pipe. OpenMode is set to NP_ACCESS_DUPLEX. This activates full duplex access to the named pipe. There will be no inheritance to child process, and no write-through (write-through only affects remote pipes). PipeMode is set to "NP_WMESG | NP_RMESG | 0x01". This specifies that the pipe should be read as a message stream for both reading and writing and an instance count of 1 (only one instance of the named pipe can be created at a time). The pipe will block on Read/Write if no data is available.
#define INCL_DOSNMPIPES /* Named-pipe values */ #include <os2.h> #include <stdio.h> UCHAR ucFileName[40]; /* Pipe name */ HPIPE hpPipeHandle; /* Pipe handle (returned) */ ULONG ulOpenMode; /* Open-mode parameters */ ULONG ulPipeMode; /* Pipe-mode parameters */ ULONG ulOutBufSize; /* Size of the out-buffer */ ULONG ulInBufSize; /* Size of the in-buffer */ ULONG ulTimeOut; /* Default value for */ /* DosWaitNPipe time-out */ /* parameter */ APIRET ulrc; /* Return code */ strcpy(ucFileName, "\\PIPE\\PIPE1"); ulOpenMode = NP_ACCESS_DUPLEX; /* Full duplex, no inheritance, */ /* no write-through */ ulPipeMode = NP_WMESG | NP_RMESG | 0x01; /* Block on read and write, message */ /* stream, instance count of 1 */ ulOutBufSize = 4096; /* The outgoing buffer must be 4KB in size */ ulInBufSize = 2048; /* The incoming buffer must be 2KB in size */ ulTimeOut = 10000; /* Time-out is 10 seconds (units are in milliseconds) */ ulrc = DosCreateNPipe(ucFileName, &hpPipeHandle, ulOpenMode, ulPipeMode, ulOutBufSize, ulInBufSize, ulTimeOut); if (ulrc != 0) { printf("DosCreateNPipe error: return code = %ld", ulrc); return; }
Once the named pipe is created, the application can call DosConnectNPipe to connect a client process to the pipe.
Once a client process connects to the pipe, the process can read from and write to the pipe. The preceding example creates a byte pipe, so the process can use DosRead and DosWrite to read from and write to the pipe.
After the client process finishes using the pipe, the server process can disconnect the pipe by using DosDisConnectNPipe. The server process can either connect again or close the named pipe by using DosClose.
When a server process creates a named pipe, it defines the pipe to the system by specifying the file write-through mode, the inheritance mode, the access and blocking modes, the pipe type, the read mode, the size of the in and out buffers, and the instance count. The following list describes these modes, types, and buffers.
Note: The terms "byte pipe" and "message pipe" always refer to the pipe type-the form in which data is written to the pipe. When the read mode of a pipe is being referred to, it is always explicitly identified as either message-read mode or byte-read mode.
Creating Multiple Instances of a Named Pipe Although each named pipe must have a unique name, a server process can create multiple instances of a pipe, all of which have the same name. A pipe instance is actually a separate pipe-that is, a unique set of pipe buffers with unique handles.
The ability to create multiple pipe instances enables the server to communicate with multiple client processes at the same time. Because a client process uses only the name of the pipe when opening it, the existence of multiple pipe instances is transparent to a client process.
The ICount parameter of DosCreateNPipe specifies the maximum number of named pipe instances that can be created. (An unlimited number can also be specified.) This parameter is specified only when the first instance of a named pipe is created; any subsequent attempt to redefine the instance count will be ignored.
If the instance count is greater than 1, the server process can create additional pipe instances by specifying the same pipe name in subsequent calls to DosCreateNPipe. Generally, the attributes of the subsequent pipe instances are defined to be the same as those of the original pipe instance, because a client process that requests the pipe has no way of controlling which pipe instance will be assigned to it.
After an additional pipe instance has been created, it is used in the same manner as the original pipe instance. That is, the same sequence of named pipe functions is used in the control or management of all named pipe instances. (See Steps in Managing Server-Client Transactions for more information.)
Note: If all of the instances of a named pipe are in use when a client calls DosOpen, ERROR_PIPE_BUSY is returned. However, the client can wait for an instance of that pipe to become available by calling DosWaitNPipe.
Multiple instances of a named pipe can be created by different processes. That is, multiple server processes can create and use instances of the same named pipe to communicate with their clients.