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.
-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 | } |