Eliminate use of sigframe and sigthread throughout.
* Makefile.in (DLL_OFILES): Add sigfe.o. Remove reliance on cygwin.def from cygwin0.dll dependency since dependence on sigfe.o implies that. Generate def file on the fly using 'gendef'. * configure.in: Don't auto-generate cygwin.def. * configure: Regenerate. * cygwin.din: Add SIGFE stuff where appropriate. * dcrt0.cc (dll_crt0_1): Initialize cygwin tls early in process startup. Set _main_tls to address of the main thread's cygwin tls. * debug.h: Remove now unneeded WFSO and WFMO declarations. * exceptions.cc (_last_thread): Define. (set_thread_state_for_signals): New function. (reset_thread_exception_for_signals): Ditto. (init_thread_for_signals): Ditto. (delete_thread_for_signals): Ditto. (capture_thread_for_signals): Ditto. (handle_exceptions): Set return address explicitly for exceptions prior to calling sig_send. (interrupt_on_return): Eliminate. (setup_handler): Add preliminary implementation for dealing with thread-specific signals by querying _main_tls. (signal_exit): Use cygthread::main_thread_id instead of mainthread.id. (call_signal_handler_now): For now, just handle the main thread. * fork.cc (vfork): Save and restore main _my_tls. * gendef: New file. Generates def file and sigfe.s file. * gentls_offsets: New file. Generates offsets for perl to use in sigfe.s. * how-signals-work.txt: Mention that info is obsolete. * init.cc (dll_entry): Initialize cygwin tls storage here. * miscfuncs.cc (low_priority_sleep): Make a C function for easier calling from asm. * perthread.h (vfork_save::tls): New element. * signal.cc (nanosleep): Replace previous use of sigframe.call_signal_handler_now with straight call to call_signal_handler_now. (abort): Ditto. * syscalls.cc (readv): Ditto. * termios.cc (tcsetattr): Ditto. * wait.cc (wait4): Ditto. * sigproc.cc (sig_dispatch_pending): Ditto. (sig_send): Ditto. * sigproc.h: Declare call_signal_handler_now. * thread.cc (pthread::thread_init_wrapper): Initialize cygwin tls. Remove obsolete and unworking signal stuff. * thread.h (verifyable_object::sigs): Eliminate. (verifyable_object::sigmask): Eliminate. (verifyable_object::sigtodo): Eliminate. (verifyable_object::exit): Make attribute noreturn. (verifyable_object::thread_init_wrapper): Ditto. (pthread_null::exit): Ditto. * winbase.h (__stackbase): Always define. * winsup.h (low_priority_sleep): Declare as a "C" function. * include/cygwin/version.h: Bump API version to reflect sigwait export. * include/sys/queue.h: Protect SLIST_ENTRY from previous declaration. * signal.cc (sigwait): Implement. * select.cc (fhandler_base::ready_for_read): Add debugging output. * devices.h: Define more device pointers via their storage. * devices.in: Don't parse things like /dev/inet/tcp, as they really have no meaning. * devices.cc: Regenerate. * gendevices: Set proper protection for output file. * cygtls.h: New file. * gendef: New file. * gentls_offsets: New file. * tlsoffsets.h: New file. Autogenerated. * config/i386/longjmp.c: Remove. File subsumed by gendef output. * config/i386/makefrag: Remove obsolete file. * fhandler.cc: Remove spurious access_worker declaration. * spawn.cc (spawnve): Make debugging output more accurate. * cygwin-gperf: Remove. * devices.cc: Remove.
This commit is contained in:
parent
ffe0063843
commit
9a4d574b8d
|
@ -1,3 +1,85 @@
|
|||
2003-11-28 Christopher Faylor <cgf@redhat.com>
|
||||
|
||||
Eliminate use of sigframe and sigthread throughout.
|
||||
* Makefile.in (DLL_OFILES): Add sigfe.o. Remove reliance on cygwin.def
|
||||
from cygwin0.dll dependency since dependence on sigfe.o implies that.
|
||||
Generate def file on the fly using 'gendef'.
|
||||
* configure.in: Don't auto-generate cygwin.def.
|
||||
* configure: Regenerate.
|
||||
* cygwin.din: Add SIGFE stuff where appropriate.
|
||||
* dcrt0.cc (dll_crt0_1): Initialize cygwin tls early in process
|
||||
startup. Set _main_tls to address of the main thread's cygwin tls.
|
||||
* debug.h: Remove now unneeded WFSO and WFMO declarations.
|
||||
* exceptions.cc (_last_thread): Define.
|
||||
(set_thread_state_for_signals): New function.
|
||||
(reset_thread_exception_for_signals): Ditto.
|
||||
(init_thread_for_signals): Ditto.
|
||||
(delete_thread_for_signals): Ditto.
|
||||
(capture_thread_for_signals): Ditto.
|
||||
(handle_exceptions): Set return address explicitly for exceptions prior
|
||||
to calling sig_send.
|
||||
(interrupt_on_return): Eliminate.
|
||||
(setup_handler): Add preliminary implementation for dealing with
|
||||
thread-specific signals by querying _main_tls.
|
||||
(signal_exit): Use cygthread::main_thread_id instead of mainthread.id.
|
||||
(call_signal_handler_now): For now, just handle the main thread.
|
||||
* fork.cc (vfork): Save and restore main _my_tls.
|
||||
* gendef: New file. Generates def file and sigfe.s file.
|
||||
* gentls_offsets: New file. Generates offsets for perl to use in
|
||||
sigfe.s.
|
||||
* how-signals-work.txt: Mention that info is obsolete.
|
||||
* init.cc (dll_entry): Initialize cygwin tls storage here.
|
||||
* miscfuncs.cc (low_priority_sleep): Make a C function for easier
|
||||
calling from asm.
|
||||
* perthread.h (vfork_save::tls): New element.
|
||||
* signal.cc (nanosleep): Replace previous use of
|
||||
sigframe.call_signal_handler_now with straight call to
|
||||
call_signal_handler_now.
|
||||
(abort): Ditto.
|
||||
* syscalls.cc (readv): Ditto.
|
||||
* termios.cc (tcsetattr): Ditto.
|
||||
* wait.cc (wait4): Ditto.
|
||||
* sigproc.cc (sig_dispatch_pending): Ditto.
|
||||
(sig_send): Ditto.
|
||||
* sigproc.h: Declare call_signal_handler_now.
|
||||
* thread.cc (pthread::thread_init_wrapper): Initialize cygwin tls.
|
||||
Remove obsolete and unworking signal stuff.
|
||||
* thread.h (verifyable_object::sigs): Eliminate.
|
||||
(verifyable_object::sigmask): Eliminate.
|
||||
(verifyable_object::sigtodo): Eliminate.
|
||||
(verifyable_object::exit): Make attribute noreturn.
|
||||
(verifyable_object::thread_init_wrapper): Ditto.
|
||||
(pthread_null::exit): Ditto.
|
||||
* winbase.h (__stackbase): Always define.
|
||||
* winsup.h (low_priority_sleep): Declare as a "C" function.
|
||||
* include/cygwin/version.h: Bump API version to reflect sigwait export.
|
||||
|
||||
* include/sys/queue.h: Protect SLIST_ENTRY from previous declaration.
|
||||
|
||||
* signal.cc (sigwait): Implement.
|
||||
|
||||
* select.cc (fhandler_base::ready_for_read): Add debugging output.
|
||||
|
||||
* devices.h: Define more device pointers via their storage.
|
||||
* devices.in: Don't parse things like /dev/inet/tcp, as they really
|
||||
have no meaning.
|
||||
* devices.cc: Regenerate.
|
||||
* gendevices: Set proper protection for output file.
|
||||
|
||||
* cygtls.h: New file.
|
||||
* gendef: New file.
|
||||
* gentls_offsets: New file.
|
||||
* tlsoffsets.h: New file. Autogenerated.
|
||||
* config/i386/longjmp.c: Remove. File subsumed by gendef output.
|
||||
* config/i386/makefrag: Remove obsolete file.
|
||||
|
||||
* fhandler.cc: Remove spurious access_worker declaration.
|
||||
|
||||
* spawn.cc (spawnve): Make debugging output more accurate.
|
||||
|
||||
* cygwin-gperf: Remove.
|
||||
* devices.cc: Remove.
|
||||
|
||||
2003-11-28 Christopher Faylor <cgf@redhat.com>
|
||||
|
||||
* speclib: Use correct EOF marker. Ensure that directory is actually
|
||||
|
|
|
@ -51,10 +51,10 @@ DEFS:=@DEFS@
|
|||
CC:=@CC@
|
||||
# FIXME: Which is it, CC or CC_FOR_TARGET?
|
||||
CC_FOR_TARGET:=$(CC)
|
||||
CFLAGS=@CFLAGS@
|
||||
CFLAGS=@CFLAGS@ -fmerge-constants -ftracer
|
||||
override CFLAGS+=-MMD ${$(*F)_CFLAGS}
|
||||
CXX=@CXX@
|
||||
CXXFLAGS=@CXXFLAGS@
|
||||
CXXFLAGS=@CXXFLAGS@ -fmerge-constants
|
||||
|
||||
AR:=@AR@
|
||||
AR_FLAGS:=qv
|
||||
|
@ -117,6 +117,7 @@ DLL_IMPORTS:=$(w32api_lib)/libkernel32.a
|
|||
|
||||
MT_SAFE_OBJECTS:=
|
||||
# Please maintain this list in sorted order, with maximum files per 80 col line
|
||||
#
|
||||
DLL_OFILES:=assert.o autoload.o bsdlib.o cxx.o cygheap.o cygthread.o dcrt0.o \
|
||||
debug.o delqueue.o devices.o dir.o dlfcn.o dll_init.o dtable.o environ.o \
|
||||
errno.o exceptions.o exec.o external.o fcntl.o fhandler.o \
|
||||
|
@ -131,10 +132,10 @@ DLL_OFILES:=assert.o autoload.o bsdlib.o cxx.o cygheap.o cygthread.o dcrt0.o \
|
|||
mmap.o msg.o net.o netdb.o ntea.o passwd.o path.o pinfo.o pipe.o \
|
||||
poll.o pthread.o regcomp.o regerror.o regexec.o regfree.o registry.o \
|
||||
resource.o scandir.o sched.o sec_acl.o sec_helper.o security.o \
|
||||
select.o sem.o shared.o shm.o signal.o sigproc.o smallprint.o spawn.o \
|
||||
strace.o strsep.o sync.o syscalls.o sysconf.o syslog.o termios.o \
|
||||
thread.o times.o tty.o uinfo.o uname.o v8_regexp.o v8_regerror.o \
|
||||
v8_regsub.o wait.o wincap.o window.o \
|
||||
select.o sem.o shared.o shm.o sigfe.o signal.o sigproc.o smallprint.o \
|
||||
spawn.o strace.o strsep.o sync.o syscalls.o sysconf.o syslog.o \
|
||||
termios.o thread.o times.o tty.o uinfo.o uname.o v8_regexp.o \
|
||||
v8_regerror.o v8_regsub.o wait.o wincap.o window.o \
|
||||
$(EXTRA_DLL_OFILES) $(EXTRA_OFILES) $(MALLOC_OFILES) $(MT_SAFE_OBJECTS)
|
||||
|
||||
GMON_OFILES:=gmon.o mcount.o profil.o
|
||||
|
@ -305,7 +306,6 @@ install_target:
|
|||
|
||||
install_host:
|
||||
|
||||
|
||||
uninstall-libs: $(TARGET_LIBS)
|
||||
rm -f $(bindir)/$(DLL_NAME); \
|
||||
for i in $^; do \
|
||||
|
@ -346,7 +346,7 @@ maintainer-clean realclean: clean
|
|||
|
||||
|
||||
# Rule to build cygwin.dll
|
||||
$(TEST_DLL_NAME): $(LDSCRIPT) $(DLL_OFILES) $(DEF_FILE) $(DLL_IMPORTS) $(LIBSERVER) $(LIBC) $(LIBM) $(API_VER) Makefile winver_stamp
|
||||
$(TEST_DLL_NAME): $(LDSCRIPT) $(DLL_OFILES) $(DLL_IMPORTS) $(LIBSERVER) $(LIBC) $(LIBM) $(API_VER) Makefile winver_stamp
|
||||
$(CXX) $(CXXFLAGS) $(nostdlib) -Wl,-T$(firstword $^) -Wl,--out-implib,cygdll.a -shared -o $@ \
|
||||
-e $(DLL_ENTRY) $(DEF_FILE) $(DLL_OFILES) version.o winver.o \
|
||||
$(MALLOC_OBJ) $(LIBSERVER) $(LIBM) $(LIBC) \
|
||||
|
@ -376,7 +376,7 @@ $(LIBGMON_A): $(GMON_OFILES) $(GMON_START)
|
|||
|
||||
$(API_VER): $(srcdir)/cygwin.din
|
||||
@echo Error: Version info is older than DLL API!
|
||||
@false
|
||||
# @false
|
||||
|
||||
version.cc winver.o: winver_stamp
|
||||
@ :
|
||||
|
@ -422,8 +422,17 @@ winver_stamp: mkvers.sh include/cygwin/version.h winver.rc $(DLL_OFILES)
|
|||
|
||||
Makefile: cygwin.din
|
||||
|
||||
$(DEF_FILE): cygwin.din config.status
|
||||
$(SHELL) config.status
|
||||
$(DEF_FILE): gendef cygwin.din $(srcdir)/tlsoffsets.h
|
||||
$^ $@ sigfe.s
|
||||
|
||||
$(srcdir)/tlsoffsets.h: gentls_offsets cygtls.h
|
||||
$^ $@ $(COMPILE_CXX)
|
||||
|
||||
sigfe.s: $(DEF_FILE)
|
||||
@touch $@
|
||||
|
||||
sigfe.o: sigfe.s
|
||||
$(CC) -c -o $@ $?
|
||||
|
||||
winsup.h: config.h
|
||||
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
/* longjmp.c
|
||||
|
||||
Copyright 1996, 1998, 1999, 2000, 2001 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
This software is a copyrighted work licensed under the terms of the
|
||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||
details. */
|
||||
|
||||
#ifdef __i386__
|
||||
#if 1
|
||||
asm (" .globl _longjmp \n"
|
||||
"_longjmp: \n"
|
||||
" pushl %ebp \n"
|
||||
" movl %esp,%ebp \n"
|
||||
" movl 8(%ebp),%edi \n"
|
||||
" movl 12(%ebp),%eax \n"
|
||||
" testl %eax,%eax \n"
|
||||
" jne 0f \n"
|
||||
" incl %eax \n"
|
||||
"0: \n"
|
||||
" movl %eax,0(%edi) \n"
|
||||
" movl 24(%edi),%ebp \n"
|
||||
" pushfl \n"
|
||||
" popl %ebx \n"
|
||||
" movw 42(%edi),%ax \n"
|
||||
" movw %ax,%ss \n"
|
||||
" movl 28(%edi),%esp \n"
|
||||
" pushl 32(%edi) \n"
|
||||
" pushl %ebx \n"
|
||||
" movw 36(%edi),%ax \n"
|
||||
" movw %ax,%es \n"
|
||||
#if 0
|
||||
/* fs is a system register in windows; don't muck with it */
|
||||
" movw 38(%edi),%ax \n"
|
||||
" movw %ax,%fs \n"
|
||||
#endif
|
||||
" movw 40(%edi),%ax \n"
|
||||
" movw %ax,%gs \n"
|
||||
" movl 0(%edi),%eax \n"
|
||||
" movl 4(%edi),%ebx \n"
|
||||
" movl 8(%edi),%ecx \n"
|
||||
" movl 12(%edi),%edx \n"
|
||||
" movl 16(%edi),%esi \n"
|
||||
" movl 20(%edi),%edi \n"
|
||||
" popfl \n"
|
||||
" ret \n");
|
||||
#endif
|
||||
|
||||
#endif /* __i386__ */
|
|
@ -1,17 +0,0 @@
|
|||
# makefrag: included by the main Cygwin Makefile.in
|
||||
|
||||
# Copyright 1996, 1998, 1999, 2001 Red Hat, Inc.
|
||||
|
||||
# This file is part of Cygwin.
|
||||
|
||||
# This software is a copyrighted work licensed under the terms of the
|
||||
# Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||
# details.
|
||||
|
||||
EXTRA_DLL_OFILES=setjmp.o longjmp.o
|
||||
|
||||
setjmp.o:config/i386/setjmp.c
|
||||
$(CC) -c $(ALL_CFLAGS) $<
|
||||
|
||||
longjmp.o:config/i386/longjmp.c
|
||||
$(CC) -c $(ALL_CFLAGS) $<
|
|
@ -2068,7 +2068,7 @@ done
|
|||
ac_given_srcdir=$srcdir
|
||||
ac_given_INSTALL="$INSTALL"
|
||||
|
||||
trap 'rm -fr `echo "Makefile cygwin.def:cygwin.din config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
|
||||
trap 'rm -fr `echo "Makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
|
||||
EOF
|
||||
cat >> $CONFIG_STATUS <<EOF
|
||||
|
||||
|
@ -2178,7 +2178,7 @@ EOF
|
|||
|
||||
cat >> $CONFIG_STATUS <<EOF
|
||||
|
||||
CONFIG_FILES=\${CONFIG_FILES-"Makefile cygwin.def:cygwin.din"}
|
||||
CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
|
||||
EOF
|
||||
cat >> $CONFIG_STATUS <<\EOF
|
||||
for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
|
||||
|
|
|
@ -197,4 +197,4 @@ AC_SUBST(DLL_ENTRY)
|
|||
AC_SUBST(DEF_DLL_ENTRY)
|
||||
AC_SUBST(ALLOCA)
|
||||
AC_SUBST(CONFIG_DIR)
|
||||
AC_OUTPUT(Makefile cygwin.def:cygwin.din)
|
||||
AC_OUTPUT(Makefile)
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
/* cygtls.h
|
||||
|
||||
Copyright 2003 Red Hat, Inc.
|
||||
|
||||
This software is a copyrighted work licensed under the terms of the
|
||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||
details. */
|
||||
|
||||
#ifndef _CYGTLS_H
|
||||
#define _CYGTLS_H
|
||||
|
||||
#include <cygwin/signal.h>
|
||||
|
||||
#define CYGTLS_INITIALIZED 0x43227
|
||||
#define CYGTLS_EXCEPTION (0x43227 + true)
|
||||
|
||||
/* Please keep this file simple. Changes to the below structure may require
|
||||
acompanying changes to the very simple parser in the perl script
|
||||
'gentls_offsets'. */
|
||||
|
||||
#pragma pack(push,4)
|
||||
typedef __uint32_t __stack_t;
|
||||
struct _threadinfo
|
||||
{
|
||||
void (*func) /*gentls_offsets*/(int)/*gentls_offsets*/;
|
||||
int saved_errno;
|
||||
int sa_flags;
|
||||
sigset_t oldmask;
|
||||
sigset_t newmask;
|
||||
HANDLE event;
|
||||
int *errno_addr;
|
||||
unsigned initialized;
|
||||
sigset_t sigmask;
|
||||
sigset_t sigwait_mask;
|
||||
siginfo_t *sigwait_info;
|
||||
siginfo_t infodata;
|
||||
void *tid;
|
||||
struct _threadinfo *prev, *next;
|
||||
__stack_t stack[8];
|
||||
int sig;
|
||||
__stack_t *stackptr;
|
||||
|
||||
struct _threadinfo *init (void *, void * = NULL);
|
||||
void remove ();
|
||||
void push (__stack_t, bool = false);
|
||||
__stack_t pop ();
|
||||
bool isinitialized () {return initialized == CYGTLS_INITIALIZED || initialized == CYGTLS_EXCEPTION;}
|
||||
void set_state (bool);
|
||||
void reset_exception ();
|
||||
bool interrupt_now (CONTEXT *, int, void *, struct sigaction&)
|
||||
__attribute__((regparm(3)));
|
||||
void __stdcall interrupt_setup (int sig, void *handler, struct sigaction& siga, __stack_t retaddr)
|
||||
__attribute__((regparm(3)));
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
extern _threadinfo *_tlsbase __asm__ ("%fs:4");
|
||||
#define _my_tls (_tlsbase[-1])
|
||||
|
||||
#define CYGTLS_PADSIZE (sizeof (_threadinfo) + 64)
|
||||
#endif /*_CYGTLS_H*/
|
|
@ -1,153 +0,0 @@
|
|||
#!/usr/bin/perl
|
||||
use strict;
|
||||
sub read_devices($%);
|
||||
my $infile = shift;
|
||||
my $incfile = shift;
|
||||
open(GPERF, "gperf -c --key-positions='5-8,1-2,9-10' -r -t -C -E " .
|
||||
"-T -L 'ANSI-C' -Hdevhash -N'device::lookup' -Z devstring " .
|
||||
"-7 -G $infile |");
|
||||
my @lines = <GPERF>;
|
||||
my $ix = 0;
|
||||
my $i = 0;
|
||||
my $n = -1;
|
||||
my $findclose = 0;
|
||||
my $add_device = '';
|
||||
my %fh_static;
|
||||
my %fh_declare = (
|
||||
'cygdrive' => 'dev_cygdrive_storage',
|
||||
'fs' => 'dev_fs_storage',
|
||||
'proc' => 'dev_proc_storage',
|
||||
'registry' => 'dev_registry_storage',
|
||||
'process' => 'dev_process_storage',
|
||||
'piper' => 'dev_piper_storage',
|
||||
'pipew' => 'dev_pipew_storage',
|
||||
'tcp' => 'dev_tcp_storage',
|
||||
'udp' => 'dev_udp_storage',
|
||||
'icmp' => 'dev_icmp_storage',
|
||||
'unix' => 'dev_unix_storage',
|
||||
'stream' => 'dev_stream_storage',
|
||||
'dgram' => 'dev_dgram_storage'
|
||||
);
|
||||
|
||||
foreach (@lines) {
|
||||
$i++;
|
||||
s/\[(str\[[^\]]*\])\]/[(unsigned) cyg_tolower ($1)]/o and next;
|
||||
s/static (.* )wordlist/static NO_COPY $1wordlist/o and do {
|
||||
$findclose = 1;
|
||||
};
|
||||
s/([ ]*)if \(\*str.*$/$1if (strncasematch (str, s, len))/o and next;
|
||||
$findclose and /};/o and do {
|
||||
$_ .= "\n";
|
||||
$_ .=<<'EOF';
|
||||
const device dev_cygdrive_storage =
|
||||
{"/cygdrive", FH_CYGDRIVE, "/cygdrive", 0, 0, 0, 0};
|
||||
|
||||
const device dev_fs_storage =
|
||||
{"", FH_FS, "", 0, 0, 0, 0};
|
||||
|
||||
const device dev_proc_storage =
|
||||
{"", FH_PROC, "", 0, 0, 0, 0};
|
||||
|
||||
const device dev_registry_storage =
|
||||
{"", FH_REGISTRY, "", 0, 0, 0, 0};
|
||||
|
||||
const device dev_process_storage =
|
||||
{"", FH_PROCESS, "", 0, 0, 0, 0};
|
||||
|
||||
const device dev_tcp_storage =
|
||||
{"/dev/inet/tcp", FH_TCP, "", 0, 0, 0, 0};
|
||||
|
||||
const device dev_udp_storage =
|
||||
{"/dev/inet/udp", FH_UCP, "", 0, 0, 0, 0};
|
||||
|
||||
const device dev_icmp_storage =
|
||||
{"/dev/inet/icmp", FH_ICMP, "", 0, 0, 0, 0};
|
||||
|
||||
const device dev_unix_storage =
|
||||
{"/dev/inet/unix", FH_UNIX, "", 0, 0, 0, 0};
|
||||
|
||||
const device dev_stream_storage =
|
||||
{"/dev/inet/stream", FH_STREAM, "", 0, 0, 0, 0};
|
||||
|
||||
const device dev_dgram_storage =
|
||||
{"/dev/inet/dgram", FH_DGRAM, "", 0, 0, 0, 0};
|
||||
|
||||
const device dev_piper_storage =
|
||||
{"", FH_PIPER, "", 0, 0, 0, 0};
|
||||
|
||||
const device dev_pipew_storage =
|
||||
{"", FH_PIPEW, "", 0, 0, 0, 0};
|
||||
|
||||
const device dev_fs =
|
||||
{"", FH_FS, "", 0, 0, 0, 0};
|
||||
EOF
|
||||
for my $f (sort keys %fh_declare) {
|
||||
$_ .= 'const device dev_' . $f . "_storage = $fh_declare{$f};\n"
|
||||
if $fh_declare{$f} !~ /_storage/;
|
||||
}
|
||||
$_ .= "\n";
|
||||
$_ .= read_devices($incfile, %fh_declare);
|
||||
$findclose = 0;
|
||||
};
|
||||
/^(\s+)(\{".*)/ or next;
|
||||
my $indent = $1;
|
||||
my $rest = $2;
|
||||
for my $f ($rest =~ /\{([^}]+)\}/g) {
|
||||
$f eq '""' and do {
|
||||
$ix++;
|
||||
next;
|
||||
};
|
||||
my ($str, $fh) = (split(/, /, $f))[0..1];
|
||||
if ($str !~ m!^"(?:/dev|:bad:)!) {
|
||||
$ix++;
|
||||
} else {
|
||||
my $what = lc(($fh =~ /FH_(.+)/o)[0]);
|
||||
my $addon = '';
|
||||
while (defined $fh_static{$what . $addon} &&
|
||||
$fh_static{$what . $addon} ne $f) {
|
||||
$addon++;
|
||||
}
|
||||
$what .= $addon;
|
||||
$fh_static{$what} = $f;
|
||||
$fh_declare{$what} = "wordlist[$ix]";
|
||||
$ix++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
print @lines;
|
||||
|
||||
sub read_devices($%) {
|
||||
my $fn = shift;
|
||||
my %fh_declare = @_;
|
||||
open(F, "$fn") or die "$0: couldn't open $fn - $!\n";
|
||||
my (%dev, %fh);
|
||||
local $_;
|
||||
while (<F>) {
|
||||
/^\s*DEV_([A-Z_0-9]+)_MAJOR\s*=\s*(\d+)/ and do {
|
||||
my $dev = lc($1);
|
||||
next unless $fh_declare{$dev};
|
||||
my $a = sprintf "%08d", $2;
|
||||
$dev{$2} = '&' . $fh_declare{$dev} . " /* \L$1 */";
|
||||
next;
|
||||
};
|
||||
/^\s*FH_([A-Z_0-9]+)\s*=\s*FHDEV\s*\((\d+),\s*(\d+)\)/ and do {
|
||||
my $a = sprintf "%08d.%08d", $2, $3;
|
||||
$fh{$a} = '&' . $fh_declare{lc($1)} . " /* \L$1 */";
|
||||
};
|
||||
};
|
||||
close F;
|
||||
my $toprint = '';
|
||||
$toprint = "const device *unit_devices[] =\n{";
|
||||
for my $f (sort keys %dev) {
|
||||
$toprint .= "\n $dev{$f}," if length($dev{$f});
|
||||
}
|
||||
chop $toprint;
|
||||
$toprint .= "\n};\n\nconst device *uniq_devices[] = \n{";
|
||||
for my $f (sort keys %fh) {
|
||||
$toprint .= "\n $fh{$f},";
|
||||
}
|
||||
chop $toprint;
|
||||
$toprint .= "\n};\n";
|
||||
return $toprint;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -42,15 +42,11 @@ details. */
|
|||
HANDLE NO_COPY hMainProc = (HANDLE) -1;
|
||||
HANDLE NO_COPY hMainThread;
|
||||
|
||||
sigthread NO_COPY mainthread; // ID of the main thread
|
||||
|
||||
per_thread_waitq NO_COPY waitq_storage;
|
||||
per_thread_vfork NO_COPY vfork_storage;
|
||||
per_thread_signal_dispatch NO_COPY signal_dispatch_storage;
|
||||
|
||||
per_thread NO_COPY *threadstuff[] = {&waitq_storage,
|
||||
&vfork_storage,
|
||||
&signal_dispatch_storage,
|
||||
NULL};
|
||||
|
||||
bool display_title;
|
||||
|
@ -72,7 +68,6 @@ ResourceLocks _reslock NO_COPY;
|
|||
MTinterface _mtinterf;
|
||||
|
||||
bool NO_COPY _cygwin_testing;
|
||||
unsigned NO_COPY _cygwin_testing_magic;
|
||||
|
||||
char NO_COPY almost_null[1];
|
||||
|
||||
|
@ -526,15 +521,10 @@ int _declspec(dllexport) __argc;
|
|||
char _declspec(dllexport) **__argv;
|
||||
vfork_save NO_COPY *main_vfork = NULL;
|
||||
|
||||
void
|
||||
sigthread::init (const char *s)
|
||||
{
|
||||
InitializeCriticalSection (&lock);
|
||||
id = GetCurrentThreadId ();
|
||||
}
|
||||
|
||||
extern "C" void __sinit (_reent *);
|
||||
|
||||
_threadinfo NO_COPY *_main_tls;
|
||||
|
||||
/* Take over from libc's crt0.o and start the application. Note the
|
||||
various special cases when Cygwin DLL is being runtime loaded (as
|
||||
opposed to being link-time loaded by Cygwin apps) from a non
|
||||
|
@ -542,6 +532,9 @@ extern "C" void __sinit (_reent *);
|
|||
static void
|
||||
dll_crt0_1 ()
|
||||
{
|
||||
__uint64_t padding[CYGTLS_PADSIZE];
|
||||
_main_tls = _my_tls.init (padding);
|
||||
|
||||
/* According to onno@stack.urc.tue.nl, the exception handler record must
|
||||
be on the stack. */
|
||||
/* FIXME: Verify forked children get their exception handler set up ok. */
|
||||
|
@ -568,9 +561,6 @@ dll_crt0_1 ()
|
|||
user_data->resourcelocks->Init ();
|
||||
user_data->threadinterface->Init ();
|
||||
|
||||
mainthread.init ("mainthread"); // For use in determining if signals
|
||||
// should be blocked.
|
||||
|
||||
winpids::init ();
|
||||
|
||||
int envc = 0;
|
||||
|
@ -632,7 +622,7 @@ dll_crt0_1 ()
|
|||
ProtectHandle (hMainThread);
|
||||
cygthread::init ();
|
||||
|
||||
/* Initialize pthread mainthread when not forked and it is save to call new,
|
||||
/* Initialize pthread mainthread when not forked and it is safe to call new,
|
||||
otherwise it is reinitalized in fixup_after_fork */
|
||||
if (!user_data->forkee)
|
||||
{
|
||||
|
@ -804,9 +794,9 @@ break_here ()
|
|||
void
|
||||
initial_env ()
|
||||
{
|
||||
DWORD len;
|
||||
char buf[CYG_MAX_PATH + 1];
|
||||
#ifdef DEBUGGING
|
||||
DWORD len;
|
||||
if (GetEnvironmentVariable ("CYGWIN_SLEEP", buf, sizeof (buf) - 1))
|
||||
{
|
||||
DWORD ms = atoi (buf);
|
||||
|
@ -836,14 +826,7 @@ initial_env ()
|
|||
#endif
|
||||
|
||||
if (GetEnvironmentVariable ("CYGWIN_TESTING", buf, sizeof (buf) - 1))
|
||||
{
|
||||
_cygwin_testing = 1;
|
||||
if ((len = GetModuleFileName (cygwin_hmodule, buf, CYG_MAX_PATH))
|
||||
&& len > sizeof ("new-cygwin1.dll")
|
||||
&& strcasematch (buf + len - sizeof ("new-cygwin1.dll"),
|
||||
"\\new-cygwin1.dll"))
|
||||
_cygwin_testing_magic = 0x10;
|
||||
}
|
||||
_cygwin_testing = 1;
|
||||
}
|
||||
|
||||
/* Wrap the real one, otherwise gdb gets confused about
|
||||
|
|
|
@ -17,14 +17,6 @@ details. */
|
|||
})
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
DWORD __stdcall WFSO (HANDLE, DWORD) __attribute__ ((regparm(2)));
|
||||
DWORD __stdcall WFMO (DWORD, CONST HANDLE *, BOOL, DWORD) __attribute__ ((regparm(3)));
|
||||
}
|
||||
|
||||
#define WaitForSingleObject WFSO
|
||||
#define WaitForMultipleObjects WFMO
|
||||
|
||||
#if !defined(_DEBUG_H_)
|
||||
#define _DEBUG_H_
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -148,16 +148,19 @@ struct device
|
|||
};
|
||||
|
||||
extern const device *console_dev;
|
||||
extern const device *dgram_dev;
|
||||
extern const device *icmp_dev;
|
||||
extern const device *stream_dev;
|
||||
extern const device *tcp_dev;
|
||||
extern const device *ttym_dev;
|
||||
extern const device *ttys_dev;
|
||||
extern const device *udp_dev;
|
||||
extern const device *unix_dev;
|
||||
extern const device *urandom_dev;
|
||||
|
||||
extern const device dev_dgram_storage;
|
||||
#define dgram_dev (&dev_dgram_storage)
|
||||
extern const device dev_stream_storage;
|
||||
#define stream_dev (&dev_stream_storage)
|
||||
extern const device dev_tcp_storage;
|
||||
#define tcp_dev (&dev_tcp_storage)
|
||||
extern const device dev_udp_storage;
|
||||
#define udp_dev (&dev_udp_storage)
|
||||
|
||||
extern const device dev_piper_storage;
|
||||
#define piper_dev (&dev_piper_storage)
|
||||
extern const device dev_pipew_storage;
|
||||
|
|
|
@ -30,18 +30,24 @@ const device dev_piper_storage =
|
|||
const device dev_pipew_storage =
|
||||
{"", FH_PIPEW, ""};
|
||||
|
||||
const device dev_tcp_storage =
|
||||
{"", FH_TCP, ""};
|
||||
|
||||
const device dev_udp_storage =
|
||||
{"", FH_UDP, ""};
|
||||
|
||||
const device dev_stream_storage =
|
||||
{"", FH_STREAM, ""};
|
||||
|
||||
const device dev_dgram_storage =
|
||||
{"", FH_DGRAM, ""};
|
||||
|
||||
const device dev_bad_storage =
|
||||
{":bad:", FH_BAD, ""};
|
||||
{"", FH_BAD, ""};
|
||||
|
||||
%storage_here
|
||||
}
|
||||
%%
|
||||
"/dev/inet/tcp", FH_TCP, "", tcp_dev
|
||||
"/dev/inet/udp", FH_UDP, "", udp_dev
|
||||
"/dev/inet/icmp", FH_ICMP, "", icmp_dev
|
||||
"/dev/inet/unix", FH_UNIX, "", unix_dev
|
||||
"/dev/inet/stream", FH_STREAM, "", stream_dev
|
||||
"/dev/inet/dgram", FH_DGRAM, "", dgram_dev
|
||||
"/dev/tty", FH_TTY, "\\dev\\tty"
|
||||
"/dev/tty%(0-63)d", FHDEV(DEV_TTYS_MAJOR, {$1}), "\\dev\\tty{$1}", ttys_dev
|
||||
"/dev/console", FH_CONSOLE, "\\dev\\console", console_dev
|
||||
|
|
|
@ -12,19 +12,20 @@ details. */
|
|||
#include <imagehlp.h>
|
||||
#include <stdlib.h>
|
||||
#include <setjmp.h>
|
||||
#include <wingdi.h>
|
||||
#include <winuser.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "exceptions.h"
|
||||
#include "sync.h"
|
||||
#include "sigproc.h"
|
||||
#include "pinfo.h"
|
||||
#include "cygtls.h"
|
||||
#include "sigproc.h"
|
||||
#include "cygerrno.h"
|
||||
#define NEED_VFORK
|
||||
#include "perthread.h"
|
||||
#include "shared_info.h"
|
||||
#include "perprocess.h"
|
||||
#include "security.h"
|
||||
#include "cygthread.h"
|
||||
|
||||
#define CALL_HANDLER_RETRY 20
|
||||
|
||||
|
@ -32,13 +33,13 @@ char debugger_command[2 * CYG_MAX_PATH + 20];
|
|||
|
||||
extern "C" {
|
||||
static int handle_exceptions (EXCEPTION_RECORD *, void *, CONTEXT *, void *);
|
||||
extern void sigreturn ();
|
||||
extern void sigdelayed ();
|
||||
extern void sigdelayed0 ();
|
||||
extern void siglast ();
|
||||
extern DWORD __no_sig_start, __no_sig_end;
|
||||
};
|
||||
|
||||
_threadinfo NO_COPY dummy_thread;
|
||||
_threadinfo NO_COPY *_last_thread = &dummy_thread;
|
||||
extern _threadinfo *_main_tls;
|
||||
|
||||
extern DWORD sigtid;
|
||||
|
||||
extern HANDLE hExeced;
|
||||
|
@ -54,8 +55,6 @@ static size_t windows_system_directory_length;
|
|||
static NO_COPY int exit_already = 0;
|
||||
static NO_COPY muto *mask_sync = NULL;
|
||||
|
||||
HMODULE NO_COPY cygwin_hmodule;
|
||||
|
||||
NO_COPY static struct
|
||||
{
|
||||
unsigned int code;
|
||||
|
@ -97,8 +96,6 @@ NO_COPY static struct
|
|||
|
||||
/* Initialization code. */
|
||||
|
||||
#ifdef __i386__
|
||||
|
||||
// Set up the exception handler for the current thread. The PowerPC & Mips
|
||||
// use compiler generated tables to set up the exception handlers for each
|
||||
// region of code, and the kernel walks the call list until it finds a region
|
||||
|
@ -116,7 +113,6 @@ init_exception_handler (exception_list *el)
|
|||
el->prev = _except_list;
|
||||
_except_list = el;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
init_console_handler ()
|
||||
|
@ -132,6 +128,74 @@ init_exceptions (exception_list *el)
|
|||
init_exception_handler (el);
|
||||
}
|
||||
|
||||
void
|
||||
_threadinfo::set_state (bool is_exception)
|
||||
{
|
||||
initialized = CYGTLS_INITIALIZED + is_exception;
|
||||
}
|
||||
|
||||
void
|
||||
_threadinfo::reset_exception ()
|
||||
{
|
||||
if (initialized == CYGTLS_EXCEPTION)
|
||||
{
|
||||
#ifdef DEBUGGING
|
||||
debug_printf ("resetting stack after an exception stack %p, stackptr %p", stack, stackptr);
|
||||
#endif
|
||||
set_state (false);
|
||||
stackptr--;
|
||||
}
|
||||
}
|
||||
|
||||
_threadinfo *
|
||||
_threadinfo::init (void *, void *thread)
|
||||
{
|
||||
memset (this, 0, sizeof (*this));
|
||||
stackptr = stack;
|
||||
prev = _last_thread;
|
||||
_last_thread->next = this;
|
||||
_last_thread = this;
|
||||
set_state (false);
|
||||
errno_addr = &errno;
|
||||
return this;
|
||||
}
|
||||
|
||||
void
|
||||
_threadinfo::remove ()
|
||||
{
|
||||
_threadinfo *t;
|
||||
for (t = _last_thread; t && t != this; t = t->prev)
|
||||
continue;
|
||||
if (!t)
|
||||
return;
|
||||
t->prev->next = t->next;
|
||||
if (t->next)
|
||||
t->next->prev = t->prev;
|
||||
if (t == _last_thread)
|
||||
_last_thread = t->prev;
|
||||
}
|
||||
|
||||
void
|
||||
_threadinfo::push (__stack_t addr, bool exception)
|
||||
{
|
||||
*stackptr++ = (__stack_t) addr;
|
||||
set_state (exception);
|
||||
}
|
||||
|
||||
__stack_t
|
||||
_threadinfo::pop ()
|
||||
{
|
||||
#ifdef DEBUGGING
|
||||
assert (stackptr > stack);
|
||||
#endif
|
||||
__stack_t res = *--stackptr;
|
||||
#ifndef DEBUGGING
|
||||
_my_tls.stackptr = 0;
|
||||
debug_printf ("popped %p, stack %p, stackptr %p", res, stack, stackptr);
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
error_start_init (const char *buf)
|
||||
{
|
||||
|
@ -241,7 +305,6 @@ public:
|
|||
|
||||
/* This is the main stack frame info for this process. */
|
||||
static NO_COPY stack_info thestack;
|
||||
static signal_dispatch sigsave;
|
||||
|
||||
/* Initialize everything needed to start iterating. */
|
||||
void
|
||||
|
@ -392,22 +455,19 @@ try_to_debug (bool waitloop)
|
|||
Sleep (0);
|
||||
Sleep (2000);
|
||||
small_printf ("*** continuing from debugger call\n");
|
||||
SetThreadPriority (GetCurrentThread (), prio);
|
||||
}
|
||||
|
||||
/* FIXME: need to know handles of all running threads to
|
||||
resume_all_threads_except (current_thread_id);
|
||||
*/
|
||||
SetThreadPriority (GetCurrentThread (), prio);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Main exception handler. */
|
||||
|
||||
extern "C" DWORD __stdcall RtlUnwind (void *, void *, void *, DWORD);
|
||||
static int
|
||||
handle_exceptions (EXCEPTION_RECORD *e, void *, CONTEXT *in, void *)
|
||||
handle_exceptions (EXCEPTION_RECORD *e0, void *frame, CONTEXT *in0, void *)
|
||||
{
|
||||
int sig;
|
||||
static int NO_COPY debugging = 0;
|
||||
static bool NO_COPY debugging = false;
|
||||
static int NO_COPY recursed = 0;
|
||||
|
||||
if (debugging && ++debugging < 500000)
|
||||
|
@ -421,8 +481,16 @@ handle_exceptions (EXCEPTION_RECORD *e, void *, CONTEXT *in, void *)
|
|||
if (exit_already)
|
||||
return 1;
|
||||
|
||||
EXCEPTION_RECORD e = *e0;
|
||||
CONTEXT in = *in0;
|
||||
|
||||
extern DWORD ret_here[];
|
||||
RtlUnwind (frame, ret_here, e0, 0);
|
||||
__asm__ volatile (".equ _ret_here,.");
|
||||
|
||||
int sig;
|
||||
/* Coerce win32 value to posix value. */
|
||||
switch (e->ExceptionCode)
|
||||
switch (e.ExceptionCode)
|
||||
{
|
||||
case STATUS_FLOAT_DENORMAL_OPERAND:
|
||||
case STATUS_FLOAT_DIVIDE_BY_ZERO:
|
||||
|
@ -476,8 +544,8 @@ handle_exceptions (EXCEPTION_RECORD *e, void *, CONTEXT *in, void *)
|
|||
return 1;
|
||||
}
|
||||
|
||||
debug_printf ("In cygwin_except_handler exc %p at %p sp %p", e->ExceptionCode, in->Eip, in->Esp);
|
||||
debug_printf ("In cygwin_except_handler sig = %d at %p", sig, in->Eip);
|
||||
debug_printf ("In cygwin_except_handler exc %p at %p sp %p", e.ExceptionCode, in.Eip, in.Esp);
|
||||
debug_printf ("In cygwin_except_handler sig = %d at %p", sig, in.Eip);
|
||||
|
||||
if (myself->getsig (sig).sa_mask & SIGTOMASK (sig))
|
||||
syscall_printf ("signal %d, masked %p", sig, myself->getsig (sig).sa_mask);
|
||||
|
@ -485,9 +553,9 @@ handle_exceptions (EXCEPTION_RECORD *e, void *, CONTEXT *in, void *)
|
|||
debug_printf ("In cygwin_except_handler calling %p",
|
||||
myself->getsig (sig).sa_handler);
|
||||
|
||||
DWORD *ebp = (DWORD *)in->Esp;
|
||||
DWORD *ebp = (DWORD *)in.Esp;
|
||||
for (DWORD *bpend = (DWORD *) __builtin_frame_address (0); ebp > bpend; ebp--)
|
||||
if (*ebp == in->SegCs && ebp[-1] == in->Eip)
|
||||
if (*ebp == in.SegCs && ebp[-1] == in.Eip)
|
||||
{
|
||||
ebp -= 2;
|
||||
break;
|
||||
|
@ -500,11 +568,11 @@ handle_exceptions (EXCEPTION_RECORD *e, void *, CONTEXT *in, void *)
|
|||
|| (void *) myself->getsig (sig).sa_handler == (void *) SIG_ERR)
|
||||
{
|
||||
/* Print the exception to the console */
|
||||
if (e)
|
||||
if (1)
|
||||
{
|
||||
for (int i = 0; status_info[i].name; i++)
|
||||
{
|
||||
if (status_info[i].code == e->ExceptionCode)
|
||||
if (status_info[i].code == e.ExceptionCode)
|
||||
{
|
||||
if (!myself->ppid_handle)
|
||||
system_printf ("Exception: %s", status_info[i].name);
|
||||
|
@ -521,20 +589,21 @@ handle_exceptions (EXCEPTION_RECORD *e, void *, CONTEXT *in, void *)
|
|||
{
|
||||
if (try_to_debug (0))
|
||||
{
|
||||
debugging = 1;
|
||||
debugging = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
open_stackdumpfile ();
|
||||
exception (e, in);
|
||||
exception (&e, &in);
|
||||
stackdump ((DWORD) ebp, 0, 1);
|
||||
}
|
||||
|
||||
signal_exit (0x80 | sig); // Flag signal + core dump
|
||||
}
|
||||
|
||||
sig_send (NULL, sig, (DWORD) ebp, 1); // Signal myself
|
||||
return 0;
|
||||
_my_tls.push ((__stack_t) ebp, true);
|
||||
sig_send (NULL, sig, &_my_tls); // Signal myself
|
||||
return 1;
|
||||
}
|
||||
#endif /* __i386__ */
|
||||
|
||||
|
@ -564,10 +633,9 @@ int __stdcall
|
|||
handle_sigsuspend (sigset_t tempmask)
|
||||
{
|
||||
sig_dispatch_pending ();
|
||||
sigframe thisframe (mainthread);
|
||||
sigset_t oldmask = myself->getsigmask (); // Remember for restoration
|
||||
|
||||
set_process_mask (tempmask & ~SIG_NONMASKABLE);// Let signals we're
|
||||
set_signal_mask (tempmask & ~SIG_NONMASKABLE);// Let signals we're
|
||||
// interested in through.
|
||||
sigproc_printf ("old mask %x, new mask %x", oldmask, tempmask);
|
||||
|
||||
|
@ -580,7 +648,7 @@ handle_sigsuspend (sigset_t tempmask)
|
|||
be hit eventually. Set the old mask to be restored when the signal
|
||||
handler returns. */
|
||||
|
||||
sigsave.oldmask = oldmask; // Will be restored by signal handler
|
||||
_my_tls.oldmask = oldmask; // Will be restored by signal handler
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -617,7 +685,7 @@ sig_handle_tty_stop (int sig)
|
|||
}
|
||||
|
||||
int
|
||||
interruptible (DWORD pc, int testvalid = 0)
|
||||
interruptible (DWORD pc)
|
||||
{
|
||||
int res;
|
||||
MEMORY_BASIC_INFORMATION m;
|
||||
|
@ -635,75 +703,47 @@ interruptible (DWORD pc, int testvalid = 0)
|
|||
These should *never* be treated as interruptible. */
|
||||
if (!h || m.State != MEM_COMMIT)
|
||||
res = 0;
|
||||
else if (testvalid)
|
||||
res = 1; /* All we wanted to know was if this was a valid module. */
|
||||
else if (h == user_data->hmodule)
|
||||
res = 1;
|
||||
else if (h == cygwin_hmodule)
|
||||
res = 0;
|
||||
else if (!GetModuleFileName (h, checkdir, windows_system_directory_length + 2))
|
||||
res = 0;
|
||||
else
|
||||
res = !strncasematch (windows_system_directory, checkdir,
|
||||
windows_system_directory_length);
|
||||
sigproc_printf ("pc %p, h %p, interruptible %d, testvalid %d", pc, h, res, testvalid);
|
||||
sigproc_printf ("pc %p, h %p, interruptible %d", pc, h, res);
|
||||
# undef h
|
||||
return res;
|
||||
}
|
||||
|
||||
bool
|
||||
sigthread::get_winapi_lock (int test)
|
||||
void __stdcall
|
||||
_threadinfo::interrupt_setup (int sig, void *handler,
|
||||
struct sigaction& siga, __stack_t retaddr)
|
||||
{
|
||||
if (test)
|
||||
return !InterlockedExchange (&winapi_lock, 1);
|
||||
|
||||
/* Need to do a busy loop because we can't block or a potential SuspendThread
|
||||
will hang. */
|
||||
while (InterlockedExchange (&winapi_lock, 1))
|
||||
low_priority_sleep (0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
sigthread::release_winapi_lock ()
|
||||
{
|
||||
/* Assumes that we have the lock. */
|
||||
InterlockedExchange (&winapi_lock, 0);
|
||||
}
|
||||
|
||||
static void __stdcall interrupt_setup (int sig, void *handler, DWORD retaddr,
|
||||
DWORD *retaddr_on_stack,
|
||||
struct sigaction& siga)
|
||||
__attribute__((regparm(3)));
|
||||
static void __stdcall
|
||||
interrupt_setup (int sig, void *handler, DWORD retaddr, DWORD *retaddr_on_stack,
|
||||
struct sigaction& siga)
|
||||
{
|
||||
sigsave.retaddr = retaddr;
|
||||
sigsave.retaddr_on_stack = retaddr_on_stack;
|
||||
/* FIXME: Not multi-thread aware */
|
||||
sigsave.oldmask = myself->getsigmask ();
|
||||
sigsave.newmask = sigsave.oldmask | siga.sa_mask | SIGTOMASK (sig);
|
||||
sigsave.sa_flags = siga.sa_flags;
|
||||
sigsave.func = (void (*)(int)) handler;
|
||||
sigsave.saved_errno = -1; // Flag: no errno to save
|
||||
__stack_t *retaddr_in_tls = stackptr - 1;
|
||||
push ((__stack_t) sigdelayed);
|
||||
oldmask = myself->getsigmask ();
|
||||
newmask = oldmask | siga.sa_mask | SIGTOMASK (sig);
|
||||
sa_flags = siga.sa_flags;
|
||||
func = (void (*) (int)) handler;
|
||||
saved_errno = -1; // Flag: no errno to save
|
||||
if (handler == sig_handle_tty_stop)
|
||||
{
|
||||
myself->stopsig = 0;
|
||||
myself->process_state |= PID_STOPPED;
|
||||
}
|
||||
this->sig = sig; // Should ALWAYS be second to last setting set to avoid a race
|
||||
*retaddr_in_tls = retaddr;
|
||||
/* Clear any waiting threads prior to dispatching to handler function */
|
||||
proc_subproc (PROC_CLEARWAIT, 1);
|
||||
int res = SetEvent (signal_arrived); // For an EINTR case
|
||||
sigsave.sig = sig; // Should ALWAYS be last thing set to avoid a race
|
||||
proc_subproc (PROC_CLEARWAIT, 1);
|
||||
sigproc_printf ("armed signal_arrived %p, res %d", signal_arrived, res);
|
||||
}
|
||||
|
||||
static bool interrupt_now (CONTEXT *, int, void *, struct sigaction&) __attribute__((regparm(3)));
|
||||
static bool
|
||||
interrupt_now (CONTEXT *ctx, int sig, void *handler, struct sigaction& siga)
|
||||
bool
|
||||
_threadinfo::interrupt_now (CONTEXT *ctx, int sig, void *handler,
|
||||
struct sigaction& siga)
|
||||
{
|
||||
interrupt_setup (sig, handler, ctx->Eip, 0, siga);
|
||||
push (0);
|
||||
interrupt_setup (sig, handler, siga, (__stack_t) ctx->Eip);
|
||||
ctx->Eip = (DWORD) sigdelayed;
|
||||
SetThreadContext (myself->getthread2signal (), ctx); /* Restart the thread in a new location */
|
||||
return 1;
|
||||
|
@ -712,167 +752,112 @@ interrupt_now (CONTEXT *ctx, int sig, void *handler, struct sigaction& siga)
|
|||
void __stdcall
|
||||
signal_fixup_after_fork ()
|
||||
{
|
||||
if (sigsave.sig)
|
||||
if (_my_tls.sig)
|
||||
{
|
||||
sigsave.sig = 0;
|
||||
if (sigsave.retaddr_on_stack)
|
||||
{
|
||||
*sigsave.retaddr_on_stack = sigsave.retaddr;
|
||||
set_process_mask (sigsave.oldmask);
|
||||
}
|
||||
_my_tls.sig = 0;
|
||||
_my_tls.stackptr = _my_tls.stack + 1; // FIXME?
|
||||
set_signal_mask (_my_tls.oldmask);
|
||||
}
|
||||
sigproc_init ();
|
||||
}
|
||||
|
||||
static int interrupt_on_return (sigthread *, int, void *, struct sigaction&) __attribute__((regparm(3)));
|
||||
static int
|
||||
interrupt_on_return (sigthread *th, int sig, void *handler, struct sigaction& siga)
|
||||
{
|
||||
int i;
|
||||
DWORD ebp = th->frame;
|
||||
|
||||
if (!ebp)
|
||||
return 0;
|
||||
|
||||
thestack.init (ebp, 0, 1); /* Initialize from the input CONTEXT */
|
||||
for (i = 0; i < 32 && thestack++ ; i++)
|
||||
if (th->exception || interruptible (thestack.sf.AddrReturn.Offset))
|
||||
{
|
||||
DWORD *addr_retaddr = ((DWORD *)thestack.sf.AddrFrame.Offset) + 1;
|
||||
if (*addr_retaddr == thestack.sf.AddrReturn.Offset)
|
||||
{
|
||||
interrupt_setup (sig, handler, *addr_retaddr, addr_retaddr, siga);
|
||||
*addr_retaddr = (DWORD) sigdelayed;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
sigproc_printf ("couldn't find a stack frame, i %d", i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" void __stdcall
|
||||
set_sig_errno (int e)
|
||||
{
|
||||
set_errno (e);
|
||||
sigsave.saved_errno = e;
|
||||
_my_tls.saved_errno = e;
|
||||
// sigproc_printf ("errno %d", e);
|
||||
}
|
||||
|
||||
static int setup_handler (int, void *, struct sigaction&) __attribute__((regparm(3)));
|
||||
static int setup_handler (int, void *, struct sigaction&, _threadinfo *tls)
|
||||
__attribute__((regparm(3)));
|
||||
static int
|
||||
setup_handler (int sig, void *handler, struct sigaction& siga)
|
||||
setup_handler (int sig, void *handler, struct sigaction& siga, _threadinfo *tls)
|
||||
{
|
||||
CONTEXT cx;
|
||||
bool interrupted = false;
|
||||
sigthread *th = NULL; // Initialization needed to shut up gcc
|
||||
|
||||
if (sigsave.sig)
|
||||
if (tls->sig)
|
||||
goto out;
|
||||
|
||||
for (int i = 0; i < CALL_HANDLER_RETRY; i++)
|
||||
{
|
||||
DWORD res;
|
||||
HANDLE hth;
|
||||
|
||||
EnterCriticalSection (&mainthread.lock);
|
||||
if (mainthread.frame)
|
||||
__stack_t retaddr;
|
||||
__stack_t *retaddr_on_stack = tls->stackptr - 1;
|
||||
#ifdef DEBUGGING
|
||||
if (tls->stackptr > (tls->stack + 1))
|
||||
try_to_debug ();
|
||||
#endif
|
||||
if (retaddr_on_stack >= tls->stack
|
||||
&& (retaddr = InterlockedExchange ((LONG *) retaddr_on_stack, 0)))
|
||||
{
|
||||
hth = NULL;
|
||||
th = &mainthread;
|
||||
}
|
||||
else
|
||||
{
|
||||
LeaveCriticalSection (&mainthread.lock);
|
||||
|
||||
if (!mainthread.get_winapi_lock (1))
|
||||
if (!retaddr)
|
||||
continue;
|
||||
tls->reset_exception ();
|
||||
tls->interrupt_setup (sig, handler, siga, retaddr);
|
||||
sigproc_printf ("interrupted known cygwin routine");
|
||||
interrupted = true;
|
||||
break;
|
||||
}
|
||||
|
||||
hth = myself->getthread2signal ();
|
||||
th = NULL;
|
||||
DWORD res;
|
||||
HANDLE hth = myself->getthread2signal ();
|
||||
|
||||
/* Suspend the thread which will receive the signal. But first ensure that
|
||||
this thread doesn't have any mutos. (FIXME: Someday we should just grab
|
||||
all of the mutos rather than checking for them)
|
||||
For Windows 95, we also have to ensure that the addresses returned by GetThreadContext
|
||||
are valid.
|
||||
If one of these conditions is not true we loop for a fixed number of times
|
||||
since we don't want to stall the signal handler. FIXME: Will this result in
|
||||
noticeable delays?
|
||||
If the thread is already suspended (which can occur when a program has called
|
||||
SuspendThread on itself then just queue the signal. */
|
||||
/* Suspend the thread which will receive the signal. But first ensure that
|
||||
this thread doesn't have any mutos. (FIXME: Someday we should just grab
|
||||
all of the mutos rather than checking for them)
|
||||
For Windows 95, we also have to ensure that the addresses returned by GetThreadContext
|
||||
are valid.
|
||||
If one of these conditions is not true we loop for a fixed number of times
|
||||
since we don't want to stall the signal handler. FIXME: Will this result in
|
||||
noticeable delays?
|
||||
If the thread is already suspended (which can occur when a program has called
|
||||
SuspendThread on itself then just queue the signal. */
|
||||
|
||||
EnterCriticalSection (&mainthread.lock);
|
||||
#ifndef DEBUGGING
|
||||
sigproc_printf ("suspending mainthread");
|
||||
sigproc_printf ("suspending mainthread");
|
||||
#else
|
||||
cx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
|
||||
if (!GetThreadContext (hth, &cx))
|
||||
memset (&cx, 0, sizeof cx);
|
||||
#if 0
|
||||
if ((cx.Eip & 0xff000000) == 0x77000000)
|
||||
try_to_debug ();
|
||||
cx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
|
||||
if (!GetThreadContext (hth, &cx))
|
||||
memset (&cx, 0, sizeof cx);
|
||||
sigproc_printf ("suspending mainthread PC %p", cx.Eip);
|
||||
#endif
|
||||
sigproc_printf ("suspending mainthread PC %p", cx.Eip);
|
||||
#endif
|
||||
res = SuspendThread (hth);
|
||||
/* Just release the lock now since we hav suspended the main thread and it
|
||||
definitely can't be grabbing it now. This will have to change, of course,
|
||||
if/when we can send signals to other than the main thread. */
|
||||
LeaveCriticalSection (&mainthread.lock);
|
||||
res = SuspendThread (hth);
|
||||
/* Just release the lock now since we hav suspended the main thread and it
|
||||
definitely can't be grabbing it now. This will have to change, of course,
|
||||
if/when we can send signals to other than the main thread. */
|
||||
|
||||
/* Just set pending if thread is already suspended */
|
||||
if (res)
|
||||
{
|
||||
mainthread.release_winapi_lock ();
|
||||
(void) ResumeThread (hth);
|
||||
break;
|
||||
}
|
||||
|
||||
mainthread.release_winapi_lock ();
|
||||
if (mainthread.frame)
|
||||
goto resume_thread; /* We just got the frame. What are the odds?
|
||||
Just loop and we'll hopefully pick it up on
|
||||
the next pass through. */
|
||||
|
||||
muto *m;
|
||||
/* FIXME: Make multi-thread aware */
|
||||
for (m = muto_start.next; m != NULL; m = m->next)
|
||||
if (m->unstable () || m->owner () == mainthread.id)
|
||||
{
|
||||
sigproc_printf ("suspended thread owns a muto (%s)", m->name);
|
||||
goto resume_thread;
|
||||
}
|
||||
|
||||
if (mainthread.frame)
|
||||
th = &mainthread;
|
||||
else
|
||||
{
|
||||
cx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
|
||||
if (!GetThreadContext (hth, &cx))
|
||||
{
|
||||
system_printf ("couldn't get context of main thread, %E");
|
||||
goto resume_thread;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (th)
|
||||
/* Just set pending if thread is already suspended */
|
||||
if (res)
|
||||
{
|
||||
interrupted = interrupt_on_return (th, sig, handler, siga);
|
||||
LeaveCriticalSection (&th->lock);
|
||||
(void) ResumeThread (hth);
|
||||
break;
|
||||
}
|
||||
|
||||
// FIXME - add check for reentering of DLL here
|
||||
|
||||
muto *m;
|
||||
/* FIXME: Make multi-thread aware */
|
||||
for (m = muto_start.next; m != NULL; m = m->next)
|
||||
if (m->unstable () || m->owner () == cygthread::main_thread_id)
|
||||
{
|
||||
sigproc_printf ("suspended thread owns a muto (%s)", m->name);
|
||||
goto resume_thread;
|
||||
}
|
||||
|
||||
cx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
|
||||
if (!GetThreadContext (hth, &cx))
|
||||
system_printf ("couldn't get context of main thread, %E");
|
||||
else if (interruptible (cx.Eip))
|
||||
interrupted = interrupt_now (&cx, sig, handler, siga);
|
||||
interrupted = tls->interrupt_now (&cx, sig, handler, siga);
|
||||
|
||||
resume_thread:
|
||||
if (hth)
|
||||
res = ResumeThread (hth);
|
||||
res = ResumeThread (hth);
|
||||
|
||||
if (interrupted)
|
||||
break;
|
||||
|
||||
sigproc_printf ("couldn't interrupt. trying again.");
|
||||
low_priority_sleep (0);
|
||||
}
|
||||
|
||||
out:
|
||||
|
@ -921,7 +906,7 @@ ctrl_c_handler (DWORD type)
|
|||
window station, one which actually represents a visible desktop.
|
||||
If not, the CTRL_LOGOFF_EVENT doesn't concern this process. */
|
||||
if (has_visible_window_station ())
|
||||
sig_send (NULL, SIGHUP);
|
||||
sig_send (myself_nowait, SIGHUP);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -954,14 +939,19 @@ ctrl_c_handler (DWORD type)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/* Set the signal mask for this process.
|
||||
Note that some signals are unmaskable, as in UNIX. */
|
||||
/* Function used by low level sig wrappers. */
|
||||
extern "C" void __stdcall
|
||||
set_process_mask (sigset_t newmask)
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
set_signal_mask (newmask);
|
||||
}
|
||||
|
||||
/* Set the signal mask for this process.
|
||||
Note that some signals are unmaskable, as in UNIX. */
|
||||
extern "C" void __stdcall
|
||||
set_signal_mask (sigset_t newmask, sigset_t& oldmask)
|
||||
{
|
||||
mask_sync->acquire (INFINITE);
|
||||
sigset_t oldmask = myself->getsigmask ();
|
||||
newmask &= ~SIG_NONMASKABLE;
|
||||
sigproc_printf ("old mask = %x, new mask = %x", myself->getsigmask (), newmask);
|
||||
myself->setsigmask (newmask); // Set a new mask
|
||||
|
@ -969,13 +959,21 @@ set_process_mask (sigset_t newmask)
|
|||
if (oldmask & ~newmask)
|
||||
sig_dispatch_pending ();
|
||||
else
|
||||
sigproc_printf ("not calling sig_dispatch_pending. sigtid %p current %p",
|
||||
sigtid, GetCurrentThreadId ());
|
||||
sigproc_printf ("not calling sig_dispatch_pending");
|
||||
return;
|
||||
}
|
||||
|
||||
_threadinfo *
|
||||
find_tls (int sig)
|
||||
{
|
||||
for (_threadinfo *t = _last_thread; t ; t = t->prev)
|
||||
if (sigismember (&t->sigwait_mask, sig))
|
||||
return t;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int __stdcall
|
||||
sig_handle (int sig, sigset_t mask)
|
||||
sig_handle (int sig, sigset_t mask, int pid, _threadinfo *tls)
|
||||
{
|
||||
if (sig == SIGCONT)
|
||||
{
|
||||
|
@ -991,26 +989,33 @@ sig_handle (int sig, sigset_t mask)
|
|||
SetEvent (sigCONT);
|
||||
}
|
||||
|
||||
int rc = 1;
|
||||
bool insigwait_mask = tls ? sigismember (&tls->sigwait_mask, sig) : false;
|
||||
if (sig != SIGKILL && sig != SIGSTOP
|
||||
&& (sigismember (&mask, sig) || main_vfork->pid
|
||||
&& (sigismember (&mask, sig)
|
||||
|| (tls
|
||||
&& (insigwait_mask || sigismember (&tls->sigmask, sig)))
|
||||
|| main_vfork->pid
|
||||
|| ISSTATE (myself, PID_STOPPED)))
|
||||
{
|
||||
sigproc_printf ("signal %d blocked", sig);
|
||||
return -1;
|
||||
if (insigwait_mask || (tls = find_tls (sig)) != NULL)
|
||||
goto thread_specific;
|
||||
rc = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
int rc = 1;
|
||||
|
||||
sigproc_printf ("signal %d processing", sig);
|
||||
struct sigaction thissig = myself->getsig (sig);
|
||||
void *handler = (void *) thissig.sa_handler;
|
||||
|
||||
myself->rusage_self.ru_nsignals++;
|
||||
|
||||
/* Clear pending SIGCONT on stop signals */
|
||||
if (sig == SIGSTOP || sig == SIGTSTP || sig == SIGTTIN || sig == SIGTTOU)
|
||||
sig_clear (SIGCONT);
|
||||
|
||||
sigproc_printf ("signal %d processing", sig);
|
||||
struct sigaction thissig = myself->getsig (sig);
|
||||
void *handler;
|
||||
handler = (void *) thissig.sa_handler;
|
||||
|
||||
myself->rusage_self.ru_nsignals++;
|
||||
|
||||
if (sig == SIGKILL)
|
||||
goto exit_sig;
|
||||
|
||||
|
@ -1025,6 +1030,8 @@ sig_handle (int sig, sigset_t mask)
|
|||
|
||||
if (handler == (void *) SIG_DFL)
|
||||
{
|
||||
if (insigwait_mask)
|
||||
goto thread_specific;
|
||||
if (sig == SIGCHLD || sig == SIGIO || sig == SIGCONT || sig == SIGWINCH
|
||||
|| sig == SIGURG)
|
||||
{
|
||||
|
@ -1059,12 +1066,18 @@ stop:
|
|||
dosig:
|
||||
/* Dispatch to the appropriate function. */
|
||||
sigproc_printf ("signal %d, about to call %p", sig, handler);
|
||||
rc = setup_handler (sig, handler, thissig);
|
||||
rc = setup_handler (sig, handler, thissig, tls ?: _main_tls);
|
||||
|
||||
done:
|
||||
sigproc_printf ("returning %d", rc);
|
||||
return rc;
|
||||
|
||||
thread_specific:
|
||||
tls->sig = sig;
|
||||
sigproc_printf ("releasing sigwait for thread");
|
||||
SetEvent (tls->event);
|
||||
goto done;
|
||||
|
||||
exit_sig:
|
||||
if (sig == SIGQUIT || sig == SIGABRT)
|
||||
{
|
||||
|
@ -1102,7 +1115,7 @@ signal_exit (int rc)
|
|||
/* Unlock any main thread mutos since we're executing with prejudice. */
|
||||
muto *m;
|
||||
for (m = muto_start.next; m != NULL; m = m->next)
|
||||
if (m->unstable () || m->owner () == mainthread.id)
|
||||
if (m->unstable () || m->owner () == cygthread::main_thread_id)
|
||||
m->reset ();
|
||||
|
||||
user_data->resourcelocks->Delete ();
|
||||
|
@ -1149,7 +1162,6 @@ events_init (void)
|
|||
windows_system_directory_length = end - windows_system_directory;
|
||||
debug_printf ("windows_system_directory '%s', windows_system_directory_length %d",
|
||||
windows_system_directory, windows_system_directory_length);
|
||||
debug_printf ("cygwin_hmodule %p", cygwin_hmodule);
|
||||
InitializeCriticalSection (&exit_lock);
|
||||
}
|
||||
|
||||
|
@ -1160,114 +1172,39 @@ events_terminate (void)
|
|||
}
|
||||
|
||||
extern "C" {
|
||||
static int __stdcall
|
||||
int __stdcall
|
||||
call_signal_handler_now ()
|
||||
{
|
||||
if (!sigsave.sig)
|
||||
int sa_flags = 0;
|
||||
while (_my_tls.sig && _my_tls.stackptr > _my_tls.stack)
|
||||
{
|
||||
sigproc_printf ("call_signal_handler_now called when no signal active");
|
||||
return 0;
|
||||
sa_flags = _my_tls.sa_flags;
|
||||
int sig = _my_tls.sig;
|
||||
void (*sigfunc) (int) = _my_tls.func;
|
||||
(void) _my_tls.pop ();
|
||||
#ifdef DEBUGGING
|
||||
if (_my_tls.stackptr > (_my_tls.stack + 1))
|
||||
try_to_debug ();
|
||||
#endif
|
||||
reset_signal_arrived ();
|
||||
sigset_t oldmask = _my_tls.oldmask;
|
||||
int this_errno = _my_tls.saved_errno;
|
||||
set_process_mask (_my_tls.newmask);
|
||||
_my_tls.sig = 0;
|
||||
sigfunc (sig);
|
||||
set_process_mask (oldmask);
|
||||
if (this_errno >= 0)
|
||||
set_errno (this_errno);
|
||||
}
|
||||
|
||||
int sa_flags = sigsave.sa_flags;
|
||||
sigproc_printf ("sa_flags %p", sa_flags);
|
||||
*sigsave.retaddr_on_stack = sigsave.retaddr;
|
||||
sigdelayed0 ();
|
||||
return sa_flags & SA_RESTART;
|
||||
}
|
||||
/* This kludge seems to keep a copy of call_signal_handler_now around
|
||||
even when compiling with -finline-functions. */
|
||||
static int __stdcall call_signal_handler_now_dummy ()
|
||||
__attribute__((alias ("call_signal_handler_now")));
|
||||
};
|
||||
|
||||
int
|
||||
sigframe::call_signal_handler ()
|
||||
{
|
||||
return unregister () ? call_signal_handler_now () : 0;
|
||||
}
|
||||
|
||||
#define pid_offset (unsigned)(((_pinfo *)NULL)->pid)
|
||||
extern "C" {
|
||||
void __stdcall
|
||||
reset_signal_arrived ()
|
||||
{
|
||||
(void) ResetEvent (signal_arrived);
|
||||
sigproc_printf ("reset signal_arrived");
|
||||
}
|
||||
|
||||
#undef errno
|
||||
#define errno ((DWORD volatile) _impure_ptr) + (((char *) &_impure_ptr->_errno) - ((char *) _impure_ptr))
|
||||
|
||||
__attribute__((const, used, noinline)) static void
|
||||
unused_sig_wrapper ()
|
||||
{
|
||||
/* Signal cleanup stuff. Cleans up stack (too bad that we didn't
|
||||
prototype signal handlers as __stdcall), calls _set_process_mask
|
||||
to restore any mask, restores any potentially clobbered registers
|
||||
and returns to original caller. */
|
||||
__asm__ volatile ("\n\
|
||||
.text \n\
|
||||
_sigreturn: \n\
|
||||
addl $4,%%esp # Remove argument \n\
|
||||
call _set_process_mask@4 \n\
|
||||
\n\
|
||||
cmpl $0,%4 # Did a signal come in? \n\
|
||||
jz 1f # No, if zero \n\
|
||||
movl %2,%%eax \n\
|
||||
movl %8,%%ebx # Where return address lives \n\
|
||||
movl %%eax,(%%ebx) # Restore return address of \n\
|
||||
# most recent caller \n\
|
||||
jmp 3f \n\
|
||||
\n\
|
||||
1: popl %%eax # saved errno \n\
|
||||
testl %%eax,%%eax # Is it < 0 \n\
|
||||
jl 2f # yup. ignore it \n\
|
||||
movl %1,%%ebx \n\
|
||||
movl %%eax,(%%ebx) \n\
|
||||
2: popl %%eax \n\
|
||||
popl %%ebx \n\
|
||||
popl %%ecx \n\
|
||||
popl %%edx \n\
|
||||
popl %%edi \n\
|
||||
popl %%esi \n\
|
||||
popf \n\
|
||||
popl %%ebp \n\
|
||||
ret \n\
|
||||
\n\
|
||||
__no_sig_start: \n\
|
||||
_sigdelayed: \n\
|
||||
pushl %2 # original return address \n\
|
||||
_sigdelayed0: \n\
|
||||
pushl %%ebp \n\
|
||||
movl %%esp,%%ebp \n\
|
||||
pushf \n\
|
||||
pushl %%esi \n\
|
||||
pushl %%edi \n\
|
||||
pushl %%edx \n\
|
||||
pushl %%ecx \n\
|
||||
pushl %%ebx \n\
|
||||
pushl %%eax \n\
|
||||
pushl %6 # saved errno \n\
|
||||
3: pushl %3 # oldmask \n\
|
||||
pushl %4 # signal argument \n\
|
||||
pushl $_sigreturn \n\
|
||||
\n\
|
||||
call _reset_signal_arrived@0 \n\
|
||||
pushl %5 # signal number \n\
|
||||
pushl %7 # newmask \n\
|
||||
\n\
|
||||
call _set_process_mask@4 \n\
|
||||
movl $0,%0 # zero the signal number as a \n\
|
||||
# flag to the signal handler thread\n\
|
||||
# that it is ok to set up sigsave\n\
|
||||
popl %%eax \n\
|
||||
jmp *%%eax \n\
|
||||
__no_sig_end: \n\
|
||||
" : "=m" (sigsave.sig)/*0*/: "X" ((char *) &_impure_ptr->_errno)/*1*/,
|
||||
"g" (sigsave.retaddr)/*2*/, "g" (sigsave.oldmask)/*3*/, "g" (sigsave.sig)/*4*/,
|
||||
"g" (sigsave.func)/*5*/, "g" (sigsave.saved_errno)/*6*/, "g" (sigsave.newmask)/*7*/,
|
||||
"g" (sigsave.retaddr_on_stack)/*8*/
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* external.cc: Interface to Cygwin internals from external programs.
|
||||
|
||||
Copyright 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
|
||||
Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.
|
||||
|
||||
Written by Christopher Faylor <cgf@cygnus.com>
|
||||
|
||||
|
|
|
@ -320,7 +320,6 @@ bool
|
|||
fhandler_base::device_access_denied (int flags)
|
||||
{
|
||||
int mode = 0;
|
||||
int access_worker (path_conv&, int);
|
||||
|
||||
if (flags & O_RDWR)
|
||||
mode |= R_OK | W_OK;
|
||||
|
|
|
@ -634,7 +634,6 @@ fork ()
|
|||
} grouped;
|
||||
|
||||
MALLOC_CHECK;
|
||||
sigframe thisframe (mainthread);
|
||||
|
||||
debug_printf ("entering");
|
||||
grouped.hParent = grouped.first_dll = NULL;
|
||||
|
@ -688,7 +687,6 @@ vfork ()
|
|||
#ifndef NEWVFORK
|
||||
return fork ();
|
||||
#else
|
||||
sigframe thisframe;
|
||||
vfork_save *vf = get_vfork_val ();
|
||||
char **esp, **pp;
|
||||
|
||||
|
@ -697,12 +695,14 @@ vfork ()
|
|||
else if (vf->pid)
|
||||
return fork ();
|
||||
|
||||
// FIXME the tls stuff could introduce a signal race if a child process
|
||||
// exits quickly.
|
||||
if (!setjmp (vf->j))
|
||||
{
|
||||
vf->pid = -1;
|
||||
__asm__ volatile ("movl %%esp,%0": "=r" (vf->vfork_esp):);
|
||||
__asm__ volatile ("movl %%ebp,%0": "=r" (vf->vfork_ebp):);
|
||||
for (pp = (char **)vf->frame, esp = vf->vfork_esp;
|
||||
for (pp = (char **) vf->frame, esp = vf->vfork_esp;
|
||||
esp <= vf->vfork_ebp + 2; pp++, esp++)
|
||||
*pp = *esp;
|
||||
vf->ctty = myself->ctty;
|
||||
|
@ -710,16 +710,17 @@ vfork ()
|
|||
vf->pgid = myself->pgid;
|
||||
int res = cygheap->fdtab.vfork_child_dup () ? 0 : -1;
|
||||
debug_printf ("%d = vfork()", res);
|
||||
call_signal_handler_now (); // FIXME: racy
|
||||
vf->tls = _my_tls;
|
||||
return res;
|
||||
}
|
||||
|
||||
vf = get_vfork_val ();
|
||||
|
||||
for (pp = (char **)vf->frame, esp = vf->vfork_esp;
|
||||
for (pp = (char **) vf->frame, esp = vf->vfork_esp;
|
||||
esp <= vf->vfork_ebp + 2; pp++, esp++)
|
||||
*esp = *pp;
|
||||
|
||||
thisframe.init (mainthread);
|
||||
cygheap->fdtab.vfork_parent_restore ();
|
||||
|
||||
myself->ctty = vf->ctty;
|
||||
|
@ -738,6 +739,9 @@ vfork ()
|
|||
vf->pid = 0;
|
||||
debug_printf ("exiting vfork, pid %d", pid);
|
||||
sig_dispatch_pending ();
|
||||
|
||||
call_signal_handler_now (); // FIXME: racy
|
||||
_my_tls = vf->tls;
|
||||
return pid;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -0,0 +1,223 @@
|
|||
#!/usr/bin/perl
|
||||
use strict;
|
||||
my $in = shift;
|
||||
my $tls_offsets = shift;
|
||||
my $out = shift;
|
||||
my $sigfe = shift;
|
||||
|
||||
$main::first = 0;
|
||||
if (!defined($in) || !defined($out) || !defined($sigfe)) {
|
||||
die "usage: $0 deffile.in cygtls.h deffile.def sigfe.s\n";
|
||||
}
|
||||
|
||||
require $tls_offsets;
|
||||
|
||||
open(IN, $in) or die "$0: couldn't open \"$in\" - $!\n";
|
||||
my @top = ();
|
||||
while (<IN>) {
|
||||
push(@top, $_);
|
||||
last if /^\s*exports\s*$/i;
|
||||
}
|
||||
my $libline = <IN>;
|
||||
my @in = <IN>;
|
||||
close(IN);
|
||||
|
||||
my %sigfe = ();
|
||||
my @data = ();
|
||||
my @nosigfuncs = ();
|
||||
my @out = ();
|
||||
for (@in) {
|
||||
/\sDATA$/o and do {
|
||||
push(@data, $_);
|
||||
next;
|
||||
};
|
||||
chomp;
|
||||
if (/=/o) {
|
||||
if (s/\s+NOSIGFE\s*$//) {
|
||||
} elsif (s/ SIGFE$//) {
|
||||
my $func = (split(' '))[2];
|
||||
$sigfe{$func} = '_sigfe_' . $func;
|
||||
}
|
||||
} else {
|
||||
my ($func, $sigfe) = m%^\s*(\S+)(?:\s+((?:NO)?SIGR?FE))?$%o;
|
||||
if (defined($sigfe) && $sigfe =~ /^NO/o) {
|
||||
$_ = $func;
|
||||
} else {
|
||||
$sigfe ||= 'sigfe';
|
||||
$_ = '_' . lc($sigfe) . '_' . $func;
|
||||
$sigfe{$func} = $_;
|
||||
$_ = $func . ' = ' . $_;
|
||||
}
|
||||
}
|
||||
s/(\S)\s+(\S)/$1 $2/go;
|
||||
s/(\S)\s+$/$1/o;
|
||||
s/^\s+(\S)/$1/o;
|
||||
push(@out, $_ . "\n");
|
||||
}
|
||||
|
||||
for (@out) {
|
||||
my ($alias, $func) = /^(\S+) = (\S+)\s*$/o;
|
||||
$_ = $alias . ' = ' . $sigfe{$func} . "\n"
|
||||
if defined($func) && $sigfe{$func};
|
||||
}
|
||||
open(OUT, '>', $out) or die "$0: couldn't open \"$out\" - $!\n";
|
||||
print OUT @top, @data, @out;
|
||||
close OUT;
|
||||
|
||||
open(SIGFE, '>', $sigfe) or die "$0: couldn't open sigfe file \"$sigfe\" - $!\n";
|
||||
|
||||
for my $k (sort keys %sigfe) {
|
||||
print SIGFE fefunc($k, $sigfe{$k});
|
||||
}
|
||||
close SIGFE;
|
||||
|
||||
sub fefunc {
|
||||
my $func = '_' . shift;
|
||||
my $fe = '_' . shift;
|
||||
my $extra;
|
||||
my $res = <<EOF;
|
||||
.extern _siglist_index
|
||||
.extern _siglist
|
||||
.extern $func
|
||||
.global $fe
|
||||
$fe:
|
||||
pushl \$$func
|
||||
jmp __sigfe
|
||||
|
||||
EOF
|
||||
if (!$main::first++) {
|
||||
$res = <<EOF . longjmp () . $res;
|
||||
.text
|
||||
.global __sigbe
|
||||
.global _sigreturn
|
||||
.global _sigdelayed
|
||||
|
||||
.stabs "_sigfe:F(0,1)",36,0,0,__sigbe
|
||||
__sigfe:
|
||||
pushl %edx
|
||||
movl %fs:4,%eax
|
||||
movl \$4,%edx
|
||||
xadd %edx,$tls::stackptr(%eax)
|
||||
leal __sigbe,%eax
|
||||
xchg %eax,8(%esp)
|
||||
movl %eax,(%edx)
|
||||
popl %edx
|
||||
ret
|
||||
|
||||
.stabs "_sigbe:F(0,1)",36,0,0,__sigbe
|
||||
__sigbe:
|
||||
pushl %eax
|
||||
pushl %edx
|
||||
movl \$-4,%edx
|
||||
1: movl %fs:4,%eax
|
||||
xadd %edx,$tls::stackptr(%eax)
|
||||
xorl %eax,%eax
|
||||
lock xchg %eax,-4(%edx)
|
||||
testl %eax,%eax
|
||||
jnz 2f
|
||||
call _low_priority_sleep
|
||||
xorl %edx,%edx
|
||||
jmp 1b
|
||||
2: xchg %eax,4(%esp)
|
||||
popl %edx
|
||||
ret
|
||||
|
||||
.stabs "sigreturn:F(0,1)",36,0,0,_sigreturn
|
||||
_sigreturn:
|
||||
addl \$4,%esp # Remove argument
|
||||
call _set_process_mask\@4
|
||||
|
||||
movl %fs:4,%eax
|
||||
|
||||
cmpl \$0,$tls::sig(%eax) # Did a signal come in?
|
||||
jnz 3f # Yes, if non-zero
|
||||
|
||||
1: popl %edx # saved errno
|
||||
testl %edx,%edx # Is it < 0
|
||||
jl 2f # yup. ignore it
|
||||
movl $tls::errno_addr(%eax),%eax
|
||||
movl %edx,(%eax)
|
||||
2: popl %eax
|
||||
popl %ebx
|
||||
popl %ecx
|
||||
popl %edx
|
||||
popl %edi
|
||||
popl %esi
|
||||
popf
|
||||
popl %ebp
|
||||
jmp __sigbe
|
||||
|
||||
.stabs "sigdelayed:F(0,1)",36,0,0,_sigdelayed
|
||||
_sigdelayed:
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
pushf
|
||||
pushl %esi
|
||||
pushl %edi
|
||||
pushl %edx
|
||||
pushl %ecx
|
||||
pushl %ebx
|
||||
pushl %eax
|
||||
movl %fs:4,%ebx
|
||||
pushl $tls::saved_errno(%ebx) # saved errno
|
||||
3: pushl $tls::oldmask(%ebx) # oldmask
|
||||
pushl $tls::sig(%ebx) # signal argument
|
||||
pushl \$_sigreturn
|
||||
|
||||
call _reset_signal_arrived\@0
|
||||
pushl $tls::func(%ebx) # signal func
|
||||
pushl $tls::newmask(%ebx) # newmask - eaten by set_process_mask
|
||||
|
||||
call _set_process_mask\@4
|
||||
movl \$0,$tls::sig(%ebx) # zero the signal number as a
|
||||
# flag to the signal handler thread
|
||||
# that it is ok to set up sigsave
|
||||
popl %ebx
|
||||
jmp *%ebx
|
||||
|
||||
EOF
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
sub longjmp {
|
||||
return <<EOF;
|
||||
|
||||
.globl _longjmp
|
||||
|
||||
_longjmp:
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
movl 8(%ebp),%edi
|
||||
movl 12(%ebp),%eax
|
||||
testl %eax,%eax
|
||||
jne 0f
|
||||
incl %eax
|
||||
0:
|
||||
movl %eax,0(%edi)
|
||||
movl 24(%edi),%ebp
|
||||
pushfl
|
||||
popl %ebx
|
||||
movw 42(%edi),%ax
|
||||
movw %ax,%ss
|
||||
movl 28(%edi),%esp
|
||||
pushl 32(%edi)
|
||||
pushl %ebx
|
||||
movw 36(%edi),%ax
|
||||
movw %ax,%es
|
||||
movw 40(%edi),%ax
|
||||
movw %ax,%gs
|
||||
movl %fs:4,%eax
|
||||
leal ($tls::stack)(%eax),%edx
|
||||
movl %edx,($tls::stackptr)(%eax)
|
||||
movl 0(%edi),%eax
|
||||
movl 4(%edi),%ebx
|
||||
movl 8(%edi),%ecx
|
||||
movl 12(%edi),%edx
|
||||
movl 16(%edi),%esi
|
||||
movl 20(%edi),%edi
|
||||
popfl
|
||||
ret
|
||||
|
||||
EOF
|
||||
}
|
|
@ -73,7 +73,13 @@ for (my $i = 0; $i < @lines; $i++) {
|
|||
redo;
|
||||
};
|
||||
}
|
||||
open(OUTPUT, '>', $output) or die "$0: couldn't open $output - $!\n";
|
||||
open(OUTPUT, '>', $output) or do {{
|
||||
if (chmod(0664, $output)) {
|
||||
open(OUTPUT, '>', $output);
|
||||
last;
|
||||
}
|
||||
die "$0: couldn't open $output - $!\n";
|
||||
}};
|
||||
print OUTPUT @lines;
|
||||
close OUTPUT;
|
||||
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
#!/usr/bin/perl -s
|
||||
my $tls = shift;
|
||||
my $tls_out = shift;
|
||||
open(TLS, $tls) or die "$0: couldn't open tls file \"$tls\" - $!\n";
|
||||
my $struct = '';
|
||||
my @fields = ();
|
||||
my $def = '';
|
||||
while (<TLS>) {
|
||||
next if $struct && (!/gentls_offsets/o && /\(/o);
|
||||
$def .= $_ if $struct;
|
||||
last if /^};/o;
|
||||
/^\s*typedef/o and do {
|
||||
$def .= $_ ;
|
||||
next;
|
||||
};
|
||||
if (!s/;.*$//o) {
|
||||
if (!$struct && /^\s*(?:struct|class)\s*([a-z_0-9]+)/o) {
|
||||
$def .= $_;
|
||||
$struct = $1
|
||||
}
|
||||
next;
|
||||
}
|
||||
s%/\*\s*gentls_offsets.*/\*\s*gentls_offsets\s*\*/%%og;
|
||||
s/(?:\[[^\]]*\]|struct|class)//o;
|
||||
s/^\s+\S+\s+//o;
|
||||
s/[\*\s()]+//go;
|
||||
for my $f (split(/,/)) {
|
||||
push(@fields, $f);
|
||||
}
|
||||
}
|
||||
close TLS;
|
||||
open(TMP, '>', "/tmp/$$.cc") or die "$0: couldn't open temporary index file \"/tmp/$$.c\" - $!\n";
|
||||
print TMP <<EOF;
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
typedef void *HANDLE;
|
||||
$def
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
$struct foo[1];
|
||||
# define foo_end ((char *) (foo + 1))
|
||||
# define offset(f) (((char *) &(foo->f)) - foo_end)
|
||||
EOF
|
||||
print TMP 'puts ("//;# autogenerated: Do not edit.\n");', "\n\n";
|
||||
for my $f (@fields) {
|
||||
print TMP ' printf ("//; $tls::', $f, ' = %d;\n", ', "offset($f));\n";
|
||||
}
|
||||
print TMP ' puts ("//; __DATA__\n");', "\n";
|
||||
for my $f (@fields) {
|
||||
print TMP ' printf ("#define tls_', $f, ' (%d)\n", ', "offset($f));\n";
|
||||
}
|
||||
|
||||
print TMP <<EOF;
|
||||
|
||||
exit (0);
|
||||
}
|
||||
EOF
|
||||
close TMP;
|
||||
system @ARGV, '-o', "/tmp/$$-1.cc", '-E', "/tmp/$$.cc";
|
||||
system 'g++', '-o', "/tmp/$$.a.out", "/tmp/$$-1.cc" and
|
||||
($? == 127 && system 'c++', '-o', "/tmp/$$.a.out", "/tmp/$$-1.cc") and
|
||||
die "$0: couldn't generate executable for offset calculation \"/tmp/$$.a.out\" - $!\n";
|
||||
open(TLS_OUT, '>', $tls_out) or die "$0: couldn't open tls index file \"tls_out\" - $!\n";
|
||||
open(OFFS, "/tmp/$$.a.out|") or die "$0: couldn't run \"/tmp/$$.a.out\" - $!\n";
|
||||
print TLS_OUT <OFFS>;
|
||||
close OFFS;
|
||||
close TLS_OUT;
|
||||
# unlink "/tmp/$$.cc", "/tmp/$$.a.out";
|
||||
exit(0);
|
|
@ -97,7 +97,6 @@ heap_init ()
|
|||
extern "C" void *
|
||||
sbrk (int n)
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
char *newtop, *newbrk;
|
||||
unsigned commitbytes, newbrksize;
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
Copyright 2001 Red Hat Inc., Christopher Faylor
|
||||
|
||||
[this information is currently obsolete -- sorry]
|
||||
How do signals work?
|
||||
|
||||
On process startup, cygwin starts a secondary thread that deals with signals.
|
||||
|
|
|
@ -229,13 +229,13 @@ details. */
|
|||
102: CW_GET_UID_FROM_SID and CW_GET_GID_FROM_SID addition to external.cc.
|
||||
103: Export getprogname, setprogname.
|
||||
104: Export msgctl, msgget, msgrcv, msgsnd, semctl, semget, semop.
|
||||
|
||||
105: Export sigwait.
|
||||
*/
|
||||
|
||||
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
|
||||
|
||||
#define CYGWIN_VERSION_API_MAJOR 0
|
||||
#define CYGWIN_VERSION_API_MINOR 104
|
||||
#define CYGWIN_VERSION_API_MINOR 105
|
||||
|
||||
/* There is also a compatibity version number associated with the
|
||||
shared memory regions. It is incremented when incompatible
|
||||
|
|
|
@ -149,6 +149,7 @@ struct name { \
|
|||
#define SLIST_HEAD_INITIALIZER(head) \
|
||||
{ NULL }
|
||||
|
||||
#undef SLIST_ENTRY
|
||||
#define SLIST_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *sle_next; /* next element */ \
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* init.cc
|
||||
|
||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
|
||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -12,6 +12,7 @@ details. */
|
|||
#include <stdlib.h>
|
||||
#include "thread.h"
|
||||
#include "perprocess.h"
|
||||
#include "cygtls.h"
|
||||
|
||||
int NO_COPY dynamically_loaded;
|
||||
|
||||
|
@ -21,17 +22,18 @@ WINAPI dll_entry (HANDLE h, DWORD reason, void *static_load)
|
|||
switch (reason)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
cygwin_hmodule = (HMODULE) h;
|
||||
_my_tls.stackptr = _my_tls.stack;
|
||||
dynamically_loaded = (static_load == NULL);
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
case DLL_THREAD_ATTACH:
|
||||
_my_tls.stackptr = _my_tls.stack;
|
||||
if (MT_INTERFACE->reent_key.set (&MT_INTERFACE->reents))
|
||||
api_fatal ("thread initialization failed");
|
||||
break;
|
||||
case DLL_THREAD_DETACH:
|
||||
/* not invoked */;
|
||||
_my_tls.remove ();
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* ioctl.cc: ioctl routines.
|
||||
|
||||
Copyright 1996, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
|
||||
Copyright 1996, 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.
|
||||
|
||||
Written by Doug Evans of Cygnus Support
|
||||
dje@cygnus.com
|
||||
|
@ -25,7 +25,6 @@ details. */
|
|||
extern "C" int
|
||||
ioctl (int fd, int cmd, ...)
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
|
||||
cygheap_fdget cfd (fd);
|
||||
if (cfd < 0)
|
||||
|
|
|
@ -302,7 +302,7 @@ sys_mbstowcs (WCHAR *tgt, const char *src, int len)
|
|||
return MultiByteToWideChar (get_cp (), 0, src, -1, tgt, len);
|
||||
}
|
||||
|
||||
extern "C" int __stdcall
|
||||
extern "C" int
|
||||
low_priority_sleep (DWORD secs)
|
||||
{
|
||||
HANDLE thisthread = GetCurrentThread ();
|
||||
|
|
|
@ -318,13 +318,13 @@ list::add_record (mmap_record r, _off64_t off, DWORD len)
|
|||
{
|
||||
mmap_record *new_recs;
|
||||
if (maxrecs == 0)
|
||||
new_recs = (mmap_record *)
|
||||
new_recs = (mmap_record *)
|
||||
cmalloc (HEAP_MMAP, 5 * sizeof (mmap_record));
|
||||
else
|
||||
new_recs = (mmap_record *)
|
||||
crealloc (recs, (maxrecs + 5) * sizeof (mmap_record));
|
||||
if (!new_recs)
|
||||
return NULL;
|
||||
return NULL;
|
||||
maxrecs += 5;
|
||||
recs = new_recs;
|
||||
}
|
||||
|
@ -425,11 +425,11 @@ map::add_list (int fd)
|
|||
{
|
||||
list *new_lists;
|
||||
if (maxlists == 0)
|
||||
new_lists = (list *) cmalloc (HEAP_MMAP, 5 * sizeof (list));
|
||||
new_lists = (list *) cmalloc (HEAP_MMAP, 5 * sizeof (list));
|
||||
else
|
||||
new_lists = (list *) crealloc (lists, (maxlists + 5) * sizeof (list));
|
||||
if (!new_lists)
|
||||
return NULL;
|
||||
return NULL;
|
||||
maxlists += 5;
|
||||
lists = new_lists;
|
||||
}
|
||||
|
@ -444,7 +444,7 @@ map::del_list (int i)
|
|||
{
|
||||
lists[i].free_recs ();
|
||||
for (; i < nlists - 1; i++)
|
||||
lists[i] = lists[i + 1];
|
||||
lists[i] = lists[i + 1];
|
||||
nlists--;
|
||||
}
|
||||
}
|
||||
|
@ -668,16 +668,16 @@ munmap (void *addr, size_t len)
|
|||
DWORD u_len;
|
||||
|
||||
while ((record_idx = map_list->search_record((caddr_t)addr, len, u_addr,
|
||||
u_len, record_idx)) >= 0)
|
||||
u_len, record_idx)) >= 0)
|
||||
{
|
||||
mmap_record *rec = map_list->get_record (record_idx);
|
||||
if (rec->unmap_pages (u_addr, u_len))
|
||||
{
|
||||
/* The whole record has been unmapped, so we now actually
|
||||
unmap it from the system in full length... */
|
||||
unmap it from the system in full length... */
|
||||
fhandler_base *fh = rec->alloc_fh ();
|
||||
fh->munmap (rec->get_handle (),
|
||||
rec->get_address (),
|
||||
rec->get_address (),
|
||||
rec->get_size ());
|
||||
rec->free_fh (fh);
|
||||
|
||||
|
@ -735,7 +735,7 @@ msync (void *addr, size_t len, int flags)
|
|||
{
|
||||
mmap_record *rec;
|
||||
for (int record_idx = 0;
|
||||
(rec = map_list->get_record (record_idx));
|
||||
(rec = map_list->get_record (record_idx));
|
||||
++record_idx)
|
||||
{
|
||||
if (rec->access ((caddr_t)addr))
|
||||
|
@ -746,7 +746,7 @@ msync (void *addr, size_t len, int flags)
|
|||
goto invalid_address_range;
|
||||
fhandler_base *fh = rec->alloc_fh ();
|
||||
int ret = fh->msync (rec->get_handle (), (caddr_t)addr, len,
|
||||
flags);
|
||||
flags);
|
||||
rec->free_fh (fh);
|
||||
|
||||
if (ret)
|
||||
|
@ -1012,7 +1012,7 @@ fixup_mmaps_after_fork (HANDLE parent)
|
|||
{
|
||||
mmap_record *rec;
|
||||
for (int record_idx = 0;
|
||||
(rec = map_list->get_record (record_idx));
|
||||
(rec = map_list->get_record (record_idx));
|
||||
++record_idx)
|
||||
{
|
||||
|
||||
|
|
|
@ -98,7 +98,6 @@ extern "C" int
|
|||
msgctl (int msqid, int cmd, struct msqid_ds *buf)
|
||||
{
|
||||
#ifdef USE_SERVER
|
||||
sigframe thisframe (mainthread);
|
||||
syscall_printf ("msgctl (msqid = %d, cmd = 0x%x, buf = %p)",
|
||||
msqid, cmd, buf);
|
||||
switch (cmd)
|
||||
|
@ -153,7 +152,6 @@ extern "C" int
|
|||
msgget (key_t key, int msgflg)
|
||||
{
|
||||
#ifdef USE_SERVER
|
||||
sigframe thisframe (mainthread);
|
||||
syscall_printf ("msgget (key = %U, msgflg = 0x%x)", key, msgflg);
|
||||
client_request_msg request (key, msgflg);
|
||||
if (request.make_request () == -1 || request.retval () == -1)
|
||||
|
@ -176,7 +174,6 @@ extern "C" ssize_t
|
|||
msgrcv (int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg)
|
||||
{
|
||||
#ifdef USE_SERVER
|
||||
sigframe thisframe (mainthread);
|
||||
syscall_printf ("msgrcv (msqid = %d, msgp = %p, msgsz = %d, "
|
||||
"msgtyp = %d, msgflg = 0x%x)",
|
||||
msqid, msgp, msgsz, msgtyp, msgflg);
|
||||
|
@ -203,7 +200,6 @@ extern "C" int
|
|||
msgsnd (int msqid, const void *msgp, size_t msgsz, int msgflg)
|
||||
{
|
||||
#ifdef USE_SERVER
|
||||
sigframe thisframe (mainthread);
|
||||
syscall_printf ("msgsnd (msqid = %d, msgp = %p, msgsz = %d, msgflg = 0x%x)",
|
||||
msqid, msgp, msgsz, msgflg);
|
||||
if (__check_invalid_read_ptr_errno (msgp, msgsz))
|
||||
|
|
|
@ -695,7 +695,6 @@ cygwin_sendto (int fd, const void *buf, int len, int flags,
|
|||
{
|
||||
int res;
|
||||
sig_dispatch_pending ();
|
||||
sigframe thisframe (mainthread);
|
||||
|
||||
fhandler_socket *fh = get (fd);
|
||||
|
||||
|
@ -719,7 +718,6 @@ cygwin_recvfrom (int fd, void *buf, int len, int flags,
|
|||
{
|
||||
int res;
|
||||
sig_dispatch_pending ();
|
||||
sigframe thisframe (mainthread);
|
||||
|
||||
fhandler_socket *fh = get (fd);
|
||||
|
||||
|
@ -876,7 +874,6 @@ cygwin_connect (int fd, const struct sockaddr *name, int namelen)
|
|||
{
|
||||
int res;
|
||||
sig_dispatch_pending ();
|
||||
sigframe thisframe (mainthread);
|
||||
|
||||
fhandler_socket *fh = get (fd);
|
||||
|
||||
|
@ -950,7 +947,6 @@ extern "C" struct servent *
|
|||
cygwin_getservbyname (const char *name, const char *proto)
|
||||
{
|
||||
sig_dispatch_pending ();
|
||||
sigframe thisframe (mainthread);
|
||||
if (check_null_str_errno (name)
|
||||
|| (proto != NULL && check_null_str_errno (proto)))
|
||||
return NULL;
|
||||
|
@ -969,7 +965,6 @@ extern "C" struct servent *
|
|||
cygwin_getservbyport (int port, const char *proto)
|
||||
{
|
||||
sig_dispatch_pending ();
|
||||
sigframe thisframe (mainthread);
|
||||
if (proto != NULL && check_null_str_errno (proto))
|
||||
return NULL;
|
||||
|
||||
|
@ -986,7 +981,6 @@ extern "C" int
|
|||
cygwin_gethostname (char *name, size_t len)
|
||||
{
|
||||
sig_dispatch_pending ();
|
||||
sigframe thisframe (mainthread);
|
||||
if (__check_null_invalid_struct_errno (name, len))
|
||||
return -1;
|
||||
|
||||
|
@ -1022,7 +1016,6 @@ cygwin_gethostbyname (const char *name)
|
|||
static int a, b, c, d;
|
||||
|
||||
sig_dispatch_pending ();
|
||||
sigframe thisframe (mainthread);
|
||||
if (check_null_str_errno (name))
|
||||
return NULL;
|
||||
|
||||
|
@ -1063,7 +1056,6 @@ extern "C" struct hostent *
|
|||
cygwin_gethostbyaddr (const char *addr, int len, int type)
|
||||
{
|
||||
sig_dispatch_pending ();
|
||||
sigframe thisframe (mainthread);
|
||||
if (__check_invalid_read_ptr_errno (addr, len))
|
||||
return NULL;
|
||||
|
||||
|
@ -1089,7 +1081,6 @@ cygwin_accept (int fd, struct sockaddr *peer, int *len)
|
|||
{
|
||||
int res;
|
||||
sig_dispatch_pending ();
|
||||
sigframe thisframe (mainthread);
|
||||
|
||||
fhandler_socket *fh = get (fd);
|
||||
|
||||
|
@ -1122,7 +1113,6 @@ cygwin_bind (int fd, const struct sockaddr *my_addr, int addrlen)
|
|||
{
|
||||
int res;
|
||||
sig_dispatch_pending ();
|
||||
sigframe thisframe (mainthread);
|
||||
fhandler_socket *fh = get (fd);
|
||||
|
||||
if (__check_invalid_read_ptr_errno (my_addr, addrlen) || !fh)
|
||||
|
@ -1140,7 +1130,6 @@ cygwin_getsockname (int fd, struct sockaddr *addr, int *namelen)
|
|||
{
|
||||
int res;
|
||||
sig_dispatch_pending ();
|
||||
sigframe thisframe (mainthread);
|
||||
|
||||
fhandler_socket *fh = get (fd);
|
||||
|
||||
|
@ -1161,7 +1150,6 @@ cygwin_listen (int fd, int backlog)
|
|||
{
|
||||
int res;
|
||||
sig_dispatch_pending ();
|
||||
sigframe thisframe (mainthread);
|
||||
fhandler_socket *fh = get (fd);
|
||||
|
||||
if (!fh)
|
||||
|
@ -1179,7 +1167,6 @@ cygwin_shutdown (int fd, int how)
|
|||
{
|
||||
int res;
|
||||
sig_dispatch_pending ();
|
||||
sigframe thisframe (mainthread);
|
||||
|
||||
fhandler_socket *fh = get (fd);
|
||||
|
||||
|
@ -1245,7 +1232,6 @@ cygwin_getpeername (int fd, struct sockaddr *name, int *len)
|
|||
{
|
||||
int res;
|
||||
sig_dispatch_pending ();
|
||||
sigframe thisframe (mainthread);
|
||||
|
||||
fhandler_socket *fh = get (fd);
|
||||
|
||||
|
@ -1286,7 +1272,6 @@ getdomainname (char *domain, size_t len)
|
|||
* Punt for now and assume MS-TCP on Win95.
|
||||
*/
|
||||
sig_dispatch_pending ();
|
||||
sigframe thisframe (mainthread);
|
||||
if (__check_null_invalid_struct_errno (domain, len))
|
||||
return -1;
|
||||
|
||||
|
@ -1900,7 +1885,6 @@ get_ifconf (struct ifconf *ifc, int what)
|
|||
struct sockaddr_in *sa;
|
||||
|
||||
sig_dispatch_pending ();
|
||||
sigframe thisframe (mainthread);
|
||||
if (check_null_invalid_struct_errno (ifc))
|
||||
return -1;
|
||||
|
||||
|
@ -1979,7 +1963,6 @@ cygwin_rcmd (char **ahost, unsigned short inport, char *locuser,
|
|||
SOCKET fd2s;
|
||||
|
||||
sig_dispatch_pending ();
|
||||
sigframe thisframe (mainthread);
|
||||
|
||||
if (check_null_invalid_struct_errno (ahost) ||
|
||||
check_null_empty_str_errno (*ahost) ||
|
||||
|
@ -2032,7 +2015,6 @@ cygwin_rresvport (int *port)
|
|||
{
|
||||
int res;
|
||||
sig_dispatch_pending ();
|
||||
sigframe thisframe (mainthread);
|
||||
|
||||
if (check_null_invalid_struct_errno (port))
|
||||
return -1;
|
||||
|
@ -2061,7 +2043,6 @@ cygwin_rexec (char **ahost, unsigned short inport, char *locuser,
|
|||
int res = -1;
|
||||
SOCKET fd2s;
|
||||
sig_dispatch_pending ();
|
||||
sigframe thisframe (mainthread);
|
||||
|
||||
if (check_null_invalid_struct_errno (ahost) ||
|
||||
check_null_empty_str_errno (*ahost) ||
|
||||
|
@ -2119,7 +2100,6 @@ socketpair (int family, int type, int protocol, int *sb)
|
|||
int len;
|
||||
|
||||
sig_dispatch_pending ();
|
||||
sigframe thisframe (mainthread);
|
||||
if (__check_null_invalid_struct_errno (sb, 2 * sizeof (int)))
|
||||
return -1;
|
||||
|
||||
|
@ -2314,7 +2294,6 @@ cygwin_recvmsg (int fd, struct msghdr *msg, int flags)
|
|||
{
|
||||
int res;
|
||||
sig_dispatch_pending ();
|
||||
sigframe thisframe (mainthread);
|
||||
|
||||
fhandler_socket *fh = get (fd);
|
||||
|
||||
|
@ -2341,7 +2320,6 @@ cygwin_sendmsg (int fd, const struct msghdr *msg, int flags)
|
|||
{
|
||||
int res;
|
||||
sig_dispatch_pending ();
|
||||
sigframe thisframe (mainthread);
|
||||
|
||||
fhandler_socket *fh = get (fd);
|
||||
|
||||
|
|
|
@ -459,7 +459,6 @@ path_conv::check (const char *src, unsigned opt,
|
|||
bool saw_symlinks = 0;
|
||||
int is_relpath;
|
||||
char *tail;
|
||||
sigframe thisframe (mainthread);
|
||||
|
||||
#if 0
|
||||
static path_conv last_path_conv;
|
||||
|
@ -3337,8 +3336,6 @@ extern "C" int
|
|||
fchdir (int fd)
|
||||
{
|
||||
int res;
|
||||
sigframe thisframe (mainthread);
|
||||
|
||||
cygheap_fdget cfd (fd);
|
||||
if (cfd >= 0)
|
||||
res = chdir (cfd->get_win32_name ());
|
||||
|
|
|
@ -48,6 +48,7 @@ public:
|
|||
};
|
||||
|
||||
#if defined (NEED_VFORK)
|
||||
#include "cygtls.h"
|
||||
class vfork_save
|
||||
{
|
||||
jmp_buf j;
|
||||
|
@ -55,6 +56,7 @@ class vfork_save
|
|||
public:
|
||||
int pid;
|
||||
DWORD frame[100];
|
||||
_threadinfo tls;
|
||||
char **vfork_ebp;
|
||||
char **vfork_esp;
|
||||
int ctty;
|
||||
|
@ -85,29 +87,6 @@ extern per_thread_vfork vfork_storage;
|
|||
extern vfork_save *main_vfork;
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
struct signal_dispatch
|
||||
{
|
||||
int arg;
|
||||
void (*func) (int);
|
||||
int sig;
|
||||
int saved_errno;
|
||||
int sa_flags;
|
||||
DWORD oldmask;
|
||||
DWORD newmask;
|
||||
DWORD retaddr;
|
||||
DWORD *retaddr_on_stack;
|
||||
};
|
||||
};
|
||||
|
||||
struct per_thread_signal_dispatch : public per_thread
|
||||
{
|
||||
signal_dispatch *get () { return (signal_dispatch *) per_thread::get (); }
|
||||
signal_dispatch *create () {return (signal_dispatch *) per_thread::create ();}
|
||||
size_t size () {return sizeof (signal_dispatch);}
|
||||
};
|
||||
|
||||
extern per_thread_waitq waitq_storage;
|
||||
extern per_thread_signal_dispatch signal_dispatch_storage;
|
||||
|
||||
extern per_thread *threadstuff[];
|
||||
|
|
|
@ -142,7 +142,7 @@ pinfo::init (pid_t n, DWORD flag, HANDLE in_h)
|
|||
|
||||
int createit = flag & (PID_IN_USE | PID_EXECED);
|
||||
DWORD access = FILE_MAP_READ
|
||||
| (flag & (PID_IN_USE | PID_EXECED | PID_MAP_RW) ? FILE_MAP_WRITE : 0);
|
||||
| (flag & (PID_IN_USE | PID_EXECED | PID_MAP_RW) ? FILE_MAP_WRITE : 0);
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
int created;
|
||||
|
@ -246,11 +246,11 @@ pinfo::set_acl()
|
|||
|
||||
sec_acl ((PACL) sa_buf, true, true, cygheap->user.sid (),
|
||||
well_known_world_sid, FILE_MAP_READ);
|
||||
if (!InitializeSecurityDescriptor( &sd, SECURITY_DESCRIPTOR_REVISION))
|
||||
debug_printf("InitializeSecurityDescriptor %E");
|
||||
else if (!SetSecurityDescriptorDacl(&sd, TRUE, (PACL) sa_buf, FALSE))
|
||||
debug_printf("SetSecurityDescriptorDacl %E");
|
||||
else if (!SetKernelObjectSecurity(h, DACL_SECURITY_INFORMATION, &sd))
|
||||
if (!InitializeSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION))
|
||||
debug_printf ("InitializeSecurityDescriptor %E");
|
||||
else if (!SetSecurityDescriptorDacl (&sd, TRUE, (PACL) sa_buf, FALSE))
|
||||
debug_printf ("SetSecurityDescriptorDacl %E");
|
||||
else if (!SetKernelObjectSecurity (h, DACL_SECURITY_INFORMATION, &sd))
|
||||
debug_printf ("SetKernelObjectSecurity %E");
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,6 @@ poll (struct pollfd *fds, unsigned int nfds, int timeout)
|
|||
int max_fd = 0;
|
||||
fd_set *read_fds, *write_fds, *except_fds;
|
||||
struct timeval tv = { timeout / 1000, (timeout % 1000) * 1000 };
|
||||
sigframe thisframe (mainthread);
|
||||
|
||||
for (unsigned int i = 0; i < nfds; ++i)
|
||||
if (fds[i].fd > max_fd)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* select.cc
|
||||
|
||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
|
||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.
|
||||
|
||||
Written by Christopher Faylor of Cygnus Solutions
|
||||
cgf@cygnus.com
|
||||
|
@ -102,7 +102,6 @@ cygwin_select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
|||
fd_set *dummy_readfds = allocfd_set (maxfds);
|
||||
fd_set *dummy_writefds = allocfd_set (maxfds);
|
||||
fd_set *dummy_exceptfds = allocfd_set (maxfds);
|
||||
sigframe thisframe (mainthread);
|
||||
|
||||
select_printf ("%d, %p, %p, %p, %p", maxfds, readfds, writefds, exceptfds, to);
|
||||
|
||||
|
@ -1086,6 +1085,7 @@ fhandler_base::ready_for_read (int fd, DWORD howlong)
|
|||
|
||||
if (WaitForSingleObject (signal_arrived, avail ? 0 : 10) == WAIT_OBJECT_0)
|
||||
{
|
||||
debug_printf ("interrupted");
|
||||
set_sig_errno (EINTR);
|
||||
avail = 0;
|
||||
break;
|
||||
|
|
|
@ -82,7 +82,6 @@ extern "C" int
|
|||
semctl (int semid, int semnum, int cmd, ...)
|
||||
{
|
||||
#ifdef USE_SERVER
|
||||
sigframe thisframe (mainthread);
|
||||
union semun arg = {0};
|
||||
if (cmd == IPC_STAT || cmd == IPC_SET || cmd == IPC_INFO || cmd == SEM_INFO
|
||||
|| cmd == GETALL || cmd == SETALL || cmd == SETVAL)
|
||||
|
@ -132,7 +131,6 @@ extern "C" int
|
|||
semget (key_t key, int nsems, int semflg)
|
||||
{
|
||||
#ifdef USE_SERVER
|
||||
sigframe thisframe (mainthread);
|
||||
syscall_printf ("semget (key = %U, nsems = %d, semflg = 0x%x)",
|
||||
key, nsems, semflg);
|
||||
client_request_sem request (key, nsems, semflg);
|
||||
|
@ -156,7 +154,6 @@ extern "C" int
|
|||
semop (int semid, struct sembuf *sops, size_t nsops)
|
||||
{
|
||||
#ifdef USE_SERVER
|
||||
sigframe thisframe (mainthread);
|
||||
syscall_printf ("semop (semid = %d, sops = %p, nsops = %d)",
|
||||
semid, sops, nsops);
|
||||
if (__check_null_invalid_struct_errno (sops, nsops * sizeof (struct sembuf)))
|
||||
|
|
|
@ -149,7 +149,6 @@ extern "C" void *
|
|||
shmat (int shmid, const void *shmaddr, int shmflg)
|
||||
{
|
||||
#ifdef USE_SERVER
|
||||
sigframe thisframe (mainthread);
|
||||
syscall_printf ("shmat (shmid = %d, shmaddr = %p, shmflg = 0x%x)",
|
||||
shmid, shmaddr, shmflg);
|
||||
|
||||
|
@ -226,7 +225,6 @@ extern "C" int
|
|||
shmctl (int shmid, int cmd, struct shmid_ds *buf)
|
||||
{
|
||||
#ifdef USE_SERVER
|
||||
sigframe thisframe (mainthread);
|
||||
syscall_printf ("shmctl (shmid = %d, cmd = %d, buf = 0x%x)",
|
||||
shmid, cmd, buf);
|
||||
switch (cmd)
|
||||
|
@ -288,7 +286,6 @@ extern "C" int
|
|||
shmdt (const void *shmaddr)
|
||||
{
|
||||
#ifdef USE_SERVER
|
||||
sigframe thisframe (mainthread);
|
||||
syscall_printf ("shmget (shmaddr = %p)", shmaddr);
|
||||
client_request_shm request (shmaddr);
|
||||
if (request.make_request () == -1 || request.retval () == -1)
|
||||
|
@ -324,7 +321,6 @@ extern "C" int
|
|||
shmget (key_t key, size_t size, int shmflg)
|
||||
{
|
||||
#ifdef USE_SERVER
|
||||
sigframe thisframe (mainthread);
|
||||
syscall_printf ("shmget (key = %U, size = %d, shmflg = 0x%x)",
|
||||
key, size, shmflg);
|
||||
/* Try allocating memory before calling cygserver. */
|
||||
|
|
|
@ -15,9 +15,11 @@ details. */
|
|||
#include <stdlib.h>
|
||||
#include "cygerrno.h"
|
||||
#include <sys/cygwin.h>
|
||||
#include "sigproc.h"
|
||||
#include "pinfo.h"
|
||||
#include "sigproc.h"
|
||||
#include "hires.h"
|
||||
#include "security.h"
|
||||
#include "cygtls.h"
|
||||
|
||||
int sigcatchers; /* FIXME: Not thread safe. */
|
||||
|
||||
|
@ -71,7 +73,6 @@ nanosleep (const struct timespec *rqtp, struct timespec *rmtp)
|
|||
{
|
||||
int res = 0;
|
||||
sig_dispatch_pending ();
|
||||
sigframe thisframe (mainthread);
|
||||
pthread_testcancel ();
|
||||
|
||||
if ((unsigned int) rqtp->tv_sec > (HIRES_DELAY_MAX / 1000 - 1)
|
||||
|
@ -92,7 +93,7 @@ nanosleep (const struct timespec *rqtp, struct timespec *rmtp)
|
|||
rem = 0;
|
||||
if (rc == WAIT_OBJECT_0)
|
||||
{
|
||||
(void) thisframe.call_signal_handler ();
|
||||
(void) call_signal_handler_now ();
|
||||
set_errno (EINTR);
|
||||
res = -1;
|
||||
}
|
||||
|
@ -129,21 +130,34 @@ usleep (unsigned int useconds)
|
|||
|
||||
extern "C" int
|
||||
sigprocmask (int sig, const sigset_t *set, sigset_t *oldset)
|
||||
{
|
||||
return handle_sigprocmask (sig, set, oldset, myself->getsigmask ());
|
||||
}
|
||||
|
||||
int __stdcall
|
||||
handle_sigprocmask (int sig, const sigset_t *set, sigset_t *oldset, sigset_t& opmask)
|
||||
{
|
||||
sig_dispatch_pending ();
|
||||
/* check that sig is in right range */
|
||||
if (sig < 0 || sig >= NSIG)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
set_errno (ESRCH);
|
||||
syscall_printf ("SIG_ERR = sigprocmask signal %d out of range", sig);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (oldset)
|
||||
*oldset = myself->getsigmask ();
|
||||
{
|
||||
if (check_null_invalid_struct_errno (oldset))
|
||||
return -1;
|
||||
*oldset = opmask;
|
||||
}
|
||||
|
||||
if (set)
|
||||
{
|
||||
sigset_t newmask = myself->getsigmask ();
|
||||
if (check_invalid_read_struct_errno (set))
|
||||
return -1;
|
||||
sigset_t newmask = opmask;
|
||||
switch (sig)
|
||||
{
|
||||
case SIG_BLOCK:
|
||||
|
@ -162,7 +176,7 @@ sigprocmask (int sig, const sigset_t *set, sigset_t *oldset)
|
|||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
(void) set_process_mask (newmask);
|
||||
(void) set_signal_mask (newmask, opmask);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -185,10 +199,7 @@ kill_worker (pid_t pid, int sig)
|
|||
if ((sendSIGCONT = (sig < 0)))
|
||||
sig = -sig;
|
||||
|
||||
#if 0
|
||||
if (dest == myself && !sendSIGCONT)
|
||||
dest = myself_nowait_nonmain;
|
||||
#endif
|
||||
DWORD process_state = dest->process_state;
|
||||
if (sig == 0)
|
||||
{
|
||||
res = proc_exists (dest) ? 0 : -1;
|
||||
|
@ -203,7 +214,7 @@ kill_worker (pid_t pid, int sig)
|
|||
else if (sendSIGCONT)
|
||||
(void) sig_send (dest, SIGCONT);
|
||||
|
||||
syscall_printf ("%d = kill_worker (%d, %d)", res, pid, sig);
|
||||
syscall_printf ("%d = kill_worker (%d, %d), process_state %p", res, pid, sig, process_state);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -216,7 +227,6 @@ raise (int sig)
|
|||
int
|
||||
kill (pid_t pid, int sig)
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
syscall_printf ("kill (%d, %d)", pid, sig);
|
||||
/* check that sig is in right range */
|
||||
if (sig < 0 || sig >= NSIG)
|
||||
|
@ -241,7 +251,6 @@ kill_pgrp (pid_t pid, int sig)
|
|||
int res = 0;
|
||||
int found = 0;
|
||||
int killself = 0;
|
||||
sigframe thisframe (mainthread);
|
||||
|
||||
sigproc_printf ("pid %d, signal %d", pid, sig);
|
||||
|
||||
|
@ -289,7 +298,6 @@ extern "C" void
|
|||
abort (void)
|
||||
{
|
||||
sig_dispatch_pending ();
|
||||
sigframe thisframe (mainthread);
|
||||
/* Flush all streams as per SUSv2.
|
||||
From my reading of this document, this isn't strictly correct.
|
||||
The streams are supposed to be flushed prior to exit. However,
|
||||
|
@ -304,10 +312,10 @@ abort (void)
|
|||
sigset_t sig_mask;
|
||||
sigfillset (&sig_mask);
|
||||
sigdelset (&sig_mask, SIGABRT);
|
||||
set_process_mask (sig_mask);
|
||||
set_signal_mask (sig_mask);
|
||||
|
||||
raise (SIGABRT);
|
||||
(void) thisframe.call_signal_handler (); /* Call any signal handler */
|
||||
(void) call_signal_handler_now (); /* Call any signal handler */
|
||||
do_exit (1); /* signal handler didn't exit. Goodbye. */
|
||||
}
|
||||
|
||||
|
@ -436,11 +444,38 @@ extern "C" int
|
|||
siginterrupt (int sig, int flag)
|
||||
{
|
||||
struct sigaction act;
|
||||
(void)sigaction(sig, NULL, &act);
|
||||
(void) sigaction(sig, NULL, &act);
|
||||
if (flag)
|
||||
act.sa_flags &= ~SA_RESTART;
|
||||
else
|
||||
act.sa_flags |= SA_RESTART;
|
||||
return sigaction(sig, &act, NULL);
|
||||
return sigaction (sig, &act, NULL);
|
||||
}
|
||||
|
||||
|
||||
extern "C" int
|
||||
sigwait (const sigset_t *set, int *sig)
|
||||
{
|
||||
pthread_testcancel ();
|
||||
_my_tls.event = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL);
|
||||
if (!_my_tls.event)
|
||||
{
|
||||
__seterrno ();
|
||||
return -1;
|
||||
}
|
||||
|
||||
_my_tls.sigwait_mask = *set;
|
||||
|
||||
switch (WaitForSingleObject (_my_tls.event, INFINITE))
|
||||
{
|
||||
case WAIT_OBJECT_0:
|
||||
CloseHandle (_my_tls.event);
|
||||
_my_tls.event = NULL;
|
||||
*sig = InterlockedExchange ((LONG *) &_my_tls.sig, (LONG) 0);
|
||||
break;
|
||||
default:
|
||||
__seterrno ();
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ details. */
|
|||
#include <sys/signal.h>
|
||||
#include "cygerrno.h"
|
||||
#include "sync.h"
|
||||
#include "cygtls.h"
|
||||
#include "sigproc.h"
|
||||
#include "pinfo.h"
|
||||
#include "security.h"
|
||||
|
@ -37,10 +38,6 @@ details. */
|
|||
*/
|
||||
#define WSSC 60000 // Wait for signal completion
|
||||
#define WPSP 40000 // Wait for proc_subproc mutex
|
||||
#define WSPX 20000 // Wait for wait_sig to terminate
|
||||
#define WWSP 20000 // Wait for wait_subproc to terminate
|
||||
|
||||
#define TOTSIGS (NSIG + __SIGOFFSET)
|
||||
|
||||
#define wake_wait_subproc() SetEvent (events[0])
|
||||
|
||||
|
@ -48,9 +45,11 @@ details. */
|
|||
|
||||
#define NZOMBIES 256
|
||||
|
||||
class sigelem
|
||||
struct sigelem
|
||||
{
|
||||
int sig;
|
||||
int pid;
|
||||
_threadinfo *tls;
|
||||
class sigelem *next;
|
||||
friend class pending_signals;
|
||||
friend int __stdcall sig_dispatch_pending ();
|
||||
|
@ -66,9 +65,9 @@ class pending_signals
|
|||
int empty;
|
||||
public:
|
||||
void reset () {curr = &start; prev = &start;}
|
||||
void add (int sig);
|
||||
void add (int sig, int pid, _threadinfo *tls);
|
||||
void del ();
|
||||
int next ();
|
||||
sigelem *next ();
|
||||
friend int __stdcall sig_dispatch_pending ();
|
||||
};
|
||||
|
||||
|
@ -78,6 +77,7 @@ struct sigpacket
|
|||
pid_t pid;
|
||||
HANDLE wakeup;
|
||||
sigset_t *mask;
|
||||
_threadinfo *tls;
|
||||
};
|
||||
|
||||
static pending_signals sigqueue;
|
||||
|
@ -112,10 +112,6 @@ int __sp_ln;
|
|||
|
||||
char NO_COPY myself_nowait_dummy[1] = {'0'};// Flag to sig_send that signal goes to
|
||||
// current process but no wait is required
|
||||
char NO_COPY myself_nowait_nonmain_dummy[1] = {'1'};// Flag to sig_send that signal goes to
|
||||
// current process but no wait is required
|
||||
// if this is the main thread.
|
||||
|
||||
HANDLE NO_COPY signal_arrived; // Event signaled when a signal has
|
||||
// resulted in a user-specified
|
||||
// function call
|
||||
|
@ -244,7 +240,7 @@ get_proc_lock (DWORD what, DWORD val)
|
|||
static BOOL __stdcall
|
||||
proc_can_be_signalled (_pinfo *p)
|
||||
{
|
||||
if (p == myself_nowait || p == myself_nowait_nonmain || p == myself)
|
||||
if (p == myself_nowait || p == myself)
|
||||
{
|
||||
assert (!wait_sig_inited);
|
||||
return 1;
|
||||
|
@ -549,10 +545,10 @@ sig_clear (int target_sig)
|
|||
sig_send (myself, -target_sig);
|
||||
else
|
||||
{
|
||||
int sig;
|
||||
sigqueue.reset ();
|
||||
while ((sig = sigqueue.next ()))
|
||||
if (sig == target_sig)
|
||||
sigelem *q;
|
||||
while ((q = sigqueue.next ()))
|
||||
if (q->sig == target_sig)
|
||||
{
|
||||
sigqueue.del ();
|
||||
break;
|
||||
|
@ -578,9 +574,8 @@ sig_dispatch_pending ()
|
|||
if (exit_state || GetCurrentThreadId () == sigtid || !sigqueue.start.next)
|
||||
return 0;
|
||||
|
||||
sigframe thisframe (mainthread);
|
||||
(void) sig_send (myself, __SIGFLUSH);
|
||||
return thisframe.call_signal_handler ();
|
||||
return call_signal_handler_now ();
|
||||
}
|
||||
|
||||
/* Message initialization. Called from dll_crt0_1
|
||||
|
@ -654,18 +649,15 @@ sigproc_terminate (void)
|
|||
* completed before returning.
|
||||
*/
|
||||
int __stdcall
|
||||
sig_send (_pinfo *p, int sig, DWORD ebp, bool exception)
|
||||
sig_send (_pinfo *p, int sig, void *tls)
|
||||
{
|
||||
int rc = 1;
|
||||
DWORD tid = GetCurrentThreadId ();
|
||||
BOOL its_me;
|
||||
HANDLE sendsig;
|
||||
bool wait_for_completion;
|
||||
sigframe thisframe;
|
||||
sigpacket pack;
|
||||
|
||||
if (p == myself_nowait_nonmain)
|
||||
p = (tid == mainthread.id) ? (_pinfo *) myself : myself_nowait;
|
||||
bool wait_for_completion;
|
||||
// FIXMENOW: Avoid using main thread's completion event!
|
||||
if (!(its_me = (p == NULL || p == myself || p == myself_nowait)))
|
||||
wait_for_completion = false;
|
||||
else
|
||||
|
@ -674,7 +666,7 @@ sig_send (_pinfo *p, int sig, DWORD ebp, bool exception)
|
|||
goto out; // Either exiting or not yet initializing
|
||||
if (wait_sig_inited)
|
||||
wait_for_sigthread ();
|
||||
wait_for_completion = p != myself_nowait;
|
||||
wait_for_completion = p != myself_nowait && _my_tls.isinitialized ();
|
||||
p = myself;
|
||||
}
|
||||
|
||||
|
@ -695,11 +687,7 @@ sig_send (_pinfo *p, int sig, DWORD ebp, bool exception)
|
|||
{
|
||||
sendsig = myself->sendsig;
|
||||
if (wait_for_completion)
|
||||
{
|
||||
if (tid == mainthread.id)
|
||||
thisframe.init (mainthread, ebp, exception);
|
||||
pack.wakeup = sigcomplete_main;
|
||||
}
|
||||
pack.wakeup = sigcomplete_main;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -735,6 +723,7 @@ sig_send (_pinfo *p, int sig, DWORD ebp, bool exception)
|
|||
|
||||
pack.sig = sig;
|
||||
pack.pid = myself->pid;
|
||||
pack.tls = (_threadinfo *) tls;
|
||||
DWORD nb;
|
||||
if (!WriteFile (sendsig, &pack, sizeof (pack), &nb, NULL) || nb != sizeof (pack))
|
||||
{
|
||||
|
@ -790,7 +779,7 @@ sig_send (_pinfo *p, int sig, DWORD ebp, bool exception)
|
|||
}
|
||||
|
||||
if (wait_for_completion)
|
||||
thisframe.call_signal_handler ();
|
||||
call_signal_handler_now ();
|
||||
|
||||
out:
|
||||
if (sig != __SIGPENDING)
|
||||
|
@ -995,7 +984,7 @@ talktome ()
|
|||
has been handled, as per POSIX. */
|
||||
|
||||
void
|
||||
pending_signals::add (int sig)
|
||||
pending_signals::add (int sig, int pid, _threadinfo *tls)
|
||||
{
|
||||
sigelem *se;
|
||||
for (se = start.next; se; se = se->next)
|
||||
|
@ -1007,6 +996,8 @@ pending_signals::add (int sig)
|
|||
se = sigs + empty;
|
||||
se->sig = sig;
|
||||
se->next = NULL;
|
||||
se->tls = tls;
|
||||
se->pid = pid;
|
||||
if (end)
|
||||
end->next = se;
|
||||
end = se;
|
||||
|
@ -1030,16 +1021,16 @@ pending_signals::del ()
|
|||
curr = next;
|
||||
}
|
||||
|
||||
int
|
||||
sigelem *
|
||||
pending_signals::next ()
|
||||
{
|
||||
int sig;
|
||||
sigelem *res;
|
||||
prev = curr;
|
||||
if (!curr || !(curr = curr->next))
|
||||
sig = 0;
|
||||
res = NULL;
|
||||
else
|
||||
sig = curr->sig;
|
||||
return sig;
|
||||
res = curr;
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Process signals by waiting for signal data to arrive in a pipe.
|
||||
|
@ -1105,7 +1096,12 @@ wait_sig (VOID *self)
|
|||
}
|
||||
|
||||
if (!pack.sig)
|
||||
continue; /* Just checking to see if we exist */
|
||||
{
|
||||
#ifdef DEBUGGING
|
||||
system_printf ("zero signal?");
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
sigset_t dummy_mask;
|
||||
if (!pack.mask)
|
||||
|
@ -1114,40 +1110,39 @@ wait_sig (VOID *self)
|
|||
pack.mask = &dummy_mask;
|
||||
}
|
||||
|
||||
sigelem *q;
|
||||
switch (pack.sig)
|
||||
{
|
||||
case __SIGCOMMUNE:
|
||||
talktome ();
|
||||
continue;
|
||||
break;
|
||||
case __SIGSTRACE:
|
||||
strace.hello ();
|
||||
continue;
|
||||
break;
|
||||
case __SIGPENDING:
|
||||
*pack.mask = 0;
|
||||
unsigned bit;
|
||||
sigqueue.reset ();
|
||||
while ((pack.sig = sigqueue.next ()))
|
||||
if (myself->getsigmask () & (bit = SIGTOMASK (pack.sig)))
|
||||
while ((q = sigqueue.next ()))
|
||||
if (myself->getsigmask () & (bit = SIGTOMASK (q->sig)))
|
||||
*pack.mask |= bit;
|
||||
break;
|
||||
case __SIGFLUSH:
|
||||
sigqueue.reset ();
|
||||
while ((q = sigqueue.next ()))
|
||||
if (sig_handle (q->sig, *pack.mask, q->pid, q->tls) > 0)
|
||||
sigqueue.del ();
|
||||
break;
|
||||
default:
|
||||
if (pack.sig < 0)
|
||||
sig_clear (-pack.sig);
|
||||
else
|
||||
{
|
||||
int sh;
|
||||
for (int i = 0; !(sh = sig_handle (pack.sig, *pack.mask)) && i < 100 ; i++)
|
||||
low_priority_sleep (0); // hopefully a temporary condition
|
||||
if (sh <= 0)
|
||||
sigqueue.add (pack.sig); // FIXME: Shouldn't add this in !sh condition
|
||||
if (sig_handle (pack.sig, *pack.mask, pack.pid, pack.tls) <= 0)
|
||||
sigqueue.add (pack.sig, pack.pid, pack.tls);// FIXME: Shouldn't add this in !sh condition
|
||||
if (pack.sig == SIGCHLD)
|
||||
proc_subproc (PROC_CLEARWAIT, 0);
|
||||
}
|
||||
case __SIGFLUSH:
|
||||
sigqueue.reset ();
|
||||
while ((pack.sig = sigqueue.next ()))
|
||||
if (sig_handle (pack.sig, *pack.mask) > 0)
|
||||
sigqueue.del ();
|
||||
break;
|
||||
}
|
||||
if (pack.wakeup)
|
||||
|
@ -1231,29 +1226,3 @@ wait_subproc (VOID *)
|
|||
sigproc_printf ("done");
|
||||
ExitThread (0);
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
/* Provide a stack frame when calling WaitFor* functions */
|
||||
|
||||
#undef WaitForSingleObject
|
||||
|
||||
DWORD __stdcall
|
||||
WFSO (HANDLE hHandle, DWORD dwMilliseconds)
|
||||
{
|
||||
DWORD ret;
|
||||
sigframe thisframe (mainthread);
|
||||
ret = WaitForSingleObject (hHandle, dwMilliseconds);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef WaitForMultipleObjects
|
||||
|
||||
DWORD __stdcall
|
||||
WFMO (DWORD nCount, CONST HANDLE *lpHandles, BOOL fWaitAll, DWORD dwMilliseconds)
|
||||
{
|
||||
DWORD ret;
|
||||
sigframe thisframe (mainthread);
|
||||
ret = WaitForMultipleObjects (nCount, lpHandles, fWaitAll, dwMilliseconds);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* sigproc.h
|
||||
|
||||
Copyright 1997, 1998, 2000, 2001, 2002 Red Hat, Inc.
|
||||
Copyright 1997, 1998, 2000, 2001, 2002, 2003 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -48,72 +48,23 @@ typedef struct struct_waitq
|
|||
HANDLE thread_ev;
|
||||
} waitq;
|
||||
|
||||
struct sigthread
|
||||
{
|
||||
DWORD id;
|
||||
DWORD frame;
|
||||
CRITICAL_SECTION lock;
|
||||
LONG winapi_lock;
|
||||
BOOL exception;
|
||||
bool get_winapi_lock (int test = 0);
|
||||
void release_winapi_lock ();
|
||||
void init (const char *s);
|
||||
};
|
||||
|
||||
class sigframe
|
||||
{
|
||||
private:
|
||||
sigthread *st;
|
||||
inline bool unregister ()
|
||||
{
|
||||
if (!st)
|
||||
return 0;
|
||||
EnterCriticalSection (&st->lock);
|
||||
st->frame = 0;
|
||||
st->exception = 0;
|
||||
st->release_winapi_lock ();
|
||||
LeaveCriticalSection (&st->lock);
|
||||
st = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
public:
|
||||
inline void set (sigthread &t, DWORD ebp, bool is_exception = 0)
|
||||
{
|
||||
DWORD oframe = t.frame;
|
||||
st = &t;
|
||||
t.frame = ebp;
|
||||
t.exception = is_exception;
|
||||
if (!oframe)
|
||||
t.get_winapi_lock ();
|
||||
}
|
||||
inline void init (sigthread &t, DWORD ebp = (DWORD) __builtin_frame_address (0), bool is_exception = 0)
|
||||
{
|
||||
if (is_exception || (!t.frame && t.id == GetCurrentThreadId ()))
|
||||
set (t, ebp, is_exception);
|
||||
else
|
||||
st = NULL;
|
||||
}
|
||||
|
||||
sigframe (): st (NULL) {}
|
||||
sigframe (sigthread &t, DWORD ebp = (DWORD) __builtin_frame_address (0)) {init (t, ebp);}
|
||||
~sigframe ()
|
||||
{
|
||||
unregister ();
|
||||
}
|
||||
|
||||
int call_signal_handler ();
|
||||
};
|
||||
|
||||
extern sigthread mainthread;
|
||||
extern HANDLE signal_arrived;
|
||||
extern HANDLE sigCONT;
|
||||
|
||||
BOOL __stdcall my_parent_is_alive ();
|
||||
int __stdcall sig_dispatch_pending ();
|
||||
extern "C" void __stdcall set_process_mask (sigset_t newmask);
|
||||
#ifdef _PINFO_H
|
||||
extern "C" void __stdcall set_signal_mask (sigset_t newmask, sigset_t& = myself->getsigmask ());
|
||||
#endif
|
||||
int __stdcall handle_sigprocmask (int sig, const sigset_t *set,
|
||||
sigset_t *oldset, sigset_t& opmask)
|
||||
__attribute__ ((regparm (3)));
|
||||
|
||||
extern "C" void __stdcall reset_signal_arrived ();
|
||||
int __stdcall sig_handle (int, sigset_t) __attribute__ ((regparm (2)));
|
||||
extern "C" int __stdcall call_signal_handler_now ();
|
||||
#ifdef _CYGTLS_H
|
||||
int __stdcall sig_handle (int, sigset_t, int, _threadinfo *) __attribute__ ((regparm (3)));
|
||||
#endif
|
||||
void __stdcall sig_clear (int) __attribute__ ((regparm (1)));
|
||||
void __stdcall sig_set_pending (int) __attribute__ ((regparm (1)));
|
||||
int __stdcall handle_sigsuspend (sigset_t);
|
||||
|
@ -127,18 +78,15 @@ void __stdcall subproc_init ();
|
|||
void __stdcall sigproc_terminate ();
|
||||
BOOL __stdcall proc_exists (_pinfo *) __attribute__ ((regparm(1)));
|
||||
BOOL __stdcall pid_exists (pid_t) __attribute__ ((regparm(1)));
|
||||
int __stdcall sig_send (_pinfo *, int, DWORD ebp = (DWORD) __builtin_frame_address (0),
|
||||
bool exception = 0) __attribute__ ((regparm(3)));
|
||||
int __stdcall sig_send (_pinfo *, int, void * = NULL) __attribute__ ((regparm(3)));
|
||||
void __stdcall signal_fixup_after_fork ();
|
||||
void __stdcall signal_fixup_after_exec ();
|
||||
void __stdcall wait_for_sigthread ();
|
||||
void __stdcall sigalloc ();
|
||||
|
||||
extern char myself_nowait_dummy[];
|
||||
extern char myself_nowait_nonmain_dummy[];
|
||||
|
||||
#define WAIT_SIG_PRIORITY THREAD_PRIORITY_TIME_CRITICAL
|
||||
|
||||
#define myself_nowait ((_pinfo *)myself_nowait_dummy)
|
||||
#define myself_nowait_nonmain ((_pinfo *)myself_nowait_nonmain_dummy)
|
||||
#endif /*_SIGPROC_H*/
|
||||
|
|
|
@ -351,7 +351,6 @@ spawn_guts (const char * prog_arg, const char *const *argv,
|
|||
{
|
||||
BOOL rc;
|
||||
pid_t cygpid;
|
||||
sigframe thisframe (mainthread);
|
||||
|
||||
MALLOC_CHECK;
|
||||
|
||||
|
@ -987,9 +986,11 @@ spawnve (int mode, const char *path, const char *const *argv,
|
|||
ret = spawn_guts (path, argv, envp, mode);
|
||||
if (vf)
|
||||
{
|
||||
debug_printf ("longjmping due to vfork");
|
||||
if (ret > 0)
|
||||
vf->restore_pid (ret);
|
||||
{
|
||||
debug_printf ("longjmping due to vfork");
|
||||
vf->restore_pid (ret);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -118,7 +118,6 @@ unlink (const char *ourname)
|
|||
{
|
||||
int res = -1;
|
||||
DWORD devn;
|
||||
sigframe thisframe (mainthread);
|
||||
|
||||
path_conv win32_name (ourname, PC_SYM_NOFOLLOW | PC_FULL);
|
||||
|
||||
|
@ -396,7 +395,6 @@ readv (int fd, const struct iovec *const iov, const int iovcnt)
|
|||
while (1)
|
||||
{
|
||||
sig_dispatch_pending ();
|
||||
sigframe thisframe (mainthread);
|
||||
|
||||
cygheap_fdget cfd (fd);
|
||||
if (cfd < 0)
|
||||
|
@ -451,7 +449,7 @@ readv (int fd, const struct iovec *const iov, const int iovcnt)
|
|||
}
|
||||
|
||||
out:
|
||||
if (res >= 0 || get_errno () != EINTR || !thisframe.call_signal_handler ())
|
||||
if (res >= 0 || get_errno () != EINTR || !call_signal_handler_now ())
|
||||
break;
|
||||
set_errno (e);
|
||||
}
|
||||
|
@ -470,7 +468,6 @@ writev (const int fd, const struct iovec *const iov, const int iovcnt)
|
|||
sig_dispatch_pending ();
|
||||
const ssize_t tot = check_iovec_for_write (iov, iovcnt);
|
||||
|
||||
sigframe thisframe (mainthread);
|
||||
cygheap_fdget cfd (fd);
|
||||
if (cfd < 0)
|
||||
goto done;
|
||||
|
@ -524,7 +521,6 @@ open (const char *unix_path, int flags, ...)
|
|||
va_list ap;
|
||||
mode_t mode = 0;
|
||||
sig_dispatch_pending ();
|
||||
sigframe thisframe (mainthread);
|
||||
|
||||
syscall_printf ("open (%s, %p)", unix_path, flags);
|
||||
if (!check_null_empty_str_errno (unix_path))
|
||||
|
@ -574,7 +570,6 @@ extern "C" _off64_t
|
|||
lseek64 (int fd, _off64_t pos, int dir)
|
||||
{
|
||||
_off64_t res;
|
||||
sigframe thisframe (mainthread);
|
||||
|
||||
if (dir != SEEK_SET && dir != SEEK_CUR && dir != SEEK_END)
|
||||
{
|
||||
|
@ -610,7 +605,6 @@ extern "C" int
|
|||
close (int fd)
|
||||
{
|
||||
int res;
|
||||
sigframe thisframe (mainthread);
|
||||
|
||||
syscall_printf ("close (%d)", fd);
|
||||
|
||||
|
@ -635,7 +629,6 @@ extern "C" int
|
|||
isatty (int fd)
|
||||
{
|
||||
int res;
|
||||
sigframe thisframe (mainthread);
|
||||
|
||||
cygheap_fdget cfd (fd);
|
||||
if (cfd < 0)
|
||||
|
@ -657,7 +650,6 @@ extern "C" int
|
|||
link (const char *a, const char *b)
|
||||
{
|
||||
int res = -1;
|
||||
sigframe thisframe (mainthread);
|
||||
path_conv real_a (a, PC_SYM_NOFOLLOW | PC_FULL);
|
||||
path_conv real_b (b, PC_SYM_NOFOLLOW | PC_FULL);
|
||||
extern BOOL allow_winsymlinks;
|
||||
|
@ -787,7 +779,7 @@ link (const char *a, const char *b)
|
|||
res = 0;
|
||||
if (!allow_winsymlinks && real_a.is_lnk_symlink ())
|
||||
SetFileAttributes (real_b, (DWORD) real_a
|
||||
| FILE_ATTRIBUTE_SYSTEM
|
||||
| FILE_ATTRIBUTE_SYSTEM
|
||||
| FILE_ATTRIBUTE_READONLY);
|
||||
|
||||
goto done;
|
||||
|
@ -865,14 +857,12 @@ done:
|
|||
extern "C" int
|
||||
chown32 (const char * name, __uid32_t uid, __gid32_t gid)
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
return chown_worker (name, PC_SYM_FOLLOW, uid, gid);
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
chown (const char * name, __uid16_t uid, __gid16_t gid)
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
return chown_worker (name, PC_SYM_FOLLOW,
|
||||
uid16touid32 (uid), gid16togid32 (gid));
|
||||
}
|
||||
|
@ -880,14 +870,12 @@ chown (const char * name, __uid16_t uid, __gid16_t gid)
|
|||
extern "C" int
|
||||
lchown32 (const char * name, __uid32_t uid, __gid32_t gid)
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
return chown_worker (name, PC_SYM_NOFOLLOW, uid, gid);
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
lchown (const char * name, __uid16_t uid, __gid16_t gid)
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
return chown_worker (name, PC_SYM_NOFOLLOW,
|
||||
uid16touid32 (uid), gid16togid32 (gid));
|
||||
}
|
||||
|
@ -895,7 +883,6 @@ lchown (const char * name, __uid16_t uid, __gid16_t gid)
|
|||
extern "C" int
|
||||
fchown32 (int fd, __uid32_t uid, __gid32_t gid)
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
cygheap_fdget cfd (fd);
|
||||
if (cfd < 0)
|
||||
{
|
||||
|
@ -945,7 +932,6 @@ extern "C" int
|
|||
chmod (const char *path, mode_t mode)
|
||||
{
|
||||
int res = -1;
|
||||
sigframe thisframe (mainthread);
|
||||
|
||||
path_conv win32_path (path);
|
||||
|
||||
|
@ -1009,7 +995,6 @@ done:
|
|||
extern "C" int
|
||||
fchmod (int fd, mode_t mode)
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
cygheap_fdget cfd (fd);
|
||||
if (cfd < 0)
|
||||
{
|
||||
|
@ -1053,7 +1038,6 @@ extern "C" int
|
|||
fstat64 (int fd, struct __stat64 *buf)
|
||||
{
|
||||
int res;
|
||||
sigframe thisframe (mainthread);
|
||||
|
||||
cygheap_fdget cfd (fd);
|
||||
if (cfd < 0)
|
||||
|
@ -1113,7 +1097,6 @@ _fstat_r (struct _reent *ptr, int fd, struct __stat32 *buf)
|
|||
extern "C" int
|
||||
fsync (int fd)
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
cygheap_fdget cfd (fd);
|
||||
if (cfd < 0)
|
||||
{
|
||||
|
@ -1189,7 +1172,6 @@ stat_worker (const char *name, struct __stat64 *buf, int nofollow)
|
|||
extern "C" int
|
||||
stat64 (const char *name, struct __stat64 *buf)
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
syscall_printf ("entering");
|
||||
return stat_worker (name, buf, 0);
|
||||
}
|
||||
|
@ -1230,7 +1212,6 @@ _stat_r (struct _reent *ptr, const char *name, struct __stat32 *buf)
|
|||
extern "C" int
|
||||
lstat64 (const char *name, struct __stat64 *buf)
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
syscall_printf ("entering");
|
||||
return stat_worker (name, buf, 1);
|
||||
}
|
||||
|
@ -1334,7 +1315,6 @@ done:
|
|||
extern "C" int
|
||||
access (const char *fn, int flags)
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
// flags were incorrectly specified
|
||||
if (flags & ~(F_OK|R_OK|W_OK|X_OK))
|
||||
{
|
||||
|
@ -1349,7 +1329,6 @@ access (const char *fn, int flags)
|
|||
extern "C" int
|
||||
rename (const char *oldpath, const char *newpath)
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
int res = 0;
|
||||
char *lnk_suffix = NULL;
|
||||
|
||||
|
@ -1484,7 +1463,6 @@ system (const char *cmdstring)
|
|||
if (check_null_empty_str_errno (cmdstring))
|
||||
return -1;
|
||||
|
||||
sigframe thisframe (mainthread);
|
||||
int res;
|
||||
const char* command[4];
|
||||
|
||||
|
@ -1800,7 +1778,6 @@ setmode (int fd, int mode)
|
|||
extern "C" int
|
||||
ftruncate64 (int fd, _off64_t length)
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
int res = -1;
|
||||
|
||||
if (length < 0)
|
||||
|
@ -1844,7 +1821,6 @@ ftruncate (int fd, _off_t length)
|
|||
extern "C" int
|
||||
truncate64 (const char *pathname, _off64_t length)
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
int fd;
|
||||
int res = -1;
|
||||
|
||||
|
@ -1887,7 +1863,6 @@ get_osfhandle (int fd)
|
|||
extern "C" int
|
||||
statfs (const char *fname, struct statfs *sfs)
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
if (!sfs)
|
||||
{
|
||||
set_errno (EFAULT);
|
||||
|
@ -1943,7 +1918,6 @@ statfs (const char *fname, struct statfs *sfs)
|
|||
extern "C" int
|
||||
fstatfs (int fd, struct statfs *sfs)
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
cygheap_fdget cfd (fd);
|
||||
if (cfd < 0)
|
||||
return -1;
|
||||
|
@ -1954,7 +1928,6 @@ fstatfs (int fd, struct statfs *sfs)
|
|||
extern "C" int
|
||||
setpgid (pid_t pid, pid_t pgid)
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
int res = -1;
|
||||
if (pid == 0)
|
||||
pid = getpid ();
|
||||
|
@ -1996,7 +1969,6 @@ out:
|
|||
extern "C" pid_t
|
||||
getpgid (pid_t pid)
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
if (pid == 0)
|
||||
pid = getpid ();
|
||||
|
||||
|
@ -2012,21 +1984,18 @@ getpgid (pid_t pid)
|
|||
extern "C" int
|
||||
setpgrp (void)
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
return setpgid (0, 0);
|
||||
}
|
||||
|
||||
extern "C" pid_t
|
||||
getpgrp (void)
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
return getpgid (0);
|
||||
}
|
||||
|
||||
extern "C" char *
|
||||
ptsname (int fd)
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
cygheap_fdget cfd (fd);
|
||||
if (cfd < 0)
|
||||
return 0;
|
||||
|
@ -2123,7 +2092,6 @@ seteuid32 (__uid32_t uid)
|
|||
return 0;
|
||||
}
|
||||
|
||||
sigframe thisframe (mainthread);
|
||||
cygsid usersid;
|
||||
user_groups &groups = cygheap->user.groups;
|
||||
HANDLE ptok, new_token = INVALID_HANDLE_VALUE;
|
||||
|
@ -2224,9 +2192,9 @@ seteuid32 (__uid32_t uid)
|
|||
issamesid = (usersid == cygheap->user.sid ());
|
||||
cygheap->user.set_sid (usersid);
|
||||
cygheap->user.current_token = new_token == ptok ? INVALID_HANDLE_VALUE
|
||||
: new_token;
|
||||
: new_token;
|
||||
if (!issamesid) /* MS KB 199190 */
|
||||
RegCloseKey(HKEY_CURRENT_USER);
|
||||
RegCloseKey (HKEY_CURRENT_USER);
|
||||
cygheap->user.reimpersonate ();
|
||||
if (!issamesid)
|
||||
user_shared_initialize (true);
|
||||
|
@ -2304,7 +2272,6 @@ setegid32 (__gid32_t gid)
|
|||
return 0;
|
||||
}
|
||||
|
||||
sigframe thisframe (mainthread);
|
||||
user_groups * groups = &cygheap->user.groups;
|
||||
cygsid gsid;
|
||||
HANDLE ptok;
|
||||
|
@ -2399,7 +2366,6 @@ setregid (__gid16_t rgid, __gid16_t egid)
|
|||
extern "C" int
|
||||
chroot (const char *newroot)
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
path_conv path (newroot, PC_SYM_FOLLOW | PC_FULL | PC_POSIX);
|
||||
|
||||
int ret;
|
||||
|
@ -2431,7 +2397,6 @@ chroot (const char *newroot)
|
|||
extern "C" int
|
||||
creat (const char *path, mode_t mode)
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
return open (path, O_WRONLY | O_CREAT | O_TRUNC, mode);
|
||||
}
|
||||
|
||||
|
@ -2444,7 +2409,6 @@ __assertfail ()
|
|||
extern "C" int
|
||||
getw (FILE *fp)
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
int w, ret;
|
||||
ret = fread (&w, sizeof (int), 1, fp);
|
||||
return ret != 1 ? EOF : w;
|
||||
|
@ -2453,7 +2417,6 @@ getw (FILE *fp)
|
|||
extern "C" int
|
||||
putw (int w, FILE *fp)
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
int ret;
|
||||
ret = fwrite (&w, sizeof (int), 1, fp);
|
||||
if (feof (fp) || ferror (fp))
|
||||
|
@ -2524,7 +2487,6 @@ memccpy (_PTR out, const _PTR in, int c, size_t len)
|
|||
extern "C" int
|
||||
nice (int incr)
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
DWORD priority[] =
|
||||
{
|
||||
IDLE_PRIORITY_CLASS,
|
||||
|
@ -2618,7 +2580,6 @@ updwtmp (const char *wtmp_file, const struct utmp *ut)
|
|||
extern "C" void
|
||||
logwtmp (const char *line, const char *user, const char *host)
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
struct utmp ut;
|
||||
memset (&ut, 0, sizeof ut);
|
||||
ut.ut_type = USER_PROCESS;
|
||||
|
@ -2636,7 +2597,6 @@ logwtmp (const char *line, const char *user, const char *host)
|
|||
extern "C" void
|
||||
login (struct utmp *ut)
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
pututline (ut);
|
||||
endutent ();
|
||||
updwtmp (_PATH_WTMP, ut);
|
||||
|
@ -2645,7 +2605,6 @@ login (struct utmp *ut)
|
|||
extern "C" int
|
||||
logout (char *line)
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
struct utmp ut_buf, *ut;
|
||||
|
||||
memset (&ut_buf, 0, sizeof ut_buf);
|
||||
|
@ -2674,7 +2633,6 @@ static char *utmp_file = (char *) _PATH_UTMP;
|
|||
static void
|
||||
internal_setutent (bool force_readwrite)
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
if (force_readwrite && utmp_readonly)
|
||||
endutent ();
|
||||
if (utmp_fd < 0)
|
||||
|
@ -2703,7 +2661,6 @@ setutent ()
|
|||
extern "C" void
|
||||
endutent ()
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
if (utmp_fd >= 0)
|
||||
{
|
||||
close (utmp_fd);
|
||||
|
@ -2715,7 +2672,6 @@ endutent ()
|
|||
extern "C" void
|
||||
utmpname (_CONST char *file)
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
if (check_null_empty_str (file))
|
||||
{
|
||||
debug_printf ("Invalid file");
|
||||
|
@ -2739,7 +2695,6 @@ static unsigned utix = 0;
|
|||
extern "C" struct utmp *
|
||||
getutent ()
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
if (utmp_fd < 0)
|
||||
{
|
||||
internal_setutent (false);
|
||||
|
@ -2756,7 +2711,6 @@ getutent ()
|
|||
extern "C" struct utmp *
|
||||
getutid (struct utmp *id)
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
if (check_null_invalid_struct_errno (id))
|
||||
return NULL;
|
||||
if (utmp_fd < 0)
|
||||
|
@ -2795,7 +2749,6 @@ getutid (struct utmp *id)
|
|||
extern "C" struct utmp *
|
||||
getutline (struct utmp *line)
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
if (check_null_invalid_struct_errno (line))
|
||||
return NULL;
|
||||
if (utmp_fd < 0)
|
||||
|
@ -2818,7 +2771,6 @@ getutline (struct utmp *line)
|
|||
extern "C" void
|
||||
pututline (struct utmp *ut)
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
if (check_null_invalid_struct (ut))
|
||||
return;
|
||||
internal_setutent (true);
|
||||
|
@ -2853,7 +2805,7 @@ pututline (struct utmp *ut)
|
|||
}
|
||||
|
||||
extern "C"
|
||||
long gethostid(void)
|
||||
long gethostid (void)
|
||||
{
|
||||
unsigned data[13] = {0x92895012,
|
||||
0x10293412,
|
||||
|
@ -2870,7 +2822,6 @@ long gethostid(void)
|
|||
0x00290012};
|
||||
|
||||
bool has_cpuid = false;
|
||||
sigframe thisframe (mainthread);
|
||||
|
||||
DWORD opmask = SetThreadAffinityMask (GetCurrentThread (), 1);
|
||||
if (!opmask)
|
||||
|
@ -2993,7 +2944,7 @@ getusershell ()
|
|||
if (!shell_fp && !(shell_fp = fopen64 (ETC_SHELLS, "rt")))
|
||||
{
|
||||
if (def_shells[shell_index])
|
||||
return strcpy (buf, def_shells[shell_index++]);
|
||||
return strcpy (buf, def_shells[shell_index++]);
|
||||
return NULL;
|
||||
}
|
||||
/* Skip white space characters. */
|
||||
|
|
|
@ -119,8 +119,6 @@ tcsetattr (int fd, int a, const struct termios *t)
|
|||
|
||||
while (1)
|
||||
{
|
||||
sigframe thisframe (mainthread);
|
||||
|
||||
res = -1;
|
||||
cygheap_fdget cfd (fd);
|
||||
if (cfd < 0)
|
||||
|
@ -148,7 +146,7 @@ tcsetattr (int fd, int a, const struct termios *t)
|
|||
e = get_errno ();
|
||||
break;
|
||||
case bg_signalled:
|
||||
if (thisframe.call_signal_handler ())
|
||||
if (call_signal_handler_now ())
|
||||
continue;
|
||||
res = -1;
|
||||
/* fall through intentionally */
|
||||
|
|
|
@ -36,12 +36,14 @@ details. */
|
|||
#include <stdlib.h>
|
||||
#include <syslog.h>
|
||||
#include "pinfo.h"
|
||||
#include "sigproc.h"
|
||||
#include "perprocess.h"
|
||||
#include "security.h"
|
||||
#include "exceptions.h"
|
||||
#include "cygtls.h"
|
||||
#include <semaphore.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/timeb.h>
|
||||
#include <exceptions.h>
|
||||
#include <sys/fcntl.h>
|
||||
|
||||
extern int threadsafe;
|
||||
|
@ -191,7 +193,6 @@ MTinterface::fixup_after_fork (void)
|
|||
{
|
||||
pthread_key::fixup_after_fork ();
|
||||
|
||||
#ifndef __SIGNALS_ARE_MULTITHREADED__
|
||||
/* As long as the signal handling not multithreaded
|
||||
switch reents storage back to _impure_ptr for the mainthread
|
||||
to support fork from threads other than the mainthread */
|
||||
|
@ -199,9 +200,8 @@ MTinterface::fixup_after_fork (void)
|
|||
reents._winsup = &winsup_reent;
|
||||
winsup_reent._process_logmask = LOG_UPTO (LOG_DEBUG);
|
||||
reent_key.set (&reents);
|
||||
#endif
|
||||
|
||||
threadcount = 1;
|
||||
threadcount = 0;
|
||||
pthread::init_mainthread ();
|
||||
|
||||
pthread::fixup_after_fork ();
|
||||
|
@ -225,7 +225,15 @@ pthread::init_mainthread ()
|
|||
api_fatal ("failed to create mainthread object");
|
||||
}
|
||||
|
||||
thread->init_current_thread ();
|
||||
thread->cygtls = &_my_tls;
|
||||
_my_tls.tid = thread;
|
||||
thread->thread_id = GetCurrentThreadId ();
|
||||
if (!DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
|
||||
GetCurrentProcess (), &thread->win32_obj_id,
|
||||
0, FALSE, DUPLICATE_SAME_ACCESS))
|
||||
thread->win32_obj_id = NULL;
|
||||
thread->set_tls_self_pointer ();
|
||||
thread->postcreate ();
|
||||
}
|
||||
|
||||
pthread *
|
||||
|
@ -238,9 +246,9 @@ pthread::self ()
|
|||
}
|
||||
|
||||
void
|
||||
pthread::set_tls_self_pointer (pthread *thisThread)
|
||||
pthread::set_tls_self_pointer ()
|
||||
{
|
||||
MT_INTERFACE->thread_self_key.set (thisThread);
|
||||
MT_INTERFACE->thread_self_key.set (this);
|
||||
}
|
||||
|
||||
pthread *
|
||||
|
@ -274,12 +282,6 @@ pthread::~pthread ()
|
|||
threads.remove (this);
|
||||
}
|
||||
|
||||
void
|
||||
pthread::set_thread_id_to_current ()
|
||||
{
|
||||
thread_id = GetCurrentThreadId ();
|
||||
}
|
||||
|
||||
void
|
||||
pthread::precreate (pthread_attr *newattr)
|
||||
{
|
||||
|
@ -334,7 +336,7 @@ pthread::create (void *(*func) (void *), pthread_attr *newattr,
|
|||
|
||||
if (!win32_obj_id)
|
||||
{
|
||||
thread_printf ("CreateThread failed: this %p LastError %E", this);
|
||||
thread_printf ("CreateThread failed: this %p, %E", this);
|
||||
magic = 0;
|
||||
}
|
||||
else
|
||||
|
@ -347,6 +349,15 @@ pthread::create (void *(*func) (void *), pthread_attr *newattr,
|
|||
void
|
||||
pthread::postcreate ()
|
||||
{
|
||||
cancel_event = ::CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
|
||||
if (!cancel_event)
|
||||
{
|
||||
system_printf ("couldn't create cancel event for main thread, %E");
|
||||
/* we need the event for correct behaviour */
|
||||
magic = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
valid = true;
|
||||
|
||||
InterlockedIncrement (&MT_INTERFACE->threadcount);
|
||||
|
@ -737,19 +748,6 @@ pthread::get_thread_id ()
|
|||
return thread_id;
|
||||
}
|
||||
|
||||
void
|
||||
pthread::init_current_thread ()
|
||||
{
|
||||
cancel_event = ::CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
|
||||
if (!DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
|
||||
GetCurrentProcess (), &win32_obj_id,
|
||||
0, FALSE, DUPLICATE_SAME_ACCESS))
|
||||
win32_obj_id = NULL;
|
||||
set_thread_id_to_current ();
|
||||
set_tls_self_pointer (this);
|
||||
valid = true;
|
||||
}
|
||||
|
||||
void
|
||||
pthread::_fixup_after_fork ()
|
||||
{
|
||||
|
@ -1892,27 +1890,19 @@ void *
|
|||
pthread::thread_init_wrapper (void *_arg)
|
||||
{
|
||||
// Setup the local/global storage of this thread
|
||||
|
||||
__uint64_t padding[CYGTLS_PADSIZE];
|
||||
pthread *thread = (pthread *) _arg;
|
||||
thread->cygtls = _my_tls.init (padding, &thread);
|
||||
_my_tls.tid = thread;
|
||||
|
||||
exception_list cygwin_except_entry;
|
||||
init_exceptions (&cygwin_except_entry); /* Initialize SIGSEGV handling, etc. */
|
||||
|
||||
thread->set_tls_self_pointer ();
|
||||
struct __reent_t local_reent;
|
||||
struct _winsup_t local_winsup;
|
||||
struct _reent local_clib;
|
||||
|
||||
struct sigaction _sigs[NSIG];
|
||||
sigset_t _sig_mask; /* one set for everything to ignore. */
|
||||
|
||||
/* According to onno@stack.urc.tue.nl, the exception handler record must
|
||||
be on the stack. */
|
||||
exception_list cygwin_except_entry;
|
||||
|
||||
/* Initialize SIGSEGV handling, etc. */
|
||||
init_exceptions (&cygwin_except_entry);
|
||||
|
||||
// setup signal structures
|
||||
thread->sigs = _sigs;
|
||||
thread->sigmask = &_sig_mask;
|
||||
thread->sigtodo = NULL;
|
||||
|
||||
memset (&local_winsup, 0, sizeof (struct _winsup_t));
|
||||
|
||||
local_reent.init_clib (local_clib);
|
||||
|
@ -1922,9 +1912,6 @@ pthread::thread_init_wrapper (void *_arg)
|
|||
|
||||
MT_INTERFACE->reent_key.set (&local_reent);
|
||||
|
||||
thread->set_thread_id_to_current ();
|
||||
set_tls_self_pointer (thread);
|
||||
|
||||
thread->mutex.lock ();
|
||||
// if thread is detached force cleanup on exit
|
||||
if (thread->attr.joinable == PTHREAD_CREATE_DETACHED && thread->joiner == NULL)
|
||||
|
@ -1943,13 +1930,6 @@ pthread::thread_init_wrapper (void *_arg)
|
|||
void *ret = thread->function (thread->arg);
|
||||
|
||||
thread->exit (ret);
|
||||
|
||||
#if 0
|
||||
// ??? This code only runs if the thread exits by returning.
|
||||
// it's all now in __pthread_exit ();
|
||||
#endif
|
||||
/* never reached */
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1970,7 +1950,6 @@ int
|
|||
pthread::create (pthread_t *thread, const pthread_attr_t *attr,
|
||||
void *(*start_routine) (void *), void *arg)
|
||||
{
|
||||
DECLARE_TLS_STORAGE;
|
||||
if (attr && !pthread_attr::is_good_object (attr))
|
||||
return EINVAL;
|
||||
|
||||
|
@ -2904,7 +2883,7 @@ pthread_kill (pthread_t thread, int sig)
|
|||
if (!pthread::is_good_object (&thread))
|
||||
return EINVAL;
|
||||
|
||||
int rval = raise (sig);
|
||||
int rval = sig ? sig_send (NULL, sig, thread->cygtls) : 0;
|
||||
|
||||
// unlock myself
|
||||
return rval;
|
||||
|
@ -2913,11 +2892,7 @@ pthread_kill (pthread_t thread, int sig)
|
|||
extern "C" int
|
||||
pthread_sigmask (int operation, const sigset_t *set, sigset_t *old_set)
|
||||
{
|
||||
int rval = sigprocmask (operation, set, old_set);
|
||||
|
||||
// unlock this myself
|
||||
|
||||
return rval;
|
||||
return handle_sigprocmask (operation, set, old_set, _my_tls.sigmask);
|
||||
}
|
||||
|
||||
/* ID */
|
||||
|
|
|
@ -305,7 +305,7 @@ protected:
|
|||
list_node *head;
|
||||
};
|
||||
|
||||
class pthread_key:public verifyable_object
|
||||
class pthread_key: public verifyable_object
|
||||
{
|
||||
public:
|
||||
static bool is_good_object (pthread_key_t const *);
|
||||
|
@ -343,7 +343,7 @@ private:
|
|||
void *fork_buf;
|
||||
};
|
||||
|
||||
class pthread_attr:public verifyable_object
|
||||
class pthread_attr: public verifyable_object
|
||||
{
|
||||
public:
|
||||
static bool is_good_object(pthread_attr_t const *);
|
||||
|
@ -357,7 +357,7 @@ public:
|
|||
~pthread_attr ();
|
||||
};
|
||||
|
||||
class pthread_mutexattr:public verifyable_object
|
||||
class pthread_mutexattr: public verifyable_object
|
||||
{
|
||||
public:
|
||||
static bool is_good_object(pthread_mutexattr_t const *);
|
||||
|
@ -367,7 +367,7 @@ public:
|
|||
~pthread_mutexattr ();
|
||||
};
|
||||
|
||||
class pthread_mutex:public verifyable_object
|
||||
class pthread_mutex: public verifyable_object
|
||||
{
|
||||
public:
|
||||
static bool is_good_object (pthread_mutex_t const *);
|
||||
|
@ -448,7 +448,8 @@ private:
|
|||
|
||||
#define WAIT_CANCELED (WAIT_OBJECT_0 + 1)
|
||||
|
||||
class pthread:public verifyable_object
|
||||
class _threadinfo;
|
||||
class pthread: public verifyable_object
|
||||
{
|
||||
public:
|
||||
HANDLE win32_obj_id;
|
||||
|
@ -459,13 +460,10 @@ public:
|
|||
bool valid;
|
||||
bool suspended;
|
||||
int cancelstate, canceltype;
|
||||
_threadinfo *cygtls;
|
||||
HANDLE cancel_event;
|
||||
pthread_t joiner;
|
||||
|
||||
/* signal handling */
|
||||
struct sigaction *sigs;
|
||||
sigset_t *sigmask;
|
||||
LONG *sigtodo;
|
||||
virtual void create (void *(*)(void *), pthread_attr *, void *);
|
||||
|
||||
pthread ();
|
||||
|
@ -488,7 +486,7 @@ public:
|
|||
static int suspend (pthread_t * thread);
|
||||
static int resume (pthread_t * thread);
|
||||
|
||||
virtual void exit (void *value_ptr);
|
||||
virtual void exit (void *value_ptr) __attribute__ ((noreturn));
|
||||
|
||||
virtual int cancel ();
|
||||
|
||||
|
@ -504,7 +502,7 @@ public:
|
|||
virtual void pop_cleanup_handler (int const execute);
|
||||
|
||||
static pthread* self ();
|
||||
static void *thread_init_wrapper (void *);
|
||||
static void *thread_init_wrapper (void *) __attribute__ ((noreturn));
|
||||
|
||||
virtual unsigned long getsequence_np();
|
||||
|
||||
|
@ -545,12 +543,10 @@ private:
|
|||
void pop_all_cleanup_handlers (void);
|
||||
void precreate (pthread_attr *);
|
||||
void postcreate ();
|
||||
void set_thread_id_to_current ();
|
||||
static void set_tls_self_pointer (pthread *);
|
||||
void set_tls_self_pointer ();
|
||||
static pthread *get_tls_self_pointer ();
|
||||
void cancel_self ();
|
||||
DWORD get_thread_id ();
|
||||
void init_current_thread ();
|
||||
};
|
||||
|
||||
class pthread_null : public pthread
|
||||
|
@ -563,7 +559,7 @@ class pthread_null : public pthread
|
|||
* as the ojbect is not verifyable
|
||||
*/
|
||||
void create (void *(*)(void *), pthread_attr *, void *);
|
||||
void exit (void *value_ptr);
|
||||
void exit (void *value_ptr) __attribute__ ((noreturn));
|
||||
int cancel ();
|
||||
void testcancel ();
|
||||
int setcancelstate (int state, int *oldstate);
|
||||
|
@ -577,7 +573,7 @@ class pthread_null : public pthread
|
|||
static pthread_null _instance;
|
||||
};
|
||||
|
||||
class pthread_condattr:public verifyable_object
|
||||
class pthread_condattr: public verifyable_object
|
||||
{
|
||||
public:
|
||||
static bool is_good_object(pthread_condattr_t const *);
|
||||
|
@ -587,7 +583,7 @@ public:
|
|||
~pthread_condattr ();
|
||||
};
|
||||
|
||||
class pthread_cond:public verifyable_object
|
||||
class pthread_cond: public verifyable_object
|
||||
{
|
||||
public:
|
||||
static bool is_good_object (pthread_cond_t const *);
|
||||
|
@ -628,7 +624,7 @@ private:
|
|||
static fast_mutex cond_initialization_lock;
|
||||
};
|
||||
|
||||
class pthread_rwlockattr:public verifyable_object
|
||||
class pthread_rwlockattr: public verifyable_object
|
||||
{
|
||||
public:
|
||||
static bool is_good_object(pthread_rwlockattr_t const *);
|
||||
|
@ -638,7 +634,7 @@ public:
|
|||
~pthread_rwlockattr ();
|
||||
};
|
||||
|
||||
class pthread_rwlock:public verifyable_object
|
||||
class pthread_rwlock: public verifyable_object
|
||||
{
|
||||
public:
|
||||
static bool is_good_object (pthread_rwlock_t const *);
|
||||
|
@ -717,7 +713,7 @@ public:
|
|||
};
|
||||
|
||||
/* shouldn't be here */
|
||||
class semaphore:public verifyable_object
|
||||
class semaphore: public verifyable_object
|
||||
{
|
||||
public:
|
||||
static bool is_good_object(sem_t const *);
|
||||
|
@ -767,9 +763,8 @@ public:
|
|||
class callback * next;
|
||||
};
|
||||
|
||||
class MTinterface
|
||||
struct MTinterface
|
||||
{
|
||||
public:
|
||||
// General
|
||||
int concurrency;
|
||||
long int threadcount;
|
||||
|
@ -789,12 +784,17 @@ public:
|
|||
void fixup_before_fork (void);
|
||||
void fixup_after_fork (void);
|
||||
|
||||
#if 1 // avoid initialization since zero is implied and
|
||||
// only use of this class is static
|
||||
MTinterface () : reent_key (NULL), thread_self_key (NULL) {}
|
||||
#else
|
||||
MTinterface () :
|
||||
concurrency (0), threadcount (1),
|
||||
concurrency (0), threadcount (0),
|
||||
pthread_prepare (NULL), pthread_child (NULL), pthread_parent (NULL),
|
||||
reent_key (NULL), thread_self_key (NULL)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
#define MT_INTERFACE user_data->threadinterface
|
||||
|
|
|
@ -34,7 +34,7 @@ details. */
|
|||
The information is used in shared.cc for the user shared.
|
||||
Final initialization occurs in uinfo_init */
|
||||
void
|
||||
cygheap_user::init()
|
||||
cygheap_user::init ()
|
||||
{
|
||||
char user_name[UNLEN + 1];
|
||||
DWORD user_name_len = UNLEN + 1;
|
||||
|
@ -80,7 +80,7 @@ cygheap_user::init()
|
|||
|
||||
for (int i = 0; i < pAcl->AceCount; i++)
|
||||
{
|
||||
if (!GetAce(pAcl, i, (LPVOID *) &pAce))
|
||||
if (!GetAce (pAcl, i, (LPVOID *) &pAce))
|
||||
system_printf ("GetAce: %E");
|
||||
else if (pAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE
|
||||
&& effec_cygsid == &pAce->SidStart)
|
||||
|
@ -115,7 +115,7 @@ internal_getlogin (cygheap_user &user)
|
|||
|
||||
if (!pw && !(pw = internal_getpwnam (user.name ()))
|
||||
&& !(pw = internal_getpwuid (DEFAULT_UID)))
|
||||
debug_printf("user not found in augmented /etc/passwd");
|
||||
debug_printf ("user not found in augmented /etc/passwd");
|
||||
else
|
||||
{
|
||||
myself->uid = pw->pw_uid;
|
||||
|
@ -313,7 +313,7 @@ cygheap_user::ontherange (homebodies what, struct passwd *pw)
|
|||
sys_mbstowcs (wlogsrv, logsrv (),
|
||||
sizeof (wlogsrv) / sizeof (*wlogsrv));
|
||||
sys_mbstowcs (wuser, winname (), sizeof (wuser) / sizeof (*wuser));
|
||||
if (!(ret = NetUserGetInfo (wlogsrv, wuser, 3,(LPBYTE *)&ui)))
|
||||
if (!(ret = NetUserGetInfo (wlogsrv, wuser, 3, (LPBYTE *) &ui)))
|
||||
{
|
||||
sys_wcstombs (homepath_env_buf, ui->usri3_home_dir, CYG_MAX_PATH);
|
||||
if (!homepath_env_buf[0])
|
||||
|
|
|
@ -55,7 +55,6 @@ wait4 (int intpid, int *status, int options, struct rusage *r)
|
|||
while (1)
|
||||
{
|
||||
sig_dispatch_pending ();
|
||||
sigframe thisframe (mainthread);
|
||||
sawsig = 0;
|
||||
if (options & ~(WNOHANG | WUNTRACED))
|
||||
{
|
||||
|
@ -100,6 +99,7 @@ wait4 (int intpid, int *status, int options, struct rusage *r)
|
|||
|
||||
if (w->status == -1)
|
||||
{
|
||||
call_signal_handler_now ();
|
||||
set_sig_errno (EINTR);
|
||||
sawsig = 1;
|
||||
res = -1;
|
||||
|
@ -115,7 +115,7 @@ wait4 (int intpid, int *status, int options, struct rusage *r)
|
|||
*status = w->status;
|
||||
|
||||
done:
|
||||
if (!sawsig || !thisframe.call_signal_handler ())
|
||||
if (!sawsig || !call_signal_handler_now ())
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -57,12 +57,12 @@ ilockcmpexch (long *t, long v, long c)
|
|||
#undef InterlockedCompareExchange
|
||||
#define InterlockedCompareExchange ilockcmpexch
|
||||
|
||||
// extern char * volatile *__stackbase __asm__ ("%fs:4");
|
||||
#ifndef EXPCGf
|
||||
#define DECLARE_TLS_STORAGE do {} while (0)
|
||||
#else
|
||||
#define DECLARE_TLS_STORAGE char **tls[4096] __attribute__ ((unused))
|
||||
extern long tls_ix;
|
||||
extern char * volatile *__stackbase __asm__ ("%fs:4");
|
||||
|
||||
extern __inline__ DWORD
|
||||
my_tlsalloc ()
|
||||
|
|
|
@ -274,6 +274,8 @@ int __stdcall __check_invalid_read_ptr_errno (const void *s, unsigned sz) __attr
|
|||
__check_null_invalid_struct ((s), sizeof (*(s)))
|
||||
#define check_null_invalid_struct_errno(s) \
|
||||
__check_null_invalid_struct_errno ((s), sizeof (*(s)))
|
||||
#define check_invalid_read_struct_errno(s) \
|
||||
__check_invalid_read_ptr_errno ((s), sizeof (*(s)))
|
||||
|
||||
struct iovec;
|
||||
ssize_t check_iovec_for_read (const struct iovec *, int) __attribute__ ((regparm(2)));
|
||||
|
@ -296,7 +298,7 @@ int symlink_worker (const char *, const char *, bool, bool)
|
|||
class path_conv;
|
||||
int access_worker (path_conv&, int) __attribute__ ((regparm (2)));
|
||||
|
||||
extern "C" int __stdcall low_priority_sleep (DWORD) __attribute__ ((regparm (1)));
|
||||
extern "C" int low_priority_sleep (DWORD) __attribute__ ((regparm (1)));
|
||||
#define SLEEP_0_STAY_LOW INFINITE
|
||||
|
||||
size_t getshmlba (void);
|
||||
|
@ -339,8 +341,6 @@ extern HANDLE hMainThread;
|
|||
extern HANDLE hMainProc;
|
||||
|
||||
extern bool cygwin_testing;
|
||||
extern unsigned _cygwin_testing_magic;
|
||||
extern HMODULE cygwin_hmodule;
|
||||
|
||||
extern char almost_null[];
|
||||
|
||||
|
|
Loading…
Reference in New Issue