⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pty.c

📁 Linux下伪终端的操作
💻 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 + -