diff options
Diffstat (limited to '')
| -rw-r--r-- | boxes.c | 75 |
1 files changed, 32 insertions, 43 deletions
| @@ -32,14 +32,6 @@ config BOXES | |||
| 32 | Stick chars means to use ASCII for the boxes instead of "graphics" characters. | 32 | Stick chars means to use ASCII for the boxes instead of "graphics" characters. |
| 33 | */ | 33 | */ |
| 34 | 34 | ||
| 35 | |||
| 36 | /* We need to catch some signals, coz some things are only sent as | ||
| 37 | signals. If we use poll or select, we get the race condition from the | ||
| 38 | signals, which can cause crashes. Poll is preferable over select in | ||
| 39 | general. So I was using poll originally. However, ppoll is Linux | ||
| 40 | specific, and worse, needs to define the following swear words... | ||
| 41 | */ | ||
| 42 | #define _GNU_SOURCE | ||
| 43 | #include "toys.h" | 35 | #include "toys.h" |
| 44 | 36 | ||
| 45 | GLOBALS( | 37 | GLOBALS( |
| @@ -1872,7 +1864,7 @@ Some editors have a shortcut command concept. The smallest unique first part of | |||
| 1872 | 1864 | ||
| 1873 | void editLine(long extra, void (*lineChar)(long extra, char *buffer), struct keyCommand * (*lineCommand)(long extra, char *command)) | 1865 | void editLine(long extra, void (*lineChar)(long extra, char *buffer), struct keyCommand * (*lineCommand)(long extra, char *command)) |
| 1874 | { | 1866 | { |
| 1875 | struct pollfd pollfds[1]; | 1867 | fd_set selectFds; |
| 1876 | struct timespec timeout; | 1868 | struct timespec timeout; |
| 1877 | sigset_t signalMask; | 1869 | sigset_t signalMask; |
| 1878 | 1870 | ||
| @@ -1906,8 +1898,8 @@ void editLine(long extra, void (*lineChar)(long extra, char *buffer), struct key | |||
| 1906 | } | 1898 | } |
| 1907 | 1899 | ||
| 1908 | // Apparently it's more portable to reset these each time. | 1900 | // Apparently it's more portable to reset these each time. |
| 1909 | memset(pollfds, 0, pollcount * sizeof(struct pollfd)); | 1901 | FD_ZERO(&selectFds); |
| 1910 | pollfds[0].events = POLLIN; pollfds[0].fd = 0; | 1902 | FD_SET(0, &selectFds); |
| 1911 | timeout.tv_sec = 0; timeout.tv_nsec = 100000000; // One tenth of a second. | 1903 | timeout.tv_sec = 0; timeout.tv_nsec = 100000000; // One tenth of a second. |
| 1912 | 1904 | ||
| 1913 | // 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). | 1905 | // 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). |
| @@ -1923,8 +1915,9 @@ void editLine(long extra, void (*lineChar)(long extra, char *buffer), struct key | |||
| 1923 | } | 1915 | } |
| 1924 | 1916 | ||
| 1925 | // TODO - Should only ask for a time out after we get an Escape. | 1917 | // TODO - Should only ask for a time out after we get an Escape. |
| 1926 | p = ppoll(pollfds, pollcount, &timeout, &signalMask); | 1918 | // I wanted to use poll, but that would mean using ppoll, which is Linux only, and involves defining swear words to get it. |
| 1927 | if (0 > p) | 1919 | p = pselect(0 + 1, &selectFds, NULL, NULL, &timeout, &signalMask); |
| 1920 | if (0 > p) | ||
| 1928 | { | 1921 | { |
| 1929 | if (EINTR == errno) | 1922 | if (EINTR == errno) |
| 1930 | continue; | 1923 | continue; |
| @@ -1941,41 +1934,37 @@ void editLine(long extra, void (*lineChar)(long extra, char *buffer), struct key | |||
| 1941 | // TODO - Send a timer event to lineCommand(). This wont be a precise timed event, but don't think we need one. | 1934 | // TODO - Send a timer event to lineCommand(). This wont be a precise timed event, but don't think we need one. |
| 1942 | } | 1935 | } |
| 1943 | 1936 | ||
| 1944 | while (0 < p) | 1937 | if (FD_ISSET(0, &selectFds)) |
| 1945 | { | 1938 | { |
| 1946 | p--; | 1939 | // I am assuming that we get the input atomically, each multibyte key fits neatly into one read. |
| 1947 | if (pollfds[p].revents & POLLIN) | 1940 | // If that's not true (which is entirely likely), then we have to get complicated with circular buffers and stuff, or just one byte at a time. |
| 1941 | j = read(0, &buffer[buffIndex], sizeof(buffer) - (buffIndex + 1)); | ||
| 1942 | if (j < 0) // An error happened. | ||
| 1948 | { | 1943 | { |
| 1949 | // I am assuming that we get the input atomically, each multibyte key fits neatly into one read. | 1944 | // For now, just ignore errors. |
| 1950 | // If that's not true (which is entirely likely), then we have to get complicated with circular buffers and stuff, or just one byte at a time. | 1945 | fprintf(stderr, "input error on %d\n", p); |
| 1951 | j = read(pollfds[p].fd, &buffer[index], sizeof(buffer) - (index + 1)); | 1946 | fflush(stderr); |
| 1952 | if (j < 0) // An error happened. | 1947 | } |
| 1953 | { | 1948 | else if (j == 0) // End of file. |
| 1954 | // For now, just ignore errors. | 1949 | { |
| 1955 | fprintf(stderr, "input error on %d\n", p); | 1950 | TT.stillRunning = 0; |
| 1956 | fflush(stderr); | 1951 | fprintf(stderr, "EOF\n"); |
| 1957 | } | 1952 | for (j = 0; buffer[j + 1]; j++) |
| 1958 | else if (j == 0) // End of file. | 1953 | fprintf(stderr, "(%x), ", (int) buffer[j]); |
| 1954 | fflush(stderr); | ||
| 1955 | } | ||
| 1956 | else | ||
| 1957 | { | ||
| 1958 | buffIndex += j; | ||
| 1959 | if (sizeof(buffer) < (buffIndex + 1)) // Ran out of buffer. | ||
| 1959 | { | 1960 | { |
| 1960 | TT.stillRunning = 0; | 1961 | fprintf(stderr, "Full buffer - %s -> %s\n", buffer, sequence); |
| 1961 | fprintf(stderr, "EOF\n"); | ||
| 1962 | for (j = 0; buffer[j + 1]; j++) | 1962 | for (j = 0; buffer[j + 1]; j++) |
| 1963 | fprintf(stderr, "(%x), ", (int) buffer[j]); | 1963 | fprintf(stderr, "(%x) %c, ", (int) buffer[j], buffer[j]); |
| 1964 | fflush(stderr); | 1964 | fflush(stderr); |
| 1965 | buffIndex = 0; | ||
| 1965 | } | 1966 | } |
| 1966 | else | 1967 | else buffer[buffIndex] = 0; |
| 1967 | { | ||
| 1968 | index += j; | ||
| 1969 | if (sizeof(buffer) < (index + 1)) // Ran out of buffer. | ||
| 1970 | { | ||
| 1971 | fprintf(stderr, "Full buffer - %s -> %s\n", buffer, command); | ||
| 1972 | for (j = 0; buffer[j + 1]; j++) | ||
| 1973 | fprintf(stderr, "(%x) %c, ", (int) buffer[j], buffer[j]); | ||
| 1974 | fflush(stderr); | ||
| 1975 | index = 0; | ||
| 1976 | } | ||
| 1977 | else buffer[index] = 0; | ||
| 1978 | } | ||
| 1979 | } | 1968 | } |
| 1980 | } | 1969 | } |
| 1981 | 1970 | ||
| @@ -2878,7 +2867,7 @@ void boxes_main(void) | |||
| 2878 | // Terminals send the SIGWINCH signal when they resize. | 2867 | // Terminals send the SIGWINCH signal when they resize. |
| 2879 | memset(&sigAction, 0, sizeof(sigAction)); | 2868 | memset(&sigAction, 0, sizeof(sigAction)); |
| 2880 | sigAction.sa_handler = handleSignals; | 2869 | sigAction.sa_handler = handleSignals; |
| 2881 | sigAction.sa_flags = SA_RESTART;// Useless since we are using poll. | 2870 | sigAction.sa_flags = SA_RESTART;// Useless if we are using poll. |
| 2882 | if (sigaction(SIGWINCH, &sigAction, &oldSigActions)) perror_exit("can't set signal handler SIGWINCH"); | 2871 | if (sigaction(SIGWINCH, &sigAction, &oldSigActions)) perror_exit("can't set signal handler SIGWINCH"); |
| 2883 | terminal_size(&W, &H); | 2872 | terminal_size(&W, &H); |
| 2884 | if (toys.optflags & FLAG_w) | 2873 | if (toys.optflags & FLAG_w) |
