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:
Christopher Faylor 2003-11-28 20:55:59 +00:00
parent ffe0063843
commit 9a4d574b8d
50 changed files with 3311 additions and 3466 deletions

View File

@ -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

View File

@ -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

View File

@ -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__ */

View File

@ -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) $<

View File

@ -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

View File

@ -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)

61
winsup/cygwin/cygtls.h Normal file
View File

@ -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*/

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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*/
);
}
}

View File

@ -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>

View File

@ -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;

View File

@ -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
}

223
winsup/cygwin/gendef Executable file
View File

@ -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
}

View File

@ -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;

71
winsup/cygwin/gentls_offsets Executable file
View File

@ -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);

View File

@ -97,7 +97,6 @@ heap_init ()
extern "C" void *
sbrk (int n)
{
sigframe thisframe (mainthread);
char *newtop, *newbrk;
unsigned commitbytes, newbrksize;

View File

@ -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.

View File

@ -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

View File

@ -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 */ \

View File

@ -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;

View File

@ -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)

View File

@ -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 ();

View File

@ -39,9 +39,9 @@ static fhandler_disk_file fh_paging_file;
for duplicating all mmaps after fork() since mmaps are not propagated
to child processes by Windows. All information must be duplicated
by hand, see fixup_mmaps_after_fork().
The class structure:
One member of class map per process, global variable mmapped_areas.
Contains a dynamic class list array. Each list entry represents all
mapping to a file, keyed by file descriptor and file name hash.
@ -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)
{

View File

@ -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))

View File

@ -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);

View File

@ -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 ());

View File

@ -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[];

View File

@ -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;
@ -243,14 +243,14 @@ pinfo::set_acl()
{
char sa_buf[1024];
SECURITY_DESCRIPTOR sd;
sec_acl ((PACL) sa_buf, true, true, cygheap->user.sid (),
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");
}

View File

@ -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)

View File

@ -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;

View File

@ -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)))

View File

@ -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. */

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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*/

View File

@ -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:

View File

@ -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;
@ -2131,7 +2099,7 @@ seteuid32 (__uid32_t uid)
BOOL token_is_internal, issamesid;
char dacl_buf[MAX_DACL_LEN (5)];
TOKEN_DEFAULT_DACL tdacl = {};
pw_new = internal_getpwuid (uid);
if (!wincap.has_security () && pw_new)
goto success_9x;
@ -2202,7 +2170,7 @@ seteuid32 (__uid32_t uid)
{
/* Avoid having HKCU use default user */
load_registry_hive (usersid);
/* Try setting owner to same value as user. */
if (!SetTokenInformation (new_token, TokenOwner,
&usersid, sizeof usersid))
@ -2221,12 +2189,12 @@ seteuid32 (__uid32_t uid)
}
CloseHandle (ptok);
issamesid = (usersid == cygheap->user.sid ());
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. */

View File

@ -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 */

View File

@ -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 */

View File

@ -253,7 +253,7 @@ List_remove (fast_mutex &mx, list_node *&head, list_node *node)
}
mx.unlock ();
}
template <class list_node> class List
{
@ -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

View File

@ -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;
@ -70,7 +70,7 @@ cygheap_user::init()
if (!SetTokenInformation (ptok, TokenOwner, &effec_cygsid, sizeof (cygsid)))
debug_printf ("SetTokenInformation(TokenOwner): %E");
/* Add the user in the default DACL if needed */
/* Add the user in the default DACL if needed */
if (!GetTokenInformation (ptok, TokenDefaultDacl, pdacl, sizeof (pdacl_buf), &siz))
system_printf ("GetTokenInformation (TokenDefaultDacl): %E");
else if (pdacl->DefaultDacl) /* Running with security */
@ -80,14 +80,14 @@ 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)
goto out;
}
pAcl->AclSize = &pdacl_buf[sizeof (pdacl_buf)] - (char *) pAcl;
if (!AddAccessAllowedAce (pAcl, ACL_REVISION, GENERIC_ALL, effec_cygsid))
if (!AddAccessAllowedAce (pAcl, ACL_REVISION, GENERIC_ALL, effec_cygsid))
system_printf ("AddAccessAllowedAce: %E");
else if (FindFirstFreeAce (pAcl, (LPVOID *) &pAce), !(pAce))
debug_printf ("FindFirstFreeAce %E");
@ -98,7 +98,7 @@ cygheap_user::init()
system_printf ("SetTokenInformation (TokenDefaultDacl): %E");
}
}
out:
out:
CloseHandle (ptok);
}
@ -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])

View File

@ -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;
}

View File

@ -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 ()

View File

@ -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[];