Weblog

All | CMT | General | NUMA | OpenSolaris | Perl | Photo | Programmers Desk | STREAMS
« Open Solaris is Good... | Main | Putnext and stack... »
20050527 Friday May 27, 2005

Playing with STREAMS module from the User-Land

Playing with STREAMS module from the User-Land

In my previous STREAMS blog entry, we discussed, how to construct a do-nothing STREAMS module. Now we will come back to the user-land and see how we can play with STREAMS modules. We will learn, how to

Show me the STREAM

Suppose that you have an open file descriptor fd and would like to know what STREAMS modules and drivers live behind the scene in the kernel in the STREAM representing the file.

The article by Rajesh Ramchandani on the Sun Developer Network provides an excellent example with the full source code of the printmod() function. It uses the I_LIST> ioctl which returns a list of modules in the struct str_mlist structure.

Please add my module

The next thing we are going to try is pushing our new module onto the STREAM. The following simple function should do the trick:

int pushmod(int fd, char *modname)
{
	int rc;

	if ((rc = ioctl(fd, I_PUSH, modname)) < 0) {
		perror("I_PUSH");
		fprintf(stderr, "pushmod(%d, %s) failed\n", fd, modname);
	}
	return rc;
}

The function takes a file descriptor and the module name and pushes the module on top of the stream. It returns 0 on success and -1 on failure. We can extend it a bit to put a whole list of modules. Suppose that the module list is a string with commas separating module names:

/* Push list of modules separated by commas */
int pushlist(int fd, char *s)
{
	char *comma = strchr(s, ',');
	int rc = 0;

	if (comma == NULL)
		return (pushmod(fd, s));

	*comma = '\0';

	if (((rc = pushmod(fd, s)) >= 0) && *(comma+1) != '\0') {
		*comma = ',';
		rc = pushlist(fd, comma + 1);
	}

	return (rc);
}

The following example demonstrates how it can be used in practice:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stropts.h>
#include <strings.h>

void main(int argc, char *argv[])
{
	if (argc == 1)
		return;

	if (pushlist(0, argv[1]) < 0)
		exit(1);
	exit(0);
}

We can name this program as pushmod.c and try it (assuming that you have installed the nullmodmodule from the previous example:


 $ cc pushmod.c -o pushmod
 $ strconf
 ttcompat
 ldterm
 ptem
 pts
 $ ./pushmod nullmod,nullmod,nullmod
 nullmod
 nullmod
 nullmod
 ttcompat
 ldterm
 ptem
 pts

I don't want to see you any more!

Finally, you may remove the module from the top of the stream using a simple call


  if ((rc = ioctl(fd1, I_POP, 0)) < 0) {
  	perror("I_POP");

Conclusions.

Now you know how to manipulate the content of the STREAM. You may want to play with it a bit and see what happens if you insert and remove some interesting modules.

NOTE: It is quite likely that your terminal window will become unusable as a result of your experiments. Many modules assume certain context and the are designed to play in concert with others, so your terminal may misbehave if it is incorrectly configured.


Technorati Tag: OpenSolaris
Technorati Tag: Solaris

( May 27 2005, 07:53:08 PM PDT ) Permalink Comments [0]

Trackback URL: http://blogs.sun.com/akolb/entry/playing_with_streams_module_from
Comments:

Post a Comment:

Name:
E-Mail:
URL:

Your Comment:

HTML Syntax: NOT allowed

Calendar

RSS Feeds

Search

Links

Navigation

Referers