diff options
| author | David Walter Seikel | 2014-01-29 22:02:32 +1000 | 
|---|---|---|
| committer | David Walter Seikel | 2014-01-29 22:02:32 +1000 | 
| commit | 53fd8efe2bcebad2e3b5c69253105356a9df7ad8 (patch) | |
| tree | 89a95feb129188cff51296b8809e7d39a23d73da | |
| parent | Signal catcher to catch those signals sent on keystrokes. (diff) | |
| download | boxes-53fd8efe2bcebad2e3b5c69253105356a9df7ad8.zip boxes-53fd8efe2bcebad2e3b5c69253105356a9df7ad8.tar.gz boxes-53fd8efe2bcebad2e3b5c69253105356a9df7ad8.tar.bz2 boxes-53fd8efe2bcebad2e3b5c69253105356a9df7ad8.tar.xz | |
Revert the signal catcher code as promised.
Diffstat (limited to '')
| -rw-r--r-- | boxes.c | 77 | 
1 files changed, 1 insertions, 76 deletions
| @@ -33,12 +33,6 @@ config BOXES | |||
| 33 | */ | 33 | */ | 
| 34 | 34 | ||
| 35 | 35 | ||
| 36 | /* We need to catch some signals, coz some key strokes used by some editors trigger signals. | ||
| 37 | If we use poll or select, we get the race condition from the signals. | ||
| 38 | Poll is preferable over select in general. So I was using poll originally. | ||
| 39 | However, ppoll is Linux specific, and worse, needs to define the following swear words... | ||
| 40 | */ | ||
| 41 | #define _GNU_SOURCE | ||
| 42 | #include "toys.h" | 36 | #include "toys.h" | 
| 43 | 37 | ||
| 44 | GLOBALS( | 38 | GLOBALS( | 
| @@ -666,7 +660,6 @@ static box *rootBox; // Parent of the rest of the boxes, or the only box. Alway | |||
| 666 | static box *currentBox; | 660 | static box *currentBox; | 
| 667 | static view *commandLine; | 661 | static view *commandLine; | 
| 668 | static int commandMode; | 662 | static int commandMode; | 
| 669 | static /*sigatomic_t*/ volatile int signalPipe[2]; | ||
| 670 | 663 | ||
| 671 | 664 | ||
| 672 | #define MEM_SIZE 128 // Chunk size for line memory allocation. | 665 | #define MEM_SIZE 128 // Chunk size for line memory allocation. | 
| @@ -1865,9 +1858,7 @@ struct CSI CSI_terminators[] = | |||
| 1865 | 1858 | ||
| 1866 | void editLine(long extra, void (*lineChar)(long extra, char *buffer), struct keyCommand * (*lineCommand)(long extra, char *command)) | 1859 | void editLine(long extra, void (*lineChar)(long extra, char *buffer), struct keyCommand * (*lineCommand)(long extra, char *command)) | 
| 1867 | { | 1860 | { | 
| 1868 | struct pollfd pollfds[2]; | 1861 | struct pollfd pollfds[1]; | 
| 1869 | struct timespec timeout = {0, 100000000}; // Timeout of one tenth of a second. | ||
| 1870 | sigset_t signalMask; | ||
| 1871 | // Get the initial command set. | 1862 | // Get the initial command set. | 
| 1872 | struct keyCommand *ourKeys = lineCommand(extra, ""); | 1863 | struct keyCommand *ourKeys = lineCommand(extra, ""); | 
| 1873 | char buffer[20], command[20], csFinal[8]; | 1864 | char buffer[20], command[20], csFinal[8]; | 
| @@ -1879,14 +1870,6 @@ void editLine(long extra, void (*lineChar)(long extra, char *buffer), struct key | |||
| 1879 | buffer[0] = 0; | 1870 | buffer[0] = 0; | 
| 1880 | command[0] = 0; | 1871 | command[0] = 0; | 
| 1881 | 1872 | ||
| 1882 | sigemptyset(&signalMask); | ||
| 1883 | sigaddset(&signalMask, SIGINT); | ||
| 1884 | sigaddset(&signalMask, SIGCONT); | ||
| 1885 | // sigaddset(&signalMask, SIGSTOP); | ||
| 1886 | // sigaddset(&signalMask, SIGINFO); | ||
| 1887 | sigaddset(&signalMask, SIGTSTP); | ||
| 1888 | sigaddset(&signalMask, SIGQUIT); | ||
| 1889 | |||
| 1890 | // TODO - OS buffered keys might be a problem, but we can't do the usual timestamp filter for now. | 1873 | // TODO - OS buffered keys might be a problem, but we can't do the usual timestamp filter for now. | 
| 1891 | TT.stillRunning = 1; | 1874 | TT.stillRunning = 1; | 
| 1892 | while (TT.stillRunning) | 1875 | while (TT.stillRunning) | 
| @@ -1906,15 +1889,11 @@ void editLine(long extra, void (*lineChar)(long extra, char *buffer), struct key | |||
| 1906 | memset(pollfds, 0, pollcount * sizeof(struct pollfd)); | 1889 | memset(pollfds, 0, pollcount * sizeof(struct pollfd)); | 
| 1907 | pollfds[0].events = POLLIN; | 1890 | pollfds[0].events = POLLIN; | 
| 1908 | pollfds[0].fd = 0; | 1891 | pollfds[0].fd = 0; | 
| 1909 | pollfds[0].events = POLLIN; | ||
| 1910 | pollfds[0].fd = signalPipe[0]; | ||
| 1911 | 1892 | ||
| 1912 | // TODO - A bit unstable at the moment, something makes it go into a horrid CPU eating edit line flicker mode sometimes. And / or vi mode can crash on exit (stack smash). | 1893 | // TODO - A bit unstable at the moment, something makes it go into a horrid CPU eating edit line flicker mode sometimes. And / or vi mode can crash on exit (stack smash). | 
| 1913 | // This might be fixed now. | 1894 | // This might be fixed now. | 
| 1914 | 1895 | ||
| 1915 | // TODO - Should only ask for a time out after we get an Escape. | 1896 | // TODO - Should only ask for a time out after we get an Escape. | 
| 1916 | p = ppoll(pollfds, pollcount, &timeout, &signalMask); | ||
| 1917 | // p = poll(pollfds, pollcount, 100); | ||
| 1918 | p = poll(pollfds, pollcount, 100); // Timeout of one tenth of a second (100). | 1897 | p = poll(pollfds, pollcount, 100); // Timeout of one tenth of a second (100). | 
| 1919 | if (0 > p) perror_exit("poll"); | 1898 | if (0 > p) perror_exit("poll"); | 
| 1920 | if (0 == p) // A timeout, trigger a time event. | 1899 | if (0 == p) // A timeout, trigger a time event. | 
| @@ -2778,35 +2757,6 @@ struct context simpleVi = | |||
| 2778 | // TODO - have any unrecognised escape key sequence start up a new box (split one) to show the "show keys" content. | 2757 | // TODO - have any unrecognised escape key sequence start up a new box (split one) to show the "show keys" content. | 
| 2779 | // That just adds each "Key is X" to the end of the content, and allows scrolling, as well as switching between other boxes. | 2758 | // That just adds each "Key is X" to the end of the content, and allows scrolling, as well as switching between other boxes. | 
| 2780 | 2759 | ||
| 2781 | struct signalTranslate | ||
| 2782 | { | ||
| 2783 | int sig; | ||
| 2784 | char key; | ||
| 2785 | }; | ||
| 2786 | |||
| 2787 | struct signalTranslate translate[] = | ||
| 2788 | { | ||
| 2789 | {SIGINT, '\x03'}, // ^C | ||
| 2790 | {SIGCONT, '\x11'}, // ^Q | ||
| 2791 | {SIGSTOP, '\x13'}, // ^S | ||
| 2792 | // {SIGINFO, '\x14'}, // ^T | ||
| 2793 | {SIGTSTP, '\x1A'}, // ^Z | ||
| 2794 | {SIGQUIT, '\x1C'} // "^\" | ||
| 2795 | }; | ||
| 2796 | |||
| 2797 | static void handleSignals(int signo) | ||
| 2798 | { | ||
| 2799 | int j; | ||
| 2800 | |||
| 2801 | for (j = 0; j < (sizeof(translate) / sizeof(*translate)); j++) | ||
| 2802 | { | ||
| 2803 | if (translate[j].sig == signo) | ||
| 2804 | { | ||
| 2805 | write(signalPipe[1], &translate[j].key, 1); | ||
| 2806 | break; | ||
| 2807 | } | ||
| 2808 | } | ||
| 2809 | } | ||
| 2810 | 2760 | ||
| 2811 | void boxes_main(void) | 2761 | void boxes_main(void) | 
| 2812 | { | 2762 | { | 
| @@ -2814,23 +2764,6 @@ void boxes_main(void) | |||
| 2814 | struct termios termio, oldtermio; | 2764 | struct termios termio, oldtermio; | 
| 2815 | char *prompt = "Enter a command : "; | 2765 | char *prompt = "Enter a command : "; | 
| 2816 | unsigned W = 80, H = 24; | 2766 | unsigned W = 80, H = 24; | 
| 2817 | int signalPipe[2]; | ||
| 2818 | struct sigaction sigAction, oldSigActions[6]; | ||
| 2819 | |||
| 2820 | // Set up pipes and signal handlers for catching keys that are normally signals. | ||
| 2821 | if (pipe(signalPipe)) perror_exit("can't open a pipe"); | ||
| 2822 | fcntl(signalPipe[0], F_SETFL, O_NONBLOCK); | ||
| 2823 | fcntl(signalPipe[1], F_SETFL, O_NONBLOCK); | ||
| 2824 | // Assumes that sigAction is not messed with by sigaction(). | ||
| 2825 | memset(&sigAction, 0, sizeof(sigAction)); | ||
| 2826 | sigAction.sa_handler = handleSignals; | ||
| 2827 | sigAction.sa_flags = SA_RESTART; // Useless since we are using poll. | ||
| 2828 | if (sigaction(SIGINT, &sigAction, &oldSigActions[0])) perror_exit("can't set signal handler SIGINT"); // Crashes with "poll: Interrupted system call" | ||
| 2829 | if (sigaction(SIGCONT, &sigAction, &oldSigActions[1])) perror_exit("can't set signal handler SIGCONT"); // Not needed it seems. | ||
| 2830 | // if (sigaction(SIGSTOP, &sigAction, &oldSigActions[2])) perror_exit("can't set signal handler SIGSTOP"); // Can't be done, screw emacs and vi. "can't set signal handler SIGSTOP: Invalid argument" | ||
| 2831 | // if (sigaction(SIGINFO, &sigAction, &oldSigActions[3])) perror_exit("can't set signal handler SIGINFO"); // No such thing as SIGINFO without special foo. | ||
| 2832 | if (sigaction(SIGTSTP, &sigAction, &oldSigActions[4])) perror_exit("can't set signal handler SIGTSTP"); // Crashes with "poll: Interrupted system call" | ||
| 2833 | if (sigaction(SIGQUIT, &sigAction, &oldSigActions[5])) perror_exit("can't set signal handler SIGQUIT"); // Crashes with "poll: Interrupted system call" if using "^\" | ||
| 2834 | 2767 | ||
| 2835 | // For testing purposes, figure out which context we use. When this gets real, the toybox multiplexer will sort this out for us instead. | 2768 | // For testing purposes, figure out which context we use. When this gets real, the toybox multiplexer will sort this out for us instead. | 
| 2836 | if (toys.optflags & FLAG_m) | 2769 | if (toys.optflags & FLAG_m) | 
| @@ -2934,14 +2867,6 @@ void boxes_main(void) | |||
| 2934 | // Restore the old terminal settings. | 2867 | // Restore the old terminal settings. | 
| 2935 | tcsetattr(0, TCSANOW, &oldtermio); | 2868 | tcsetattr(0, TCSANOW, &oldtermio); | 
| 2936 | 2869 | ||
| 2937 | // Probaly don't need to restore these before quitting, but including this in the example. | ||
| 2938 | sigaction(SIGINT, &oldSigActions[0], NULL); | ||
| 2939 | sigaction(SIGCONT, &oldSigActions[1], NULL); | ||
| 2940 | // sigaction(SIGSTOP, &oldSigActions[2], NULL); | ||
| 2941 | // sigaction(SIGINFO, &oldSigActions[3], NULL); | ||
| 2942 | sigaction(SIGTSTP, &oldSigActions[4], NULL); | ||
| 2943 | sigaction(SIGQUIT, &oldSigActions[5], NULL); | ||
| 2944 | |||
| 2945 | puts("\n"); | 2870 | puts("\n"); | 
| 2946 | fflush(stdout); | 2871 | fflush(stdout); | 
| 2947 | } | 2872 | } | 
