diff options
Diffstat (limited to 'bin')
-rw-r--r-- | bin/man1/ptee.1 | 11 | ||||
-rw-r--r-- | bin/ptee.c | 49 |
2 files changed, 53 insertions, 7 deletions
diff --git a/bin/man1/ptee.1 b/bin/man1/ptee.1 index ba615f27..bb381ecb 100644 --- a/bin/man1/ptee.1 +++ b/bin/man1/ptee.1 @@ -8,6 +8,7 @@ . .Sh SYNOPSIS .Nm +.Op Fl t Ar ms .Ar command ... .Cm > .Ar file @@ -32,6 +33,16 @@ Type .Ic ^Q to toggle writing to standard output. . +.Pp +The arguments are as follows: +.Bl -tag -width Ds +.It Fl t Ar ms +Write a media copy sequence +to standard output every +.Ar ms +milliseconds. +.El +. .Sh SEE ALSO .Xr script 1 . diff --git a/bin/ptee.c b/bin/ptee.c index 335e0e67..52350a21 100644 --- a/bin/ptee.c +++ b/bin/ptee.c @@ -15,11 +15,14 @@ */ #include <err.h> +#include <errno.h> #include <poll.h> +#include <signal.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <sys/ioctl.h> +#include <sys/time.h> #include <sys/wait.h> #include <sysexits.h> #include <termios.h> @@ -40,8 +43,22 @@ static void restoreTerm(void) { tcsetattr(STDIN_FILENO, TCSADRAIN, &saveTerm); } +static void handler(int sig) { + (void)sig; +} + int main(int argc, char *argv[]) { - if (argc < 2) return EX_USAGE; + int timer = 0; + for (int opt; 0 < (opt = getopt(argc, argv, "t:"));) { + switch (opt) { + break; case 't': timer = atoi(optarg); + break; default: return EX_USAGE; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) return EX_USAGE; if (isatty(STDOUT_FILENO)) errx(EX_USAGE, "stdout is not redirected"); int error = tcgetattr(STDIN_FILENO, &saveTerm); @@ -62,10 +79,21 @@ int main(int argc, char *argv[]) { if (pid < 0) err(EX_OSERR, "forkpty"); if (!pid) { - execvp(argv[1], &argv[1]); - err(EX_NOINPUT, "%s", argv[1]); + execvp(argv[0], argv); + err(EX_NOINPUT, "%s", argv[0]); } + if (timer) { + signal(SIGALRM, handler); + struct timeval tv = { + .tv_sec = timer / 1000, + .tv_usec = timer % 1000 * 1000, + }; + struct itimerval itv = { tv, tv }; + setitimer(ITIMER_REAL, &itv, NULL); + } + + char mc[] = "\x1B[10i"; bool stop = false; byte buf[4096]; @@ -73,7 +101,16 @@ int main(int argc, char *argv[]) { { .events = POLLIN, .fd = STDIN_FILENO }, { .events = POLLIN, .fd = pty }, }; - while (0 < poll(fds, 2, -1)) { + for (;;) { + int nfds = poll(fds, 2, -1); + if (nfds < 0 && errno != EINTR) err(EX_IOERR, "poll"); + + if (nfds < 0) { + ssize_t wlen = write(STDOUT_FILENO, mc, sizeof(mc) - 1); + if (wlen < 0) err(EX_IOERR, "write"); + continue; + } + if (fds[0].revents & POLLIN) { ssize_t rlen = read(STDIN_FILENO, buf, sizeof(buf)); if (rlen < 0) err(EX_IOERR, "read"); @@ -84,8 +121,7 @@ int main(int argc, char *argv[]) { } if (rlen == 1 && buf[0] == CTRL('S')) { - char dump[] = "\x1B[10i"; - ssize_t wlen = write(STDOUT_FILENO, dump, sizeof(dump) - 1); + ssize_t wlen = write(STDOUT_FILENO, mc, sizeof(mc) - 1); if (wlen < 0) err(EX_IOERR, "write"); continue; } @@ -112,5 +148,4 @@ int main(int argc, char *argv[]) { if (dead < 0) err(EX_OSERR, "waitpid"); if (dead) return WIFEXITED(status) ? WEXITSTATUS(status) : EX_SOFTWARE; } - err(EX_IOERR, "poll"); } |