Skip to content

Instantly share code, notes, and snippets.

@michaelfm1211
Last active September 25, 2022 23:04
Show Gist options
  • Save michaelfm1211/93c6d68d17a8766475c2ae845bc9cf4a to your computer and use it in GitHub Desktop.
Save michaelfm1211/93c6d68d17a8766475c2ae845bc9cf4a to your computer and use it in GitHub Desktop.
C program that simulates the (deprecated) HTML <marquee> tag
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
bool rflag = false;
float speed = 0.05;
char *str;
size_t str_len;
char *buf;
int usage() {
fprintf(stderr, "usage: marquee [-h] [-r] [-s speed] 'text'\n");
return 1;
}
void make_payload(size_t cols) {
buf = malloc(str_len + cols + 2);
for (size_t i = 0; i < cols; i++) {
buf[i] = ' ';
}
buf[cols] = '\0';
strcat(buf, str);
strcat(buf, " ");
}
void print_payload(size_t cols) {
char *ptr = buf;
while (*ptr) {
printf("\r%.*s", (int)cols, ptr);
ptr++;
if ((unsigned long)(ptr - buf) > cols + str_len) {
if (rflag)
ptr = buf;
else
break;
}
usleep(speed * 1000000);
}
}
void cleanup() {
fputs("\x1b[?25h\x1b[F", stdout);
free(buf);
exit(0);
}
int main(int argc, char *argv[]) {
if (argc < 2)
return usage();
// warn if stdout isn't a tty
if (!isatty(STDOUT_FILENO))
fprintf(stderr, "warning: stdout is not a tty\n");
// call cleanup() on SIGINT or SIGQUIT
signal(SIGINT, cleanup);
signal(SIGQUIT, cleanup);
// get size of the terminal window
struct winsize win;
ioctl(0, TIOCGWINSZ, &win);
// disable buffering and hide cursor
setbuf(stdout, NULL);
fputs("\x1b[?25l", stdout);
// getopt
char ch;
while ((ch = getopt(argc, argv, "rs:h")) != -1) {
switch (ch) {
case 'r':
rflag = true;
break;
case 's':
speed = atof(optarg);
break;
case '?':
case 'h':
default:
return usage();
}
}
if (argv[optind] == NULL)
return usage();
str = argv[optind];
str_len = strlen(str);
make_payload(win.ws_col);
print_payload(win.ws_col);
cleanup();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment