aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--newlib/Makefile.in21
-rw-r--r--newlib/libc/machine/riscv/Makefile.inc2
-rw-r--r--newlib/libc/machine/riscv/stpcpy.c7
-rw-r--r--newlib/libc/machine/riscv/strcpy.c52
-rw-r--r--newlib/libc/machine/riscv/strlen.c48
-rw-r--r--newlib/libc/machine/riscv/sys/asm.h4
-rw-r--r--newlib/libc/machine/riscv/sys/string.h107
-rw-r--r--winsup/cygwin/fhandler/console.cc49
-rw-r--r--winsup/cygwin/local_includes/fhandler.h4
-rw-r--r--winsup/cygwin/release/3.6.15
10 files changed, 200 insertions, 99 deletions
diff --git a/newlib/Makefile.in b/newlib/Makefile.in
index a1319a8..52b5d80 100644
--- a/newlib/Makefile.in
+++ b/newlib/Makefile.in
@@ -856,7 +856,7 @@ check_PROGRAMS =
@HAVE_LIBC_MACHINE_PRU_TRUE@am__append_113 = libc/machine/pru/setjmp.s
@HAVE_LIBC_MACHINE_RISCV_TRUE@am__append_114 = \
@HAVE_LIBC_MACHINE_RISCV_TRUE@ libc/machine/riscv/memmove.S libc/machine/riscv/memmove-stub.c libc/machine/riscv/memset.S libc/machine/riscv/memcpy-asm.S libc/machine/riscv/memcpy.c libc/machine/riscv/strlen.c \
-@HAVE_LIBC_MACHINE_RISCV_TRUE@ libc/machine/riscv/strcpy.c libc/machine/riscv/strcmp.S libc/machine/riscv/setjmp.S libc/machine/riscv/ieeefp.c libc/machine/riscv/ffs.c
+@HAVE_LIBC_MACHINE_RISCV_TRUE@ libc/machine/riscv/strcpy.c libc/machine/riscv/stpcpy.c libc/machine/riscv/strcmp.S libc/machine/riscv/setjmp.S libc/machine/riscv/ieeefp.c libc/machine/riscv/ffs.c
@HAVE_LIBC_MACHINE_RL78_TRUE@am__append_115 = libc/machine/rl78/setjmp.S
@HAVE_LIBC_MACHINE_RX_TRUE@am__append_116 = \
@@ -2183,6 +2183,7 @@ am__objects_51 = libc/ssp/libc_a-chk_fail.$(OBJEXT) \
@HAVE_LIBC_MACHINE_RISCV_TRUE@ libc/machine/riscv/libc_a-memcpy.$(OBJEXT) \
@HAVE_LIBC_MACHINE_RISCV_TRUE@ libc/machine/riscv/libc_a-strlen.$(OBJEXT) \
@HAVE_LIBC_MACHINE_RISCV_TRUE@ libc/machine/riscv/libc_a-strcpy.$(OBJEXT) \
+@HAVE_LIBC_MACHINE_RISCV_TRUE@ libc/machine/riscv/libc_a-stpcpy.$(OBJEXT) \
@HAVE_LIBC_MACHINE_RISCV_TRUE@ libc/machine/riscv/libc_a-strcmp.$(OBJEXT) \
@HAVE_LIBC_MACHINE_RISCV_TRUE@ libc/machine/riscv/libc_a-setjmp.$(OBJEXT) \
@HAVE_LIBC_MACHINE_RISCV_TRUE@ libc/machine/riscv/libc_a-ieeefp.$(OBJEXT) \
@@ -9178,6 +9179,9 @@ libc/machine/riscv/libc_a-strlen.$(OBJEXT): \
libc/machine/riscv/libc_a-strcpy.$(OBJEXT): \
libc/machine/riscv/$(am__dirstamp) \
libc/machine/riscv/$(DEPDIR)/$(am__dirstamp)
+libc/machine/riscv/libc_a-stpcpy.$(OBJEXT): \
+ libc/machine/riscv/$(am__dirstamp) \
+ libc/machine/riscv/$(DEPDIR)/$(am__dirstamp)
libc/machine/riscv/libc_a-strcmp.$(OBJEXT): \
libc/machine/riscv/$(am__dirstamp) \
libc/machine/riscv/$(DEPDIR)/$(am__dirstamp)
@@ -13141,6 +13145,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@libc/machine/riscv/$(DEPDIR)/libc_a-memmove.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@libc/machine/riscv/$(DEPDIR)/libc_a-memset.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@libc/machine/riscv/$(DEPDIR)/libc_a-setjmp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@libc/machine/riscv/$(DEPDIR)/libc_a-stpcpy.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@libc/machine/riscv/$(DEPDIR)/libc_a-strcmp.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@libc/machine/riscv/$(DEPDIR)/libc_a-strcpy.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@libc/machine/riscv/$(DEPDIR)/libc_a-strlen.Po@am__quote@
@@ -34800,6 +34805,20 @@ libc/machine/riscv/libc_a-strcpy.obj: libc/machine/riscv/strcpy.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libc_a_CPPFLAGS) $(CPPFLAGS) $(libc_a_CFLAGS) $(CFLAGS) -c -o libc/machine/riscv/libc_a-strcpy.obj `if test -f 'libc/machine/riscv/strcpy.c'; then $(CYGPATH_W) 'libc/machine/riscv/strcpy.c'; else $(CYGPATH_W) '$(srcdir)/libc/machine/riscv/strcpy.c'; fi`
+libc/machine/riscv/libc_a-stpcpy.o: libc/machine/riscv/stpcpy.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libc_a_CPPFLAGS) $(CPPFLAGS) $(libc_a_CFLAGS) $(CFLAGS) -MT libc/machine/riscv/libc_a-stpcpy.o -MD -MP -MF libc/machine/riscv/$(DEPDIR)/libc_a-stpcpy.Tpo -c -o libc/machine/riscv/libc_a-stpcpy.o `test -f 'libc/machine/riscv/stpcpy.c' || echo '$(srcdir)/'`libc/machine/riscv/stpcpy.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libc/machine/riscv/$(DEPDIR)/libc_a-stpcpy.Tpo libc/machine/riscv/$(DEPDIR)/libc_a-stpcpy.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libc/machine/riscv/stpcpy.c' object='libc/machine/riscv/libc_a-stpcpy.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libc_a_CPPFLAGS) $(CPPFLAGS) $(libc_a_CFLAGS) $(CFLAGS) -c -o libc/machine/riscv/libc_a-stpcpy.o `test -f 'libc/machine/riscv/stpcpy.c' || echo '$(srcdir)/'`libc/machine/riscv/stpcpy.c
+
+libc/machine/riscv/libc_a-stpcpy.obj: libc/machine/riscv/stpcpy.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libc_a_CPPFLAGS) $(CPPFLAGS) $(libc_a_CFLAGS) $(CFLAGS) -MT libc/machine/riscv/libc_a-stpcpy.obj -MD -MP -MF libc/machine/riscv/$(DEPDIR)/libc_a-stpcpy.Tpo -c -o libc/machine/riscv/libc_a-stpcpy.obj `if test -f 'libc/machine/riscv/stpcpy.c'; then $(CYGPATH_W) 'libc/machine/riscv/stpcpy.c'; else $(CYGPATH_W) '$(srcdir)/libc/machine/riscv/stpcpy.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libc/machine/riscv/$(DEPDIR)/libc_a-stpcpy.Tpo libc/machine/riscv/$(DEPDIR)/libc_a-stpcpy.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libc/machine/riscv/stpcpy.c' object='libc/machine/riscv/libc_a-stpcpy.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libc_a_CPPFLAGS) $(CPPFLAGS) $(libc_a_CFLAGS) $(CFLAGS) -c -o libc/machine/riscv/libc_a-stpcpy.obj `if test -f 'libc/machine/riscv/stpcpy.c'; then $(CYGPATH_W) 'libc/machine/riscv/stpcpy.c'; else $(CYGPATH_W) '$(srcdir)/libc/machine/riscv/stpcpy.c'; fi`
+
libc/machine/riscv/libc_a-ieeefp.o: libc/machine/riscv/ieeefp.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libc_a_CPPFLAGS) $(CPPFLAGS) $(libc_a_CFLAGS) $(CFLAGS) -MT libc/machine/riscv/libc_a-ieeefp.o -MD -MP -MF libc/machine/riscv/$(DEPDIR)/libc_a-ieeefp.Tpo -c -o libc/machine/riscv/libc_a-ieeefp.o `test -f 'libc/machine/riscv/ieeefp.c' || echo '$(srcdir)/'`libc/machine/riscv/ieeefp.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libc/machine/riscv/$(DEPDIR)/libc_a-ieeefp.Tpo libc/machine/riscv/$(DEPDIR)/libc_a-ieeefp.Po
diff --git a/newlib/libc/machine/riscv/Makefile.inc b/newlib/libc/machine/riscv/Makefile.inc
index 47bbce0..4d6c046 100644
--- a/newlib/libc/machine/riscv/Makefile.inc
+++ b/newlib/libc/machine/riscv/Makefile.inc
@@ -1,3 +1,3 @@
libc_a_SOURCES += \
%D%/memmove.S %D%/memmove-stub.c %D%/memset.S %D%/memcpy-asm.S %D%/memcpy.c %D%/strlen.c \
- %D%/strcpy.c %D%/strcmp.S %D%/setjmp.S %D%/ieeefp.c %D%/ffs.c
+ %D%/strcpy.c %D%/stpcpy.c %D%/strcmp.S %D%/setjmp.S %D%/ieeefp.c %D%/ffs.c
diff --git a/newlib/libc/machine/riscv/stpcpy.c b/newlib/libc/machine/riscv/stpcpy.c
new file mode 100644
index 0000000..9243457
--- /dev/null
+++ b/newlib/libc/machine/riscv/stpcpy.c
@@ -0,0 +1,7 @@
+#include <string.h>
+#include <stdbool.h>
+
+char *stpcpy(char *dst, const char *src)
+{
+ return __libc_strcpy(dst, src, false);
+}
diff --git a/newlib/libc/machine/riscv/strcpy.c b/newlib/libc/machine/riscv/strcpy.c
index 08aef64..f770493 100644
--- a/newlib/libc/machine/riscv/strcpy.c
+++ b/newlib/libc/machine/riscv/strcpy.c
@@ -10,57 +10,9 @@
*/
#include <string.h>
-#include <stdint.h>
+#include <stdbool.h>
char *strcpy(char *dst, const char *src)
{
- char *dst0 = dst;
-
-#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
-#if !(__riscv_misaligned_slow || __riscv_misaligned_fast)
- int misaligned = ((uintptr_t)dst | (uintptr_t)src) & (sizeof (long) - 1);
- if (__builtin_expect(!misaligned, 1))
-#endif
- {
- long *ldst = (long *)dst;
- const long *lsrc = (const long *)src;
-
- while (!__libc_detect_null(*lsrc))
- *ldst++ = *lsrc++;
-
- dst = (char *)ldst;
- src = (const char *)lsrc;
-
- char c0 = src[0];
- char c1 = src[1];
- char c2 = src[2];
- if (!(*dst++ = c0)) return dst0;
- if (!(*dst++ = c1)) return dst0;
- char c3 = src[3];
- if (!(*dst++ = c2)) return dst0;
- if (sizeof (long) == 4) goto out;
- char c4 = src[4];
- if (!(*dst++ = c3)) return dst0;
- char c5 = src[5];
- if (!(*dst++ = c4)) return dst0;
- char c6 = src[6];
- if (!(*dst++ = c5)) return dst0;
- if (!(*dst++ = c6)) return dst0;
-
-out:
- *dst++ = 0;
- return dst0;
- }
-#endif /* not PREFER_SIZE_OVER_SPEED */
-
- char ch;
- do
- {
- ch = *src;
- src++;
- dst++;
- *(dst - 1) = ch;
- } while (ch);
-
- return dst0;
+ return __libc_strcpy(dst, src, true);
}
diff --git a/newlib/libc/machine/riscv/strlen.c b/newlib/libc/machine/riscv/strlen.c
index 3b04066..7e5d416 100644
--- a/newlib/libc/machine/riscv/strlen.c
+++ b/newlib/libc/machine/riscv/strlen.c
@@ -11,6 +11,7 @@
#include <string.h>
#include <stdint.h>
+#include "sys/asm.h"
size_t strlen(const char *str)
{
@@ -21,33 +22,44 @@ size_t strlen(const char *str)
;
return str - start - 1;
#else
- if (__builtin_expect ((uintptr_t)str & (sizeof (long) - 1), 0)) do
+ if (__builtin_expect ((uintxlen_t)str & (sizeof (uintxlen_t) - 1), 0)) do
{
char ch = *str;
str++;
if (!ch)
- return str - start - 1;
- } while ((uintptr_t)str & (sizeof (long) - 1));
+ return str - start - 1;
+ } while ((uintxlen_t)str & (sizeof (uintxlen_t) - 1));
- unsigned long *ls = (unsigned long *)str;
- while (!__libc_detect_null (*ls++))
+ uintxlen_t *ps = (uintxlen_t *)str;
+ uintxlen_t psval;
+
+ while (!__libc_detect_null ((psval = *ps++)))
;
- asm volatile ("" : "+r"(ls)); /* prevent "optimization" */
+ asm volatile ("" : "+r"(ps)); /* prevent "optimization" */
+
+ str = (const char *)ps;
+ size_t ret = str - start, sp = sizeof (*ps);
- str = (const char *)ls;
- size_t ret = str - start, sl = sizeof (long);
+ #if __riscv_zbb
+ psval = ~__LIBC_RISCV_ZBB_ORC_B(psval);
+ psval = __LIBC_RISCV_ZBB_CNT_Z(psval);
- char c0 = str[0 - sl], c1 = str[1 - sl], c2 = str[2 - sl], c3 = str[3 - sl];
- if (c0 == 0) return ret + 0 - sl;
- if (c1 == 0) return ret + 1 - sl;
- if (c2 == 0) return ret + 2 - sl;
- if (sl == 4 || c3 == 0) return ret + 3 - sl;
+ return ret + (psval >> 3) - sp;
+ #else
+ char c0 = str[0 - sp], c1 = str[1 - sp], c2 = str[2 - sp], c3 = str[3 - sp];
+ if (c0 == 0) return ret + 0 - sp;
+ if (c1 == 0) return ret + 1 - sp;
+ if (c2 == 0) return ret + 2 - sp;
+ if (c3 == 0) return ret + 3 - sp;
- c0 = str[4 - sl], c1 = str[5 - sl], c2 = str[6 - sl], c3 = str[7 - sl];
- if (c0 == 0) return ret + 4 - sl;
- if (c1 == 0) return ret + 5 - sl;
- if (c2 == 0) return ret + 6 - sl;
+ #if __riscv_xlen == 64
+ c0 = str[4 - sp], c1 = str[5 - sp], c2 = str[6 - sp];
+ if (c0 == 0) return ret + 4 - sp;
+ if (c1 == 0) return ret + 5 - sp;
+ if (c2 == 0) return ret + 6 - sp;
+ #endif
- return ret + 7 - sl;
+ return ret + 7 - sp;
+ #endif
#endif /* not PREFER_SIZE_OVER_SPEED */
}
diff --git a/newlib/libc/machine/riscv/sys/asm.h b/newlib/libc/machine/riscv/sys/asm.h
index 8c8aeb3..0a354b2 100644
--- a/newlib/libc/machine/riscv/sys/asm.h
+++ b/newlib/libc/machine/riscv/sys/asm.h
@@ -12,6 +12,8 @@
#ifndef _SYS_ASM_H
#define _SYS_ASM_H
+#include <stdint.h>
+
/*
* Macros to handle different pointer/register sizes for 32/64-bit code
*/
@@ -20,11 +22,13 @@
# define SZREG 8
# define REG_S sd
# define REG_L ld
+typedef uint64_t uintxlen_t;
#elif __riscv_xlen == 32
# define PTRLOG 2
# define SZREG 4
# define REG_S sw
# define REG_L lw
+typedef uint32_t uintxlen_t;
#else
# error __riscv_xlen must equal 32 or 64
#endif
diff --git a/newlib/libc/machine/riscv/sys/string.h b/newlib/libc/machine/riscv/sys/string.h
index beebe31..b65635c 100644
--- a/newlib/libc/machine/riscv/sys/string.h
+++ b/newlib/libc/machine/riscv/sys/string.h
@@ -12,12 +12,113 @@
#ifndef _SYS_STRING_H
#define _SYS_STRING_H
-static __inline unsigned long __libc_detect_null(unsigned long w)
+#include <stdbool.h>
+#include "asm.h"
+
+#if __riscv_zbb
+ #include <riscv_bitmanip.h>
+
+ // Determine which intrinsics to use based on XLEN and endianness
+ #if __riscv_xlen == 64
+ #define __LIBC_RISCV_ZBB_ORC_B(x) __riscv_orc_b_64(x)
+
+ #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ #define __LIBC_RISCV_ZBB_CNT_Z(x) __riscv_ctz_64(x)
+ #else
+ #define __LIBC_RISCV_ZBB_CNT_Z(x) __riscv_clz_64(x)
+ #endif
+ #else
+ #define __LIBC_RISCV_ZBB_ORC_B(x) __riscv_orc_b_32(x)
+
+ #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ #define __LIBC_RISCV_ZBB_CNT_Z(x) __riscv_ctz_32(x)
+ #else
+ #define __LIBC_RISCV_ZBB_CNT_Z(x) __riscv_clz_32(x)
+ #endif
+ #endif
+#endif
+
+
+static __inline uintxlen_t __libc_detect_null(uintxlen_t w)
{
- unsigned long mask = 0x7f7f7f7f;
- if (sizeof (long) == 8)
+#if __riscv_zbb
+ /*
+ If there are any zeros in each byte of the register, all bits will
+ be unset for that byte value, otherwise, all bits will be set.
+ If the value is -1, all bits are set, meaning no null byte was found.
+ */
+ return __LIBC_RISCV_ZBB_ORC_B(w) != -1;
+#else
+ uintxlen_t mask = 0x7f7f7f7f;
+ #if __riscv_xlen == 64
mask = ((mask << 16) << 16) | mask;
+ #endif
return ~(((w & mask) + mask) | w | mask);
+#endif
}
+
+static __inline char *__libc_strcpy(char *dst, const char *src, bool ret_start)
+{
+ char *dst0 = dst;
+
+#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
+#if !(__riscv_misaligned_slow || __riscv_misaligned_fast)
+ int misaligned = ((uintxlen_t)dst | (uintxlen_t)src) & (sizeof (uintxlen_t) - 1);
+ if (__builtin_expect(!misaligned, 1))
+#endif
+ {
+ uintxlen_t *pdst = (uintxlen_t *)dst;
+ const uintxlen_t *psrc = (const uintxlen_t *)src;
+
+ while (!__libc_detect_null(*psrc))
+ *pdst++ = *psrc++;
+
+ dst = (char *)pdst;
+ src = (const char *)psrc;
+
+ if (ret_start)
+ {
+ if (!(*dst++ = src[0])) return dst0;
+ if (!(*dst++ = src[1])) return dst0;
+ if (!(*dst++ = src[2])) return dst0;
+ if (!(*dst++ = src[3])) return dst0;
+ #if __riscv_xlen == 64
+ if (!(*dst++ = src[4])) return dst0;
+ if (!(*dst++ = src[5])) return dst0;
+ if (!(*dst++ = src[6])) return dst0;
+ #endif
+ }
+ else
+ {
+ if (!(*dst++ = src[0])) return dst - 1;
+ if (!(*dst++ = src[1])) return dst - 1;
+ if (!(*dst++ = src[2])) return dst - 1;
+ if (!(*dst++ = src[3])) return dst - 1;
+ #if __riscv_xlen == 64
+ if (!(*dst++ = src[4])) return dst - 1;
+ if (!(*dst++ = src[5])) return dst - 1;
+ if (!(*dst++ = src[6])) return dst - 1;
+ dst0 = dst;
+ #endif
+ }
+
+ *dst = 0;
+ return dst0;
+ }
+#endif /* not PREFER_SIZE_OVER_SPEED */
+
+ char ch;
+ do
+ {
+ ch = *src;
+ src++;
+ dst++;
+ *(dst - 1) = ch;
+ } while (ch);
+
+ return ret_start ? dst0 : dst - 1;
+}
+
+
#endif
diff --git a/winsup/cygwin/fhandler/console.cc b/winsup/cygwin/fhandler/console.cc
index da335b3..f162698 100644
--- a/winsup/cygwin/fhandler/console.cc
+++ b/winsup/cygwin/fhandler/console.cc
@@ -804,6 +804,9 @@ fhandler_console::rabuflen ()
return con_ra.rabuflen;
}
+static DWORD prev_input_mode_backup;
+static DWORD prev_output_mode_backup;
+
/* The function set_{in,out}put_mode() should be static so that they
can be called even after the fhandler_console instance is deleted. */
void
@@ -818,11 +821,11 @@ fhandler_console::set_input_mode (tty::cons_mode m, const termios *t,
GetConsoleMode (p->input_handle, &oflags);
DWORD flags = oflags
& (ENABLE_EXTENDED_FLAGS | ENABLE_INSERT_MODE | ENABLE_QUICK_EDIT_MODE);
- con.curr_input_mode = m;
switch (m)
{
case tty::restore:
- flags |= ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT;
+ flags = con.prev_input_mode;
+ con.prev_input_mode = prev_input_mode_backup;
break;
case tty::cygwin:
flags |= ENABLE_WINDOW_INPUT;
@@ -846,6 +849,12 @@ fhandler_console::set_input_mode (tty::cons_mode m, const termios *t,
flags |= ENABLE_PROCESSED_INPUT;
break;
}
+ if (con.curr_input_mode != tty::cygwin && m == tty::cygwin)
+ {
+ prev_input_mode_backup = con.prev_input_mode;
+ con.prev_input_mode = oflags;
+ }
+ con.curr_input_mode = m;
SetConsoleMode (p->input_handle, flags);
if (!(oflags & ENABLE_VIRTUAL_TERMINAL_INPUT)
&& (flags & ENABLE_VIRTUAL_TERMINAL_INPUT)
@@ -868,10 +877,11 @@ fhandler_console::set_output_mode (tty::cons_mode m, const termios *t,
if (con.orig_virtual_terminal_processing_mode)
flags |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
WaitForSingleObject (p->output_mutex, mutex_timeout);
- con.curr_output_mode = m;
switch (m)
{
case tty::restore:
+ flags = con.prev_output_mode;
+ con.prev_output_mode = prev_output_mode_backup;
break;
case tty::cygwin:
if (wincap.has_con_24bit_colors () && !con_is_legacy)
@@ -883,6 +893,12 @@ fhandler_console::set_output_mode (tty::cons_mode m, const termios *t,
flags |= DISABLE_NEWLINE_AUTO_RETURN;
break;
}
+ if (con.curr_output_mode != tty::cygwin && m == tty::cygwin)
+ {
+ prev_output_mode_backup = con.prev_output_mode;
+ GetConsoleMode (p->output_handle, &con.prev_output_mode);
+ }
+ con.curr_output_mode = m;
acquire_attach_mutex (mutex_timeout);
DWORD resume_pid = attach_console (con.owner);
SetConsoleMode (p->output_handle, flags);
@@ -916,7 +932,7 @@ fhandler_console::cleanup_for_non_cygwin_app (handle_set_t *p)
/* Cleaning-up console mode for non-cygwin app. */
/* conmode can be tty::restore when non-cygwin app is
exec'ed from login shell. */
- tty::cons_mode conmode = cons_mode_on_close (p);
+ tty::cons_mode conmode = cons_mode_on_close ();
set_output_mode (conmode, ti, p);
set_input_mode (conmode, ti, p);
set_disable_master_thread (con.owner == GetCurrentProcessId ());
@@ -1978,9 +1994,8 @@ fhandler_console::close (int flag)
if (shared_console_info[unit] && myself->ppid == 1
&& (dev_t) myself->ctty == get_device ())
{
- tty::cons_mode conmode = cons_mode_on_close (&handle_set);
- set_output_mode (conmode, &get_ttyp ()->ti, &handle_set);
- set_input_mode (conmode, &get_ttyp ()->ti, &handle_set);
+ set_output_mode (tty::restore, &get_ttyp ()->ti, &handle_set);
+ set_input_mode (tty::restore, &get_ttyp ()->ti, &handle_set);
set_disable_master_thread (true, this);
}
@@ -4687,26 +4702,10 @@ fhandler_console::fstat (struct stat *st)
}
tty::cons_mode
-fhandler_console::cons_mode_on_close (handle_set_t *p)
+fhandler_console::cons_mode_on_close ()
{
- const _minor_t unit = p->unit;
-
if (myself->ppid != 1) /* Execed from normal cygwin process. */
return tty::cygwin;
- if (!process_alive (con.owner)) /* The Master process already died. */
- return tty::restore;
- if (con.owner == GetCurrentProcessId ()) /* Master process */
- return tty::restore;
-
- PROCESS_BASIC_INFORMATION pbi;
- NTSTATUS status =
- NtQueryInformationProcess (GetCurrentProcess (), ProcessBasicInformation,
- &pbi, sizeof (pbi), NULL);
- if (NT_SUCCESS (status)
- && con.owner == (DWORD) pbi.InheritedFromUniqueProcessId)
- /* The parent is the stub process. */
- return tty::restore;
-
- return tty::native; /* Otherwise */
+ return tty::restore; /* otherwise, restore */
}
diff --git a/winsup/cygwin/local_includes/fhandler.h b/winsup/cygwin/local_includes/fhandler.h
index b00a1a1..8c71d84 100644
--- a/winsup/cygwin/local_includes/fhandler.h
+++ b/winsup/cygwin/local_includes/fhandler.h
@@ -2146,6 +2146,8 @@ class dev_console
bool disable_master_thread;
tty::cons_mode curr_input_mode;
tty::cons_mode curr_output_mode;
+ DWORD prev_input_mode;
+ DWORD prev_output_mode;
bool master_thread_suspended;
int num_processed; /* Number of input events in the current input buffer
already processed by cons_master_thread(). */
@@ -2366,7 +2368,7 @@ private:
void setup_pcon_hand_over ();
static void pcon_hand_over_proc ();
- static tty::cons_mode cons_mode_on_close (handle_set_t *);
+ static tty::cons_mode cons_mode_on_close ();
friend tty_min * tty_list::get_cttyp ();
};
diff --git a/winsup/cygwin/release/3.6.1 b/winsup/cygwin/release/3.6.1
new file mode 100644
index 0000000..0b54b5f
--- /dev/null
+++ b/winsup/cygwin/release/3.6.1
@@ -0,0 +1,5 @@
+Fixes:
+------
+
+- Console mode is really restored to the previous mode.
+ Addresses: https://github.com/msys2/msys2-runtime/issues/268