summaryrefslogtreecommitdiff
path: root/share/hackvr/examples/hackvr_term/pty.c
blob: 6903bc3809772e9d99537b21b310c94a1a7627b6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#define _XOPEN_SOURCE 500 //ptsname
#define _XOPEN_SOURCE_EXTENDED
#include <stdio.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

int main(int argc,char *argv[]) {
  char *pts;
  char in;//I dunno.
  int r;
  int pid;
  int eof1,eof2;
  int master,slave;
  master=open("/dev/ptmx",O_RDWR);
  if(master == -1) return 1;
  pts=ptsname(master);
//  printf("%s\n",pts);
//  system("ls -l /dev/pts/*");
  grantpt(master);
  unlockpt(master);
//  system("ls -l /dev/pts/*");
  if(pts == NULL) return 2;
  slave=open(pts,O_RDWR);
  if(slave == -1) {
   perror("open");
   return 3;
  }
  argv++;
  fcntl(master,F_SETFL,O_NONBLOCK);
//  fcntl(slave,F_SETFL,O_NONBLOCK);
  fcntl(0,F_SETFL,O_NONBLOCK);
  fcntl(1,F_SETFL,O_NONBLOCK);
  fcntl(2,F_SETFL,O_NONBLOCK);
  switch(pid=fork()) {
    case -1:
      return 4;//fork failed
    case 0://child
      setsid();
      close(master);
      dup2(slave,0);
      dup2(slave,1);
      dup2(slave,2);
      execv(argv[0],argv);//execute arguments.
      return 5;//exec failed
    default:
      break;
  }
  eof1=0;
  eof2=0;
  for(;!(eof1 || eof2);) {
    if(waitpid(-1,0,WNOHANG) > 0) {
      return 0;//fuck if I know.
      //we got a dead child. let's bail.
    }
    switch(r=read(0,&in,1)) {
     case 0: eof1=1;;//EOF
     case -1: if(errno != EAGAIN) eof1=1; break;//EAGAIN probably.
     default: write(master,&in,r);
    }
    switch(r=read(master,&in,1)) {
     case 0: eof2=1;;//EOF
     case -1: if(errno != EAGAIN) eof2=1; break;//EAGAIN probably
     default: write(1,&in,r);
    }
    usleep(100);//kek
  }
}