Skip to content

Instantly share code, notes, and snippets.

@srd424
Created September 9, 2023 10:54
Show Gist options
  • Save srd424/e8649dae5cd6c3b17ac0d7de0ffcb2ff to your computer and use it in GitHub Desktop.
Save srd424/e8649dae5cd6c3b17ac0d7de0ffcb2ff to your computer and use it in GitHub Desktop.
Terrible hack for preloading custom readline functions
/* gcc -Wall -fPIC -shared -o fzf_readline.so fzf_readline.c -ldl */
/* a much nastier version of https://github.com/lincheney/rl_custom_function,
* but works with readline in Debian/Ubuntu
*/
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>
#include <dlfcn.h>
int init_done=0;
char *(*origfn)(const char*);
static rl_command_func_t *get_custom() {
void *lib=dlopen("/usr/lib/librl_custom_complete.so", RTLD_LAZY);
if(!lib) {
fprintf(stderr, "couldn't open custom func lib\n");
return NULL;
}
rl_command_func_t *func = dlsym(lib, "rl_custom_function");
if(!func) {
fprintf(stderr, "couldn't find func\n");
}
return func;
}
char *readline (const char *prompt) {
printf("In our own readline\n");
if (init_done)
return (*origfn)(prompt);
printf("doing init\n");
origfn = dlsym(RTLD_NEXT, "readline");
if (!origfn) {
fprintf(stderr, "couldn't resolve original readline(), aborting\n");
exit(255);
}
rl_command_func_t *custom = get_custom();
if (custom) {
int (*addfun)(const char *, rl_command_func_t *);
addfun=dlsym(RTLD_NEXT, "rl_add_funmap_entry");
if(!addfun) {
fprintf(stderr, "couldn't resolve rl_add_funmap_entry()\n");
} else {
int res=(*addfun)("rl_custom_complete", custom);
printf("add_funmap_entry returned %u\n",res);
}
}
init_done=1;
return (*origfn)(prompt);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment