scott@talarian.UUCP (Scott Weitzenkamp) (10/03/89)
Late last week, I posted a query on how to to emulate Unix-domain sockets and select(2) using vanilla AT&T System V/386 3.2. I said that poll(2) had a timeout granularity of seconds (it is really milliseconds). ---------------------------------------------------------------------- Guy Harris (auspex!guy) confirmed my fears: tty's, pipes, and named pipes are not STREAMS devices in the version from AT&T. ---------------------------------------------------------------------- Doug McCallum (ico.isc.com!dougm) said that STREAMS devices are my best bet. The undocumented /dev/spx is "probably the only STREAMS device you have if you don't have a network package added". Does vanilla System V/386 3.2 provide *ANY* mechanism that I can use to emulate Unix domain sockets and select(2)? I am writing a server Nope. Most vendors probably leave /dev/spx in though. Streams is the only mechanism that has a select like feature in a generic 3.2. Worst case would be to write a simple spx like driver. The System V function poll(2) looks like it would make a nice substitute for select(2), even though the timeout granularity is in seconds instead of microseconds. I'd willing to take what I can get. timeout granularity is not in seconds, it is in milliseconds rounded up to the hardware granularity. On 386 base 3.2, this is 100HZ, not 1 second. However, what STREAMS devices do I have at my disposal? Are stdin, stderr, and stdout STREAMS devices? Are pipes STREAMS devices? What about named pipes? Not much. stdin/out/err are not streams devices and pipes are not either. If /dev/spx is there it is probably the only Streams device you have if you don't have a network package added. I've seem mention in this newsgroup of the undocumented device /dev/spx, which is a "stream pipe", but it seems that /dev/spx comes with RFS, and I do not have RFS installed (I *WILL* install it if someone can show me how to use /dev/spx to emulate sockets). As I said, many vendors include spx. ISC does in 386/ix. You can't quite emulate sockets, but you can get enough to make many things work. Any of the samples posted in the past week or so would do to get you going. I will include my sample below. If your server is priviledged, you can open /dev/spx, do an fstat on it to find out the major/minor device number and then "mknod" the file name you want to use as the rendezvous point. The clients would open /dev/spx to get two new endpoints, link them together and then open the server's stream pipe and send one end of the connected pair to the server. The server then uses the new file descriptor to talk to the client. The client closes the end that was sent to the server and now has a bidirectional stream to communicate over. I already know about the standard System V IPC mechanisms: message queues, semaphores, and shared memory. These won't do: I want a file descriptor. Am I going to have to break down and buy an Ethernet card and Lachman TCP/IP ? :-( :-( You shouldn't have to. Also, there are other packages available that could do what you want. There are other TCP/IP, some OSI and AT&T Starlan. Lachman is now part of ISC so I am not being negative about the product, just that you might not need it. A rough outline of how to write the socket emulation: socket open /dev/spx connect open /dev/spx connect new spx to the one handed in as the connect fd open <server spx filename> send one end of connected pair to server close that file descriptor close server file descriptor accept use I_GETFD to read a new file descriptor sent by a client return that fd bind create the file with mknod after determining the major/minor device number (only works for priviledged process) With a little bit of work, you can come very close. Hope this is of some help, Doug McCallum Interactive Systems Corp dougm@ico.isc.com ----------------sample /dev/spx program------------------- /* * 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. 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"); } ---------------------------------------------------------------------- John Redden (ttidca.TTI.COM!redden) writes: I would also be very interested in the results of you poll, so if you don't post them to the net please send them to me. One fellow that works here took the public domain internet code and ported it into the SysV.3 kernel in about two weeks. He used the file system switch among other things to implement unix domain sockets. If you want to send him questions his name is Michael Bloom and his domain name address is mb@<the same as mine at TTI>. Anyway, the reason I am interested in poll system call for streams is that we already have a very robust logging system based on streams and I want to add the syslog library call supported under BSD. It currently uses unix domain sockets and I want a single logging system using streams. But I have to make sure that poll is robust enough to replace select. John Redden Unix systems development Citicorp TTI (213) 450-9111 ---------------------------------------------------------------------- Scott Weitzenkamp, Talarian Corporation, Mountain View, CA uunet!talarian!scott scott@talarian.uu.net (415) 941-9417 "Welcome to the late show, starring NULL and void" -- Men At Work Mail responses, and I'll summarize to the net. -- Scott Weitzenkamp, Talarian Corporation, Mountain View, CA uunet!talarian!scott scott@talarian.uu.net (415) 941-9417 "Welcome to the late show, starring NULL and void" -- Men At Work Mail responses, and I'll summarize to the net.