commit: f1dd9a109f67ff77ce8a312cb737ab68a3f3a3fb Author: Sam James <sam <AT> gentoo <DOT> org> AuthorDate: Tue May 14 00:11:53 2024 +0000 Commit: Sam James <sam <AT> gentoo <DOT> org> CommitDate: Tue May 14 00:12:25 2024 +0000 URL: https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=f1dd9a10
Drop ecma48-cpr Obsolete as of bfd5710de9b14712c4a621259b951bd10489d0c0. A neat tool, but it ended up not being a good fit for the reasons described in that commit. Signed-off-by: Sam James <sam <AT> gentoo.org> ecma48-cpr.c | 239 ----------------------------------------------------------- meson.build | 7 -- 2 files changed, 246 deletions(-) diff --git a/ecma48-cpr.c b/ecma48-cpr.c deleted file mode 100644 index d910f6f..0000000 --- a/ecma48-cpr.c +++ /dev/null @@ -1,239 +0,0 @@ -/* - * ecma48-cpr.c - * Treat STDIN as a tty and report the cursor position using the CPR sequence. - * - * Originally distributed as wsize.c by Stephen J. Friedl <[email protected]>. - * Repurposed for gentoo-functions by Kerin F. Millar <[email protected]>. - * This software is in the public domain. - */ - -#define _POSIX_C_SOURCE 200809L - -#define PROGRAM "ecma48-cpr" -#define READ_TIMEOUT_NS 250000000 -#define BUFSIZE 100 -#define MAX_LOOPS 20 - -#include <signal.h> -#include <stdbool.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <termios.h> -#include <time.h> -#include <unistd.h> - -static struct termios save_tty; -static bool is_timed_out = false; -static bool is_tty_saved = false; - -static void cleanup(void); -static void die(char const * const errmsg); -static void on_signal(int const signo); - -#ifndef __APPLE__ -static timer_t init_timer(void); -#endif - -int -main(void) { - /* - * Establish that STDIN is a terminal. - */ - if (! isatty(STDIN_FILENO)) { - die("cannot determine the cursor position because stdin is not a tty"); - } - - /* - * Duplicate STDIN to a new file descriptor before reopening it as a - * writeable stream. - */ - int fd = dup(STDIN_FILENO); - FILE *tty; - if (fd < 0) { - die("failed to dup stdin"); - } else { - tty = fdopen(fd, "w"); - if (tty == NULL) { - die("failed to re-open the tty for writing"); - } - } - - /* - * Save the current terminal settings. - */ - if (tcgetattr(STDIN_FILENO, &save_tty) != 0) { - die("failed to obtain the current terminal settings"); - } else { - is_tty_saved = true; - } - - /* - * Duplicate the current terminal settings for modification. - */ - struct termios new_tty = save_tty; - - /* - * Turn off ECHO, so that the response from the terminal isn't printed. - * Also, the terminal must be operating in its noncanonical mode, - * thereby ensuring that its input is always immediately available, - * with no processing having been performed. - */ - new_tty.c_lflag &= ~(ECHO | ICANON | IXON); - - /* - * Set an interbyte timeout of 1 decisecond. The timer is started only - * after the first byte is read, so read(2) will block until then. - */ - new_tty.c_cc[VMIN] = 1; - new_tty.c_cc[VTIME] = 1; - - /* - * Prepare to catch our signals. We treat both an interrupt and a - * depleted timer as essentially the same thing: fatal errors. - */ - struct sigaction act = { - .sa_handler = on_signal, - .sa_flags = 0 - }; - sigemptyset(&act.sa_mask); - sigaction(SIGALRM, &act, NULL); - - - /* - * Ignore the signals most likely to interrupt the process from hereon. - */ - signal(SIGINT, SIG_IGN); - signal(SIGTERM, SIG_IGN); - signal(SIGTSTP, SIG_IGN); - - /* - * Try to apply the new terminal settings. - */ - if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &new_tty) != 0) { - die("failed to modify the terminal settings"); - } else if (fprintf(tty, "\033[6n") != 4) { - die("failed to write the CPR sequence to the terminal"); - } else if (fclose(tty) != 0) { - die("failed to flush the stream after writing the CPR sequence"); - } - - /* - * A timeout is required, just in case read(2) proves unable to read an - * initial byte, otherwise causing the program to hang. - */ -#ifdef __APPLE__ - alarm(1); -#else - timer_t timerid = init_timer(); -#endif - - /* - * Read up to (sizeof ibuf - 1) bytes of input in total. Upon each - * successful read, scan the input buffer for a valid ECMA4-8 CPR - * response. Abort if no such response is found within MAX_LOOPS - * iterations. - */ - char ibuf[BUFSIZE]; - char const * const imax = ibuf + sizeof ibuf - 1; - char *iptr = ibuf; - int maxloops = MAX_LOOPS; - int row = -1; - int col = -1; - ssize_t nr; - while (--maxloops > 0 && (nr = read(STDIN_FILENO, iptr, imax - iptr)) > 0) { - iptr += nr; - *iptr = '\0'; /* NUL-terminate for strchr(3) and sscanf(3) */ - char const *p; - if ((p = strchr(ibuf, '\033')) != 0) { - if (sscanf(p, "\033[%d;%dR", &row, &col) == 2) { - break; - } else { - col = -1; - row = -1; - } - } - } - - /* - * Deactivate the timer. - */ -#ifdef __APPLE__ - alarm(0); -#else - timer_delete(timerid); -#endif - - /* - * Die in the case that the timer fired. - */ - if (is_timed_out) { - die("timed out waiting for the terminal to respond to CPR"); - } - - /* - * Restore the original terminal settings. - */ - cleanup(); - - /* - * Print the cursor position, provided both col and row are above zero. - */ - if (col < 1 || row < 1) { - die("failed to read the cursor position"); - } else if (printf("%d %d\n", row, col) == -1 || fflush(stdout) == EOF) { - return EXIT_FAILURE; - } else { - return EXIT_SUCCESS; - } -} - -#ifndef __APPLE__ -static timer_t -init_timer(void) { - timer_t timerid; - struct sigevent event = { - .sigev_value.sival_ptr = &timerid, - .sigev_notify = SIGEV_SIGNAL, - .sigev_signo = SIGALRM - }; - if (timer_create(CLOCK_REALTIME, &event, &timerid) == -1) { - die("failed to create a per-process timer"); - } else { - struct itimerspec timer = { - .it_value.tv_nsec = READ_TIMEOUT_NS, - .it_interval.tv_nsec = 0, - .it_interval.tv_sec = 0, - .it_value.tv_sec = 0 - }; - if (timer_settime(timerid, 0, &timer, NULL) == -1) { - die("failed to configure the per-process timer"); - } - } - return timerid; -} -#endif - -/* - * Tries to restore the terminal settings. Only one attempt will ever be made. - */ -static void -cleanup(void) { - bool const is_saved = is_tty_saved; - if (is_saved) { - tcsetattr(STDIN_FILENO, TCSAFLUSH, &save_tty); - is_tty_saved = false; - } -} - -static void -die(char const * const errmsg) { - cleanup(); - fprintf(stderr, "%s: %s\n", PROGRAM, errmsg); - exit(EXIT_FAILURE); -} - -static void -on_signal(int const signo) { - is_timed_out = true; -} diff --git a/meson.build b/meson.build index f18c5f8..05dba85 100644 --- a/meson.build +++ b/meson.build @@ -25,13 +25,6 @@ install_man( 'consoletype.1', ) -executable( - 'ecma48-cpr', - 'ecma48-cpr.c', - install: true, - install_dir: get_option('prefix') / 'lib' / 'gentoo' -) - do_tests = get_option('tests') if do_tests test(
