Skip to content

Instantly share code, notes, and snippets.

@wooosh
Last active August 13, 2019 02:30
Show Gist options
  • Save wooosh/924f01628d32134e7dfd66c38a0aee9e to your computer and use it in GitHub Desktop.
Save wooosh/924f01628d32134e7dfd66c38a0aee9e to your computer and use it in GitHub Desktop.
Async Module Script
#include <sys/ioctl.h>
#include <stdio.h>
#include <sys/poll.h>
#include <stdlib.h>
#include <string.h>
struct str_sized {
size_t size;
char* str;
};
int main(int argc, char** argv) {
if (argc == 1) {
puts("Usage: hopper program1 program2 ...");
return 1;
}
// Shift out the name of the program
argc--;
argv++;
// Create an array of file deescriptors to be monitored
struct pollfd* plist = malloc(argc*sizeof(struct pollfd));
FILE** flist = malloc(argc*sizeof(FILE*));
struct str_sized* buffer = malloc(argc*sizeof(struct str_sized));
int ret;
int needupdate = 0;
for (int i=0; i<argc; i++) {
// Start the script
flist[i] = popen(argv[i], "r");
plist[i].fd = fileno(flist[i]);
// Only monitor input events
plist[i].events = POLLIN;
buffer[i].size = 1;
buffer[i].str = malloc(1);
}
for (;;) {
// Wait for events
ret = poll(plist, argc, -1);
if (ret == -1) {
perror("poll");
return 1;
}
// Check which file descriptors have been updated
for (int i=0; i<argc; i++) {
// Remove closed file descriptors
if (plist[i].revents & POLLHUP) {
pclose(flist[i]);
plist[i].fd = -1;
plist[i].events = 0;
}
// Update if new data comes in
else if (plist[i].revents & POLLIN) {
getline(&buffer[i].str, &buffer[i].size, flist[i]);
buffer[i].str[strlen(buffer[i].str)-1] = '\0';
needupdate = 1;
}
}
// Only output text when text has been updated
if (needupdate) {
for (int i=0; i<argc; i++)
printf("%s", buffer[i].str);
printf("\n");
fflush(stdout);
needupdate = 0;
}
}
}

Installing hopper is very simple. First you must compile it using the following command: gcc hopper.c -o hopper And then move it to usr/bin/ so it can be executed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment