|
|
Some applications may want to associate a Stream or STREAMS-based pipe with an existing node in the file system name space. For example, a server process may create a pipe, name one end of the pipe, and allow unrelated processes to communicate with it over that named end.
A STREAMS file descriptor can be named by attaching that file descriptor to a node in the file system name space. The routine fattach (see also fattach(S)) is used to name a STREAMS file descriptor. fattach(S). Its format is
int fattach (int fildes, char *path)where fildes is an open file descriptor that refers to either a STREAMS-based pipe or a STREAMS device driver (or a pseudo device driver), and path is an existing node in the file system name space (for example, regular file, directory, character special file, and so forth).
The path cannot have a Stream already attached to it. It cannot be a mount point for a file system nor the root of a file system. A user must be an owner of the path with write permission or a user with the appropriate privileges to attach the file descriptor.
If the path is in use when the routine fattach is executed, those processes accessing the path are not interrupted and any data associated with the path before the call to the fattach routine will continue to be accessible by those processes.
After a Stream is named, all subsequent operations (for example, open(S)) on the path operate on the named Stream. Thus, it is possible that a user process has one file descriptor pointing to the data originally associated with the path and another file descriptor pointing to a named Stream.
Once the Stream has been named, the stat system call on path shows information for the Stream. If the named Stream is a pipe, the stat(S) information shows that path is a pipe. If the Stream is a device driver or a pseudo-device driver, path appears as a device. The initial modes, permissions, and ownership of the named Stream are taken from the attributes of the path. The user can issue the system calls chmod and chown to alter the attributes of the named Stream and not affect the original attributes of the path, nor the original attributes of the STREAMS file.
The size represented in the stat information reflects the number of unread bytes of data currently at the Stream head. This size is not necessarily the number of bytes written to the Stream.
A STREAMS-based file descriptor can be attached to many different paths at the same time (that is, a Stream can have many names attached to it). The modes, ownership, and permissions of these paths may vary, but operations on any of these paths access the same Stream.
Named Streams can have modules pushed on them, be polled, be passed as file descriptors, and be used for any other STREAMS operation.
A named Stream can be disassociated from a file with the fdetach routine (see also fdetach(S)), which has the following format:
int fdetach (char *path)where path is the name of the previously named Stream. Only the owner of path or the user with the appropriate privileges may disassociate the Stream from its name. The Stream may be disassociated from its name while processes are accessing it. If these processes have the named Stream open at the time of the fdetach call, the processes do not get an error, and continue to access the Stream. However, after the disassociation, later operations on path access the underlying file rather than the named Stream.
If only one end of the pipe is named, the last close of the other end causes the named end to be automatically detached. If the named Stream is a device and not a pipe, the last close does not cause the Stream to be detached.
If there is no named Stream or the user does not have access permissions on path or on the named Stream, fdetach returns -1 with errno set to EINVAL. Otherwise, fdetach returns 0 for success.
A Stream remains attached with or without an active server process. If a server aborted, the only way a named Stream is cleaned up is if the server executed a clean up routine that explicitly detached and closed down the Stream.
If the named Stream is that of a pipe with only one end attached, clean up occurs automatically. The named end of the pipe is forced to be detached when the other end closes down. If there are no other references after the pipe is detached, the Stream is deallocated and cleaned up. Thus, a forced detach of a pipe end occurs when the server is aborted.
If both ends of the pipe are named, the pipe remains attached even after all processes have exited. In order for the pipe to become detached, a server process has to explicitly invoke a program that executes the fdetach routine.
To eliminate the need for the server process to invoke the program, the fdetach(ADM) command can be used. This command accepts a pathname that is a path to a named Stream. When the command is invoked, the Stream is detached from the path. If the name is the only reference to the Stream, the Stream is also deallocated.
A user invoking the fdetach(ADM) command must be an owner of the named Stream or a user with the appropriate permissions.
The function isastream (see also isastream(S)) may be used to determine if a file descriptor is associated with a STREAMS device. Its format is
int isastream (int fildes)where fildes refers to an open file. isastream returns 1 if fildes represents a STREAMS file, and 0 if not. On failure, isastream returns -1 with errno set to EBADF.
This function is useful for client processes communicating with a server process over a named Stream to check whether the file has been overlaid by a Stream before sending any data over the file.
Named Streams are useful for passing file descriptors between unrelated processes. A user process can send a file descriptor to another process by invoking the ioctl I_SENDFD on one end of a named Stream. This sends a message containing a file pointer to the Stream head at the other end of the pipe. Another process can retrieve that message containing the file pointer by invoking the ioctl I_RECVFD on the other end of the pipe.