aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--boxes.c75
1 files changed, 32 insertions, 43 deletions
diff --git a/boxes.c b/boxes.c
index 9e556c0..f358e18 100644
--- a/boxes.c
+++ b/boxes.c
@@ -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
37signals. If we use poll or select, we get the race condition from the
38signals, which can cause crashes. Poll is preferable over select in
39general. So I was using poll originally. However, ppoll is Linux
40specific, and worse, needs to define the following swear words...
41*/
42#define _GNU_SOURCE
43#include "toys.h" 35#include "toys.h"
44 36
45GLOBALS( 37GLOBALS(
@@ -1872,7 +1864,7 @@ Some editors have a shortcut command concept. The smallest unique first part of
1872 1864
1873void editLine(long extra, void (*lineChar)(long extra, char *buffer), struct keyCommand * (*lineCommand)(long extra, char *command)) 1865void 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)