With I_LINK and I_UNLINK ioctls, the file descriptor associated with the Stream above the multiplexor used to set up the lower multiplexor connections must remain open for the duration of the configuration. Closing the file descriptor associated with the controlling Stream dismantles the whole multiplexing configuration. Some applications may not want to keep a process running merely to hold the multiplexor configuration together. Therefore, ``free-standing'' links below a multiplexor are needed. A persistent link is such a link. It is similar to a STREAMS multiplexor link, except that a process is not needed to hold the links together. After the multiplexor has been set up, the process may close all file descriptors and exit, and the multiplexor remains intact.
Two ioctls, I_PLINK and I_PUNLINK, are used to create and remove persistent links that are associated with the Stream above the multiplexor. close and I_UNLINK are not able to disconnect the persistent links.
The format of I_PLINK is
ioctl(fd0, I_PLINK, fd1)
The first file descriptor, fd0, must reference the Stream connected to the multiplexing driver and the second file descriptor, fd1, must reference the Stream to be connected below the multiplexor. The persistent link can be created in the following way:
upper_stream_fd = open("/dev/mux", O_RDWR); lower_stream_fd = open("/dev/driver", O_RDWR); muxid = ioctl(upper_stream_fd, I_PLINK, lower_stream_fd); /* * save muxid in a file */ exit(0);
``open of MUXdriver and Driver1'' shows how open establishes a Stream between the device and the Stream head.
open of MUXdriver and Driver1
The persistent link can still exist even if the file descriptor associated with the upper Stream to the multiplexing driver is closed. The I_PLINK ioctl returns an integer value, muxid, that can be used for dismantling the multiplexing configuration. If the process that created the persistent link still exists, it may pass the muxid value to some other process to dismantle the link, if the dismantling is desired, or it can leave the muxid value in a file so that other processes may find it later. ``Multiplexor after I_PLINK'' shows a multiplexor after I_PLINK.
Multiplexor after I_PLINK
Several users can open the MUXdriver and send data to Driver1 since the persistent link to Driver1 remains intact. This is shown in ``Other users opening a MUXdriver''.
Other users opening a MUXdriver
The I_PUNLINK ioctl is used for dismantling the persistent link. Its format is
ioctl(fd0, I_PUNLINK, muxid)
where the fd0 is the file descriptor associated with Stream connected to the multiplexing driver from above. The muxid is returned by the I_PLINK ioctl for the Stream that was connected below the multiplexor. The I_PUNLINK removes the persistent link between the multiplexor referenced by the fd0 and the Stream to the driver designated by the muxid. Each of the bottom persistent links can be disconnected individually. An I_PUNLINK ioctl with the muxid value of MUXID_ALL removes all persistent links below the multiplexing driver referenced by fd0.
The following dismantles the previously given configuration:
fd = open("/dev/mux", O_RDWR); /* * retrieve muxid from the file */ ioctl(fd, I_PUNLINK, muxid); exit(0);
The use of the ioctls I_PLINK and I_PUNLINK should not be intermixed with I_LINK and I_UNLINK. Any attempt to unlink a regular link with I_PUNLINK or to unlink a persistent link with I_UNLINK ioctl causes the errno value of EINVAL to be returned.
Because multilevel multiplexing configurations are allowed in STREAMS, it is possible to have a situation where persistent links exist below a multiplexor whose Stream is connected to the above multiplexor by regular links. Closing the file descriptor associated with the controlling Stream removes the regular link but not the persistent links below it. On the other hand, regular links are allowed to exist below a multiplexor whose Stream is connected to the above multiplexor with persistent links. In this case, the regular links are removed if the persistent link above is removed and no other references to the lower Streams exist.
The construction of cycles is not allowed when creating links. A cycle could be constructed by creating a persistent link of multiplexor 2 below multiplexor 1 and then closing the controlling file descriptor associated with the multiplexor 2 and reopening it again and then linking the multiplexor 1 below the multiplexor 2, but this is not allowed. The operating system prevents a multiplexor configuration from containing a cycle to ensure that messages cannot be routed infinitely, thus creating an infinite loop or overflowing the kernel stack.