📄 pty.c
字号:
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <termios.h>#include <signal.h>#include <errno.h>#include "pty_fork.c"#include "fig18.20"static void set_noecho(int);static void loop(int);#define BUFFSIZE 1024int main(int argc, char *argv[]){ int fdm, c, interactive, noecho; pid_t pid; char slave_name[20]; struct termios orig_termios; struct winsize size; char buf[BUFFSIZE]; interactive = isatty(STDIN_FILENO); noecho = 0; opterr = 0; while ((c = getopt(argc, argv, "en")) != EOF) { switch (c) { case 'e': noecho = 1; break; case 'n': interactive = 0; break; case '?': fprintf(stderr, "unrecognized option: -%c\n", optopt); exit(1); } } //if (optind >= argc) { // fprintf(stderr, "usage: pty [ -d driver -einv ] program [ arg ... ]\n"); // exit(1); //} if (interactive) { if (tcgetattr(STDIN_FILENO, &orig_termios) < 0) { fprintf(stderr, "tcgetattr error on stdin\n"); exit(1); } if (ioctl(STDIN_FILENO, TIOCGWINSZ, (char *) &size) < 0) { fprintf(stderr, "TIOCGWINSZ error\n"); exit(1); } pid = pty_fork(&fdm, slave_name, sizeof(slave_name), &orig_termios, &size); } else { pid = pty_fork(&fdm, slave_name, sizeof(slave_name), NULL, NULL); } if (pid < 0) { fprintf(stderr, "fork error\n"); exit(1); } else if (pid == 0) { if (noecho) set_noecho(STDIN_FILENO); if (execvp(argv[optind], &argv[optind]) < 0) { fprintf(stderr, "can't execute: %s\n", argv[optind]); exit(1); } }// write(fdm, "hello\n", 6);// if (dup2(fdm, STDIN_FILENO) != STDIN_FILENO) {// fprintf(stderr, "dup2 error to stdin\n");// exit(1);// }// while ((c = fgetc(stdin)) != EOF) {// char cr = c;// write(1, &cr, 1);// }// if (interactive) { //if (tty_raw(STDIN_FILENO) < 0) { if (tty_cbreak(STDIN_FILENO) < 0) { fprintf(stderr, "tty_raw error\n"); exit(1); } if (atexit(tty_atexit) < 0) { fprintf(stderr, "atexit error\n"); exit(1); } } loop(fdm); exit(0);}static void set_noecho(int fd){ struct termios stermios; if (tcgetattr(fd, &stermios) < 0) { fprintf(stderr, "tcgetattr error\n"); exit(1); } stermios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); stermios.c_oflag &= ~(ONLCR); if (tcsetattr(fd, TCSANOW, &stermios) < 0) { fprintf(stderr, "tcsetattr error\n"); exit(1); }}static volatile int sigcaught;typedef void Sigfunc(int);static Sigfunc * signal_intr(int signo, Sigfunc *func);static void sig_term(int signo);static void loop(int ptym){ pid_t child; int nread; char buf[BUFFSIZE]; if ((child = fork()) < 0) { fprintf(stderr, "fork error:%s\n", strerror(errno)); exit(1); } else if (child == 0) { for ( ; ; ) { if ((nread = read(STDIN_FILENO, buf, BUFFSIZE)) < 0) { fprintf(stderr, "read error from stdin:%s\n", strerror(errno)); exit(1); } else if (nread == 0) break; if (write(ptym, buf, nread) != nread) { fprintf(stderr, "writen error to master pty:%s\n", strerror(errno)); exit(1); } } kill(getppid(), SIGTERM); exit(0); } if (signal_intr(SIGTERM, sig_term) == SIG_ERR) { fprintf(stderr, "signal_intr error for SIGTERM:%s\n", strerror(errno)); exit(1); } for ( ; ; ) { if ((nread = read(ptym, buf, BUFFSIZE)) <= 0) break; if (write(STDOUT_FILENO, buf, nread) != nread) { fprintf(stderr, "writen error to stdout:%s\n", strerror(errno)); exit(1); } } if (sigcaught == 0) kill(child, SIGTERM);}static Sigfunc * signal_intr(int signo, Sigfunc *func){ struct sigaction act, oact; act.sa_handler = func; sigemptyset(&act.sa_mask); act.sa_flags = 0; act.sa_flags |= SA_INTERRUPT; if (sigaction(signo, &act, &oact) < 0) return(SIG_ERR); return(oact.sa_handler);}static void sig_term(int signo){ sigcaught = 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -