diff options
author | David Walter Seikel | 2014-01-30 13:57:08 +1000 |
---|---|---|
committer | David Walter Seikel | 2014-01-30 13:57:08 +1000 |
commit | 1d24a8ef1768e5512cc0e5794b7435078bc8a926 (patch) | |
tree | 7855621f16870bb2414780fe040b7128f18ec624 | |
parent | Change the made up MC windows and command line keys. Now more MC like. (diff) | |
download | boxes-1d24a8ef1768e5512cc0e5794b7435078bc8a926.zip boxes-1d24a8ef1768e5512cc0e5794b7435078bc8a926.tar.gz boxes-1d24a8ef1768e5512cc0e5794b7435078bc8a926.tar.bz2 boxes-1d24a8ef1768e5512cc0e5794b7435078bc8a926.tar.xz |
Convert to using pselect(), more portable than ppoll().
-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) |