pcg@aber-cs.UUCP (Piercarlo Grandi) (02/02/90)
I have received some request some time ago for an idea of how to use the /dev/ptmx device. /dev/ptmx is a multiplexor named pipe device; you configure a number of ptm devices, each of which has two ends, to which two programs can be attached. When you open /dev/ptmx (a clone device) you get a fd to one of them; another program can then communicate with you by opening the other side. You can either have a single program that opens /dev/ptmx and serves any program that opens one of the other sides (/dev/ptsXXX), or viceversa, the server opens all the /dev/ptsXXX sides and whenever a client wants to communicate it opens /dev/ptmx and gets a master side. Applications are named pipes, and pseudo ttys; the latter happen when you push the line discipline module "ldterm" onto the slave side. There is a virtually undocumented library, /usr/lib/libpt.a, that deals with such entities. I believe that it is essentially the code below. As usual, this example is provided as is, with no warranties, etc..., and is no way related to any activity of my employer, that I thank for the permission to use News. This snippet of code is also not copyrighted at all. Too small for it to make sense. ------8<-------------------------8<------------------------------------------- #include <sys/types.h> #include <sys/stat.h> #include <sys/fcntl.h> #include <sys/stream.h> #include <sys/ptms.h> int main() { int ptm,pts; struct stat st; int u; char buf[128]; /* /dev/ptmx is a clone device that will select a free /dev/ptmXXX device and return a file descriptor to it (note that /dev/ptmXXX files do not actually exist, even if they could well be created). */ if ((ptm = open("/dev/ptmx",O_RDWR|O_NDELAY)) == 0) { perror("opening /dev/ptmx"); return 1; } /* Now ptm contains a file descriptor to the master side of a /dev/ptmXXX /dev/ptsXXX pair. */ if (fstat(ptm,&st) < 0) { perror("stat'ing /dev/ptmx"); return 1; } printf("ptm major %u, minor %u\n",st.st_rdev>>8,st.st_rdev&0xff); /* We unlock the slave side, otherwise only us or our children will be able to open it. */ if (ioctl(ptm,UNLKPT,buf) < 0) { perror("unlocking ptm"); close(ptm); return 1; } /* We open the /dev/ptsXXX device with the same XXX as the /dev/ptmXXX device we got from cloning /dev/ptmx */ sprintf(buf,"/dev/pts%03u",st.st_rdev&0xff); if ((pts = open(buf,O_RDWR|O_NDELAY)) == 0) { perror("opening pts"); return 1; } if (fstat(ptm,&st) < 0) { perror("stat'ing pts"); return 1; } printf("pts major %u, minor %u\n",st.st_rdev>>8,st.st_rdev&0xff); /* Here we have a child write a test string into the /dev/ptsXXX stream; we will read it from the /dev/ptmXXX master and print it. */ if (fork()) close(pts); else { close(ptm); strcpy(buf,"PTS side working!!!!\n"); write(pts,buf,strlen(buf)); close(pts); } while ((u = read(ptm,buf,sizeof buf)) != -3) if (u <= 0) sleep(1); else write(1,buf,u); close(ptm); return 0; } ------8<-------------------------8<------------------------------------------- -- Piercarlo "Peter" Grandi | ARPA: pcg%cs.aber.ac.uk@nsfnet-relay.ac.uk Dept of CS, UCW Aberystwyth | UUCP: ...!mcvax!ukc!aber-cs!pcg Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@cs.aber.ac.uk
jgd@rsiatl.UUCP (John G. De Armond) (02/02/90)
pcg@aber-cs.UUCP (Piercarlo Grandi) writes: >I have received some request some time ago for an idea of how >to use the /dev/ptmx device. >There is a virtually undocumented library, /usr/lib/libpt.a, >that deals with such entities. I believe that it is essentially >the code below. Thanks a bunch for the code. could you point us toward whatever documentation is available on the pty library? Much appreciated. John -- John De Armond, WD4OQC | We can no more blame our loss of freedom on congress- Radiation Systems, Inc. | men than we can prostitution on pimps. Both simply Atlanta, Ga | provide broker services for their customers. emory!rsiatl!jgd | - Dr. W Williams | **I am the NRA**