← index
cplusplus11.Examples/UNIX/pseudo/terminal.cpp
Source: cplusplus11.Examples/UNIX/pseudo/terminal.cpp
/* Adapted from "the Linux Programming Interface"
 Chapter 64
 
 
 */
#include<iostream>
#include<string>
#include"pterm.hpp"

static const int BUF_SIZE=256;
static const int MAX_NAME=1000;
termios orig;

void ttyReset() {
    if(tcsetattr(STDIN_FILENO, TCSANOW, &orig) == -1)
        error("tcsetattr");
}

int main(int argc, char **argv) {
    
    char sname[MAX_NAME];
    const char *shell;
    int m_fd, s_fd;
    winsize ws;
    fd_set in_fds;
    char buf[BUF_SIZE];
    ssize_t bytesRead;
    pid_t cid;
    
    if(tcgetattr(STDIN_FILENO, &orig) == -1)
        error("tcgetattr");
    
    if(ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) < 0)
        error("ioctl");
    
    cid = pty_Fork(&m_fd, sname, MAX_NAME, &orig, &ws);
    if(cid == -1)
        error("pty_Fork");
    if(cid == 0) {
        shell = getenv("SHELL");
        if(shell == NULL || *shell == '\0')
            shell = "/bin/sh";
        
        execlp(shell, shell, (char*) NULL);
        error("execlp");
    }
    
    s_fd = open((argc > 1) ? argv[1] : "typescript", O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
    if(s_fd == -1)
        error("open typescript");
    
    tty_SetRaw(STDIN_FILENO, &orig);
    if(atexit(ttyReset) != 0)
        error("atexit");
    
    while(1) {
        FD_ZERO(&in_fds);
        FD_SET(STDIN_FILENO, &in_fds);
        FD_SET(m_fd, &in_fds);
        
        if(select(m_fd + 1, &in_fds, NULL, NULL, NULL) == -1)
            error("select");
        
        if(FD_ISSET(STDIN_FILENO, &in_fds)) {
            bytesRead = read(STDIN_FILENO, buf, BUF_SIZE);
            if(bytesRead <= 0)
                exit(EXIT_SUCCESS);
            if(write(m_fd, buf, bytesRead) != bytesRead)
                error("partial write", false);
        }
        
        if(FD_ISSET(m_fd, &in_fds)) {
            bytesRead = read(m_fd, buf, BUF_SIZE);
            if(bytesRead <= 0)
                exit(EXIT_SUCCESS);
            if(write(STDOUT_FILENO, buf, bytesRead) != bytesRead)
                error("partial/failed write\n", false);
            if(write(s_fd, buf, bytesRead) != bytesRead)
                error("partial/failed write\n", false);
        }
    }
        
    
    
    
    return 0;
}