aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/bindings/wtf-bindings.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/bun.js/bindings/wtf-bindings.cpp')
-rw-r--r--src/bun.js/bindings/wtf-bindings.cpp134
1 files changed, 134 insertions, 0 deletions
diff --git a/src/bun.js/bindings/wtf-bindings.cpp b/src/bun.js/bindings/wtf-bindings.cpp
index ccf71f8eb..6fd10721a 100644
--- a/src/bun.js/bindings/wtf-bindings.cpp
+++ b/src/bun.js/bindings/wtf-bindings.cpp
@@ -2,6 +2,8 @@
#include "wtf/StackTrace.h"
#include "wtf/dtoa.h"
+#include "wtf/Lock.h"
+#include "termios.h"
extern "C" double WTF__parseDouble(const LChar* string, size_t length, size_t* position)
{
@@ -13,6 +15,138 @@ extern "C" void WTF__copyLCharsFromUCharSource(LChar* destination, const UChar*
WTF::StringImpl::copyCharacters(destination, source, length);
}
+static int orig_termios_fd = -1;
+static struct termios orig_termios;
+static WTF::Lock orig_termios_lock;
+
+static int current_tty_mode = 0;
+static struct termios orig_tty_termios;
+
+int uv__tcsetattr(int fd, int how, const struct termios* term)
+{
+ int rc;
+
+ do
+ rc = tcsetattr(fd, how, term);
+ while (rc == -1 && errno == EINTR);
+
+ if (rc == -1)
+ return errno;
+
+ return 0;
+}
+
+static void uv__tty_make_raw(struct termios* tio)
+{
+ assert(tio != NULL);
+
+#if defined __sun || defined __MVS__
+ /*
+ * This implementation of cfmakeraw for Solaris and derivatives is taken from
+ * http://www.perkin.org.uk/posts/solaris-portability-cfmakeraw.html.
+ */
+ tio->c_iflag &= ~(IMAXBEL | IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
+ tio->c_oflag &= ~OPOST;
+ tio->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
+ tio->c_cflag &= ~(CSIZE | PARENB);
+ tio->c_cflag |= CS8;
+
+ /*
+ * By default, most software expects a pending read to block until at
+ * least one byte becomes available. As per termio(7I), this requires
+ * setting the MIN and TIME parameters appropriately.
+ *
+ * As a somewhat unfortunate artifact of history, the MIN and TIME slots
+ * in the control character array overlap with the EOF and EOL slots used
+ * for canonical mode processing. Because the EOF character needs to be
+ * the ASCII EOT value (aka Control-D), it has the byte value 4. When
+ * switching to raw mode, this is interpreted as a MIN value of 4; i.e.,
+ * reads will block until at least four bytes have been input.
+ *
+ * Other platforms with a distinct MIN slot like Linux and FreeBSD appear
+ * to default to a MIN value of 1, so we'll force that value here:
+ */
+ tio->c_cc[VMIN] = 1;
+ tio->c_cc[VTIME] = 0;
+#else
+ cfmakeraw(tio);
+#endif /* #ifdef __sun */
+}
+
+extern "C" int
+Bun__ttySetMode(int fd, int mode)
+{
+ struct termios tmp;
+ int expected;
+ int rc;
+
+ if (current_tty_mode == mode)
+ return 0;
+
+ if (current_tty_mode == 0 && mode != 0) {
+ do {
+ rc = tcgetattr(fd, &orig_tty_termios);
+ } while (rc == -1 && errno == EINTR);
+
+ if (rc == -1)
+ return errno;
+
+ {
+ /* This is used for uv_tty_reset_mode() */
+ LockHolder locker(orig_termios_lock);
+
+ if (orig_termios_fd == -1) {
+ orig_termios = orig_termios;
+ orig_termios_fd = fd;
+ }
+ }
+ }
+
+ tmp = orig_tty_termios;
+ switch (mode) {
+ case 0: // normal
+ break;
+ case 1: // raw
+ tmp.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
+ tmp.c_oflag |= (ONLCR);
+ tmp.c_cflag |= (CS8);
+ tmp.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
+ tmp.c_cc[VMIN] = 1;
+ tmp.c_cc[VTIME] = 0;
+ break;
+ case 2: // io
+ uv__tty_make_raw(&tmp);
+ break;
+ }
+
+ /* Apply changes after draining */
+ rc = uv__tcsetattr(fd, TCSADRAIN, &tmp);
+ if (rc == 0)
+ current_tty_mode = mode;
+
+ return rc;
+}
+
+int uv_tty_reset_mode(void)
+{
+ int saved_errno;
+ int err;
+
+ saved_errno = errno;
+
+ if (orig_termios_lock.tryLock())
+ return 16; // UV_EBUSY; /* In uv_tty_set_mode(). */
+
+ err = 0;
+ if (orig_termios_fd != -1)
+ err = uv__tcsetattr(orig_termios_fd, TCSANOW, &orig_termios);
+
+ orig_termios_lock.unlock();
+ errno = saved_errno;
+
+ return err;
+}
+
extern "C" void Bun__crashReportWrite(void* ctx, const char* message, size_t length);
extern "C" void Bun__crashReportDumpStackTrace(void* ctx)
{