Initial commit

This commit is contained in:
Scott Garrett committed 2026-09-04 13:55:06 -04:00
commit 85b0d6b5ac
3 files changed
+133

No files matched your search

+2
View File
@@ -0,0 +1,2 @@
.DS_Store
baud
+72
View File
@@ -0,0 +1,72 @@
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h>
/*
baud - A tool to simulate a specified baud rate in a pipe.
I wrote this to be able to play some of the old VT100/ansi animations
at the rate of your choice. Since most terminal emulator apps render
the text as fast as the system can (which is effectively instantaneous),
the animations do not actually animate. This allows you to add
a throttle to view as if you were on an actual serial terminal.
It takes one parameter, which is the desired baud rate. If you do not
specify one, it will use the default defined below. Extra parameters
will be ignored.
-- Scott Garrett
version 2022050401
*/
#define defaultbaudrate 9600
int main(int argc, char *argv[])
{
int baudrate;
int c;
if ( argc == 1 )
baudrate = defaultbaudrate;
else
baudrate = atoi(argv[1]);
/* Cannot have a negative baud rate, and 0 makes no sense
(and would cause a division by zero).
*/
if ( baudrate <= 0 )
{
printf("Invalid baud rate: %d\n", baudrate);
exit(1);
}
/* Convert the desired baud rate into nanoseconds */
int baud = 10000000000 / baudrate;
/* Make sure the final value is in the valid range that nanosleep()
supports.
*/
if ( baud < 0 || baud > 999999999 )
{
printf("Invalid baud rate: %d\n", baudrate);
exit(1);
}
/* Now that we know the desired baud rate delay in nanoseconds,
load up the struct with the values. 0 seconds and the baud rate delay.
*/
struct timespec remaining, request = {0, baud};
while ((c = getchar()) != EOF)
{
/* Here we grab a character from stdin, write it, flush it out
so it is seen immediately, then pause for "remaining" nanoseconds.
*/
putchar((char)c);
fflush(stdout);
int response = nanosleep(&request, &remaining);
}
}
Executable
+59
View File
@@ -0,0 +1,59 @@
#!/usr/bin/env python3
"""pty_baud.py – run a shell behind two baud-rate simulators."""
import os, pty, sys, tty, termios, select, subprocess
BAUD = sys.argv[1] if len(sys.argv) > 1 else "baud"
SHELL = ["bash", "--norc"]
master, slave = pty.openpty()
shell = subprocess.Popen(SHELL, stdin=slave, stdout=slave, stderr=slave,
preexec_fn=os.setsid, close_fds=True)
os.close(slave)
baud_out = subprocess.Popen([BAUD], stdin=subprocess.PIPE,
stdout=subprocess.PIPE)
baud_in = subprocess.Popen([BAUD], stdin=subprocess.PIPE,
stdout=subprocess.PIPE)
# ── flatten every endpoint to an int fd ──────────────────────────
fd_term = sys.stdin.fileno()
fd_baud_in_stdin = baud_in.stdin.fileno()
fd_baud_in_out = baud_in.stdout.fileno()
fd_baud_out_in = baud_out.stdin.fileno()
fd_baud_out_out = baud_out.stdout.fileno()
# master is already an int from openpty()
old = termios.tcgetattr(fd_term)
tty.setraw(fd_term)
def pump(r, w):
try:
d = os.read(r, 4096) # r is already an int
except OSError:
return False
if not d:
return False
try:
os.write(w, d) # w is already an int
except OSError:
return False
return True
try:
while True:
r, _, _ = select.select(
[fd_term, master, fd_baud_in_out, fd_baud_out_out],
[], [], 0.01)
if fd_term in r: pump(fd_term, fd_baud_in_stdin)
if master in r: pump(master, fd_baud_out_in)
if fd_baud_in_out in r: pump(fd_baud_in_out, master)
if fd_baud_out_out in r: pump(fd_baud_out_out, fd_term)
except KeyboardInterrupt:
pass
finally:
termios.tcsetattr(fd_term, termios.TCSADRAIN, old)
for p in (shell, baud_in, baud_out):
try: p.terminate()
except OSError: pass