Last active
September 10, 2022 17:42
-
-
Save zed/71bc51d8968dc04f44076596ec5f73ef to your computer and use it in GitHub Desktop.
setting EXTPROC on the master side works on Linux
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/extproc |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** from @Hans Lub's answer | |
https://stackoverflow.com/questions/21641754/when-pty-pseudo-terminal-slave-fd-settings-are-changed-by-tcsetattr-how-ca | |
Demo program for managing a pty in packet mode with the slave's | |
** EXTPROC bit set, where the master gets notified of changes in the | |
** slaves terminal attributes | |
** | |
** save as extproc.c, compile with gcc -o extproc extproc.c -lutil | |
*/ | |
#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; // fd of master side | |
pid_t pid; | |
if((pid = forkpty(&master, NULL, NULL, NULL))) { // we're parent | |
fd_set rfds, xfds; | |
int retval, nread, status = 0, nonzero = 1; | |
char buf[BUFSIZE]; | |
ioctl(master, TIOCPKT, &nonzero); // initiate packet mode - necessary to get notified of | |
// ioctl() on the slave side | |
struct termios tio; | |
// First set the EXTPROC bit in the XXX *master* end termios structure | |
tcgetattr(master, &tio); | |
tio.c_lflag |= EXTPROC; | |
tcsetattr(master, TCSANOW, &tio); | |
while(1) { | |
// prepare the file descriptor sets | |
FD_ZERO(&rfds); | |
FD_SET(master, &rfds); | |
FD_ZERO(&xfds); | |
FD_SET(master, &xfds); | |
// now wait until status of master changes | |
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'; | |
// In packet mode *buf will be the status byte , and buf + 1 the "payload" | |
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 { // child | |
// Wait a bit and do an ordinary write() | |
sleep(1); | |
write(STDOUT_FILENO,"blah", 4); | |
// Wait a bit and change the pty terminal attributes. This will be picked up by the master end | |
sleep(1); | |
struct termios tio; | |
tcgetattr(STDIN_FILENO, &tio); | |
tio.c_cc[VINTR] = 0x07; | |
tcsetattr(STDIN_FILENO, TCSANOW, &tio); | |
// Wait a bit and exit | |
sleep(1); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
NAME := $(patsubst %.c,%,$(wildcard *.c)) | |
LDLIBS= -lutil | |
run: $(NAME) | |
./$(NAME) |
Awesome, I wander how you knew how to do this, I haven't find any information on this.
Can pty be used if we have serial in userspace and want to treat it as a regular linux device in /dev ? (which can be opened and set baudread, and read/write to) , thanks,.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You 're setting EXTPROC on standard input here, it should be done on
master
in order to work!