mirror of
https://github.com/aap/pdp6.git
synced 2026-01-11 23:53:31 +00:00
changed handling of TTYs; you now connect to a tty device, misc/mkpty is used to create a pty to be used by the emulator
This commit is contained in:
parent
44fa353ea0
commit
136ae33449
119
misc/mkpty.c
Normal file
119
misc/mkpty.c
Normal file
@ -0,0 +1,119 @@
|
||||
/* 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>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
/* read from pty, write to tty */
|
||||
if(pfd[0].revents & POLLIN){
|
||||
if(n = read(ptyin, &c, 1), n <= 0)
|
||||
return;
|
||||
else
|
||||
write(ttyout, &c, 1);
|
||||
}
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@ -12,7 +12,7 @@
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <poll.h>
|
||||
#include "../args.h"
|
||||
#include "../src/args.h"
|
||||
|
||||
char *argv0;
|
||||
struct termios tiosaved;
|
||||
|
||||
@ -751,7 +751,6 @@ wake_pi(void *dev)
|
||||
apr->pi_active = 0;
|
||||
if(bus->c12 & F28)
|
||||
apr->pi_active = 1;
|
||||
printf("%o %o\n", apr->pir, apr->pio);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
10
src/main.c
10
src/main.c
@ -537,7 +537,7 @@ getms(void)
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [-td]\n", argv0);
|
||||
fprintf(stderr, "usage: %s [-t] [-d debugfile] [-c ttyfile]\n", argv0);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -559,9 +559,10 @@ main(int argc, char *argv[])
|
||||
int delay;
|
||||
int i;
|
||||
int w, h;
|
||||
const char *outfile;
|
||||
const char *outfile, *ttyfile;
|
||||
|
||||
outfile = "/dev/null";
|
||||
ttyfile = "/tmp/6tty";
|
||||
ARGBEGIN{
|
||||
case 't':
|
||||
dotrace = 1;
|
||||
@ -569,6 +570,9 @@ main(int argc, char *argv[])
|
||||
case 'd':
|
||||
outfile = EARGF(usage());
|
||||
break;
|
||||
case 'c':
|
||||
ttyfile = EARGF(usage());
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}ARGEND;
|
||||
@ -679,6 +683,8 @@ main(int argc, char *argv[])
|
||||
inittty(&tty, &apr.iobus);
|
||||
initptr(&ptr, &apr.iobus);
|
||||
initptp(&ptp, &apr.iobus);
|
||||
if(ttyfile)
|
||||
attachdevtty(&tty, ttyfile);
|
||||
showmem(&apr.membus);
|
||||
|
||||
for(;;){
|
||||
|
||||
@ -448,6 +448,7 @@ struct Tty
|
||||
int fd;
|
||||
};
|
||||
void inittty(Tty *tty, IOBus *bus);
|
||||
void attachdevtty(Tty *tty, const char *path);
|
||||
|
||||
|
||||
|
||||
|
||||
74
src/tty.c
74
src/tty.c
@ -1,10 +1,8 @@
|
||||
#include "pdp6.h"
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <pthread.h>
|
||||
#include <termios.h>
|
||||
#include <pthread.h>
|
||||
#include <poll.h>
|
||||
|
||||
static void
|
||||
@ -13,52 +11,24 @@ recalc_tty_req(Tty *tty)
|
||||
setreq(tty->bus, TTY, tty->tto_flag || tty->tti_flag ? tty->pia : 0);
|
||||
}
|
||||
|
||||
/* TODO: implement some kind of sleep if no tty is attached */
|
||||
static void*
|
||||
ttythread(void *dev)
|
||||
{
|
||||
int sockfd, newsockfd, portno, clilen;
|
||||
char buf;
|
||||
struct sockaddr_in serv_addr, cli_addr;
|
||||
int n;
|
||||
char c;
|
||||
Tty *tty;
|
||||
|
||||
tty = dev;
|
||||
sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(sockfd < 0){
|
||||
perror("error: socket");
|
||||
exit(1);
|
||||
}
|
||||
memset(&serv_addr, 0, sizeof(serv_addr));
|
||||
portno = 6666;
|
||||
serv_addr.sin_family = AF_INET;
|
||||
serv_addr.sin_addr.s_addr = INADDR_ANY;
|
||||
serv_addr.sin_port = htons(portno);
|
||||
if(bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0){
|
||||
perror("error: bind");
|
||||
exit(1);
|
||||
}
|
||||
listen(sockfd,5);
|
||||
clilen = sizeof(cli_addr);
|
||||
|
||||
while(newsockfd = accept(sockfd, (struct sockaddr*)&cli_addr, &clilen)){
|
||||
printf("TTY attached\n");
|
||||
tty->fd = newsockfd;
|
||||
while(n = read(tty->fd, &buf, 1), n > 0){
|
||||
for(;;){
|
||||
while(tty->fd >= 0 && (n = read(tty->fd, &c, 1)) > 0){
|
||||
tty->tti_busy = 1;
|
||||
//fprintf(stderr, "(got.%c)", buf);
|
||||
tty->tti = buf|0200;
|
||||
tty->tti = c|0200;
|
||||
tty->tti_busy = 0;
|
||||
tty->tti_flag = 1;
|
||||
recalc_tty_req(tty);
|
||||
}
|
||||
tty->fd = -1;
|
||||
close(newsockfd);
|
||||
}
|
||||
if(newsockfd < 0){
|
||||
perror("error: accept");
|
||||
exit(1);
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -122,6 +92,34 @@ wake_tty(void *dev)
|
||||
recalc_tty_req(tty);
|
||||
}
|
||||
|
||||
void
|
||||
attachdevtty(Tty *tty, const char *path)
|
||||
{
|
||||
int fd;
|
||||
struct termios tio;
|
||||
|
||||
fd = tty->fd;
|
||||
if(fd >= 0){
|
||||
tty->fd = -1;
|
||||
close(fd);
|
||||
}
|
||||
fd = open(path, O_RDWR);
|
||||
if(fd < 0)
|
||||
goto fail;
|
||||
if(tcgetattr(fd, &tio) < 0)
|
||||
goto fail;
|
||||
cfmakeraw(&tio);
|
||||
// cfsetspeed(&tio, B300);
|
||||
if(tcsetattr(fd, TCSAFLUSH, &tio) < 0)
|
||||
goto fail;
|
||||
tty->fd = fd;
|
||||
return;
|
||||
|
||||
fail:
|
||||
if(fd >= 0) close(fd);
|
||||
fprintf(stderr, "couldn't open tty %s\n", path);
|
||||
}
|
||||
|
||||
void
|
||||
inittty(Tty *tty, IOBus *bus)
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user