The I_LIST call with arg pointing
to the str_list structure returns the number of entries
that have been filled into the sl_modlist array (the number
represents the number of modules including the driver). If there is not enough
space in the sl_modlist array or sl_nmods
is less than 1, the I_LIST call fails and errno is set to EINVAL. If arg
or the sl_modlist array points outside the allocated address
space, EFAULT is returned.
Example 4-1 I_LIST ioctl
#include <stdio.h>
#include <string.h>
#include <stropts.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/socket.h>
main(int argc, const char **argv)
{
int s, i;
unsigned int mods;
struct str_list mod_list;struct str_mlist *mlist;
/* Get a socket... */
if ((s = socket(AF_INET, SOCK_STREAM, 0)) <= 0) {
perror("socket: ");
exit(1);
}
/* Determine the number of modules in the stream */
if ((mods = ioctl(s, I_LIST, 0)) < 0) {
perror("I_LIST ioctl");
}
if (mods == 0) {
printf("No modules\n");
exit(1);
} else {
printf("%d modules\n", mods);
}
/* Allocate memory for all of the module names */
mlist = (struct str_mlist *)
calloc(mods, sizeof (struct str_mlist));
if (mlist == 0) {
perror("malloc failure");
exit(1);
}
mod_list.sl_modlist = mlist;
mod_list.sl_nmods = mods;
/* Do the ioctl and get the module names... */
if (ioctl(s, I_LIST, &mod_list) < 0) {
exit(1);
}
/* Print out the name of the modules... */
for (i = 0; i < mods; i++) {
printf("s: %s\n", mod_list.sl_modlist[i].l_name);
}
/* Free the calloc'd structures... */
free(mlist);
return(0);
}
|
Other ioctl Commands
streamio(7I)
details the ioctl(2) commands shown in Table 4-2.
Table 4-2 Other ioctl Commands
ioctl Calls | Description |
I_ANCHOR | Prevents the removal of a STREAMS module with an I_POP call. Any process can place an anchor on a stream, but once
placed, an anchor can only be removed by a privileged process. |
I_LOOK | Retrieves the name of the module just below the stream
head |
I_FLUSH | Flushes all input or output queues |
I_FLUSHBAND | Flushes a band of messages |
I_FIND | Compares the names of all modules present in the stream
to a specific name |
I_PEEK | Enables the user to look at information in the
first message on the stream head read queue without taking the message off
the queue |
I_SRDOPT | Sets the read mode using a series of flag options in the
argument |
I_GRDOPT | Indicates the read mode in an int |
I_NREAD | Counts the data bytes in data blocks in the first message
on the stream head read queue |
I_FDINSERT | Creates a message from a user buffer,
adds information about another stream, and sends the message downstream |
I_SWROPT | Sets the write mode using the value of the argument |
I_GWROPT | Returns the current write mode setting |
I_SENDFD | Requests that the stream send a message with file pointer
to the stream head at the other end of a STREAMS pipe |
I_RECVFD | Retrieves the file descriptor of the message sent by an I_SENDFD ioctl(2)
over a STREAMS pipe |
I_ATMARK | Lets the application see if the current message on the stream
head read queue is marked by a module downstream |
I_CKBAND | Checks if the message of a given priority band exists on
the stream head read queue |
I_GETBAND | Returns the priority band of the first message on the stream
head read queue |
I_CANPUT | Checks if a certain band is writable |
I_SETCLTIME | Enables the user to set the time the
stream head will delay when a stream is closing if data exists on the write
queues |
I_GETCLTIME | Returns the close time delay |
I_LINK | Connects two streams |
I_UNLINK | Disconnects two streams |
I_PLINK | Connects two streams with a persistent link below a multiplexing
driver |
I_PUNLINK | Disconnects two streams that have been connected with a
persistent link |
Message Direction
Various system calls let the user create messages and send
them downstream and prioritize the messages.
Table 4-3 Send and Receive Messages
putmsg(2) | Creates
a message from the caller supplied control and data buffers and
sends the message downstream |
putpmsg(2) | Does the same as putmsg(2)
and enables the caller to specify a priority band for the message |
getmsg(2) | Retrieves M_DATA, M_PROTO, or M_PCPROTO
or high priority messages from the stream head, and places the contents
into two user buffers |
getpmsg(2) | Does
the same as getmsg(2) and enables the caller to specify a priority band for the message |
The stream head guarantees that the control part of a message generated
by putmsg(2)
is at least 64 bytes long. This promotes reusability of the buffer. When the
buffer is a reasonable size, modules and drivers may reuse the buffer for
other headers.
stropts.h contains the specification of strbuf, which describes
the control and data buffers.
Flush Handling
All modules and drivers are expected to handle the flushing of messages.
The user may cause data to be flushed of queued messages from a stream by the submission of an I_FLUSH ioctl(2). Data
may be flushed from the read side, write side, or both sides of a stream.
ioctl (fd, I_FLUSH, arg);
|
Table 4-4 describes the arguments that may be passed to M_FLUSH.
Table 4-4 M_FLUSH Arguments and bi_flag
values
Flag | Description |
FLUSHR | Flushes read
side of stream |
FLUSHW | Flushes write
queue |
FLUSHRW | Flushes both read
and write queues |
In addition to being able to flush all
the data from a queue, a specific band may be flushed
using the I_FLUSHBAND ioctl(2).
ioctl (fd, I_FLUSHBAND, bandp);
|
The ioctl(2)
is passed a pointer to a bandinfo structure. The bi_pri field indicates the band priority to be flushed (values from
0 to 255). The bi_flag field indicates the type of flush
to do. The legal values for bi_flag are defined in Table 4-4. bandinfo has the following format:
struct bandinfo {
unsigned char bi_pri;
int bi_flag;
};
|
See "Flushing Priority Band", which describes M_FLUSHBAND processing, for details on how modules and drivers should handle
flush band requests.