1
0
mirror of https://github.com/aap/pdp6.git synced 2026-01-13 15:27:46 +00:00
aap.pdp6/misc/mkpty.c

135 lines
2.2 KiB
C

/* Creates a pty and connects it to the process tty.
* As an optional argument it takes a filename and symlinks /dev/pts/N. */
#define _XOPEN_SOURCE 600 /* for ptys */
#define _DEFAULT_SOURCE /* for cfmakeraw */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <poll.h>
#include <errno.h>
#include <time.h>
struct termios tiosaved;
int
raw(int fd)
{
struct termios tio;
if(tcgetattr(fd, &tio) < 0) return -1;
tiosaved = tio;
cfmakeraw(&tio);
if(tcsetattr(fd, TCSAFLUSH, &tio) < 0) return -1;
return 0;
}
int
reset(int fd)
{
if(tcsetattr(0, TCSAFLUSH, &tiosaved) < 0) return -1;
return 0;
}
#define BAUD 30
struct timespec slp = { 0, 1000*1000*1000 / BAUD };
struct timespec hupslp = { 0, 100*1000*1000 };
//#define SLEEP nanosleep(&slp, NULL)
#define SLEEP
void
readwrite(int ttyin, int ttyout, int ptyin, int ptyout)
{
int n;
struct pollfd pfd[2];
char c;
pfd[0].fd = ptyin;
pfd[0].events = POLLIN;
pfd[1].fd = ttyin;
pfd[1].events = POLLIN;
while(pfd[0].fd != -1){
n = poll(pfd, 2, -1);
if(n < 0){
perror("error poll");
return;
}
if(n == 0)
return;
if(pfd[0].revents & POLLHUP)
nanosleep(&hupslp, NULL);
/* read from pty, write to tty */
if(pfd[0].revents & POLLIN){
if(n = read(ptyin, &c, 1), n <= 0)
return;
else{
//if(c == '\a') c = '.';
write(ttyout, &c, 1);
SLEEP;
}
}
/* read from tty, write to pty */
if(pfd[1].revents & POLLIN){
if(n = read(ttyin, &c, 1), n <= 0)
return;
else{
if(c == 035)
return;
write(ptyout, &c, 1);
SLEEP;
}
}
}
}
int
main(int argc, char *argv[])
{
int fd;
int slv;
const char *ptylink;
ptylink = NULL;
if(argc > 1)
ptylink = argv[1];
fd = posix_openpt(O_RDWR);
if(fd < 0)
return 1;
if(grantpt(fd) < 0)
return 2;
if(unlockpt(fd) < 0)
return 3;
if(ptylink){
unlink(ptylink);
if(symlink(ptsname(fd), ptylink) < 0)
fprintf(stderr, "Error: %s\n", strerror(errno));
}
printf("%s\n", ptsname(fd));
slv = open(ptsname(fd), O_RDWR);
if(slv < 0)
return 4;
raw(slv);
close(slv);
raw(0);
readwrite(0, 1, fd, fd);
close(fd);
reset(0);
if(ptylink)
unlink(ptylink);
return 0;
}