Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin')
-rw-r--r--winsup/cygwin/ChangeLog350
-rw-r--r--winsup/cygwin/DevNotes16
-rw-r--r--winsup/cygwin/cygheap.cc6
-rw-r--r--winsup/cygwin/cygheap_malloc.h8
-rw-r--r--winsup/cygwin/cygserver_ipc.h9
-rw-r--r--winsup/cygwin/cygwin.sc.in46
-rw-r--r--winsup/cygwin/dcrt0.cc8
-rw-r--r--winsup/cygwin/dir.cc5
-rw-r--r--winsup/cygwin/environ.cc48
-rw-r--r--winsup/cygwin/exception.h66
-rw-r--r--winsup/cygwin/exceptions.cc84
-rw-r--r--winsup/cygwin/external.cc21
-rw-r--r--winsup/cygwin/fhandler.h78
-rw-r--r--winsup/cygwin/fhandler_console.cc848
-rw-r--r--winsup/cygwin/fhandler_dsp.cc49
-rw-r--r--winsup/cygwin/flock.cc28
-rwxr-xr-xwinsup/cygwin/gendef22
-rw-r--r--winsup/cygwin/grp.cc6
-rw-r--r--winsup/cygwin/include/cygwin/config.h3
-rw-r--r--winsup/cygwin/include/cygwin/socket.h2
-rw-r--r--winsup/cygwin/include/cygwin/version.h6
-rw-r--r--winsup/cygwin/include/sys/cygwin.h16
-rw-r--r--winsup/cygwin/libc/strptime.cc19
-rw-r--r--winsup/cygwin/localtime.cc30
-rw-r--r--winsup/cygwin/ntea.cc28
-rw-r--r--winsup/cygwin/pinfo.cc99
-rw-r--r--winsup/cygwin/release/1.7.2944
-rw-r--r--winsup/cygwin/sec_auth.cc6
-rw-r--r--winsup/cygwin/setlsapwd.cc2
-rw-r--r--winsup/cygwin/shm.cc4
-rw-r--r--winsup/cygwin/sigproc.cc18
-rw-r--r--winsup/cygwin/sigproc.h16
32 files changed, 1327 insertions, 664 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index d2e188499..cbb43c71c 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,353 @@
+2014-04-07 Corinna Vinschen <corinna@vinschen.de>
+
+ * cygserver_ipc.h (ipc_set_proc_info): Add bool parameter to specify
+ whether or not to send signal_arrived.
+ * shm.cc (client_request_shm::client_request_shm): Call
+ ipc_set_proc_info with bool parameter set to true to not send
+ signal_arrived.
+
+2014-04-04 Corinna Vinschen <corinna@vinschen.de>
+
+ * ntea.cc (EA_BUFSIZ): Fix comment.
+ (read_ea): Use tmp_pathbuf for local buffer rather than alloca.
+ Throughout change ZwQueryEaFile to NtQueryEaFile in comments.
+
+2014-04-04 Corinna Vinschen <corinna@vinschen.de>
+
+ * ntea.cc (EA_BUFSIZ): Reduce to 64K. Add comment to explain why.
+
+2014-03-29 Christopher Faylor <me.cygwin2014@cgf.cx>
+
+ * DevNotes: Add entry cgf-000025.
+ * exceptions.cc (_cygtls::signal_debugger): Reorganize to avoid
+ contacting the debugger if we have already done so via the exception
+ handler. Eliminate need for goto. Remove an ifdef in favor of just
+ allocating a larger buffer.
+
+2014-03-28 Corinna Vinschen <corinna@vinschen.de>
+
+ * dcrt0.cc (dll_crt0_0): Install myfault exception handler on x86_64.
+ * exception.h (exception_list): Typedef as void on x86_64.
+ (exception::handler_installed): Remove.
+ (exception::handle_while_being_debugged): Remove.
+ (exception::myfault_handle): Declare for x86_64.
+ (exception::handle): Declare as ordinary exception handler on x86_64
+ as well.
+ (exception::exception): Drop previous code (again). Install
+ exception::handle as SEH handler.
+ (exception::install_myfault_handler): New x86_64-only method to
+ install exception::myfault_handle as VEH handler. Explain why.
+ (exception::~exception): For x86_64, define frame end label (again).
+ * exceptions.cc (CYG_EXC_CONTINUE_EXECUTION): Drop definition.
+ (CYG_EXC_CONTINUE_SEARCH): Ditto.
+ (exception::myfault_handle): New x86_64-only method, VEH handler to
+ handle myfault exceptions.
+ (exception::handle): Define as ordinary exception handler on x86_64
+ as well. Use ExceptionContinueExecution and ExceptionContinueSearch
+ throughout instead of deleted Cygwin macros. Don't handle myfault
+ exceptions on x86_64.
+
+2014-03-28 Corinna Vinschen <corinna@vinschen.de>
+
+ * sec_auth.cc (create_token): Initialize lsa handle to NULL, rather than
+ to INVALID_HANDLE_VALUE.
+ (lsaauth): Ditto.
+ (lsaprivkeyauth): Ditto.
+ * setlsapwd.cc (setlsapwd): Don't initialize lsa handle.
+
+2014-03-28 Corinna Vinschen <corinna@vinschen.de>
+
+ * exceptions.cc (_cygtls::signal_debugger): Move memcpy to copy context
+ from incoming siginfo_t to thread_context, too.
+
+2014-03-27 Corinna Vinschen <corinna@vinschen.de>
+
+ * gendef (_sigbe/x86_64): Fix typo in .seh_proc pseudo-op.
+ (setjmp/x86_64): Drop storing ExceptionList pointer in jmp_buf->Frame.
+ Drop comment. Store likely frame in rdx. Jump to __setjmpex.
+ (__setjmpex): New function providing setjmp functionality. Fetch
+ jmp_buf->Frame from rdx, like MSVCRT setjmpex.
+ (__sjfault/x86_64): Store rdx content in jmp_buf->Frame.
+ (__ljfault/x86_64): Don't restore ExceptionList pointer.
+ (longjmp/x86_64): Ditto.
+
+2014-03-19 Christopher Faylor <me.cygwin2014@cgf.cx>
+
+ * fhandler_dsp.cc (fhandler_dev_dsp::ioctl): Actually pass ioctl
+ argument to _ioctl.
+
+2014-03-19 Christopher Faylor <me.cygwin2014@cgf.cx>
+
+ * fhandler.h (fhandler_dev_dsp): Remove variable names from
+ declarations.
+ (fhandler_dev_dsp::close_audio_in): Make __reg1.
+ (fhandler_dev_dsp::close_audio_out): Make __reg2.
+ * fhandler_dsp.cc (fhandler_dev_dsp::close_audio_in): Make __reg1.
+ (fhandler_dev_dsp::close_audio_out): Make __reg2.
+ (fhandler_dev_dsp::close): Don't abruptly terminate sound just because
+ we are exiting.
+
+2014-03-19 Corinna Vinschen <corinna@vinschen.de>
+
+ * exception.h (exception::handle_while_being_debugged): Declare.
+ (exception::exception): Install unhandled exception filter.
+ * exceptions.cc (exception::handle_while_being_debugged): New method.
+
+2014-03-18 Christopher Faylor <me.cygwin2014@cgf.cx>
+
+ * fhandler_dsp.cc (fhandler_dev_dsp::fixup_after_fork): Actually call
+ _fixup_after_fork rather than looping forever.
+ (fhandler_dev_dsp::fixup_after_exec): Ditto.
+
+2014-03-18 Corinna Vinschen <corinna@vinschen.de>
+
+ Partially revert patch from 2014-03-04.
+ * exception.h (exception::handler_installed): Declare.
+ (exception::exception): Install vectored exception handler on x86_64.
+ (exception::~exception): Remove for x86_64.
+ * exceptions.cc (exception::handler_installed): Define.
+
+2014-03-17 Christopher Faylor <me.cygwin2014@cgf.cx>
+
+ * sigproc.h (no_thread_exit_protect): New class.
+ * sigproc.cc (thread_exit): Use no_thread_exit_protect to determine if
+ we need to coordinate ThreadExit/ExitProcess.
+ * fhandler_dsp.cc (fhandler_dev_dsp::Audio_out::stop): Use
+ no_thread_exit_protect to kludge around waiting for waveOutClose as it
+ waits for a thread that never exits.
+ (fhandler_dev_dsp::Audio_in::stop): Ditto for waveInClose.
+
+2014-03-16 Christopher Faylor <me.cygwin2014@cgf.cx>
+
+ * fhandler.h (fhandler_dev_dsp::base): New method.
+ (fhandler_dev_dsp::_read): Ditto.
+ (fhandler_dev_dsp::_write): Ditto.
+ (fhandler_dev_dsp::_ioctl): Ditto.
+ (fhandler_dev_dsp::_fixup_after_fork): Ditto.
+ (fhandler_dev_dsp::_fixup_after_exec): Ditto.
+ * fhandler_dsp.cc (fhandler_dev_dsp::read): Call real function via
+ base() pointer.
+ (fhandler_dev_dsp::write): Ditto.
+ (fhandler_dev_dsp::ioctl): Ditto.
+ (fhandler_dev_dsp::fixup_after_fork): Ditto.
+ (fhandler_dev_dsp::fixup_after_exec): Ditto.
+ (fhandler_dev_dsp::_read): Rename by adding an leading underscore.
+ (fhandler_dev_dsp::_write): Ditto.
+ (fhandler_dev_dsp::_ioctl): Ditto.
+ (fhandler_dev_dsp::_fixup_after_fork): Ditto.
+ (fhandler_dev_dsp::_fixup_after_exec): Ditto.
+
+2014-03-12 Corinna Vinschen <corinna@vinschen.de>
+
+ * include/cygwin/socket.h (IPV6_JOIN_GROUP): Revert.
+ (IPV6_LEAVE_GROUP): Ditto.
+
+2014-03-10 Christopher Faylor <me.cygwin2014@cgf.cx>
+
+ * fhandler.h (dev_console::b): Redefine as CONSOLE_SCREEN_BUFFER_INFO
+ for use with older OS.
+ * fhandler_console.cc (dev_console::fillin): Ditto for
+ GetConsoleScreenBufferInfo.
+
+2014-03-10 Christopher Faylor <me.cygwin2014@cgf.cx>
+
+ * fhandler_console.cc (dev_console::save_restore): Save entire line of
+ current cursor position.
+
+2014-03-09 Christopher Faylor <me.cygwin2014@cgf.cx>
+
+ * fhandler_console.cc (fhandler_console::save_restore): Save only until
+ last written row and, because of this, don't bother trying to restore
+ the screen buffer size. Set cursor position after refilling buffer.
+ (fhandler_console::write): Use absolute paths when saving/restoring
+ cursor position or suffer odd problems after a saved screen is
+ restored.
+
+2014-03-09 Christopher Faylor <me.cygwin2014@cgf.cx>
+
+ * fhandler.h (fhandler_console::dwBufferSize): Delete.
+ (fhandler_console::dwCursorPosition): Ditto.
+ (fhandler_console::wAttributes): Ditto.
+ (fhandler_console::b): New field encompassing previously disparate
+ screen buffer info.
+ (fhandler_console::save_bufsize): Rename from savebufsiz
+ (fhandler_console::save_buf): Rename sfrom savebuf.
+ (fhandler_console::save_cursor): New field.
+ (fhandler_console::save_restore): New function.
+ (fhandler_console::con): Rename from dev_state.
+ (fhandler_console::focus_aware): Accommodate name change.
+ * fhandler_console.cc: Use 'b' field of dev_console throughout instead
+ of disparate names. Accommodate dev_state -> con rename.
+ (dev_state:save_restore): New function. Attempt to save the entire
+ screen buffer rather than just the visible part. Clear the buffer when
+ saving, like Linux.
+ (fhandler_console::char_command): Use con.save_restore() for
+ Save/restore screen sequence.
+
+2014-03-09 Christopher Faylor <me.cygwin2014@cgf.cx>
+
+ * sigproc.cc (_cygtls::remove_wq): Reset thread_ev inside of lock. Set
+ to NULL when done.
+
+2014-03-09 Christopher Faylor <me.cygwin2014@cgf.cx>
+
+ * fhandler_console.cc (fhandler_console::char_command): Properly use
+ calculated value rather than directly using dev_state.args[0].
+
+2014-03-09 Christopher Faylor <me.cygwin2014@cgf.cx>
+
+ * dir.cc (opendir): Propagate any errno from build_fh_name.
+
+2014-03-05 Corinna Vinschen <corinna@vinschen.de>
+
+ * include/cygwin/config.h (__TM_GMTOFF): Define.
+ (__TM_ZONE): Define.
+
+2014-03-05 Corinna Vinschen <corinna@vinschen.de>
+
+ * localtime.cc: Define TM_GMTOFF and TM_ZONE based on __TM_GMTOFF and
+ __TM_ZONE being defined. Throughout, write to these struct tm members
+ only if CYGWIN_VERSION_CHECK_FOR_EXTRA_TM_MEMBERS is true.
+ * libc/strptime.cc: Ditto.
+ * include/cygwin/version.h (CYGWIN_VERSION_CHECK_FOR_EXTRA_TM_MEMBERS):
+ Define.
+ (CYGWIN_VERSION_API_MINOR): Bump to 272.
+
+2014-03-04 Corinna Vinschen <corinna@vinschen.de>
+
+ * exception.h (exception::handler_installed): Remove.
+ (exception::exception): Remove old code. Manually install SEH handler
+ instead.
+ (exception::~exception): For x86_64, define frame end label.
+ * exceptions.cc (exception::handler_installed): Remove.
+
+2014-03-03 Corinna Vinschen <corinna@vinschen.de>
+
+ * exception.h (exception::exception): Install vectored exception
+ handler rather than vectored continue handler.
+
+2014-02-25 Christopher Faylor <me.cygwin2014@cgf.cx>
+
+ * fhandler.h (fhandler_console::scroll_buffer_screen): New function.
+ * fhandler_console.cc (fhandler_console::scroll_buffer_screen): New function.
+ (fhandler_console::char_command): Use scroll_buffer_screen as appropriate.
+ (dev_console::scroll_buffer): Remove if 0'ed block.
+
+2014-02-22 Corinna Vinschen <corinna@vinschen.de>
+
+ * external.cc (cygwin_internal): Add cases for CW_GETPWSID and
+ CW_GETGRSID.
+ * include/sys/cygwin.h (cygwin_getinfo_types): Add CW_SETENT, CW_GETENT,
+ CW_ENDENT, CW_GETNSSSEP, CW_GETPWSID and CW_GETGRSID.
+
+2014-02-22 Christopher Faylor <me.cygwin2014@cgf.cx>
+
+ * dev_console::scroll_buffer): Reinstate clipping region.
+
+2014-02-22 Christopher Faylor <me.cygwin2014@cgf.cx>
+
+ * fhandler.h (dev_console::is_fullscreen): Delete.
+ (dev_console::scroll_window): Return bool indicating success.
+ (dev_console::scroll_screen): New function.
+ (dev_console::clear_screen): New function.
+ (fhandler_console::clear_screen): Make __reg3.
+ (fhandler_console::cursor_set): Ditto.
+ (fhandler_console::cursor_get): Ditto.
+ (fhandler_console::cursor_rel): Ditto.
+ * fhandler_console.cc (dev_console::scroll_buffer): Adapt from
+ fhandler_console.
+ (fhandler_console::scroll_buffer): Use dev_console function.
+ (dev_console::is_fullscreen): Delete.
+ (dev_console::scroll_window): Return true if we cleared the screen.
+ Shrink/grow buffer first before scrolling to ensure that there is
+ sufficient space after scrolling.
+ (fhandler_console::clear_screen): Make reg3, use dev_console function.
+ (dev_console::clear_screen): New function adapted from
+ fhandler_console.
+ (fhandler_console::cursor_set): Make __reg3.
+ (fhandler_console::cursor_rel): Ditto.
+ (fhandler_console::cursor_get): Ditto.
+ (fhandler_console::write): Fix "reverse index".
+
+2014-02-20 Corinna Vinschen <corinna@vinschen.de>
+
+ * grp.cc (getgrouplist): Fix previous fix so ret is only set to ngroups
+ if ngroups isn't too small.
+
+2014-02-20 Corinna Vinschen <corinna@vinschen.de>
+
+ * grp.cc (get_groups): Don't add gid to list if it's ILLEGAL_GID.
+ (getgrouplist): Return number of groups, just like glibc.
+
+2014-02-15 Christopher Faylor <me.cygwin2014@cgf.cx>
+
+ * DevNotes: Add entry cgf-000024.
+ * fhandler.h (dev_console::state): Remove trailing underscore.
+ (dev_console::args): Ditto.
+ (dev_console::nargs): Ditto.
+ (dev_console::info): Eliminate subclass.
+ (dev_console::dwEnd): New field.
+ (dev_console::scroll_window): New function.
+ (dev_console::is_fullscreen): Ditto.
+ (dev_console::fillin): Rename from fillin_info.
+ (fhandler_console::scroll_buffer): Rename from scroll_screen.
+ * fhandler_console.cc: Throughout s/dev_state\.info/dev_state/g.
+ Accommodate other name changes.
+ (dev_console::fillin): Accommodate rename. Notice max x/y written to.
+ Forgo memset if GetConsoleScreenBufferInfo fails.
+ (fhandler_console::scroll_buffer): Accommodate rename. Don't treat y
+ coordinate of zero as top of screen.
+ (dev_console::is_fullscreen): New function.
+ (dev_console::scroll_window): Ditto.
+ (fhandler_console::clear_screen): Just scroll the screen when clearing
+ the screen in a state where the screen buffer is bigger than the
+ screen.
+ (fhandler_console::char_command): Try harder to get 'S' and 'T' working
+ in the presence of a screen buffer. Use temporary 'n' variable rather
+ than dev_state.args[0]. Use GNU ?: shortcut method.
+
+2014-02-14 Christopher Faylor <me.cygwin2014@cgf.cx>
+
+ * pinfo.cc (winpids::add): Always copy pinfo structure when winpid.
+ Fill out dwProcessId explicitly to handle exec from a windows process.
+ (winpids::enum_processes): Reorganize to iterate over known cygwin pids
+ when !winpid. Simplify logic. Don't do duplicate detection for
+ winpid.
+
+2014-02-11 Christopher Faylor <me.cygwin2014@cgf.cx>
+
+ * cygwin.sc.in: More closely emulate default pe/i386 linker script.
+
+2014-02-10 Corinna Vinschen <corinna@vinschen.de>
+
+ * cygheap.cc (cwcsdup): Change parameter to correct PWCSTR.
+ (cwcsdup1): Ditto.
+ * cygheap_malloc.h: Change declarations accordingly.
+
+2014-02-10 Corinna Vinschen <corinna@vinschen.de>
+
+ * dcrt0.cc (child_info_spawn::handle_spawn): Call fixup_lockf_after_exec
+ with additional argument to specify if the process has been execed
+ or spawned.
+ * flock.cc (fixup_lockf_after_exec): Take bool parameter to handle
+ exec and spawn differently. In case of spawn, just give up POSIX
+ locks in favor of the still running parent. Add comments to explain.
+
+2014-02-09 Christopher Faylor <me.cygwin2014@cgf.cx>
+
+ * environ.cc (strbrk): Properly deal with environment variable sans
+ quote.
+
+2014-02-09 Christopher Faylor <me.cygwin2014@cgf.cx>
+
+ * environ.cc (strbrk): New function.
+ (parse_options): Use strbrk to parse CYGWIN environment variable.
+
+2014-02-09 Christopher Faylor <me.cygwin2014@cgf.cx>
+
+ * sigproc.cc (sig_send): Don't bother with an error message if we are
+ exiting.
+
2014-02-06 Corinna Vinschen <corinna@vinschen.de>
* fhandler_disk_file.cc (fhandler_disk_file::fchown): Fix typo in
diff --git a/winsup/cygwin/DevNotes b/winsup/cygwin/DevNotes
index 3016075ec..0f480954a 100644
--- a/winsup/cygwin/DevNotes
+++ b/winsup/cygwin/DevNotes
@@ -1,3 +1,19 @@
+2014-03-29 cgf-000025
+
+Reorganized _cygtls::signal_debugger to avoid sending anything to the
+debugger if we've seen an exception. I think it used to work that way
+and I changed it without noting why. It sure seems like, if we don't do
+this, gdb will see two signals and, it really does, when there has been
+a Windows-recognized exception.
+
+2014-02-15 cgf-000024
+
+Wow. It's hard getting the screen handling stuff working correctly when
+there is a screen buffer larger than screen size and vice versa. These
+changes attempt to use SetConsoleWindowInfo whenever possible so that
+the contents of the screen buffer are never wiped out. They also fix
+some previously misbehaving "scroll the screen" commands.
+
2013-06-07 cgf-000023
Given the fact that the signal thread never exits there is no need
diff --git a/winsup/cygwin/cygheap.cc b/winsup/cygwin/cygheap.cc
index ea6eaa1a9..1ccbbaf5f 100644
--- a/winsup/cygwin/cygheap.cc
+++ b/winsup/cygwin/cygheap.cc
@@ -1,7 +1,7 @@
/* cygheap.cc: Cygwin heap manager.
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
- 2011, 2012, 2013 Red Hat, Inc.
+ 2011, 2012, 2013, 2014 Red Hat, Inc.
This file is part of Cygwin.
@@ -478,7 +478,7 @@ ccalloc_abort (cygheap_types x, size_t n, size_t size)
}
extern "C" PWCHAR __reg1
-cwcsdup (const PWCHAR s)
+cwcsdup (PCWSTR s)
{
MALLOC_CHECK;
PWCHAR p = (PWCHAR) cmalloc (HEAP_STR, (wcslen (s) + 1) * sizeof (WCHAR));
@@ -490,7 +490,7 @@ cwcsdup (const PWCHAR s)
}
extern "C" PWCHAR __reg1
-cwcsdup1 (const PWCHAR s)
+cwcsdup1 (PCWSTR s)
{
MALLOC_CHECK;
PWCHAR p = (PWCHAR) cmalloc (HEAP_1_STR, (wcslen (s) + 1) * sizeof (WCHAR));
diff --git a/winsup/cygwin/cygheap_malloc.h b/winsup/cygwin/cygheap_malloc.h
index a4ab2462e..088243ee3 100644
--- a/winsup/cygwin/cygheap_malloc.h
+++ b/winsup/cygwin/cygheap_malloc.h
@@ -1,7 +1,7 @@
/* cygheap_malloc.h: Cygwin heap manager allocation functions.
- Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011
- Red Hat, Inc.
+ Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011,
+ 2014 Red Hat, Inc.
This file is part of Cygwin.
@@ -48,8 +48,8 @@ void *__reg3 ccalloc (cygheap_types, size_t, size_t);
void *__reg2 cmalloc_abort (cygheap_types, size_t);
void *__reg2 crealloc_abort (void *, size_t);
void *__reg3 ccalloc_abort (cygheap_types, size_t, size_t);
-PWCHAR __reg1 cwcsdup (const PWCHAR);
-PWCHAR __reg1 cwcsdup1 (const PWCHAR);
+PWCHAR __reg1 cwcsdup (PCWSTR);
+PWCHAR __reg1 cwcsdup1 (PCWSTR);
char *__reg1 cstrdup (const char *);
char *__reg1 cstrdup1 (const char *);
void __reg2 cfree_and_set (char *&, char * = NULL);
diff --git a/winsup/cygwin/cygserver_ipc.h b/winsup/cygwin/cygserver_ipc.h
index 4ed3cdf51..52f9f5ddd 100644
--- a/winsup/cygwin/cygserver_ipc.h
+++ b/winsup/cygwin/cygserver_ipc.h
@@ -1,6 +1,6 @@
/* cygserver_ipc.h
- Copyright 2002, 2003, 2004, 2012, 2013 Red Hat, Inc.
+ Copyright 2002, 2003, 2004, 2012, 2013, 2014 Red Hat, Inc.
This file is part of Cygwin.
@@ -34,7 +34,7 @@ struct proc {
#ifdef __INSIDE_CYGWIN__
#include "sigproc.h"
extern inline void
-ipc_set_proc_info (proc &blk)
+ipc_set_proc_info (proc &blk, bool in_fork = false)
{
blk.cygpid = getpid ();
blk.winpid = GetCurrentProcessId ();
@@ -43,7 +43,10 @@ ipc_set_proc_info (proc &blk)
blk.gidcnt = 0;
blk.gidlist = NULL;
blk.is_admin = false;
- _my_tls.set_signal_arrived (true, blk.signal_arrived);
+ if (in_fork)
+ blk.signal_arrived = NULL;
+ else
+ _my_tls.set_signal_arrived (true, blk.signal_arrived);
}
#endif /* __INSIDE_CYGWIN__ */
diff --git a/winsup/cygwin/cygwin.sc.in b/winsup/cygwin/cygwin.sc.in
index db64a80e4..279da858f 100644
--- a/winsup/cygwin/cygwin.sc.in
+++ b/winsup/cygwin/cygwin.sc.in
@@ -59,9 +59,17 @@ SECTIONS
{
*(.rdata)
*(SORT(.rdata$*))
- *(.eh_frame)
*(.rdata_cygwin_nocopy)
- }
+ __rt_psrelocs_start = .;
+ *(.rdata_runtime_pseudo_reloc)
+ __rt_psrelocs_end = .;
+
+ }
+ __rt_psrelocs_size = __rt_psrelocs_end - __rt_psrelocs_start;
+ ___RUNTIME_PSEUDO_RELOC_LIST_END__ = .;
+ __RUNTIME_PSEUDO_RELOC_LIST_END__ = .;
+ ___RUNTIME_PSEUDO_RELOC_LIST__ = . - __rt_psrelocs_size;
+ __RUNTIME_PSEUDO_RELOC_LIST__ = . - __rt_psrelocs_size;
.eh_frame ALIGN(__section_alignment__) :
{
*(.eh_frame*)
@@ -87,11 +95,6 @@ SECTIONS
{
*(.edata)
}
- .rsrc BLOCK(__section_alignment__) :
- {
- *(.rsrc)
- *(SORT(.rsrc$*))
- }
.reloc BLOCK(__section_alignment__) :
{
*(.reloc)
@@ -100,6 +103,20 @@ SECTIONS
{
*(.cygwin_dll_common)
}
+ .idata ALIGN(__section_alignment__) :
+ {
+ /* This cannot currently be handled with grouped sections.
+ See pe.em:sort_sections. */
+ SORT(*)(.idata$2)
+ SORT(*)(.idata$3)
+ /* These zeroes mark the end of the import list. */
+ LONG (0); LONG (0); LONG (0); LONG (0); LONG (0);
+ SORT(*)(.idata$4)
+ SORT(*)(.idata$5)
+ SORT(*)(.idata$6)
+ SORT(*)(.idata$7)
+ . = ALIGN(16);
+ }
.gnu_debuglink_overlay ALIGN(__section_alignment__) (NOLOAD):
{
BYTE(0) /* c */
@@ -116,19 +133,10 @@ SECTIONS
BYTE(0) /* \0 */
LONG(0) /* checksum */
}
- .idata ALIGN(__section_alignment__) :
+ .rsrc BLOCK(__section_alignment__) :
{
- /* This cannot currently be handled with grouped sections.
- See pe.em:sort_sections. */
- SORT(*)(.idata$2)
- SORT(*)(.idata$3)
- /* These zeroes mark the end of the import list. */
- LONG (0); LONG (0); LONG (0); LONG (0); LONG (0);
- SORT(*)(.idata$4)
- SORT(*)(.idata$5)
- SORT(*)(.idata$6)
- SORT(*)(.idata$7)
- . = ALIGN(16);
+ *(.rsrc)
+ *(SORT(.rsrc$*))
_SYM (_cygheap_start) = ABSOLUTE(.);
}
.cygheap ALIGN(__section_alignment__) :
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
index d348d9bd5..15977aae9 100644
--- a/winsup/cygwin/dcrt0.cc
+++ b/winsup/cygwin/dcrt0.cc
@@ -655,7 +655,7 @@ child_info_spawn::get_parent_handle ()
void
child_info_spawn::handle_spawn ()
{
- extern void fixup_lockf_after_exec ();
+ extern void fixup_lockf_after_exec (bool);
HANDLE h;
if (!dynamically_loaded || get_parent_handle ())
{
@@ -706,7 +706,7 @@ child_info_spawn::handle_spawn ()
}
signal_fixup_after_exec ();
- fixup_lockf_after_exec ();
+ fixup_lockf_after_exec (type == _CH_EXEC);
}
/* Retrieve and store system directory for later use. Note that the
@@ -795,6 +795,10 @@ dll_crt0_0 ()
_main_tls = &_my_tls;
+#ifdef __x86_64__
+ exception::install_myfault_handler ();
+#endif
+
/* Initialize signal processing here, early, in the hopes that the creation
of a thread early in the process will cause more predictability in memory
layout for the main thread. */
diff --git a/winsup/cygwin/dir.cc b/winsup/cygwin/dir.cc
index c1f8a897b..01b9ab882 100644
--- a/winsup/cygwin/dir.cc
+++ b/winsup/cygwin/dir.cc
@@ -58,6 +58,11 @@ opendir (const char *name)
fh = build_fh_name (name, PC_SYM_FOLLOW);
if (!fh)
res = NULL;
+ else if (fh->error ())
+ {
+ set_errno (fh->error ());
+ res = NULL;
+ }
else if (fh->exists ())
res = fh->opendir (-1);
else
diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc
index 295f4248a..a53b5f085 100644
--- a/winsup/cygwin/environ.cc
+++ b/winsup/cygwin/environ.cc
@@ -137,13 +137,54 @@ static struct parse_thing
{NULL, {0}, setdword, 0, {{0}, {0}}}
};
+/* Return a possibly-quoted token.
+ Returns NULL when no more tokens available. */
+static char *
+strbrk(char *&buf)
+{
+ buf += strspn(buf, " \t");
+ if (!*buf)
+ return NULL;
+ char *tok = buf;
+ char *sep = buf + strcspn(buf, " \t");
+ char *quotestart = strchr(buf, '"');
+ if (!quotestart || quotestart > sep)
+ {
+ buf = sep + !!*sep; /* Don't point beyond EOS */
+ quotestart = NULL;
+ }
+ else
+ {
+ char *quote = quotestart;
+ sep = NULL;
+ while (!sep)
+ {
+ char *clquote = strchr (quote + 1, '"');
+ if (!clquote)
+ sep = strchr (quote, '\0');
+ else if (clquote[-1] != '\\')
+ sep = clquote;
+ else
+ {
+ memmove (clquote - 1, clquote, 1 + strchr (clquote, '\0') - clquote);
+ quote = clquote - 1;
+ }
+ }
+ buf = sep + 1;
+ memmove (quotestart, quotestart + 1, sep - quotestart);
+ sep--;
+ }
+ *sep = '\0';
+ return tok;
+}
+
+
/* Parse a string of the form "something=stuff somethingelse=more-stuff",
silently ignoring unknown "somethings". */
static void __stdcall
parse_options (const char *inbuf)
{
int istrue;
- char *p, *lasts;
parse_thing *k;
if (inbuf == NULL)
@@ -168,9 +209,8 @@ parse_options (const char *inbuf)
}
char *buf = strcpy ((char *) alloca (strlen (inbuf) + 1), inbuf);
- for (p = strtok_r (buf, " \t", &lasts);
- p != NULL;
- p = strtok_r (NULL, " \t", &lasts))
+
+ while (char *p = strbrk (buf))
{
char *keyword_here = p;
if (!(istrue = !ascii_strncasematch (p, "no", 2)))
diff --git a/winsup/cygwin/exception.h b/winsup/cygwin/exception.h
index 80569e8d5..83cb21fcf 100644
--- a/winsup/cygwin/exception.h
+++ b/winsup/cygwin/exception.h
@@ -104,32 +104,33 @@ typedef struct _exception_list
} exception_list;
extern exception_list *_except_list asm ("%fs:0");
+#else
+typedef void exception_list;
#endif /* !__x86_64 */
class exception
{
#ifdef __x86_64__
- static bool handler_installed;
- static int handle (LPEXCEPTION_POINTERS);
+ static LONG myfault_handle (LPEXCEPTION_POINTERS ep);
#else
exception_list el;
exception_list *save;
- static int handle (EXCEPTION_RECORD *, exception_list *, CONTEXT *, void *);
#endif /* __x86_64__ */
+ static int handle (EXCEPTION_RECORD *, exception_list *, CONTEXT *, void *);
public:
exception () __attribute__ ((always_inline))
{
+ /* Install SEH handler. */
#ifdef __x86_64__
- if (!handler_installed)
- {
- handler_installed = true;
- /* The unhandled exception filter goes first. It won't work if the
- executable is debugged, but then the vectored continue handler
- kicks in. For some reason the vectored continue handler doesn't
- get called if no unhandled exception filter is installed. */
- SetUnhandledExceptionFilter (handle);
- AddVectoredContinueHandler (1, handle);
- }
+ asm volatile ("\n\
+ 1: \n\
+ .seh_handler \
+ _ZN9exception6handleEP17_EXCEPTION_RECORDPvP8_CONTEXTS2_, \
+ @except \n\
+ .seh_handlerdata \n\
+ .long 1 \n\
+ .rva 1b, 2f, 2f, 2f \n\
+ .seh_code \n");
#else
save = _except_list;
el.handler = handle;
@@ -137,7 +138,44 @@ public:
_except_list = &el;
#endif /* __x86_64__ */
};
-#ifndef __x86_64__
+#ifdef __x86_64__
+ static void install_myfault_handler () __attribute__ ((always_inline))
+ {
+ /* Install myfault exception handler as VEH. Here's what happens:
+ Some Windows DLLs (advapi32, for instance) are using SEH to catch
+ exceptions inside its own functions. If we install a VEH handler
+ to catch all exceptions, our Cygwin VEH handler would illegitimatly
+ handle exceptions inside of Windows DLLs which are usually handled
+ by its own SEH handler. So, for standard exceptions we use an SEH
+ handler as installed in the constructor above so as not to override
+ the SEH handlers in Windows DLLs.
+ But we have a special case, myfault handling. The myfault handling
+ catches exceptions inside of the Cygwin DLL, some of them entirely
+ expected as in verifyable_object_isvalid. The ultimately right thing
+ to do would be to install SEH handlers for each of these cases.
+ But there are two problems with that:
+
+ 1. It would be a massive and, partially unreliable change in the
+ calling functions due to the incomplete SEH support in GCC.
+
+ 2. It doesn't always work. Certain DLLs appear to call Cygwin
+ functions during DLL initialization while the SEH handler is
+ not installed in the active call frame. For these cases we
+ need a more generic approach.
+
+ So, what we do here is to install a myfault VEH handler. This
+ function is called from dll_crt0_0, so the myfault handler is
+ available very early. */
+ AddVectoredExceptionHandler (1, myfault_handle);
+ }
+ ~exception () __attribute__ ((always_inline))
+ {
+ asm volatile ("\n\
+ nop \n\
+ 2: \n\
+ nop \n");
+ }
+#else
~exception () __attribute__ ((always_inline)) { _except_list = save; }
#endif /* !__x86_64__ */
};
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index ceddbbca5..120d71b0e 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -545,47 +545,43 @@ rtl_unwind (exception_list *frame, PEXCEPTION_RECORD e)
popl %%ebx \n\
": : "r" (frame), "r" (e));
}
-#endif
-
-/* Main exception handler. */
+#endif /* __x86_64 */
#ifdef __x86_64__
-#define CYG_EXC_CONTINUE_EXECUTION EXCEPTION_CONTINUE_EXECUTION
-#define CYG_EXC_CONTINUE_SEARCH EXCEPTION_CONTINUE_SEARCH
-
-bool exception::handler_installed NO_COPY;
+/* myfault vectored exception handler */
+LONG
+exception::myfault_handle (LPEXCEPTION_POINTERS ep)
+{
+ _cygtls& me = _my_tls;
-int
-exception::handle (LPEXCEPTION_POINTERS ep)
-#else
-#define CYG_EXC_CONTINUE_EXECUTION ExceptionContinueExecution
-#define CYG_EXC_CONTINUE_SEARCH ExceptionContinueSearch
+ if (me.andreas)
+ me.andreas->leave (); /* Return from a "san" caught fault */
+ return EXCEPTION_CONTINUE_SEARCH;
+}
+#endif /* __x86_64 */
+/* Main exception handler. */
int
exception::handle (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in, void *)
-#endif
{
static bool NO_COPY debugging;
_cygtls& me = _my_tls;
+#ifndef __x86_64__
if (me.andreas)
me.andreas->leave (); /* Return from a "san" caught fault */
-
-#ifdef __x86_64__
- EXCEPTION_RECORD *e = ep->ExceptionRecord;
- CONTEXT *in = ep->ContextRecord;
#endif
if (debugging && ++debugging < 500000)
{
SetThreadPriority (hMainThread, THREAD_PRIORITY_NORMAL);
- return CYG_EXC_CONTINUE_EXECUTION;
+ return ExceptionContinueExecution;
}
/* If we're exiting, tell Windows to keep looking for an
exception handler. */
if (exit_state || e->ExceptionFlags)
- return CYG_EXC_CONTINUE_SEARCH;
+ return ExceptionContinueSearch;
siginfo_t si = {};
si.si_code = SI_KERNEL;
@@ -654,7 +650,7 @@ exception::handle (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in, void
1))
{
case MMAP_NORESERVE_COMMITED:
- return CYG_EXC_CONTINUE_EXECUTION;
+ return ExceptionContinueExecution;
case MMAP_RAISE_SIGBUS: /* MAP_NORESERVE page, commit failed, or
access to mmap page beyond EOF. */
si.si_signo = SIGBUS;
@@ -688,13 +684,13 @@ exception::handle (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in, void
want CloseHandle to return an error. This can be revisited
if gcc ever supports Windows style structured exception
handling. */
- return CYG_EXC_CONTINUE_EXECUTION;
+ return ExceptionContinueExecution;
default:
/* If we don't recognize the exception, we have to assume that
we are doing structured exception handling, and we let
something else handle it. */
- return CYG_EXC_CONTINUE_SEARCH;
+ return ExceptionContinueSearch;
}
debug_printf ("In cygwin_except_handler exception %y at %p sp %p", e->ExceptionCode, in->_GR(ip), in->_GR(sp));
@@ -730,7 +726,7 @@ exception::handle (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in, void
else
{
debugging = true;
- return CYG_EXC_CONTINUE_EXECUTION;
+ return ExceptionContinueExecution;
}
/* FIXME: Probably should be handled in signal processing code */
@@ -765,7 +761,7 @@ exception::handle (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in, void
sig_send (NULL, si, &me); /* Signal myself */
me.incyg--;
e->ExceptionFlags = 0;
- return CYG_EXC_CONTINUE_EXECUTION;
+ return ExceptionContinueExecution;
}
/* Utilities to call a user supplied exception handler. */
@@ -1465,43 +1461,29 @@ _cygtls::call_signal_handler ()
void
_cygtls::signal_debugger (siginfo_t& si)
{
- HANDLE th = NULL;
- if (isinitialized () && being_debugged ())
+ HANDLE th;
+ /* If si.si_cyg is set then the signal was already sent to the debugger. */
+ if (isinitialized () && !si.si_cyg && (th = (HANDLE) *this)
+ && being_debugged () && SuspendThread (th) >= 0)
{
CONTEXT c;
- CONTEXT *pc;
-
- if (si.si_cyg)
- pc = ((cygwin_exception *) si.si_cyg)->context ();
- else if (!(th = (HANDLE) *this))
- return;
- else
+ c.ContextFlags = CONTEXT_FULL;
+ if (GetThreadContext (th, &c))
{
- SuspendThread (th);
- c.ContextFlags = CONTEXT_FULL;
- if (GetThreadContext (th, &c))
- pc = &c;
- else
- goto out;
if (incyg)
#ifdef __x86_64__
c.Rip = retaddr ();
#else
c.Eip = retaddr ();
#endif
- memcpy (&thread_context, pc, (&thread_context._internal -
+ memcpy (&thread_context, &c, (&thread_context._internal -
(unsigned char *) &thread_context));
+ /* Enough space for 32/64 bit addresses */
+ char sigmsg[2 * sizeof (_CYGWIN_SIGNAL_STRING " ffffffff ffffffffffffffff")];
+ __small_sprintf (sigmsg, _CYGWIN_SIGNAL_STRING " %d %y %p", si.si_signo,
+ thread_id, &thread_context);
+ OutputDebugString (sigmsg);
}
-#ifdef __x86_64__
- char sigmsg[2 * sizeof (_CYGWIN_SIGNAL_STRING " ffffffff ffffffffffffffff")];
-#else
- char sigmsg[2 * sizeof (_CYGWIN_SIGNAL_STRING " ffffffff ffffffff")];
-#endif
- __small_sprintf (sigmsg, _CYGWIN_SIGNAL_STRING " %d %y %p", si.si_signo,
- thread_id, &thread_context);
- OutputDebugString (sigmsg);
+ ResumeThread (th);
}
-out:
- if (th)
- ResumeThread (th);
}
diff --git a/winsup/cygwin/external.cc b/winsup/cygwin/external.cc
index 4dc87bf80..47b18809c 100644
--- a/winsup/cygwin/external.cc
+++ b/winsup/cygwin/external.cc
@@ -1,7 +1,7 @@
/* external.cc: Interface to Cygwin internals from external programs.
Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
- 2008, 2009, 2010, 2011, 2012 Red Hat, Inc.
+ 2008, 2009, 2010, 2011, 2012, 2014 Red Hat, Inc.
Written by Christopher Faylor <cgf@cygnus.com>
@@ -26,6 +26,7 @@ details. */
#include "child_info.h"
#include "environ.h"
#include "cygserver_setpwd.h"
+#include "pwdgrp.h"
#include <unistd.h>
#include <stdlib.h>
#include <wchar.h>
@@ -553,6 +554,24 @@ cygwin_internal (cygwin_getinfo_types t, ...)
}
break;
+ case CW_GETPWSID:
+ {
+ va_arg (arg, int);
+ PSID psid = va_arg (arg, PSID);
+ cygpsid sid (psid);
+ res = (uintptr_t) internal_getpwsid (sid);
+ }
+ break;
+
+ case CW_GETGRSID:
+ {
+ va_arg (arg, int);
+ PSID psid = va_arg (arg, PSID);
+ cygpsid sid (psid);
+ res = (uintptr_t) internal_getgrsid (sid);
+ }
+ break;
+
default:
set_errno (ENOSYS);
}
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index aa3c351c4..c738071de 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -1263,9 +1263,9 @@ class dev_console
int meta_mask;
/* Output state */
- int state_;
- int args_[MAXARGS];
- int nargs_;
+ int state;
+ int args[MAXARGS];
+ int nargs;
unsigned rarg;
bool saw_question_mark;
bool saw_greater_than_sign;
@@ -1287,25 +1287,21 @@ class dev_console
/* saved cursor coordinates */
int savex, savey;
- /* saved screen */
- COORD savebufsiz;
- PCHAR_INFO savebuf;
struct
{
- short Top, Bottom;
+ short Top;
+ short Bottom;
} scroll_region;
- struct console_attrs
- {
- SHORT winTop;
- SHORT winBottom;
- COORD dwWinSize;
- COORD dwBufferSize;
- COORD dwCursorPosition;
- WORD wAttributes;
- int set_cl_x (cltype);
- int set_cl_y (cltype);
- } info;
+
+ CONSOLE_SCREEN_BUFFER_INFO b;
+ COORD dwWinSize;
+ COORD dwEnd;
+
+ /* saved screen */
+ COORD save_bufsize;
+ PCHAR_INFO save_buf;
+ COORD save_cursor;
COORD dwLastCursorPosition;
COORD dwMousePosition; /* scroll-adjusted coord of mouse event */
@@ -1326,8 +1322,14 @@ class dev_console
DWORD con_to_str (char *d, int dlen, WCHAR w);
DWORD str_to_con (mbtowc_p, const char *, PWCHAR d, const char *s, DWORD sz);
void set_color (HANDLE);
- bool fillin_info (HANDLE);
void set_default_attr ();
+ int set_cl_x (cltype);
+ int set_cl_y (cltype);
+ bool fillin (HANDLE);
+ bool __reg3 scroll_window (HANDLE, int, int, int, int);
+ void __reg3 scroll_buffer (HANDLE, int, int, int, int, int, int);
+ void __reg3 clear_screen (HANDLE, int, int, int, int);
+ void __reg3 save_restore (HANDLE, char);
friend class fhandler_console;
};
@@ -1339,7 +1341,7 @@ public:
struct console_state
{
tty_min tty_min_state;
- dev_console dev_state;
+ dev_console con;
};
private:
static const unsigned MAX_WRITE_CHARS;
@@ -1357,11 +1359,12 @@ private:
/* Output calls */
void set_default_attr ();
- void clear_screen (cltype, cltype, cltype, cltype);
- void scroll_screen (int, int, int, int, int, int);
- void cursor_set (bool, int, int);
- void cursor_get (int *, int *);
- void cursor_rel (int, int);
+ void scroll_buffer (int, int, int, int, int, int);
+ void scroll_buffer_screen (int, int, int, int, int, int);
+ void __reg3 clear_screen (cltype, cltype, cltype, cltype);
+ void __reg3 cursor_set (bool, int, int);
+ void __reg3 cursor_get (int *, int *);
+ void __reg3 cursor_rel (int, int);
inline void write_replacement_char ();
inline bool write_console (PWCHAR, DWORD, DWORD&);
const unsigned char *write_normal (unsigned const char*, unsigned const char *);
@@ -1410,7 +1413,7 @@ private:
int ioctl (unsigned int cmd, void *);
int init (HANDLE, DWORD, mode_t);
bool mouse_aware (MOUSE_EVENT_RECORD& mouse_event);
- bool focus_aware () {return shared_console_info->dev_state.use_focus;}
+ bool focus_aware () {return shared_console_info->con.use_focus;}
select_record *select_read (select_stuff *);
select_record *select_write (select_stuff *);
@@ -1787,18 +1790,25 @@ class fhandler_dev_dsp: public fhandler_base
Audio_in *audio_in_;
public:
fhandler_dev_dsp ();
+ fhandler_dev_dsp *base () const {return (fhandler_dev_dsp *)archetype;}
- int open (int flags, mode_t mode = 0);
- ssize_t __stdcall write (const void *ptr, size_t len);
- void __reg3 read (void *ptr, size_t& len);
- int ioctl (unsigned int cmd, void *);
- off_t lseek (off_t, int) { return 0; }
+ int open (int, mode_t mode = 0);
+ ssize_t __stdcall write (const void *, size_t);
+ void __reg3 read (void *, size_t&);
+ int ioctl (unsigned int, void *);
int close ();
- void fixup_after_fork (HANDLE parent);
+ void fixup_after_fork (HANDLE);
void fixup_after_exec ();
+
private:
- void close_audio_in ();
- void close_audio_out (bool immediately = false);
+ ssize_t __stdcall _write (const void *, size_t);
+ void __reg3 _read (void *, size_t&);
+ int _ioctl (unsigned int, void *);
+ void _fixup_after_fork (HANDLE);
+ void _fixup_after_exec ();
+
+ void __reg1 close_audio_in ();
+ void __reg2 close_audio_out (bool = false);
bool use_archetype () const {return true;}
fhandler_dev_dsp (void *) {}
diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc
index caaf5eae2..7a97fc461 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -42,9 +42,9 @@ details. */
#define ALT_PRESSED (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)
#define CTRL_PRESSED (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)
-#define dev_state (shared_console_info->dev_state)
-#define srTop (dev_state.info.winTop + dev_state.scroll_region.Top)
-#define srBottom ((dev_state.scroll_region.Bottom < 0) ? dev_state.info.winBottom : dev_state.info.winTop + dev_state.scroll_region.Bottom)
+#define con (shared_console_info->con)
+#define srTop (con.b.srWindow.Top + con.scroll_region.Top)
+#define srBottom ((con.scroll_region.Bottom < 0) ? con.b.srWindow.Bottom : con.b.srWindow.Top + con.scroll_region.Bottom)
const char *get_nonascii_key (INPUT_RECORD&, char *);
@@ -172,17 +172,16 @@ fhandler_console::setup ()
{
if (set_unit ())
{
-
- dev_state.scroll_region.Bottom = -1;
- dev_state.dwLastCursorPosition.X = -1;
- dev_state.dwLastCursorPosition.Y = -1;
- dev_state.dwLastMousePosition.X = -1;
- dev_state.dwLastMousePosition.Y = -1;
- dev_state.dwLastButtonState = 0; /* none pressed */
- dev_state.last_button_code = 3; /* released */
- dev_state.underline_color = FOREGROUND_GREEN | FOREGROUND_BLUE;
- dev_state.dim_color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
- dev_state.meta_mask = LEFT_ALT_PRESSED;
+ con.scroll_region.Bottom = -1;
+ con.dwLastCursorPosition.X = -1;
+ con.dwLastCursorPosition.Y = -1;
+ con.dwLastMousePosition.X = -1;
+ con.dwLastMousePosition.Y = -1;
+ con.dwLastButtonState = 0; /* none pressed */
+ con.last_button_code = 3; /* released */
+ con.underline_color = FOREGROUND_GREEN | FOREGROUND_BLUE;
+ con.dim_color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
+ con.meta_mask = LEFT_ALT_PRESSED;
/* Set the mask that determines if an input keystroke is modified by
META. We set this based on the keyboard layout language loaded
for the current thread. The left <ALT> key always generates
@@ -193,9 +192,9 @@ fhandler_console::setup ()
these keyboards right <ALT> (called AltGr) is used to produce the
shell symbols and should not be interpreted as META. */
if (PRIMARYLANGID (LOWORD (GetKeyboardLayout (0))) == LANG_ENGLISH)
- dev_state.meta_mask |= RIGHT_ALT_PRESSED;
- dev_state.set_default_attr ();
- dev_state.backspace_keycode = CERASE;
+ con.meta_mask |= RIGHT_ALT_PRESSED;
+ con.set_default_attr ();
+ con.backspace_keycode = CERASE;
shared_console_info->tty_min_state.is_console = true;
}
}
@@ -239,39 +238,35 @@ dev_console::str_to_con (mbtowc_p f_mbtowc, const char *charset,
bool
fhandler_console::set_raw_win32_keyboard_mode (bool new_mode)
{
- bool old_mode = dev_state.raw_win32_keyboard_mode;
- dev_state.raw_win32_keyboard_mode = new_mode;
- syscall_printf ("raw keyboard mode %sabled", dev_state.raw_win32_keyboard_mode ? "en" : "dis");
+ bool old_mode = con.raw_win32_keyboard_mode;
+ con.raw_win32_keyboard_mode = new_mode;
+ syscall_printf ("raw keyboard mode %sabled", con.raw_win32_keyboard_mode ? "en" : "dis");
return old_mode;
};
void
fhandler_console::set_cursor_maybe ()
{
- CONSOLE_SCREEN_BUFFER_INFO now;
-
- if (!GetConsoleScreenBufferInfo (get_output_handle (), &now))
- return;
-
- if (dev_state.dwLastCursorPosition.X != now.dwCursorPosition.X ||
- dev_state.dwLastCursorPosition.Y != now.dwCursorPosition.Y)
+ con.fillin (get_output_handle ());
+ if (con.dwLastCursorPosition.X != con.b.dwCursorPosition.X ||
+ con.dwLastCursorPosition.Y != con.b.dwCursorPosition.Y)
{
- SetConsoleCursorPosition (get_output_handle (), now.dwCursorPosition);
- dev_state.dwLastCursorPosition = now.dwCursorPosition;
+ SetConsoleCursorPosition (get_output_handle (), con.b.dwCursorPosition);
+ con.dwLastCursorPosition = con.b.dwCursorPosition;
}
}
void
fhandler_console::send_winch_maybe ()
{
- SHORT y = dev_state.info.dwWinSize.Y;
- SHORT x = dev_state.info.dwWinSize.X;
- dev_state.fillin_info (get_output_handle ());
+ SHORT y = con.dwWinSize.Y;
+ SHORT x = con.dwWinSize.X;
+ con.fillin (get_output_handle ());
- if (y != dev_state.info.dwWinSize.Y || x != dev_state.info.dwWinSize.X)
+ if (y != con.dwWinSize.Y || x != con.dwWinSize.X)
{
- dev_state.scroll_region.Top = 0;
- dev_state.scroll_region.Bottom = -1;
+ con.scroll_region.Top = 0;
+ con.scroll_region.Bottom = -1;
get_ttyp ()->kill_pgrp (SIGWINCH);
}
}
@@ -280,7 +275,7 @@ fhandler_console::send_winch_maybe ()
bool
fhandler_console::mouse_aware (MOUSE_EVENT_RECORD& mouse_event)
{
- if (!dev_state.use_mouse)
+ if (!con.use_mouse)
return 0;
/* Adjust mouse position by window scroll buffer offset
@@ -290,17 +285,17 @@ fhandler_console::mouse_aware (MOUSE_EVENT_RECORD& mouse_event)
/* Cannot adjust position by window scroll buffer offset */
return 0;
- dev_state.dwMousePosition.X = mouse_event.dwMousePosition.X - now.srWindow.Left;
- dev_state.dwMousePosition.Y = mouse_event.dwMousePosition.Y - now.srWindow.Top;
+ con.dwMousePosition.X = mouse_event.dwMousePosition.X - now.srWindow.Left;
+ con.dwMousePosition.Y = mouse_event.dwMousePosition.Y - now.srWindow.Top;
return ((mouse_event.dwEventFlags == 0 || mouse_event.dwEventFlags == DOUBLE_CLICK)
- && mouse_event.dwButtonState != dev_state.dwLastButtonState)
+ && mouse_event.dwButtonState != con.dwLastButtonState)
|| mouse_event.dwEventFlags == MOUSE_WHEELED
|| (mouse_event.dwEventFlags == MOUSE_MOVED
- && (dev_state.dwMousePosition.X != dev_state.dwLastMousePosition.X
- || dev_state.dwMousePosition.Y != dev_state.dwLastMousePosition.Y)
- && ((dev_state.use_mouse >= 2 && mouse_event.dwButtonState)
- || dev_state.use_mouse >= 3));
+ && (con.dwMousePosition.X != con.dwLastMousePosition.X
+ || con.dwMousePosition.Y != con.dwLastMousePosition.Y)
+ && ((con.use_mouse >= 2 && mouse_event.dwButtonState)
+ || con.use_mouse >= 3));
}
void __reg3
@@ -372,7 +367,7 @@ fhandler_console::read (void *pv, size_t& buflen)
#define virtual_key_code (input_rec.Event.KeyEvent.wVirtualKeyCode)
#define control_key_state (input_rec.Event.KeyEvent.dwControlKeyState)
- dev_state.nModifiers = 0;
+ con.nModifiers = 0;
#ifdef DEBUGGING
/* allow manual switching to/from raw mode via ctrl-alt-scrolllock */
@@ -381,12 +376,12 @@ fhandler_console::read (void *pv, size_t& buflen)
((control_key_state & (LEFT_ALT_PRESSED | LEFT_CTRL_PRESSED)) == (LEFT_ALT_PRESSED | LEFT_CTRL_PRESSED))
)
{
- set_raw_win32_keyboard_mode (!dev_state.raw_win32_keyboard_mode);
+ set_raw_win32_keyboard_mode (!con.raw_win32_keyboard_mode);
continue;
}
#endif
- if (dev_state.raw_win32_keyboard_mode)
+ if (con.raw_win32_keyboard_mode)
{
__small_sprintf (tmp, "\033{%u;%u;%u;%u;%u;%luK",
input_rec.Event.KeyEvent.bKeyDown,
@@ -419,22 +414,22 @@ fhandler_console::read (void *pv, size_t& buflen)
continue;
if (control_key_state & SHIFT_PRESSED)
- dev_state.nModifiers |= 1;
+ con.nModifiers |= 1;
if (control_key_state & RIGHT_ALT_PRESSED)
- dev_state.nModifiers |= 2;
+ con.nModifiers |= 2;
if (control_key_state & CTRL_PRESSED)
- dev_state.nModifiers |= 4;
+ con.nModifiers |= 4;
if (control_key_state & LEFT_ALT_PRESSED)
- dev_state.nModifiers |= 8;
+ con.nModifiers |= 8;
/* Allow Backspace to emit ^? and escape sequences. */
if (input_rec.Event.KeyEvent.wVirtualKeyCode == VK_BACK)
{
- char c = dev_state.backspace_keycode;
+ char c = con.backspace_keycode;
nread = 0;
if (control_key_state & ALT_PRESSED)
{
- if (dev_state.metabit)
+ if (con.metabit)
c |= 0x80;
else
tmp[nread++] = '\e';
@@ -455,14 +450,14 @@ fhandler_console::read (void *pv, size_t& buflen)
toadd = get_nonascii_key (input_rec, tmp);
if (!toadd)
{
- dev_state.nModifiers = 0;
+ con.nModifiers = 0;
continue;
}
nread = strlen (toadd);
}
else
{
- nread = dev_state.con_to_str (tmp + 1, 59, wch);
+ nread = con.con_to_str (tmp + 1, 59, wch);
/* Determine if the keystroke is modified by META. The tricky
part is to distinguish whether the right Alt key should be
recognized as Alt, or as AltGr. */
@@ -486,7 +481,7 @@ fhandler_console::read (void *pv, size_t& buflen)
else
toadd = tmp + 1;
}
- else if (dev_state.metabit)
+ else if (con.metabit)
{
tmp[1] |= 0x80;
toadd = tmp + 1;
@@ -497,7 +492,7 @@ fhandler_console::read (void *pv, size_t& buflen)
tmp[1] = cyg_tolower (tmp[1]);
toadd = tmp;
nread++;
- dev_state.nModifiers &= ~4;
+ con.nModifiers &= ~4;
}
}
#undef ich
@@ -551,34 +546,34 @@ fhandler_console::read (void *pv, size_t& buflen)
if (mouse_event.dwEventFlags == MOUSE_MOVED)
{
- b = dev_state.last_button_code;
+ b = con.last_button_code;
}
- else if (mouse_event.dwButtonState < dev_state.dwLastButtonState && !dev_state.ext_mouse_mode6)
+ else if (mouse_event.dwButtonState < con.dwLastButtonState && !con.ext_mouse_mode6)
{
b = 3;
strcpy (sz, "btn up");
}
- else if ((mouse_event.dwButtonState & 1) != (dev_state.dwLastButtonState & 1))
+ else if ((mouse_event.dwButtonState & 1) != (con.dwLastButtonState & 1))
{
b = 0;
strcpy (sz, "btn1 down");
}
- else if ((mouse_event.dwButtonState & 2) != (dev_state.dwLastButtonState & 2))
+ else if ((mouse_event.dwButtonState & 2) != (con.dwLastButtonState & 2))
{
b = 2;
strcpy (sz, "btn2 down");
}
- else if ((mouse_event.dwButtonState & 4) != (dev_state.dwLastButtonState & 4))
+ else if ((mouse_event.dwButtonState & 4) != (con.dwLastButtonState & 4))
{
b = 1;
strcpy (sz, "btn3 down");
}
- if (dev_state.ext_mouse_mode6 /* distinguish release */
- && mouse_event.dwButtonState < dev_state.dwLastButtonState)
+ if (con.ext_mouse_mode6 /* distinguish release */
+ && mouse_event.dwButtonState < con.dwLastButtonState)
mode6_term = 'm';
- dev_state.last_button_code = b;
+ con.last_button_code = b;
if (mouse_event.dwEventFlags == MOUSE_MOVED)
{
@@ -588,46 +583,46 @@ fhandler_console::read (void *pv, size_t& buflen)
else
{
/* Remember the modified button state */
- dev_state.dwLastButtonState = mouse_event.dwButtonState;
+ con.dwLastButtonState = mouse_event.dwButtonState;
}
}
/* Remember mouse position */
- dev_state.dwLastMousePosition.X = dev_state.dwMousePosition.X;
- dev_state.dwLastMousePosition.Y = dev_state.dwMousePosition.Y;
+ con.dwLastMousePosition.X = con.dwMousePosition.X;
+ con.dwLastMousePosition.Y = con.dwMousePosition.Y;
/* Remember the modifiers */
- dev_state.nModifiers = 0;
+ con.nModifiers = 0;
if (mouse_event.dwControlKeyState & SHIFT_PRESSED)
- dev_state.nModifiers |= 0x4;
+ con.nModifiers |= 0x4;
if (mouse_event.dwControlKeyState & ALT_PRESSED)
- dev_state.nModifiers |= 0x8;
+ con.nModifiers |= 0x8;
if (mouse_event.dwControlKeyState & CTRL_PRESSED)
- dev_state.nModifiers |= 0x10;
+ con.nModifiers |= 0x10;
/* Indicate the modifiers */
- b |= dev_state.nModifiers;
+ b |= con.nModifiers;
/* We can now create the code. */
- if (dev_state.ext_mouse_mode6)
+ if (con.ext_mouse_mode6)
{
__small_sprintf (tmp, "\033[<%d;%d;%d%c", b,
- dev_state.dwMousePosition.X + 1,
- dev_state.dwMousePosition.Y + 1,
+ con.dwMousePosition.X + 1,
+ con.dwMousePosition.Y + 1,
mode6_term);
nread = strlen (tmp);
}
- else if (dev_state.ext_mouse_mode15)
+ else if (con.ext_mouse_mode15)
{
__small_sprintf (tmp, "\033[%d;%d;%dM", b + 32,
- dev_state.dwMousePosition.X + 1,
- dev_state.dwMousePosition.Y + 1);
+ con.dwMousePosition.X + 1,
+ con.dwMousePosition.Y + 1);
nread = strlen (tmp);
}
- else if (dev_state.ext_mouse_mode5)
+ else if (con.ext_mouse_mode5)
{
- unsigned int xcode = dev_state.dwMousePosition.X + ' ' + 1;
- unsigned int ycode = dev_state.dwMousePosition.Y + ' ' + 1;
+ unsigned int xcode = con.dwMousePosition.X + ' ' + 1;
+ unsigned int ycode = con.dwMousePosition.Y + ' ' + 1;
__small_sprintf (tmp, "\033[M%c", b + ' ');
nread = 4;
@@ -654,8 +649,8 @@ fhandler_console::read (void *pv, size_t& buflen)
}
else
{
- unsigned int xcode = dev_state.dwMousePosition.X + ' ' + 1;
- unsigned int ycode = dev_state.dwMousePosition.Y + ' ' + 1;
+ unsigned int xcode = con.dwMousePosition.X + ' ' + 1;
+ unsigned int ycode = con.dwMousePosition.Y + ' ' + 1;
if (xcode >= 256)
xcode = 0;
if (ycode >= 256)
@@ -665,8 +660,8 @@ fhandler_console::read (void *pv, size_t& buflen)
nread = 6; /* tmp may contain NUL bytes */
}
syscall_printf ("mouse: %s at (%d,%d)", sz,
- dev_state.dwMousePosition.X,
- dev_state.dwMousePosition.Y);
+ con.dwMousePosition.X,
+ con.dwMousePosition.Y);
toadd = tmp;
}
@@ -674,7 +669,7 @@ fhandler_console::read (void *pv, size_t& buflen)
break;
case FOCUS_EVENT:
- if (dev_state.use_focus)
+ if (con.use_focus)
{
if (input_rec.Event.FocusEvent.bSetFocus)
__small_sprintf (tmp, "\033[I");
@@ -734,82 +729,79 @@ fhandler_console::set_input_state ()
}
bool
-dev_console::fillin_info (HANDLE h)
+dev_console::fillin (HANDLE h)
{
bool ret;
- CONSOLE_SCREEN_BUFFER_INFO linfo;
- if ((ret = GetConsoleScreenBufferInfo (h, &linfo)))
+ if ((ret = GetConsoleScreenBufferInfo (h, &b)))
{
- info.winTop = linfo.srWindow.Top;
- info.winBottom = linfo.srWindow.Bottom;
- info.dwWinSize.Y = 1 + linfo.srWindow.Bottom - linfo.srWindow.Top;
- info.dwWinSize.X = 1 + linfo.srWindow.Right - linfo.srWindow.Left;
- info.dwBufferSize = linfo.dwSize;
- info.dwCursorPosition = linfo.dwCursorPosition;
- info.wAttributes = linfo.wAttributes;
+ dwWinSize.Y = 1 + b.srWindow.Bottom - b.srWindow.Top;
+ dwWinSize.X = 1 + b.srWindow.Right - b.srWindow.Left;
+ if (b.dwSize.Y != b.dwSize.Y || b.dwSize.X != b.dwSize.X)
+ dwEnd.X = dwEnd.Y = 0;
+ if (b.dwCursorPosition.Y > dwEnd.Y
+ || (b.dwCursorPosition.Y >= dwEnd.Y && b.dwCursorPosition.X > dwEnd.X))
+ dwEnd = b.dwCursorPosition;
}
else
{
- memset (&info, 0, sizeof info);
- info.dwWinSize.Y = 25;
- info.dwWinSize.X = 80;
- info.winBottom = 24;
+ memset (&b, 0, sizeof (b));
+ dwWinSize.Y = 25;
+ dwWinSize.X = 80;
+ b.srWindow.Bottom = 24;
+ b.srWindow.Right = 79;
}
return ret;
}
+void __reg3
+dev_console::scroll_buffer (HANDLE h, int x1, int y1, int x2, int y2, int xn, int yn)
+{
/* Scroll the screen context.
x1, y1 - ul corner
x2, y2 - dr corner
xn, yn - new ul corner
Negative values represents current screen dimensions
*/
-void
-fhandler_console::scroll_screen (int x1, int y1, int x2, int y2, int xn, int yn)
-{
SMALL_RECT sr1, sr2;
CHAR_INFO fill;
COORD dest;
-
- dev_state.fillin_info (get_output_handle ());
- sr1.Left = x1 >= 0 ? x1 : dev_state.info.dwWinSize.X - 1;
- if (y1 == 0)
- sr1.Top = dev_state.info.winTop;
- else
- sr1.Top = y1 > 0 ? y1 : dev_state.info.winBottom;
- sr1.Right = x2 >= 0 ? x2 : dev_state.info.dwWinSize.X - 1;
- if (y2 == 0)
- sr1.Bottom = dev_state.info.winTop;
- else
- sr1.Bottom = y2 > 0 ? y2 : dev_state.info.winBottom;
- sr2.Top = srTop;
+ fill.Char.AsciiChar = ' ';
+ fill.Attributes = current_win32_attr;
+
+ fillin (h);
+ sr1.Left = x1 >= 0 ? x1 : dwWinSize.X - 1;
+ sr1.Top = y1 >= 0 ? y1 : b.srWindow.Bottom;
+ sr1.Right = x2 >= 0 ? x2 : dwWinSize.X - 1;
+ sr1.Bottom = y2 >= 0 ? y2 : b.srWindow.Bottom;
+ sr2.Top = b.srWindow.Top + scroll_region.Top;
sr2.Left = 0;
- sr2.Bottom = srBottom;
- sr2.Right = dev_state.info.dwWinSize.X - 1;
+ sr2.Bottom = (scroll_region.Bottom < 0) ? b.srWindow.Bottom : b.srWindow.Top + scroll_region.Bottom;
+ sr2.Right = dwWinSize.X - 1;
if (sr1.Bottom > sr2.Bottom && sr1.Top <= sr2.Bottom)
sr1.Bottom = sr2.Bottom;
- dest.X = xn >= 0 ? xn : dev_state.info.dwWinSize.X - 1;
- if (yn == 0)
- dest.Y = dev_state.info.winTop;
- else
- dest.Y = yn > 0 ? yn : dev_state.info.winBottom;
- fill.Char.AsciiChar = ' ';
- fill.Attributes = dev_state.current_win32_attr;
- ScrollConsoleScreenBuffer (get_output_handle (), &sr1, &sr2, dest, &fill);
+ dest.X = xn >= 0 ? xn : dwWinSize.X - 1;
+ dest.Y = yn >= 0 ? yn : b.srWindow.Bottom;
+ ScrollConsoleScreenBuffer (h, &sr1, &sr2, dest, &fill);
+}
-#if 0 /* CGF: 2014-01-04 Assuming that we don't need this anymore */
- /* ScrollConsoleScreenBuffer on Windows 95 is buggy - when scroll distance
- * is more than half of screen, filling doesn't work as expected */
+inline void
+fhandler_console::scroll_buffer (int x1, int y1, int x2, int y2, int xn, int yn)
+{
+ con.scroll_buffer (get_output_handle (), x1, y1, x2, y2, xn, yn);
+}
- if (sr1.Top == sr1.Bottom)
- /* nothing to do */;
- else if (dest.Y <= sr1.Top) /* forward scroll */
- clear_screen (0, 1 + dest.Y + sr1.Bottom - sr1.Top, sr2.Right, sr2.Bottom);
- else /* reverse scroll */
- clear_screen (0, sr1.Top, sr2.Right, dest.Y - 1);
-#endif
+inline void
+fhandler_console::scroll_buffer_screen (int x1, int y1, int x2, int y2, int xn, int yn)
+{
+ if (y1 >= 0)
+ y1 += con.b.srWindow.Top;
+ if (y2 >= 0)
+ y1 += con.b.srWindow.Top;
+ if (yn >= 0)
+ yn += con.b.srWindow.Top;
+ con.scroll_buffer (get_output_handle (), x1, y1, x2, y2, xn, yn);
}
int
@@ -860,12 +852,12 @@ fhandler_console::open (int flags, mode_t)
}
set_output_handle (h);
- if (dev_state.fillin_info (get_output_handle ()))
+ if (con.fillin (get_output_handle ()))
{
- dev_state.current_win32_attr = dev_state.info.wAttributes;
- if (!dev_state.default_color)
- dev_state.default_color = dev_state.info.wAttributes;
- dev_state.set_default_attr ();
+ con.current_win32_attr = con.b.wAttributes;
+ if (!con.default_color)
+ con.default_color = con.b.wAttributes;
+ con.set_default_attr ();
}
get_ttyp ()->rstcons (false);
@@ -912,13 +904,13 @@ fhandler_console::ioctl (unsigned int cmd, void *arg)
case TIOCGWINSZ:
int st;
- st = dev_state.fillin_info (get_output_handle ());
+ st = con.fillin (get_output_handle ());
if (st)
{
/* *not* the buffer size, the actual screen size... */
/* based on Left Top Right Bottom of srWindow */
- ((struct winsize *) arg)->ws_row = dev_state.info.dwWinSize.Y;
- ((struct winsize *) arg)->ws_col = dev_state.info.dwWinSize.X;
+ ((struct winsize *) arg)->ws_row = con.dwWinSize.Y;
+ ((struct winsize *) arg)->ws_col = con.dwWinSize.X;
syscall_printf ("WINSZ: (row=%d,col=%d)",
((struct winsize *) arg)->ws_row,
((struct winsize *) arg)->ws_col);
@@ -935,13 +927,13 @@ fhandler_console::ioctl (unsigned int cmd, void *arg)
bg_check (SIGTTOU);
return 0;
case KDGKBMETA:
- *(int *) arg = (dev_state.metabit) ? K_METABIT : K_ESCPREFIX;
+ *(int *) arg = (con.metabit) ? K_METABIT : K_ESCPREFIX;
return 0;
case KDSKBMETA:
if ((intptr_t) arg == K_METABIT)
- dev_state.metabit = TRUE;
+ con.metabit = TRUE;
else if ((intptr_t) arg == K_ESCPREFIX)
- dev_state.metabit = FALSE;
+ con.metabit = FALSE;
else
{
set_errno (EINVAL);
@@ -951,7 +943,7 @@ fhandler_console::ioctl (unsigned int cmd, void *arg)
case TIOCLINUX:
if (*(unsigned char *) arg == 6)
{
- *(unsigned char *) arg = (unsigned char) dev_state.nModifiers;
+ *(unsigned char *) arg = (unsigned char) con.nModifiers;
return 0;
}
set_errno (EINVAL);
@@ -1189,52 +1181,98 @@ dev_console::set_default_attr ()
}
int
-dev_console::console_attrs::set_cl_x (cltype x)
+dev_console::set_cl_x (cltype x)
{
if (x == cl_disp_beg || x == cl_buf_beg)
return 0;
if (x == cl_disp_end)
return dwWinSize.X - 1;
if (x == cl_buf_end)
- return dwBufferSize.X - 1;
- return dwCursorPosition.X;
+ return b.dwSize.X - 1;
+ return b.dwCursorPosition.X;
}
int
-dev_console::console_attrs::set_cl_y (cltype y)
+dev_console::set_cl_y (cltype y)
{
if (y == cl_buf_beg)
return 0;
if (y == cl_disp_beg)
- return winTop;
+ return b.srWindow.Top;
if (y == cl_disp_end)
- return winBottom;
+ return b.srWindow.Bottom;
if (y == cl_buf_end)
- return dwBufferSize.Y - 1;
- return dwCursorPosition.Y;
+ return b.dwSize.Y - 1;
+ return b.dwCursorPosition.Y;
}
-
+
+bool
+dev_console::scroll_window (HANDLE h, int x1, int y1, int x2, int y2)
+{
+ if (save_buf || x1 != 0 || x2 != dwWinSize.X - 1 || y1 != b.srWindow.Top
+ || y2 != b.srWindow.Bottom || b.dwSize.Y <= dwWinSize.Y)
+ return false;
+
+ SMALL_RECT sr;
+ int toscroll = 2 + dwEnd.Y - b.srWindow.Top;
+ int shrink = 1 + toscroll + b.srWindow.Bottom - b.dwSize.Y;
+ sr.Left = sr.Right = dwEnd.X = 0;
+ /* Can't increment dwEnd yet since we may not have space in
+ the buffer. */
+ SetConsoleCursorPosition (h, dwEnd);
+ if (shrink > 0)
+ {
+ COORD c = b.dwSize;
+ c.Y = dwEnd.Y - shrink;
+ SetConsoleScreenBufferSize (h, c);
+ SetConsoleScreenBufferSize (h, b.dwSize);
+ dwEnd.Y = 0;
+ fillin (h);
+ toscroll = 2 + dwEnd.Y - b.srWindow.Top;
+ }
+
+ sr.Top = sr.Bottom = toscroll;
+
+ SetConsoleWindowInfo (h, FALSE, &sr);
+
+ dwEnd.Y++;
+ SetConsoleCursorPosition (h, dwEnd);
+
+ fillin (h);
+ return true;
+}
+
/*
* Clear the screen context from x1/y1 to x2/y2 cell.
* Negative values represents current screen dimensions
*/
-void
+void __reg3
fhandler_console::clear_screen (cltype xc1, cltype yc1, cltype xc2, cltype yc2)
{
+ HANDLE h = get_output_handle ();
+ con.fillin (h);
+
+ int x1 = con.set_cl_x (xc1);
+ int y1 = con.set_cl_y (yc1);
+ int x2 = con.set_cl_x (xc2);
+ int y2 = con.set_cl_y (yc2);
+
+ /* Detect special case - scroll the screen if we have a buffer in order to
+ preserve the buffer. */
+ if (!con.scroll_window (h, x1, y1, x2, y2))
+ con.clear_screen (h, x1, y1, x2, y2);
+}
+
+void __reg3
+dev_console::clear_screen (HANDLE h, int x1, int y1, int x2, int y2)
+{
COORD tlc;
DWORD done;
int num;
- dev_state.fillin_info (get_output_handle ());
-
- int x1 = dev_state.info.set_cl_x (xc1);
- int y1 = dev_state.info.set_cl_y (yc1);
- int x2 = dev_state.info.set_cl_x (xc2);
- int y2 = dev_state.info.set_cl_y (yc2);
+ num = abs (y1 - y2) * b.dwSize.X + abs (x1 - x2) + 1;
- num = abs (y1 - y2) * dev_state.info.dwBufferSize.X + abs (x1 - x2) + 1;
-
- if ((y2 * dev_state.info.dwBufferSize.X + x2) > (y1 * dev_state.info.dwBufferSize.X + x1))
+ if ((y2 * b.dwSize.X + x2) > (y1 * b.dwSize.X + x1))
{
tlc.X = x1;
tlc.Y = y1;
@@ -1244,42 +1282,35 @@ fhandler_console::clear_screen (cltype xc1, cltype yc1, cltype xc2, cltype yc2)
tlc.X = x2;
tlc.Y = y2;
}
- FillConsoleOutputCharacterA (get_output_handle (), ' ',
- num,
- tlc,
- &done);
- FillConsoleOutputAttribute (get_output_handle (),
- dev_state.current_win32_attr,
- num,
- tlc,
- &done);
+ FillConsoleOutputCharacterA (h, ' ', num, tlc, &done);
+ FillConsoleOutputAttribute (h, current_win32_attr, num, tlc, &done);
}
-void
+void __reg3
fhandler_console::cursor_set (bool rel_to_top, int x, int y)
{
COORD pos;
- dev_state.fillin_info (get_output_handle ());
+ con.fillin (get_output_handle ());
#if 0
- /* Setting y to the current winBottom here is the reason that the window
+ /* Setting y to the current b.srWindow.Bottom here is the reason that the window
isn't scrolled back to the current cursor position like it's done in
any other terminal. Rather, the curser is forced to the bottom of the
currently scrolled region. This breaks the console buffer content if
output is generated while the user had the window scrolled back. This
behaviour is very old, it has no matching ChangeLog entry.
Just disable for now but keep the code in for future reference. */
- if (y > dev_state.info.winBottom)
- y = dev_state.info.winBottom;
+ if (y > con.b.srWindow.Bottom)
+ y = con.b.srWindow.Bottom;
else
#endif
if (y < 0)
y = 0;
else if (rel_to_top)
- y += dev_state.info.winTop;
+ y += con.b.srWindow.Top;
- if (x > dev_state.info.dwWinSize.X)
- x = dev_state.info.dwWinSize.X - 1;
+ if (x > con.dwWinSize.X)
+ x = con.dwWinSize.X - 1;
else if (x < 0)
x = 0;
@@ -1288,21 +1319,21 @@ fhandler_console::cursor_set (bool rel_to_top, int x, int y)
SetConsoleCursorPosition (get_output_handle (), pos);
}
-void
+void __reg3
fhandler_console::cursor_rel (int x, int y)
{
- dev_state.fillin_info (get_output_handle ());
- x += dev_state.info.dwCursorPosition.X;
- y += dev_state.info.dwCursorPosition.Y;
+ con.fillin (get_output_handle ());
+ x += con.b.dwCursorPosition.X;
+ y += con.b.dwCursorPosition.Y;
cursor_set (false, x, y);
}
-void
+void __reg3
fhandler_console::cursor_get (int *x, int *y)
{
- dev_state.fillin_info (get_output_handle ());
- *y = dev_state.info.dwCursorPosition.Y;
- *x = dev_state.info.dwCursorPosition.X;
+ con.fillin (get_output_handle ());
+ *y = con.b.dwCursorPosition.Y;
+ *x = con.b.dwCursorPosition.X;
}
/* VT100 line drawing graphics mode maps `abcdefghijklmnopqrstuvwxyz{|}~ to
@@ -1344,9 +1375,9 @@ static const wchar_t __vt100_conv[31] = {
inline
bool fhandler_console::write_console (PWCHAR buf, DWORD len, DWORD& done)
{
- if (dev_state.iso_2022_G1
- ? dev_state.vt100_graphics_mode_G1
- : dev_state.vt100_graphics_mode_G0)
+ if (con.iso_2022_G1
+ ? con.vt100_graphics_mode_G1
+ : con.vt100_graphics_mode_G0)
for (DWORD i = 0; i < len; i ++)
if (buf[i] >= (unsigned char) '`' && buf[i] <= (unsigned char) '~')
buf[i] = __vt100_conv[buf[i] - (unsigned char) '`'];
@@ -1395,7 +1426,7 @@ delta (SHORT first, SHORT second)
needed until it succeeds in reading the entire screen buffer. */
static BOOL
ReadConsoleOutputWrapper (HANDLE h, PCHAR_INFO buf, COORD bufsiz,
- SMALL_RECT& region)
+ SMALL_RECT region)
{
COORD coord = {};
SHORT width = delta (region.Left, region.Right);
@@ -1419,6 +1450,61 @@ ReadConsoleOutputWrapper (HANDLE h, PCHAR_INFO buf, COORD bufsiz,
return success;
}
+void
+dev_console::save_restore (HANDLE h, char c)
+{
+ if (c == 'h') /* save */
+ {
+ fillin (h);
+ save_bufsize.X = b.dwSize.X;
+ if ((save_bufsize.Y = dwEnd.Y + 2) > b.dwSize.Y)
+ save_bufsize.X = b.dwSize.Y;
+
+ if (save_buf)
+ cfree (save_buf);
+ size_t screen_size = sizeof (CHAR_INFO) * save_bufsize.X * save_bufsize.Y;
+ save_buf = (PCHAR_INFO) cmalloc_abort (HEAP_1_BUF, screen_size);
+
+ save_cursor = b.dwCursorPosition; /* Remember where we were. */
+
+ SMALL_RECT now = {}; /* Read the whole buffer */
+ now.Bottom = save_bufsize.Y - 1;
+ now.Right = save_bufsize.X - 1;
+ if (!ReadConsoleOutputWrapper (h, save_buf, save_bufsize, now))
+ debug_printf ("ReadConsoleOutputWrapper(h, ...) failed during save, %E");
+
+ /* Position at top of buffer */
+ COORD cob = {};
+ if (!SetConsoleCursorPosition (h, cob))
+ debug_printf ("SetConsoleCursorInfo(%p, ...) failed during save, %E", h);
+
+ /* Clear entire buffer */
+ clear_screen (h, 0, 0, now.Right, now.Bottom);
+ b.dwCursorPosition.X = b.dwCursorPosition.Y = dwEnd.X = dwEnd.Y = 0;
+ }
+ else if (save_buf)
+ {
+ COORD cob = {};
+ SMALL_RECT now = {};
+ now.Bottom = save_bufsize.Y - 1;
+ now.Right = save_bufsize.X - 1;
+ /* Restore whole buffer */
+ BOOL res = WriteConsoleOutputW (h, save_buf, save_bufsize, cob, &now);
+ if (!res)
+ debug_printf ("WriteConsoleOutputW failed, %E");
+
+ cfree (save_buf);
+ save_buf = NULL;
+
+ /* Position where we were previously */
+ if (!SetConsoleCursorPosition (h, save_cursor))
+ debug_printf ("SetConsoleCursorInfo(%p, ...) failed during restore, %E", h);
+ /* Get back correct version of buffer information */
+ dwEnd.X = dwEnd.Y = 0;
+ fillin (h);
+ }
+}
+
#define BAK 1
#define ESC 2
#define NOR 0
@@ -1474,118 +1560,118 @@ static const char base_chars[256] =
void
fhandler_console::char_command (char c)
{
- int x, y;
+ int x, y, n;
char buf[40];
switch (c)
{
case 'm': /* Set Graphics Rendition */
- for (int i = 0; i <= dev_state.nargs_; i++)
- switch (dev_state.args_[i])
+ for (int i = 0; i <= con.nargs; i++)
+ switch (con.args[i])
{
case 0: /* normal color */
- dev_state.set_default_attr ();
+ con.set_default_attr ();
break;
case 1: /* bold */
- dev_state.intensity = INTENSITY_BOLD;
+ con.intensity = INTENSITY_BOLD;
break;
case 2: /* dim */
- dev_state.intensity = INTENSITY_DIM;
+ con.intensity = INTENSITY_DIM;
break;
case 4: /* underlined */
- dev_state.underline = 1;
+ con.underline = 1;
break;
case 5: /* blink mode */
- dev_state.blink = true;
+ con.blink = true;
break;
case 7: /* reverse */
- dev_state.reverse = true;
+ con.reverse = true;
break;
case 8: /* invisible */
- dev_state.intensity = INTENSITY_INVISIBLE;
+ con.intensity = INTENSITY_INVISIBLE;
break;
case 10: /* end alternate charset */
- dev_state.alternate_charset_active = false;
+ con.alternate_charset_active = false;
break;
case 11: /* start alternate charset */
- dev_state.alternate_charset_active = true;
+ con.alternate_charset_active = true;
break;
case 22:
case 28:
- dev_state.intensity = INTENSITY_NORMAL;
+ con.intensity = INTENSITY_NORMAL;
break;
case 24:
- dev_state.underline = false;
+ con.underline = false;
break;
case 25:
- dev_state.blink = false;
+ con.blink = false;
break;
case 27:
- dev_state.reverse = false;
+ con.reverse = false;
break;
case 30: /* BLACK foreground */
- dev_state.fg = 0;
+ con.fg = 0;
break;
case 31: /* RED foreground */
- dev_state.fg = FOREGROUND_RED;
+ con.fg = FOREGROUND_RED;
break;
case 32: /* GREEN foreground */
- dev_state.fg = FOREGROUND_GREEN;
+ con.fg = FOREGROUND_GREEN;
break;
case 33: /* YELLOW foreground */
- dev_state.fg = FOREGROUND_RED | FOREGROUND_GREEN;
+ con.fg = FOREGROUND_RED | FOREGROUND_GREEN;
break;
case 34: /* BLUE foreground */
- dev_state.fg = FOREGROUND_BLUE;
+ con.fg = FOREGROUND_BLUE;
break;
case 35: /* MAGENTA foreground */
- dev_state.fg = FOREGROUND_RED | FOREGROUND_BLUE;
+ con.fg = FOREGROUND_RED | FOREGROUND_BLUE;
break;
case 36: /* CYAN foreground */
- dev_state.fg = FOREGROUND_BLUE | FOREGROUND_GREEN;
+ con.fg = FOREGROUND_BLUE | FOREGROUND_GREEN;
break;
case 37: /* WHITE foreg */
- dev_state.fg = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
+ con.fg = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
break;
case 39:
- dev_state.fg = dev_state.default_color & FOREGROUND_ATTR_MASK;
+ con.fg = con.default_color & FOREGROUND_ATTR_MASK;
break;
case 40: /* BLACK background */
- dev_state.bg = 0;
+ con.bg = 0;
break;
case 41: /* RED background */
- dev_state.bg = BACKGROUND_RED;
+ con.bg = BACKGROUND_RED;
break;
case 42: /* GREEN background */
- dev_state.bg = BACKGROUND_GREEN;
+ con.bg = BACKGROUND_GREEN;
break;
case 43: /* YELLOW background */
- dev_state.bg = BACKGROUND_RED | BACKGROUND_GREEN;
+ con.bg = BACKGROUND_RED | BACKGROUND_GREEN;
break;
case 44: /* BLUE background */
- dev_state.bg = BACKGROUND_BLUE;
+ con.bg = BACKGROUND_BLUE;
break;
case 45: /* MAGENTA background */
- dev_state.bg = BACKGROUND_RED | BACKGROUND_BLUE;
+ con.bg = BACKGROUND_RED | BACKGROUND_BLUE;
break;
case 46: /* CYAN background */
- dev_state.bg = BACKGROUND_BLUE | BACKGROUND_GREEN;
+ con.bg = BACKGROUND_BLUE | BACKGROUND_GREEN;
break;
case 47: /* WHITE background */
- dev_state.bg = BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED;
+ con.bg = BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED;
break;
case 49:
- dev_state.bg = dev_state.default_color & BACKGROUND_ATTR_MASK;
+ con.bg = con.default_color & BACKGROUND_ATTR_MASK;
break;
}
- dev_state.set_color (get_output_handle ());
+ con.set_color (get_output_handle ());
break;
case 'q': /* Set cursor style (DECSCUSR) */
- if (dev_state.saw_space)
+ if (con.saw_space)
{
CONSOLE_CURSOR_INFO console_cursor_info;
GetConsoleCursorInfo (get_output_handle (), & console_cursor_info);
- switch (dev_state.args_[0])
+ switch (con.args[0])
{
case 0: /* blinking block */
case 1: /* blinking block (default) */
@@ -1599,7 +1685,7 @@ fhandler_console::char_command (char c)
SetConsoleCursorInfo (get_output_handle (), & console_cursor_info);
break;
default: /* use value as percentage */
- console_cursor_info.dwSize = dev_state.args_[0];
+ console_cursor_info.dwSize = con.args[0];
SetConsoleCursorInfo (get_output_handle (), & console_cursor_info);
break;
}
@@ -1607,18 +1693,18 @@ fhandler_console::char_command (char c)
break;
case 'h':
case 'l':
- if (!dev_state.saw_question_mark)
+ if (!con.saw_question_mark)
{
- switch (dev_state.args_[0])
+ switch (con.args[0])
{
case 4: /* Insert mode */
- dev_state.insert_mode = (c == 'h') ? true : false;
- syscall_printf ("insert mode %sabled", dev_state.insert_mode ? "en" : "dis");
+ con.insert_mode = (c == 'h') ? true : false;
+ syscall_printf ("insert mode %sabled", con.insert_mode ? "en" : "dis");
break;
}
break;
}
- switch (dev_state.args_[0])
+ switch (con.args[0])
{
case 25: /* Show/Hide Cursor (DECTCEM) */
{
@@ -1632,84 +1718,39 @@ fhandler_console::char_command (char c)
break;
}
case 47: /* Save/Restore screen */
- if (c == 'h') /* save */
- {
- CONSOLE_SCREEN_BUFFER_INFO now;
-
- if (!GetConsoleScreenBufferInfo (get_output_handle (), &now))
- break;
-
- /* Assume starting from 0/0 */
- dev_state.savebufsiz.X = 1 + now.srWindow.Right;
- dev_state.savebufsiz.Y = 1 + now.srWindow.Bottom;
-
- if (dev_state.savebuf)
- cfree (dev_state.savebuf);
- size_t screen_size = sizeof (CHAR_INFO) * dev_state.savebufsiz.X * dev_state.savebufsiz.Y;
- dev_state.savebuf = (PCHAR_INFO) cmalloc_abort (HEAP_1_BUF, screen_size);
-
- BOOL res = ReadConsoleOutputWrapper (get_output_handle (),
- dev_state.savebuf,
- dev_state.savebufsiz,
- now.srWindow);
- if (!res)
- debug_printf ("ReadConsoleOutputWrapper failed, %E");
- }
- else /* restore */
- {
- if (!dev_state.savebuf)
- break;
-
- CONSOLE_SCREEN_BUFFER_INFO now;
- COORD cob = { 0, 0 };
-
- if (!GetConsoleScreenBufferInfo (get_output_handle (), &now))
- {
- debug_printf ("GetConsoleScreenBufferInfo(%y, %y), %E", get_output_handle (), &now);
- break;
- }
-
- BOOL res = WriteConsoleOutputW (get_output_handle (), dev_state.savebuf,
- dev_state.savebufsiz, cob, &now.srWindow);
- if (!res)
- debug_printf ("WriteConsoleOutputW failed, %E");
-
- cfree (dev_state.savebuf);
- dev_state.savebuf = NULL;
- dev_state.savebufsiz.X = dev_state.savebufsiz.Y = 0;
- }
+ con.save_restore (get_output_handle (), c);
break;
case 67: /* DECBKM ("DEC Backarrow Key Mode") */
- dev_state.backspace_keycode = (c == 'h' ? CTRL('H') : CERASE);
+ con.backspace_keycode = (c == 'h' ? CTRL('H') : CERASE);
break;
case 1000: /* Mouse tracking */
- dev_state.use_mouse = (c == 'h') ? 1 : 0;
+ con.use_mouse = (c == 'h') ? 1 : 0;
break;
case 1002: /* Mouse button event tracking */
- dev_state.use_mouse = (c == 'h') ? 2 : 0;
+ con.use_mouse = (c == 'h') ? 2 : 0;
break;
case 1003: /* Mouse any event tracking */
- dev_state.use_mouse = (c == 'h') ? 3 : 0;
+ con.use_mouse = (c == 'h') ? 3 : 0;
break;
case 1004: /* Focus in/out event reporting */
- dev_state.use_focus = (c == 'h') ? true : false;
+ con.use_focus = (c == 'h') ? true : false;
break;
case 1005: /* Extended mouse mode */
- dev_state.ext_mouse_mode5 = c == 'h';
+ con.ext_mouse_mode5 = c == 'h';
break;
case 1006: /* SGR extended mouse mode */
- dev_state.ext_mouse_mode6 = c == 'h';
+ con.ext_mouse_mode6 = c == 'h';
break;
case 1015: /* Urxvt extended mouse mode */
- dev_state.ext_mouse_mode15 = c == 'h';
+ con.ext_mouse_mode15 = c == 'h';
break;
case 2000: /* Raw keyboard mode */
@@ -1717,23 +1758,23 @@ fhandler_console::char_command (char c)
break;
default: /* Ignore */
- syscall_printf ("unknown h/l command: %d", dev_state.args_[0]);
+ syscall_printf ("unknown h/l command: %d", con.args[0]);
break;
}
break;
case 'J':
- switch (dev_state.args_[0])
+ switch (con.args[0])
{
case 0: /* Clear to end of screen */
clear_screen (cl_curr_pos, cl_curr_pos, cl_disp_end, cl_disp_end);
break;
case 1: /* Clear from beginning of screen to cursor */
- cursor_get (&x, &y);
clear_screen (cl_disp_beg, cl_disp_beg, cl_curr_pos, cl_curr_pos);
break;
case 2: /* Clear screen */
+ cursor_get (&x, &y);
clear_screen (cl_disp_beg, cl_disp_beg, cl_disp_end, cl_disp_end);
- cursor_set (true, 0, 0);
+ cursor_set (false, x, y);
break;
default:
goto bad_escape;
@@ -1741,19 +1782,19 @@ fhandler_console::char_command (char c)
break;
case 'A':
- cursor_rel (0, -(dev_state.args_[0] ? dev_state.args_[0] : 1));
+ cursor_rel (0, -(con.args[0] ?: 1));
break;
case 'B':
- cursor_rel (0, dev_state.args_[0] ? dev_state.args_[0] : 1);
+ cursor_rel (0, con.args[0] ?: 1);
break;
case 'C':
- cursor_rel (dev_state.args_[0] ? dev_state.args_[0] : 1, 0);
+ cursor_rel (con.args[0] ?: 1, 0);
break;
case 'D':
- cursor_rel (-(dev_state.args_[0] ? dev_state.args_[0] : 1),0);
+ cursor_rel (-(con.args[0] ?: 1),0);
break;
case 'K':
- switch (dev_state.args_[0])
+ switch (con.args[0])
{
case 0: /* Clear to end of line */
clear_screen (cl_curr_pos, cl_curr_pos, cl_disp_end, cl_curr_pos);
@@ -1770,78 +1811,78 @@ fhandler_console::char_command (char c)
break;
case 'H':
case 'f':
- cursor_set (true, (dev_state.args_[1] ? dev_state.args_[1] : 1) - 1,
- (dev_state.args_[0] ? dev_state.args_[0] : 1) - 1);
+ cursor_set (true, (con.args[1] ?: 1) - 1,
+ (con.args[0] ?: 1) - 1);
break;
case 'G': /* hpa - position cursor at column n - 1 */
cursor_get (&x, &y);
- cursor_set (false, (dev_state.args_[0] ? dev_state.args_[0] - 1 : 0), y);
+ cursor_set (false, (con.args[0] ? con.args[0] - 1 : 0), y);
break;
case 'd': /* vpa - position cursor at line n */
cursor_get (&x, &y);
- cursor_set (true, x, (dev_state.args_[0] ? dev_state.args_[0] - 1 : 0));
+ cursor_set (true, x, (con.args[0] ? con.args[0] - 1 : 0));
break;
case 's': /* Save cursor position */
- cursor_get (&dev_state.savex, &dev_state.savey);
- dev_state.savey -= dev_state.info.winTop;
+ cursor_get (&con.savex, &con.savey);
+ con.savey -= con.b.srWindow.Top;
break;
case 'u': /* Restore cursor position */
- cursor_set (true, dev_state.savex, dev_state.savey);
+ cursor_set (true, con.savex, con.savey);
break;
case 'I': /* TAB */
cursor_get (&x, &y);
cursor_set (false, 8 * (x / 8 + 1), y);
break;
case 'L': /* AL - insert blank lines */
- dev_state.args_[0] = dev_state.args_[0] ? dev_state.args_[0] : 1;
+ n = con.args[0] ?: 1;
cursor_get (&x, &y);
- scroll_screen (0, y, -1, -1, 0, y + dev_state.args_[0]);
+ scroll_buffer (0, y, -1, -1, 0, y + n);
break;
case 'M': /* DL - delete lines */
- dev_state.args_[0] = dev_state.args_[0] ? dev_state.args_[0] : 1;
+ n = con.args[0] ?: 1;
cursor_get (&x, &y);
- scroll_screen (0, y + dev_state.args_[0], -1, -1, 0, y);
+ scroll_buffer (0, y + n, -1, -1, 0, y);
break;
case '@': /* IC - insert chars */
- dev_state.args_[0] = dev_state.args_[0] ? dev_state.args_[0] : 1;
+ n = con.args[0] ?: 1;
cursor_get (&x, &y);
- scroll_screen (x, y, -1, y, x + dev_state.args_[0], y);
+ scroll_buffer (x, y, -1, y, x + n, y);
break;
case 'P': /* DC - delete chars */
- dev_state.args_[0] = dev_state.args_[0] ? dev_state.args_[0] : 1;
+ n = con.args[0] ?: 1;
cursor_get (&x, &y);
- scroll_screen (x + dev_state.args_[0], y, -1, y, x, y);
+ scroll_buffer (x + n, y, -1, y, x, y);
break;
case 'S': /* SF - Scroll forward */
- dev_state.args_[0] = dev_state.args_[0] ? dev_state.args_[0] : 1;
- scroll_screen (0, dev_state.args_[0], -1, -1, 0, 0);
+ n = con.args[0] ?: 1;
+ scroll_buffer_screen (0, n, -1, -1, 0, 0);
break;
case 'T': /* SR - Scroll down */
- dev_state.fillin_info (get_output_handle ());
- dev_state.args_[0] = dev_state.args_[0] ? dev_state.args_[0] : 1;
- scroll_screen (0, 0, -1, -1, 0, dev_state.info.winTop + dev_state.args_[0]);
+ con.fillin (get_output_handle ());
+ n = con.b.srWindow.Top + con.args[0] ?: 1;
+ scroll_buffer_screen (0, 0, -1, -1, 0, n);
break;
case 'X': /* ec - erase chars */
- dev_state.args_[0] = dev_state.args_[0] ? dev_state.args_[0] : 1;
+ n = con.args[0] ?: 1;
cursor_get (&x, &y);
- scroll_screen (x + dev_state.args_[0], y, -1, y, x, y);
- scroll_screen (x, y, -1, y, x + dev_state.args_[0], y);
+ scroll_buffer (x + n, y, -1, y, x, y);
+ scroll_buffer (x, y, -1, y, x + n, y);
break;
case 'Z': /* Back tab */
cursor_get (&x, &y);
cursor_set (false, ((8 * (x / 8 + 1)) - 8), y);
break;
case 'b': /* Repeat char #1 #2 times */
- if (dev_state.insert_mode)
+ if (con.insert_mode)
{
cursor_get (&x, &y);
- scroll_screen (x, y, -1, y, x + dev_state.args_[1], y);
+ scroll_buffer (x, y, -1, y, x + con.args[1], y);
}
- while (dev_state.args_[1]--)
- WriteFile (get_output_handle (), &dev_state.args_[0], 1, (DWORD *) &x, 0);
+ while (con.args[1]--)
+ WriteFile (get_output_handle (), &con.args[0], 1, (DWORD *) &x, 0);
break;
case 'c': /* u9 - Terminal enquire string */
- if (dev_state.saw_greater_than_sign)
+ if (con.saw_greater_than_sign)
/* Generate Secondary Device Attribute report, using 67 = ASCII 'C'
to indicate Cygwin (convention used by Rxvt, Urxvt, Screen, Mintty),
and cygwin version for terminal version. */
@@ -1854,12 +1895,12 @@ fhandler_console::char_command (char c)
puts_readahead (buf);
break;
case 'n':
- switch (dev_state.args_[0])
+ switch (con.args[0])
{
case 6: /* u7 - Cursor position request */
cursor_get (&x, &y);
- y -= dev_state.info.winTop;
- /* x -= dev_state.info.winLeft; // not available yet */
+ y -= con.b.srWindow.Top;
+ /* x -= con.b.srWindow.Left; // not available yet */
__small_sprintf (buf, "\033[%d;%dR", y + 1, x + 1);
puts_readahead (buf);
break;
@@ -1868,8 +1909,8 @@ fhandler_console::char_command (char c)
}
break;
case 'r': /* Set Scroll region */
- dev_state.scroll_region.Top = dev_state.args_[0] ? dev_state.args_[0] - 1 : 0;
- dev_state.scroll_region.Bottom = dev_state.args_[1] ? dev_state.args_[1] - 1 : -1;
+ con.scroll_region.Top = con.args[0] ? con.args[0] - 1 : 0;
+ con.scroll_region.Bottom = con.args[1] ? con.args[1] - 1 : -1;
cursor_set (true, 0, 0);
break;
case 'g': /* TAB set/clear */
@@ -1901,7 +1942,7 @@ fhandler_console::write_normal (const unsigned char *src,
const unsigned char *found = src;
size_t ret;
mbstate_t ps;
- UINT cp = dev_state.get_console_cp ();
+ UINT cp = con.get_console_cp ();
const char *charset;
mbtowc_p f_mbtowc;
@@ -1951,7 +1992,7 @@ fhandler_console::write_normal (const unsigned char *src,
/* Valid multibyte sequence? Process. */
if (nfound)
{
- buf_len = dev_state.str_to_con (f_mbtowc, charset, write_buf,
+ buf_len = con.str_to_con (f_mbtowc, charset, write_buf,
(const char *) trunc_buf.buf,
nfound - trunc_buf.buf);
if (!write_console (write_buf, buf_len, done))
@@ -1997,7 +2038,7 @@ do_print:
if (found != src)
{
DWORD len = found - src;
- buf_len = dev_state.str_to_con (f_mbtowc, charset, write_buf,
+ buf_len = con.str_to_con (f_mbtowc, charset, write_buf,
(const char *) src, len);
if (!buf_len)
{
@@ -2007,11 +2048,11 @@ do_print:
return 0;
}
- if (dev_state.insert_mode)
+ if (con.insert_mode)
{
int x, y;
cursor_get (&x, &y);
- scroll_screen (x, y, -1, y, x + buf_len, y);
+ scroll_buffer (x, y, -1, y, x + buf_len, y);
}
if (!write_console (write_buf, buf_len, done))
@@ -2032,26 +2073,26 @@ do_print:
switch (base_chars[*found])
{
case SO: /* Shift Out: Invoke G1 character set (ISO 2022) */
- dev_state.iso_2022_G1 = true;
+ con.iso_2022_G1 = true;
break;
case SI: /* Shift In: Invoke G0 character set (ISO 2022) */
- dev_state.iso_2022_G1 = false;
+ con.iso_2022_G1 = false;
break;
case BEL:
beep ();
break;
case ESC:
- dev_state.state_ = gotesc;
+ con.state = gotesc;
break;
case DWN:
cursor_get (&x, &y);
if (y >= srBottom)
{
- if (y >= dev_state.info.winBottom && !dev_state.scroll_region.Top)
+ if (y >= con.b.srWindow.Bottom && !con.scroll_region.Top)
WriteConsoleW (get_output_handle (), L"\n", 1, &done, 0);
else
{
- scroll_screen (0, srTop + 1, -1, srBottom, 0, srTop);
+ scroll_buffer (0, srTop + 1, -1, srBottom, 0, srTop);
y--;
}
}
@@ -2123,8 +2164,8 @@ fhandler_console::write (const void *vsrc, size_t len)
while (src < end)
{
- paranoid_printf ("char %0c state is %d", *src, dev_state.state_);
- switch (dev_state.state_)
+ paranoid_printf ("char %0c state is %d", *src, con.state);
+ switch (con.state)
{
case normal:
src = write_normal (src, end);
@@ -2134,112 +2175,111 @@ fhandler_console::write (const void *vsrc, size_t len)
case gotesc:
if (*src == '[') /* CSI Control Sequence Introducer */
{
- dev_state.state_ = gotsquare;
- dev_state.saw_question_mark = false;
- dev_state.saw_greater_than_sign = false;
- dev_state.saw_space = false;
- for (dev_state.nargs_ = 0; dev_state.nargs_ < MAXARGS; dev_state.nargs_++)
- dev_state.args_[dev_state.nargs_] = 0;
- dev_state.nargs_ = 0;
+ con.state = gotsquare;
+ con.saw_question_mark = false;
+ con.saw_greater_than_sign = false;
+ con.saw_space = false;
+ for (con.nargs = 0; con.nargs < MAXARGS; con.nargs++)
+ con.args[con.nargs] = 0;
+ con.nargs = 0;
}
else if (*src == ']') /* OSC Operating System Command */
{
- dev_state.rarg = 0;
- dev_state.my_title_buf[0] = '\0';
- dev_state.state_ = gotrsquare;
+ con.rarg = 0;
+ con.my_title_buf[0] = '\0';
+ con.state = gotrsquare;
}
else if (*src == '(') /* Designate G0 character set */
{
- dev_state.state_ = gotparen;
+ con.state = gotparen;
}
else if (*src == ')') /* Designate G1 character set */
{
- dev_state.state_ = gotrparen;
+ con.state = gotrparen;
}
else if (*src == 'M') /* Reverse Index (scroll down) */
{
- dev_state.fillin_info (get_output_handle ());
- scroll_screen (0, 0, -1, -1, 0, dev_state.info.winTop + 1);
- dev_state.state_ = normal;
+ con.fillin (get_output_handle ());
+ scroll_buffer_screen (0, 0, -1, -1, 0, 1);
+ con.state = normal;
}
else if (*src == 'c') /* RIS Full Reset */
{
- dev_state.set_default_attr ();
- dev_state.vt100_graphics_mode_G0 = false;
- dev_state.vt100_graphics_mode_G1 = false;
- dev_state.iso_2022_G1 = false;
+ con.set_default_attr ();
+ con.vt100_graphics_mode_G0 = false;
+ con.vt100_graphics_mode_G1 = false;
+ con.iso_2022_G1 = false;
cursor_set (false, 0, 0);
clear_screen (cl_buf_beg, cl_buf_beg, cl_buf_end, cl_buf_end);
- dev_state.state_ = normal;
+ con.state = normal;
}
else if (*src == '8') /* DECRC Restore cursor position */
{
- cursor_set (true, dev_state.savex, dev_state.savey);
- dev_state.state_ = normal;
+ cursor_set (false, con.savex, con.savey);
+ con.state = normal;
}
else if (*src == '7') /* DECSC Save cursor position */
{
- cursor_get (&dev_state.savex, &dev_state.savey);
- dev_state.savey -= dev_state.info.winTop;
- dev_state.state_ = normal;
+ cursor_get (&con.savex, &con.savey);
+ con.state = normal;
}
else if (*src == 'R') /* ? */
- dev_state.state_ = normal;
+ con.state = normal;
else
{
- dev_state.state_ = normal;
+ con.state = normal;
}
src++;
break;
case gotarg1:
if (isdigit (*src))
{
- dev_state.args_[dev_state.nargs_] = dev_state.args_[dev_state.nargs_] * 10 + *src - '0';
+ con.args[con.nargs] = con.args[con.nargs] * 10 + *src - '0';
src++;
}
else if (*src == ';')
{
src++;
- dev_state.nargs_++;
- if (dev_state.nargs_ >= MAXARGS)
- dev_state.nargs_--;
+ con.nargs++;
+ if (con.nargs >= MAXARGS)
+ con.nargs--;
}
else if (*src == ' ')
{
src++;
- dev_state.saw_space = true;
- dev_state.state_ = gotcommand;
+ con.saw_space = true;
+ con.state = gotcommand;
}
else
- dev_state.state_ = gotcommand;
+ con.state = gotcommand;
break;
case gotcommand:
char_command (*src++);
- dev_state.state_ = normal;
+ con.state = normal;
break;
case gotrsquare:
if (isdigit (*src))
- dev_state.rarg = dev_state.rarg * 10 + (*src - '0');
- else if (*src == ';' && (dev_state.rarg == 2 || dev_state.rarg == 0))
- dev_state.state_ = gettitle;
+ con.rarg = con.rarg * 10 + (*src - '0');
+ else if (*src == ';' && (con.rarg == 2 || con.rarg == 0))
+ con.state = gettitle;
else
- dev_state.state_ = eattitle;
+ con.state = eattitle;
src++;
break;
case eattitle:
case gettitle:
{
- int n = strlen (dev_state.my_title_buf);
+ int n = strlen (con.my_title_buf);
if (*src < ' ')
{
- if (*src == '\007' && dev_state.state_ == gettitle)
- set_console_title (dev_state.my_title_buf);
- dev_state.state_ = normal;
+ if (*src == '\007' && con.state == gettitle)
+ set_console_title (con.my_title_buf);
+ con.state = normal;
}
else if (n < TITLESIZE)
{
- dev_state.my_title_buf[n++] = *src;
- dev_state.my_title_buf[n] = '\0';
+ con.my_title_buf[n++] = *src;
+ con.my_title_buf[n] = '\0';
}
src++;
break;
@@ -2247,38 +2287,38 @@ fhandler_console::write (const void *vsrc, size_t len)
case gotsquare:
if (*src == ';')
{
- dev_state.state_ = gotarg1;
- dev_state.nargs_++;
+ con.state = gotarg1;
+ con.nargs++;
src++;
}
else if (isalpha (*src))
- dev_state.state_ = gotcommand;
+ con.state = gotcommand;
else if (*src != '@' && !isalpha (*src) && !isdigit (*src))
{
if (*src == '?')
- dev_state.saw_question_mark = true;
+ con.saw_question_mark = true;
else if (*src == '>')
- dev_state.saw_greater_than_sign = true;
+ con.saw_greater_than_sign = true;
/* ignore any extra chars between [ and first arg or command */
src++;
}
else
- dev_state.state_ = gotarg1;
+ con.state = gotarg1;
break;
case gotparen: /* Designate G0 Character Set (ISO 2022) */
if (*src == '0')
- dev_state.vt100_graphics_mode_G0 = true;
+ con.vt100_graphics_mode_G0 = true;
else
- dev_state.vt100_graphics_mode_G0 = false;
- dev_state.state_ = normal;
+ con.vt100_graphics_mode_G0 = false;
+ con.state = normal;
src++;
break;
case gotrparen: /* Designate G1 Character Set (ISO 2022) */
if (*src == '0')
- dev_state.vt100_graphics_mode_G1 = true;
+ con.vt100_graphics_mode_G1 = true;
else
- dev_state.vt100_graphics_mode_G1 = false;
- dev_state.state_ = normal;
+ con.vt100_graphics_mode_G1 = false;
+ con.state = normal;
src++;
break;
}
diff --git a/winsup/cygwin/fhandler_dsp.cc b/winsup/cygwin/fhandler_dsp.cc
index 80b014219..af6c2ea07 100644
--- a/winsup/cygwin/fhandler_dsp.cc
+++ b/winsup/cygwin/fhandler_dsp.cc
@@ -435,6 +435,7 @@ fhandler_dev_dsp::Audio_out::stop (bool immediately)
debug_printf ("%u = waveOutUnprepareHeader(%p)", rc, pHdr);
}
+ no_thread_exit_protect for_now (true);
rc = waveOutClose (dev_);
debug_printf ("%u = waveOutClose()", rc);
@@ -810,6 +811,7 @@ fhandler_dev_dsp::Audio_in::stop ()
debug_printf ("%u = waveInUnprepareHeader(%p)", rc, pHdr);
}
+ no_thread_exit_protect for_now (true);
rc = waveInClose (dev_);
debug_printf ("%u = waveInClose()", rc);
@@ -1003,6 +1005,37 @@ fhandler_dev_dsp::fhandler_dev_dsp ():
dev ().parse (FH_OSS_DSP);
}
+ssize_t __stdcall
+fhandler_dev_dsp::write (const void *ptr, size_t len)
+{
+ return base ()->_write (ptr, len);
+}
+
+void __reg3
+fhandler_dev_dsp::read (void *ptr, size_t& len)
+{
+ return base ()->_read (ptr, len);
+}
+
+int
+fhandler_dev_dsp::ioctl (unsigned int cmd, void *buf)
+{
+ return base ()->_ioctl (cmd, buf);
+}
+
+void
+fhandler_dev_dsp::fixup_after_fork (HANDLE parent)
+{
+ base ()->_fixup_after_fork (parent);
+}
+
+void
+fhandler_dev_dsp::fixup_after_exec ()
+{
+ base ()->_fixup_after_exec ();
+}
+
+
int
fhandler_dev_dsp::open (int flags, mode_t mode)
{
@@ -1046,7 +1079,7 @@ fhandler_dev_dsp::open (int flags, mode_t mode)
#define IS_READ() ((get_flags() & O_ACCMODE) != O_WRONLY)
ssize_t __stdcall
-fhandler_dev_dsp::write (const void *ptr, size_t len)
+fhandler_dev_dsp::_write (const void *ptr, size_t len)
{
debug_printf ("ptr=%p len=%ld", ptr, len);
int len_s = len;
@@ -1092,7 +1125,7 @@ fhandler_dev_dsp::write (const void *ptr, size_t len)
}
void __reg3
-fhandler_dev_dsp::read (void *ptr, size_t& len)
+fhandler_dev_dsp::_read (void *ptr, size_t& len)
{
debug_printf ("ptr=%p len=%ld", ptr, len);
@@ -1127,7 +1160,7 @@ fhandler_dev_dsp::read (void *ptr, size_t& len)
audio_in_->read ((char *)ptr, (int&)len);
}
-void
+void __reg1
fhandler_dev_dsp::close_audio_in ()
{
if (audio_in_)
@@ -1138,7 +1171,7 @@ fhandler_dev_dsp::close_audio_in ()
}
}
-void
+void __reg2
fhandler_dev_dsp::close_audio_out (bool immediately)
{
if (audio_out_)
@@ -1154,12 +1187,12 @@ fhandler_dev_dsp::close ()
{
debug_printf ("audio_in=%p audio_out=%p", audio_in_, audio_out_);
close_audio_in ();
- close_audio_out (exit_state != ES_NOT_EXITING);
+ close_audio_out ();
return fhandler_base::close ();
}
int
-fhandler_dev_dsp::ioctl (unsigned int cmd, void *buf)
+fhandler_dev_dsp::_ioctl (unsigned int cmd, void *buf)
{
debug_printf ("audio_in=%p audio_out=%p", audio_in_, audio_out_);
int *intbuf = (int *) buf;
@@ -1362,7 +1395,7 @@ fhandler_dev_dsp::ioctl (unsigned int cmd, void *buf)
}
void
-fhandler_dev_dsp::fixup_after_fork (HANDLE parent)
+fhandler_dev_dsp::_fixup_after_fork (HANDLE parent)
{ // called from new child process
debug_printf ("audio_in=%p audio_out=%p",
audio_in_, audio_out_);
@@ -1375,7 +1408,7 @@ fhandler_dev_dsp::fixup_after_fork (HANDLE parent)
}
void
-fhandler_dev_dsp::fixup_after_exec ()
+fhandler_dev_dsp::_fixup_after_exec ()
{
debug_printf ("audio_in=%p audio_out=%p, close_on_exec %d",
audio_in_, audio_out_, close_on_exec ());
diff --git a/winsup/cygwin/flock.cc b/winsup/cygwin/flock.cc
index 53069694d..5ea3e067d 100644
--- a/winsup/cygwin/flock.cc
+++ b/winsup/cygwin/flock.cc
@@ -439,7 +439,7 @@ fhandler_base::del_my_locks (del_lock_called_from from)
wait on. If the node has been abandoned due to close_on_exec on the
referencing fhandlers, remove the inode entirely. */
void
-fixup_lockf_after_exec ()
+fixup_lockf_after_exec (bool exec)
{
inode_t *node, *next_node;
@@ -464,13 +464,29 @@ fixup_lockf_after_exec ()
else
{
node->LOCK ();
- for (lockf_t *lock = node->i_lockf; lock; lock = lock->lf_next)
+ lockf_t *lock, *n_lock;
+ lockf_t **prev = &node->i_lockf;
+ for (lock = *prev; lock && (n_lock = lock->lf_next, 1); lock = n_lock)
if (lock->lf_flags & F_POSIX)
{
- lock->del_lock_obj (NULL);
- lock->lf_wid = myself->dwProcessId;
- lock->lf_ver = 0;
- lock->create_lock_obj ();
+ if (exec)
+ {
+ /* The parent called exec. The lock is passed to the child.
+ Recreate lock object with changed ownership. */
+ lock->del_lock_obj (NULL);
+ lock->lf_wid = myself->dwProcessId;
+ lock->lf_ver = 0;
+ lock->create_lock_obj ();
+ }
+ else
+ {
+ /* The parent called spawn. The parent continues to hold
+ the POSIX lock, ownership is not passed to the child.
+ Give up the lock in the child. */
+ *prev = n_lock;
+ lock->close_lock_obj ();
+ delete lock;
+ }
}
node->UNLOCK ();
}
diff --git a/winsup/cygwin/gendef b/winsup/cygwin/gendef
index a7c036f61..cef34a5ab 100755
--- a/winsup/cygwin/gendef
+++ b/winsup/cygwin/gendef
@@ -164,7 +164,7 @@ _sigfe: # stack is aligned on entry!
jmp *%rax # and jmp to it
.seh_endproc
- .seh_proc _sigfe
+ .seh_proc _sigbe
_sigbe: # return here after cygwin syscall
# stack is aligned on entry!
.seh_endprologue
@@ -589,10 +589,17 @@ sub longjmp {
.seh_proc setjmp
setjmp:
.seh_endprologue
- # We use the Windows jmp_buf layout. Store ExceptionList in Frame.
+ leaq 8(%rsp),%rdx
+ jmp __setjmpex
+ .seh_endproc
+
+ .globl __setjmpex
+ .seh_proc __setjmpex
+__setjmpex:
+ .seh_endprologue
+ # We use the Windows jmp_buf layout.
# Store alternative stackptr in Spare.
- movq %gs:0,%r10
- movq %r10,(%rcx)
+ movq %rdx,(%rcx)
movq %rbx,0x8(%rcx)
movq %rsp,0x10(%rcx)
movq %rbp,0x18(%rcx)
@@ -631,8 +638,7 @@ setjmp:
__sjfault:
.seh_endprologue
# Like setjmp, just w/o storing the alternate stackptr.
- movq %gs:0,%r10
- movq %r10,(%rcx)
+ movq %rdx,(%rcx)
movq %rbx,0x8(%rcx)
movq %rsp,0x10(%rcx)
movq %rbp,0x18(%rcx)
@@ -662,8 +668,6 @@ __sjfault:
.globl __ljfault
.seh_proc __ljfault
__ljfault:
- movq (%rcx),%r10
- movq %r10,%gs:0
movq 0x8(%rcx),%rbx
movq 0x10(%rcx),%rsp
movq 0x18(%rcx),%rbp
@@ -708,8 +712,6 @@ longjmp:
decl $tls::stacklock(%r11) # relinquish lock
xorl %r10d,%r10d
movl %r10d,$tls::incyg(%r11) # we're definitely not in cygwin anymore
- movq (%rcx),%r10
- movq %r10,%gs:0
movq 0x8(%rcx),%rbx
movq 0x10(%rcx),%rsp
movq 0x18(%rcx),%rbp
diff --git a/winsup/cygwin/grp.cc b/winsup/cygwin/grp.cc
index 7ff9e59b2..b84966ad5 100644
--- a/winsup/cygwin/grp.cc
+++ b/winsup/cygwin/grp.cc
@@ -447,7 +447,7 @@ get_groups (const char *user, gid_t gid, cygsidlist &gsids)
cygsid usersid, grpsid;
if (usersid.getfrompw (pw))
get_server_groups (gsids, usersid, pw);
- if (grpsid.getfromgr (gr))
+ if (gid != ILLEGAL_GID && grpsid.getfromgr (gr))
gsids += grpsid;
cygheap->user.reimpersonate ();
}
@@ -501,9 +501,11 @@ getgrouplist (const char *user, gid_t gid, gid_t *groups, int *ngroups)
groups[cnt] = gr->gr_gid;
++cnt;
}
+ *ngroups = cnt;
if (cnt > *ngroups)
ret = -1;
- *ngroups = cnt;
+ else
+ ret = cnt;
syscall_printf ( "%d = getgrouplist(%s, %u, %p, %d)",
ret, user, gid, groups, *ngroups);
diff --git a/winsup/cygwin/include/cygwin/config.h b/winsup/cygwin/include/cygwin/config.h
index 68b469afb..d3c68a502 100644
--- a/winsup/cygwin/include/cygwin/config.h
+++ b/winsup/cygwin/include/cygwin/config.h
@@ -79,6 +79,9 @@ extern char *_tlsbase __asm__ ("%fs:4");
#define _WANT_C99_TIME_FORMATS 1
#define _GLIBC_EXTENSION 1
#define _STDIO_BSD_SEMANTICS 1
+#define __TM_GMTOFF tm_gmtoff
+#define __TM_ZONE tm_zone
+
#if defined(__INSIDE_CYGWIN__) || defined(_COMPILING_NEWLIB)
#define __EXPORT __declspec(dllexport)
#define __IMPORT
diff --git a/winsup/cygwin/include/cygwin/socket.h b/winsup/cygwin/include/cygwin/socket.h
index f1f8b2659..8288c8320 100644
--- a/winsup/cygwin/include/cygwin/socket.h
+++ b/winsup/cygwin/include/cygwin/socket.h
@@ -258,6 +258,8 @@ struct OLD_msghdr
#define IPV6_MULTICAST_LOOP 11
#define IPV6_ADD_MEMBERSHIP 12
#define IPV6_DROP_MEMBERSHIP 13
+#define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP
+#define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP
#define IPV6_DONTFRAG 14
#define IPV6_PKTINFO 19
#define IPV6_HOPLIMIT 21
diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h
index 03e9b55bb..e77e7104a 100644
--- a/winsup/cygwin/include/cygwin/version.h
+++ b/winsup/cygwin/include/cygwin/version.h
@@ -104,6 +104,9 @@ details. */
#define CYGWIN_VERSION_USE_PSEUDO_RELOC_IN_DLL(u) \
(CYGWIN_VERSION_PER_PROCESS_API_VERSION_COMBINED (u) >= 227)
+#define CYGWIN_VERSION_CHECK_FOR_EXTRA_TM_MEMBERS \
+ (CYGWIN_VERSION_USER_API_VERSION_COMBINED >= 272)
+
#define CYGWIN_VERSION_CYGWIN_CONV 181
/* API_MAJOR 0.0: Initial version. API_MINOR changes:
@@ -442,12 +445,13 @@ details. */
270: Redefine mtget.mt_resid field to contain current partition as well
as number of partitions on tape.
271: Export posix_spawn, posix_spawnp, and helper functions.
+ 272: Export tm_gmtoff and tm_zone members.
*/
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
#define CYGWIN_VERSION_API_MAJOR 0
-#define CYGWIN_VERSION_API_MINOR 271
+#define CYGWIN_VERSION_API_MINOR 272
/* There is also a compatibity version number associated with the
shared memory regions. It is incremented when incompatible
diff --git a/winsup/cygwin/include/sys/cygwin.h b/winsup/cygwin/include/sys/cygwin.h
index 705aa7f64..24026cf57 100644
--- a/winsup/cygwin/include/sys/cygwin.h
+++ b/winsup/cygwin/include/sys/cygwin.h
@@ -1,7 +1,7 @@
/* sys/cygwin.h
Copyright 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
- 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
+ 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
This file is part of Cygwin.
@@ -143,7 +143,13 @@ typedef enum
CW_CVT_ENV_TO_WINENV,
CW_ALLOC_DRIVE_MAP,
CW_MAP_DRIVE_MAP,
- CW_FREE_DRIVE_MAP
+ CW_FREE_DRIVE_MAP,
+ CW_SETENT,
+ CW_GETENT,
+ CW_ENDENT,
+ CW_GETNSSSEP,
+ CW_GETPWSID,
+ CW_GETGRSID
} cygwin_getinfo_types;
#define CW_LOCK_PINFO CW_LOCK_PINFO
@@ -194,6 +200,12 @@ typedef enum
#define CW_ALLOC_DRIVE_MAP CW_ALLOC_DRIVE_MAP
#define CW_MAP_DRIVE_MAP CW_MAP_DRIVE_MAP
#define CW_FREE_DRIVE_MAP CW_FREE_DRIVE_MAP
+#define CW_SETENT CW_SETENT
+#define CW_GETENT CW_GETENT
+#define CW_ENDENT CW_ENDENT
+#define CW_GETNSSSEP CW_GETNSSSEP
+#define CW_GETPWSID CW_GETPWSID
+#define CW_GETGRSID CW_GETGRSID
/* Token type for CW_SET_EXTERNAL_TOKEN */
enum
diff --git a/winsup/cygwin/libc/strptime.cc b/winsup/cygwin/libc/strptime.cc
index eeaab831c..1f14818a2 100644
--- a/winsup/cygwin/libc/strptime.cc
+++ b/winsup/cygwin/libc/strptime.cc
@@ -48,6 +48,13 @@ __RCSID("$NetBSD: strptime.c,v 1.28 2008/04/28 20:23:01 martin Exp $");
#include <tzfile.h>
#include "../locale/timelocal.h"
+#ifdef __TM_GMTOFF
+# define TM_GMTOFF __TM_GMTOFF
+#endif
+#ifdef __TM_ZONE
+# define TM_ZONE __TM_ZONE
+#endif
+
#ifdef __weak_alias
__weak_alias(strptime,_strptime)
#endif
@@ -653,10 +660,12 @@ literal:
if (strncmp((const char *)bp, gmt, 3) == 0) {
tm->tm_isdst = 0;
#ifdef TM_GMTOFF
- tm->TM_GMTOFF = 0;
+ if (CYGWIN_VERSION_CHECK_FOR_EXTRA_TM_MEMBERS)
+ tm->TM_GMTOFF = 0;
#endif
#ifdef TM_ZONE
- tm->TM_ZONE = gmt;
+ if (CYGWIN_VERSION_CHECK_FOR_EXTRA_TM_MEMBERS)
+ tm->TM_ZONE = gmt;
#endif
bp += 3;
} else {
@@ -668,10 +677,12 @@ literal:
if (ep != NULL) {
tm->tm_isdst = i;
#ifdef TM_GMTOFF
- tm->TM_GMTOFF = -(timezone);
+ if (CYGWIN_VERSION_CHECK_FOR_EXTRA_TM_MEMBERS)
+ tm->TM_GMTOFF = -(timezone);
#endif
#ifdef TM_ZONE
- tm->TM_ZONE = tzname[i];
+ if (CYGWIN_VERSION_CHECK_FOR_EXTRA_TM_MEMBERS)
+ tm->TM_ZONE = tzname[i];
#endif
}
bp = ep;
diff --git a/winsup/cygwin/localtime.cc b/winsup/cygwin/localtime.cc
index a5307101e..29371703e 100644
--- a/winsup/cygwin/localtime.cc
+++ b/winsup/cygwin/localtime.cc
@@ -344,6 +344,13 @@ struct tzhead {
#include "fcntl.h"
+#ifdef __TM_GMTOFF
+# define TM_GMTOFF __TM_GMTOFF
+#endif
+#ifdef __TM_ZONE
+# define TM_ZONE __TM_ZONE
+#endif
+
/*
** SunOS 4.1.1 headers lack O_BINARY.
*/
@@ -1740,7 +1747,8 @@ localsub(const timezone_t sp, const time_t * const timep, const long offset,
if (sp == lclptr)
tzname[tmp->tm_isdst] = &sp->chars[ttisp->tt_abbrind];
#ifdef TM_ZONE
- tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind];
+ if (CYGWIN_VERSION_CHECK_FOR_EXTRA_TM_MEMBERS)
+ tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind];
#endif /* defined TM_ZONE */
return result;
}
@@ -1793,13 +1801,16 @@ gmtsub(const timezone_t sp, const time_t *const timep, const long offset,
** "UTC+xxxx" or "UTC-xxxx" if offset is non-zero,
** but this is no time for a treasure hunt.
*/
- if (offset != 0)
- tmp->TM_ZONE = wildabbr;
- else {
- if (gmtptr == NULL)
- tmp->TM_ZONE = gmt;
- else tmp->TM_ZONE = gmtptr->chars;
- }
+ if (CYGWIN_VERSION_CHECK_FOR_EXTRA_TM_MEMBERS)
+ {
+ if (offset != 0)
+ tmp->TM_ZONE = wildabbr;
+ else {
+ if (gmtptr == NULL)
+ tmp->TM_ZONE = gmt;
+ else tmp->TM_ZONE = gmtptr->chars;
+ }
+ }
#endif /* defined TM_ZONE */
return result;
}
@@ -1978,7 +1989,8 @@ timesub(const timezone_t sp, const time_t *const timep, const long offset,
tmp->tm_mday = (int) (idays + 1);
tmp->tm_isdst = 0;
#ifdef TM_GMTOFF
- tmp->TM_GMTOFF = offset;
+ if (CYGWIN_VERSION_CHECK_FOR_EXTRA_TM_MEMBERS)
+ tmp->TM_GMTOFF = offset;
#endif /* defined TM_GMTOFF */
return tmp;
}
diff --git a/winsup/cygwin/ntea.cc b/winsup/cygwin/ntea.cc
index 3c860096e..2fb205a04 100644
--- a/winsup/cygwin/ntea.cc
+++ b/winsup/cygwin/ntea.cc
@@ -1,7 +1,7 @@
/* ntea.cc: code for manipulating Extended Attributes
Copyright 1997, 1998, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009,
- 2010, 2011 Red Hat, Inc.
+ 2010, 2011, 2014 Red Hat, Inc.
This file is part of Cygwin.
@@ -17,15 +17,26 @@ details. */
#include "dtable.h"
#include "cygheap.h"
#include "ntdll.h"
+#include "tls_pbuf.h"
#include <stdlib.h>
#include <attr/xattr.h>
#define MAX_EA_NAME_LEN 256
#define MAX_EA_VALUE_LEN 65536
-/* At least one maximum sized entry fits. */
-#define EA_BUFSIZ (sizeof (FILE_FULL_EA_INFORMATION) + MAX_EA_NAME_LEN \
- + MAX_EA_VALUE_LEN)
+/* At least one maximum sized entry fits.
+ CV 2014-04-04: NtQueryEaFile function chokes on buffers bigger than 64K
+ with STATUS_INVALID_PARAMETER if the handle points to a file
+ on a remote share, at least on Windows 7 and later.
+ In theory the buffer should have a size of
+
+ sizeof (FILE_FULL_EA_INFORMATION) + MAX_EA_NAME_LEN
+ + MAX_EA_VALUE_LEN
+
+ (65804 bytes), but we're opting for simplicity here, and
+ a 64K buffer has the advantage that we can use a tmp_pathbuf
+ buffer, rather than having to alloca 64K from stack. */
+#define EA_BUFSIZ MAX_EA_VALUE_LEN
#define NEXT_FEA(p) ((PFILE_FULL_EA_INFORMATION) (p->NextEntryOffset \
? (char *) p + p->NextEntryOffset : NULL))
@@ -41,8 +52,9 @@ read_ea (HANDLE hdl, path_conv &pc, const char *name, char *value, size_t size)
ULONG glen = 0;
PFILE_GET_EA_INFORMATION gea = NULL;
PFILE_FULL_EA_INFORMATION fea;
+ tmp_pathbuf tp;
/* We have to store the latest EaName to compare with the next one, since
- ZwQueryEaFile has a bug when accessing files on a remote share. It
+ NtQueryEaFile has a bug when accessing files on a remote share. It
returns the last EA entry of the file infinitely. Even utilizing the
optional EaIndex only helps marginally. If you use that, the last
EA in the file is returned twice. */
@@ -72,7 +84,7 @@ read_ea (HANDLE hdl, path_conv &pc, const char *name, char *value, size_t size)
hdl = NULL;
}
- fea = (PFILE_FULL_EA_INFORMATION) alloca (EA_BUFSIZ);
+ fea = (PFILE_FULL_EA_INFORMATION) tp.w_get ();
if (name)
{
@@ -148,10 +160,10 @@ read_ea (HANDLE hdl, path_conv &pc, const char *name, char *value, size_t size)
}
if (name)
{
- /* Another weird behaviour of ZwQueryEaFile. If you ask for a
+ /* Another weird behaviour of NtQueryEaFile. If you ask for a
specific EA which is not present in the file's EA list, you don't
get a useful error code like STATUS_NONEXISTENT_EA_ENTRY. Rather
- ZwQueryEaFile returns success with the entry's EaValueLength
+ NtQueryEaFile returns success with the entry's EaValueLength
set to 0. */
if (!fea->EaValueLength)
{
diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc
index f56d338c3..478cc4874 100644
--- a/winsup/cygwin/pinfo.cc
+++ b/winsup/cygwin/pinfo.cc
@@ -1174,7 +1174,10 @@ winpids::add (DWORD& nelem, bool winpid, DWORD pid)
/* If we're just looking for winpids then don't do any special cygwin "stuff* */
if (winpid)
- goto out;
+ {
+ perform_copy = true;
+ goto out;
+ }
/* !p means that we couldn't find shared memory for this pid. Probably means
that it isn't a cygwin process. */
@@ -1239,6 +1242,8 @@ out:
p.release ();
p.procinfo = pnew;
p.destroy = false;
+ if (winpid)
+ p->dwProcessId = pid;
}
}
}
@@ -1250,70 +1255,51 @@ DWORD
winpids::enum_processes (bool winpid)
{
DWORD nelem = 0;
- DWORD cygwin_pid_nelem = 0;
- NTSTATUS status;
- ULONG context;
- struct fdbi
- {
- DIRECTORY_BASIC_INFORMATION dbi;
- WCHAR buf[2][NAME_MAX + 1];
- } f;
- HANDLE dir = get_shared_parent_dir ();
- BOOLEAN restart = TRUE;
-
- while (NT_SUCCESS (NtQueryDirectoryObject (dir, &f, sizeof f, TRUE, restart,
- &context, NULL)))
+
+ if (!winpid)
{
- restart = FALSE;
- f.dbi.ObjectName.Buffer[f.dbi.ObjectName.Length / sizeof (WCHAR)] = L'\0';
- if (wcsncmp (f.dbi.ObjectName.Buffer, L"cygpid.", 7) == 0)
+ HANDLE dir = get_shared_parent_dir ();
+ BOOLEAN restart = TRUE;
+ ULONG context;
+ struct fdbi
{
- DWORD pid = wcstoul (f.dbi.ObjectName.Buffer + 7, NULL, 10);
- add (nelem, false, pid);
+ DIRECTORY_BASIC_INFORMATION dbi;
+ WCHAR buf[2][NAME_MAX + 1];
+ } f;
+ while (NT_SUCCESS (NtQueryDirectoryObject (dir, &f, sizeof f, TRUE,
+ restart, &context, NULL)))
+ {
+ restart = FALSE;
+ f.dbi.ObjectName.Buffer[f.dbi.ObjectName.Length / sizeof (WCHAR)] = L'\0';
+ if (wcsncmp (f.dbi.ObjectName.Buffer, L"cygpid.", 7) == 0)
+ {
+ DWORD pid = wcstoul (f.dbi.ObjectName.Buffer + 7, NULL, 10);
+ add (nelem, false, pid);
+ }
}
}
- cygwin_pid_nelem = nelem;
-
- if (winpid)
+ else
{
static DWORD szprocs;
static PSYSTEM_PROCESS_INFORMATION procs;
- if (!szprocs)
+ while (1)
{
- procs = (PSYSTEM_PROCESS_INFORMATION)
- malloc (sizeof (*procs) + (szprocs = 200 * sizeof (*procs)));
- if (!procs)
+ PSYSTEM_PROCESS_INFORMATION new_p = (PSYSTEM_PROCESS_INFORMATION)
+ realloc (procs, szprocs += 200 * sizeof (*procs));
+ if (!new_p)
{
system_printf ("out of memory reading system process "
"information");
return 0;
}
- }
-
- for (;;)
- {
- status =
- NtQuerySystemInformation (SystemProcessInformation,
- procs, szprocs, NULL);
+ procs = new_p;
+ NTSTATUS status = NtQuerySystemInformation (SystemProcessInformation,
+ procs, szprocs, NULL);
if (NT_SUCCESS (status))
break;
- if (status == STATUS_INFO_LENGTH_MISMATCH)
- {
- PSYSTEM_PROCESS_INFORMATION new_p;
-
- new_p = (PSYSTEM_PROCESS_INFORMATION)
- realloc (procs, szprocs += 200 * sizeof (*procs));
- if (!new_p)
- {
- system_printf ("out of memory reading system process "
- "information");
- return 0;
- }
- procs = new_p;
- }
- else
+ if (status != STATUS_INFO_LENGTH_MISMATCH)
{
system_printf ("error %y reading system process information",
status);
@@ -1322,23 +1308,14 @@ winpids::enum_processes (bool winpid)
}
PSYSTEM_PROCESS_INFORMATION px = procs;
- for (;;)
+ char *&pxc = (char *&)px;
+ while (1)
{
if (px->UniqueProcessId)
- {
- bool do_add = true;
- for (unsigned i = 0; i < cygwin_pid_nelem; ++i)
- if (pidlist[i] == (uintptr_t) px->UniqueProcessId)
- {
- do_add = false;
- break;
- }
- if (do_add)
- add (nelem, true, (DWORD) (uintptr_t) px->UniqueProcessId);
- }
+ add (nelem, true, (DWORD) (uintptr_t) px->UniqueProcessId);
if (!px->NextEntryOffset)
break;
- px = (PSYSTEM_PROCESS_INFORMATION) ((char *) px + px->NextEntryOffset);
+ pxc += px->NextEntryOffset;
}
}
return nelem;
diff --git a/winsup/cygwin/release/1.7.29 b/winsup/cygwin/release/1.7.29
new file mode 100644
index 000000000..4896934f6
--- /dev/null
+++ b/winsup/cygwin/release/1.7.29
@@ -0,0 +1,44 @@
+What's new:
+-----------
+
+- Allow quoting of arguments to the CYGWIN environment variable, i.e.,
+ set CYGWIN=error_start="c:\bin\someprogram -T"
+
+
+What changed:
+-------------
+
+
+Bug Fixes
+---------
+
+- Try harder to do the right thing in the presence of console screen buffers,
+ i.e., never clear the screen buffer unless the user asked for it. Also
+ fix screen escape sequences which attempted to scroll the screen.
+ Addresses: http://cygwin.com/ml/cygwin/2014-02/threads.html#00274
+
+- Make "ps -W" report different WINPIDs for processes that have been execed
+ from, e.g., cmd.
+ Addresses: http://cygwin.com/ml/cygwin/2014-02/threads.html#00382
+
+- Avoid error messages from the signal handler if we're exiting.
+ Addresses: A random irc #cygwin complaint.
+
+- Fix return value from getgrouplist function to behave like glibc.
+
+- Fix initialization of open_memstream which could lead to dropping the
+ entire string.
+ Addresses: http://cygwin.com/ml/cygwin/2014-03/threads.html#00413
+
+- Fix problem where ending chunk of audio was missing when accessing /dev/dsp.
+ Addresses: http://cygwin.com/ml/cygwin/2014-03/threads.html#00117
+
+- Fix exception handling on x86_64.
+ Addresses: http://cygwin.com/ml/cygwin/2014-03/threads.html#00026
+
+- Fix reading extended attributes from files on remote shares.
+ Addresses: A personally encountered spurious error message:
+ mv: listing attributes of `//server/share/file': Invalid argument
+
+- Fix sending an invalid pointer to cygserver during fork.
+ Addresses: http://cygwin.com/ml/cygwin/2014-04/msg00001.html
diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc
index dfec53ca9..4a604939b 100644
--- a/winsup/cygwin/sec_auth.cc
+++ b/winsup/cygwin/sec_auth.cc
@@ -806,7 +806,7 @@ HANDLE
create_token (cygsid &usersid, user_groups &new_groups, struct passwd *pw)
{
NTSTATUS status;
- LSA_HANDLE lsa = INVALID_HANDLE_VALUE;
+ LSA_HANDLE lsa = NULL;
cygsidlist tmp_gsids (cygsidlist_auto, 12);
@@ -970,7 +970,7 @@ lsaauth (cygsid &usersid, user_groups &new_groups, struct passwd *pw)
cygsidlist tmp_gsids (cygsidlist_auto, 12);
cygpsid pgrpsid;
LSA_STRING name;
- HANDLE lsa_hdl = NULL, lsa = INVALID_HANDLE_VALUE;
+ HANDLE lsa_hdl = NULL, lsa = NULL;
LSA_OPERATIONAL_MODE sec_mode;
NTSTATUS status, sub_status;
ULONG package_id, size;
@@ -1211,7 +1211,7 @@ HANDLE
lsaprivkeyauth (struct passwd *pw)
{
NTSTATUS status;
- HANDLE lsa = INVALID_HANDLE_VALUE;
+ HANDLE lsa = NULL;
HANDLE token = NULL;
WCHAR sid[256];
WCHAR domain[MAX_DOMAIN_NAME_LEN + 1];
diff --git a/winsup/cygwin/setlsapwd.cc b/winsup/cygwin/setlsapwd.cc
index e86696b80..e6c17bd4a 100644
--- a/winsup/cygwin/setlsapwd.cc
+++ b/winsup/cygwin/setlsapwd.cc
@@ -41,7 +41,7 @@ unsigned long
setlsapwd (const char *passwd, const char *username)
{
unsigned long ret = (unsigned long) -1;
- HANDLE lsa = INVALID_HANDLE_VALUE;
+ HANDLE lsa;
WCHAR sid[128];
WCHAR key_name[128 + wcslen (CYGWIN_LSA_KEY_PREFIX)];
PWCHAR data_buf = NULL;
diff --git a/winsup/cygwin/shm.cc b/winsup/cygwin/shm.cc
index 226d2ee91..03213781a 100644
--- a/winsup/cygwin/shm.cc
+++ b/winsup/cygwin/shm.cc
@@ -1,6 +1,6 @@
/* shm.cc: XSI IPC interface for Cygwin.
- Copyright 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2012, 2013
+ Copyright 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2012, 2013, 2014
Red Hat, Inc.
This file is part of Cygwin.
@@ -85,7 +85,7 @@ client_request_shm::client_request_shm (proc *p1)
: client_request (CYGSERVER_REQUEST_SHM, &_parameters, sizeof (_parameters))
{
_parameters.in.shmop = SHMOP_shmfork;
- ipc_set_proc_info (_parameters.in.ipcblk);
+ ipc_set_proc_info (_parameters.in.ipcblk, true);
_parameters.in.forkargs = *p1;
}
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index 2dfec5a0b..eb61755a1 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -39,6 +39,8 @@ struct sigaction *global_sigs;
const char *__sp_fn ;
int __sp_ln;
+bool no_thread_exit_protect::flag;
+
char NO_COPY myself_nowait_dummy[1] = {'0'};// Flag to sig_send that signal goes to
// current process but no wait is required
@@ -336,6 +338,8 @@ _cygtls::remove_wq (DWORD wait)
if (exit_state < ES_FINAL && waitq_head.next && sync_proc_subproc
&& sync_proc_subproc.acquire (wait))
{
+ ForceCloseHandle1 (wq.thread_ev, wq_ev);
+ wq.thread_ev = NULL;
for (waitq *w = &waitq_head; w->next != NULL; w = w->next)
if (w->next == &wq)
{
@@ -344,7 +348,6 @@ _cygtls::remove_wq (DWORD wait)
}
sync_proc_subproc.release ();
}
- ForceCloseHandle1 (wq.thread_ev, wq_ev);
}
}
@@ -445,6 +448,8 @@ void
exit_thread (DWORD res)
{
# undef ExitThread
+ if (no_thread_exit_protect ())
+ ExitThread (res);
sigfillset (&_my_tls.sigmask); /* No signals wanted */
lock_process for_now; /* May block indefinitely when exiting. */
HANDLE h;
@@ -464,7 +469,7 @@ exit_thread (DWORD res)
siginfo_t si = {__SIGTHREADEXIT, SI_KERNEL};
si.si_cyg = h;
sig_send (myself_nowait, si, &_my_tls);
- ExitThread (0);
+ ExitThread (res);
}
int __reg3
@@ -639,12 +644,9 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
sigproc_printf ("WriteFile for pipe %p failed, %E", sendsig);
ForceCloseHandle (sendsig);
}
- else
- {
- if (!p->exec_sendsig)
- system_printf ("error sending signal %d to pid %d, pipe handle %p, %E",
- si.si_signo, p->pid, sendsig);
- }
+ else if (!p->exec_sendsig && !exit_state)
+ system_printf ("error sending signal %d, pipe handle %p, nb %u, packsize %u, %E",
+ si.si_signo, p->pid, sendsig, nb, packsize);
if (GetLastError () == ERROR_BROKEN_PIPE)
set_errno (ESRCH);
else
diff --git a/winsup/cygwin/sigproc.h b/winsup/cygwin/sigproc.h
index e73e33aeb..c6ef13e24 100644
--- a/winsup/cygwin/sigproc.h
+++ b/winsup/cygwin/sigproc.h
@@ -83,6 +83,22 @@ int kill_pgrp (pid_t, siginfo_t&);
void __reg1 exit_thread (DWORD) __attribute__ ((noreturn));
void __reg1 setup_signal_exit (int);
+class no_thread_exit_protect
+{
+ static bool flag;
+ bool modify;
+public:
+ no_thread_exit_protect (int) {flag = true; modify = true;}
+ ~no_thread_exit_protect ()
+ {
+ if (modify)
+ flag = false;
+ }
+ no_thread_exit_protect () {modify = false;}
+ operator int () {return flag;}
+};
+
+
extern "C" void sigdelayed ();
extern char myself_nowait_dummy[];