Blob


1 #!/usr/bin/env perl
3 use v5.10;
4 use warnings;
5 use IPC::Open3;
7 my $cachedir = $ENV{HOME}. "/.cache";
8 my $cachefile = $cachedir."/mymenu";
9 my %progs;
11 $SIG{CHLD} = "IGNORE";
13 if (! -d $cachedir) {
14 mkdir $cachedir or die "Cannot create cache dir ". $cachedir;
15 }
17 if (-e $cachefile) {
18 open my $f, "<", $cachefile;
19 while (<$f>) {
20 my ($c, $p) = split / /, $_;
21 chomp $p;
22 $progs{$p} = $c + 0;
23 }
24 close $f;
25 }
27 foreach my $p (split /:/, $ENV{PATH}) {
28 opendir my $d, $p or next;
29 foreach (readdir $d) {
30 if (-x "$p/$_" and ! (-d "$p/$_")) {
31 if (! exists $progs{$_}) {
32 $progs{$_} = 0;
33 }
34 }
35 }
36 closedir $d;
37 }
39 my $args = join ' ', @ARGV;
40 my $pid = open3(my $c_in, my $c_out, my $c_err, "mymenu $args") or die("Failed open3(): $!");
41 foreach (sort {$progs{$b} <=> $progs{$a} or lc($a) cmp lc($b)} keys %progs) {
42 print $c_in $_."\n";
43 }
44 close($c_in);
46 while (my $p = <$c_out>) {
47 chomp $p;
48 $progs{$p} += 1;
49 say "gonna exec $p";
51 if (!fork()) {
52 # i'm the child
53 exec $p;
54 }
55 }
57 say "Updating cache...";
58 open my $f, ">", $cachefile;
59 foreach (keys %progs) {
60 print $f $progs{$_} ." ". $_ ."\n" if $progs{$_} != 0;
61 }
62 close($f);
64 waitpid(-1, 0);