Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
LD_PRELOAD trick for completing command options
- X-seq: zsh-workers 25210
- From: Stephane Chazelas <Stephane_Chazelas@xxxxxxxx>
- To: Zsh hackers list <zsh-workers@xxxxxxxxxx>
- Subject: LD_PRELOAD trick for completing command options
- Date: Wed, 18 Jun 2008 17:16:02 +0100
- Mail-followup-to: Zsh hackers list <zsh-workers@xxxxxxxxxx>
- Mailing-list: contact zsh-workers-help@xxxxxxxxxx; run by ezmlm
Hiya,
I'm just submitting this idea in case nobody had it before:
what about adding a small LD_PRELOAD wrapper for the getopts and
getopt_long functions in the installation of zsh (on systems
that support it) that could be used by the completion system for
the completion of options:
The completion system could do some nm -D to check whether the
command uses getopt or getopt_long, check that the command is
not setuid/setgid, and run the command with
LD_PRELOAD=/that/wrapper cmd, and parse the output from the
wrapper.
Maybe not something to do for every command, but for commands
for which we don't have a completion yet and know that doing
this hack won't harm.
Something like:
$ LD_PRELOAD=./a.so w -: 3>&1
hlusfVo
$ LD_PRELOAD=./a.so who -: 3>&1
abdlmpqrstuwHT
all:0:a
boot:0:b
count:0:q
dead:0:d
heading:0:H
ips:0:
login:0:l
lookup:0:
message:0:T
mesg:0:T
process:0:p
runlevel:0:r
short:0:s
time:0:t
users:0:u
writable:0:T
help:0:
version:0:
#define _GNU_SOURCE
#include <stdlib.h>
#include <getopt.h>
#include <stdio.h>
#include <string.h>
int getopt_long(int argc, char * const argv[],
const char *optstring,
const struct option *longopts, int *longindex) {
FILE* f = fdopen(3, "w");
if (!f)
exit(111);
fprintf(f, "%s\n", optstring);
while (longopts->name) {
int val = longopts->val;
fprintf(f, "%s:%d:", longopts->name, longopts->has_arg);
if (longopts->flag == NULL &&
val > 0 &&
val <= 0xFF &&
val != ':' &&
strchr(optstring, val))
fprintf(f, "%c\n", val);
else
fprintf(f, "\n");
longopts++;
}
exit(112);
}
int getopt(int argc, char * const argv[],
const char *optstring) {
FILE* f = fdopen(3, "w");
if (!f)
exit(111);
fprintf(f, "%s\n", optstring);
exit(112);
}
Cheers,
Stéphane
Messages sorted by:
Reverse Date,
Date,
Thread,
Author