how to create stream pipe (S5R3) ?

Doug McCallum dougm at ico.ISC.COM
Thu Jan 12 12:43:43 AEST 1989


In article <244 at hsi86.hsi.UUCP> stevens at hsi.UUCP (Richard Stevens) writes:
>I'm trying to figure out how to create a "stream pipe" with System 5,
>Release 3.2 (386 version).  The streamio(7) man page says the only
>way to pass a file descriptor is using these, but I can't find
>any reference as to how a stream pipe is created.  In Steve

I don't believe there is any "clear" documentation on using them since
the streams pipe is sort of a kludge to get RFS started.  I say kludge
because spx violates most STREAMS conventions and has problems if you
attempt to push a module on it.  You also need to be running as root
to do things unless you get prearranged dev entries.  (this is based
on V.3.0 not 3.2)

Quick summary is that you open /dev/spx twice, connect the two
streams, create a device file for one of them (using the major/minor
found via fstat) and close the one that you want others to connect on.

Hope this is of some help,
Doug McCallum
Interactive Systems Corp.
dougm at ico.isc.com


The following is a quick-and-dirty program to show the mechanism of
setting one up.
---------------------------------------------------------------------
/*
 * spdemo
 *	This program gets a pair of "streams pipe" file descriptors from
 * 	the clone open of "/dev/spx".  It then finds the major/minor
 *	number of the second descriptor, creates the special device file
 *	"/tmp/sp_server", links the two "pipes" together and then waits in
 *	a "getmsg" on the first file descriptor which will block until
 *	something gets written on the sp_server file.  A simple test is to
 *	run the following command:
 *		date >/tmp/sp_server
 *	from another terminal.  spdemo will print the date out.  Almost
 *	any streams operation may be performed, however.
 */

#include <stdio.h>
#include <sys/types.h>
#include <sys/stream.h>
#include <stropts.h>
#include <sys/stat.h>
#include <sys/fcntl.h>

main()
{
  queue_t *dummy;
  int fd, fd2;

  struct stat statbuf;

  struct strbuf b1, b2;
  struct strfdinsert ins;

  char buff1[1024], buff2[1024];
  int opts = 0;

  fd = open("/dev/spx", O_RDWR);
  if (fd<0){
	perror("open");
	exit(1);
  }
  fd2 = open("/dev/spx", O_RDWR);
  if (fd2<0){
	perror("open");
	exit(1);
  }
  ins.databuf.maxlen = ins.databuf.len = -1;
  ins.databuf.buf = NULL;
  ins.ctlbuf.maxlen = ins.ctlbuf.len = sizeof(queue_t *);
  ins.ctlbuf.buf = &dummy;
  ins.offset = 0;
  ins.fildes = fd;
  ins.flags = 0;
  if (ioctl(fd2, I_FDINSERT, &ins)<0){
	perror("I_FDINSERT");
	exit(2);
  }

  if(fstat(fd2, &statbuf)<0){
	perror("fstat");
	exit(3);
  }
  if (mknod("/tmp/sp_server", S_IFCHR|0666, statbuf.st_rdev)<0){
	perror("mknod");
	exit(4);
  }

  b1.maxlen = sizeof buff1;
  b1.len = 0;
  b1.buf = buff1;

  b2.maxlen = sizeof buff2;
  b2.len = 0;
  b2.buf = buff2;

  if (getmsg(fd, &b1, &b2, &opts)<0){
	perror("getmsg");
  } else {
	if (b1.len > 0){
	    printf("control\n");
	}
	if (b2.len > 0){
	    printf("data: [%s]\n", buff2);
	}
  }
  unlink("/tmp/sp_server");
}



More information about the Comp.unix.wizards mailing list