Home | History | Annotate | Download | only in toolbox
      1 #include <signal.h>
      2 #include <stdio.h>
      3 #include <stdlib.h>
      4 #include <string.h>
      5 #include <unistd.h>
      6 
      7 int main(int, char **);
      8 
      9 static int toolbox_main(int argc, char **argv)
     10 {
     11     // "toolbox foo ..." is equivalent to "foo ..."
     12     if (argc > 1) {
     13         return main(argc - 1, argv + 1);
     14     } else {
     15         printf("Toolbox!\n");
     16         return 0;
     17     }
     18 }
     19 
     20 #define TOOL(name) int name##_main(int, char**);
     21 #include "tools.h"
     22 #undef TOOL
     23 
     24 static struct
     25 {
     26     const char *name;
     27     int (*func)(int, char**);
     28 } tools[] = {
     29     { "toolbox", toolbox_main },
     30 #define TOOL(name) { #name, name##_main },
     31 #include "tools.h"
     32 #undef TOOL
     33     { 0, 0 },
     34 };
     35 
     36 static void SIGPIPE_handler(int signal) {
     37     // Those desktop Linux tools that catch SIGPIPE seem to agree that it's
     38     // a successful way to exit, not a failure. (Which makes sense --- we were
     39     // told to stop by a reader, rather than failing to continue ourselves.)
     40     _exit(0);
     41 }
     42 
     43 int main(int argc, char **argv)
     44 {
     45     int i;
     46     char *name = argv[0];
     47 
     48     // Let's assume that none of this code handles broken pipes. At least ls,
     49     // ps, and top were broken (though I'd previously added this fix locally
     50     // to top). We exit rather than use SIG_IGN because tools like top will
     51     // just keep on writing to nowhere forever if we don't stop them.
     52     signal(SIGPIPE, SIGPIPE_handler);
     53 
     54     if((argc > 1) && (argv[1][0] == '@')) {
     55         name = argv[1] + 1;
     56         argc--;
     57         argv++;
     58     } else {
     59         char *cmd = strrchr(argv[0], '/');
     60         if (cmd)
     61             name = cmd + 1;
     62     }
     63 
     64     for(i = 0; tools[i].name; i++){
     65         if(!strcmp(tools[i].name, name)){
     66             return tools[i].func(argc, argv);
     67         }
     68     }
     69 
     70     printf("%s: no such tool\n", argv[0]);
     71     return -1;
     72 }
     73