From: katrin@csd.uu.se (Katrin Boberg)
Newsgroups: comp.unix.wizards
Subject: pty/tty com
Date: 12 Oct 1992 15:09:46 GMT
Organization: /home/groucho/csd/katrin/.organization
Distribution: comp
NNTP-Posting-Host: groucho.csd.uu.se

I have problem to set up a communication with pty/tty:s. 
I find a pty, open the pty and tty. Then I do fork(). In the father 
I close the tty and write in the pty. In the child the pty is closed,
then I call select() and it sucseeds. But I can't read anything.

Do I have to do anything special to 'start' the communication?

				Katrin

----------------------------------------------------------------------
#include <stdio.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/termios.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/ttold.h>

char pos[] = "0123456789abcdef";

get_tty(tname,pname)
    char *tname, *pname;
{
    int i, p, index;
    char c;
    char tline[255];

	for (c = 'p'; c <= 's'; c++) {
		struct stat stb;
		strcpy(tline,"/dev/ptyXX");
		index = strlen("/dev/pty");
		tline[index] = c;
		tline[index+1] = '0';
		if (stat(tline, &stb) < 0)
			break;
		for (i = 0; i < 16; i++) {
			tline[index+1] = pos[i];
			p = open(tline, 2);
			if (p > 0)
				goto gotpty;
		}
	}
	return(0);
 gotpty:                   /* Got a tty pair */
    close(p);
    strcpy(pname,tline);
    strcpy(tname, tline);
    tname[strlen("/dev/")] = 't';
    return(1);
}   /* End of |get_tty| */


main(argc,argv)
    int argc;
    char **argv;
{
  int t_fd, p_fd, childpid;
  int ch;
  char pname[255], tname[255];
  struct termios *tio;
  
  if(get_tty(tname,pname)) {
    fprintf(stderr,"TTY: %s \n",tname);
    p_fd = open(pname,O_RDWR);
    t_fd = open(tname,O_RDWR);
    if(t_fd < 0) {
      close(p_fd);
      perror("Can't open tty.\n");
      exit(2);
    }
  } else {
    perror("Can't find tty.\n");
    exit(2);
  }
  
  if((childpid = fork()) == -1) {
    close(t_fd);
    close(p_fd);
    printf("Can't fork.\n");
    exit(2);
  }

  
  if(childpid) {
    /* parent process */
    FILE *pfile;
    struct termios tio_p;
    int statusp;

    close(t_fd);
    if((pfile = fdopen(p_fd,"r+")) == (FILE *)0) {
      printf("can't open %s for writing.\n",pname);
      close(p_fd);
      exit(1);
    }
    ioctl(p_fd, TCGETS, &tio_p);
    tio_p.c_iflag |= IGNCR | ICRNL;
    ioctl(p_fd, TCSETS, &tio_p);
    ioctl(p_fd,TIOCSTART,NULL);
    
    fputs("Note from parent via pty.",pfile);
    fputs("\n",pfile);
    fflush(pfile);

    (void) wait(&statusp); 
    fclose(pfile);
    close(p_fd);

  } else {
    /* childprocess */
    FILE *tfile;
    char *in, ch;
    fd_set mask, mmask;
    struct timeval time;
    int width;


    close(p_fd);
    if((tfile = fdopen(t_fd,"r+")) == (FILE *)0) {
      printf("can't open %s for writing.\n",tname);
      close(t_fd);
      exit(1);
    }
    ioctl(t_fd,TIOCSTART,NULL);

    time.tv_sec = 5;
    time.tv_usec = 0;
    FD_ZERO(&mmask);
    FD_SET(fileno(tfile),&mmask);

    mask = mmask;
    
    width = ulimit(t_fd,width);
    if(select(width,&mask,NULL,NULL,time) < 0) {
      perror("Couldn't detect anyting on readstream.\n");
      exit(3);
    }
    if(FD_ISSET(t_fd,&mask)) {
      ch = fgetc(in);
      while(ch != '\n') {
	ch = fgetc(in);
	fprintf(stderr,"recieved %d\n",ch);
	printf("reading %d\n",ch);
	fflush(stdout);
      }
    } 
    
    fclose(tfile);
    close(t_fd);

  } 
}