Yes, this is possible (on Linux and before 2004, FreeBSD) by using pty in batch mode and setting the EXTPROC flag on it.
ioctl(master, TIOCPKT, &nonzero). read : , , , - ( " ( ) " )
, , , . a select() , ,
EXTPROC pty tcsetattr() - select() , , - fd, , , , linux, tcgetattr() .
, EXTPROC pty, . .
EXTPROC ( - ), ( shoud at , - linux termios tty_ioctl). linux drivers/tty/n_tty.c, , termios termios select() , tcsetattr(), , .
: J.F. Sebastians , , EXTRPOC linux:
#include <stdio.h>
#include <pty.h>
#include <termios.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/select.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
#define BUFSIZE 512
void main() {
int master;
pid_t pid;
if((pid = forkpty(&master, NULL, NULL, NULL))) {
fd_set rfds, xfds;
int retval, nread, status = 0, nonzero = 1;
char buf[BUFSIZE];
ioctl(master, TIOCPKT, &nonzero);
while(1) {
setbuf(stdout, NULL);
FD_ZERO(&rfds);
FD_SET(master, &rfds);
FD_ZERO(&xfds);
FD_SET(master, &xfds);
printf("---- waiting for something to happen -----\n");
select(1 + master, &rfds, NULL, &xfds, NULL);
char *r_text = (FD_ISSET(master, &rfds) ? "master ready for reading" : "- ");
char *x_text = (FD_ISSET(master, &xfds) ? "exception on master" : "- ");
printf("rfds: %s, xfds: %s\n", r_text, x_text);
if ((nread = read(master, buf, BUFSIZE-1)) < 0)
perror("read error");
else {
buf[nread] = '\0';
char *pkt_txt = (*buf & TIOCPKT_IOCTL ? " (TIOCPKT_IOCTL)" : "");
printf("read %d bytes: status byte %x%s, payload <%s>\n", nread, *buf, pkt_txt, buf + 1);
}
if (waitpid(pid, &status, WNOHANG) && WIFEXITED(status)) {
printf("child exited with status %x\n", status);
exit(EXIT_SUCCESS);
}
}
} else {
struct termios tio;
tcgetattr(STDIN_FILENO, &tio);
tio.c_lflag |= EXTPROC;
tcsetattr(STDIN_FILENO, TCSANOW, &tio);
sleep(1);
write(STDOUT_FILENO,"blah", 4);
sleep(1);
tio.c_cc[VINTR] = 0x07;
tcsetattr(STDIN_FILENO, TCSANOW, &tio);
sleep(1);
}
}
:
---- waiting for something to happen -----
rfds: master ready for reading, xfds: exception on master
read 1 bytes: status byte 40 (TIOCPKT_IOCTL), payload <>
---- waiting for something to happen -----
rfds: master ready for reading, xfds: -
read 5 bytes: status byte 0, payload <blah>
---- waiting for something to happen -----
rfds: master ready for reading, xfds: exception on master
read 1 bytes: status byte 40 (TIOCPKT_IOCTL), payload <>
---- waiting for something to happen -----
rfds: master ready for reading, xfds: -
read error: Input/output error
child exited with status 0
, - pty tty ( termios), Linux ( termios: termios ).
, EXTPROC , .
, , , .