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

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2004-02-13 22:34:32 +0300
committerChristopher Faylor <me@cgf.cx>2004-02-13 22:34:32 +0300
commitedc4f86ad282702ab7c029cf65b87ec616bda05e (patch)
tree2abde4171eaab1863d78128ba2ef6418485eff57 /winsup
parentb3535c273043da91247840c4af64bb573d5517c4 (diff)
* Makefile.in (clean): Remove sigfe.s.
(sigfe.s): Ensure that sigfe.s will be regenerated if it does not exist. * dll_init.cc (dll_dllcrt0): Simplify initializing tests. * exceptions.cc (setup_handler): Detect when stub caller is either spinning or has acquired the lock after being suspended to avoid windows problems with suspending a win32 API call. * cygtls.h (_cygtls::spinning): Declare new element. * gendef: Remove unused _siglist_index and _siglist declaration. (_sigfe): Set spinning element when potentially looping, waiting for lock. (_sigbe): Ditto. (_cygtls::lock): Ditto. (_longjmp): Ditto. * tlsoffsets.h: Regenerate. * pinfo.cc (_pinfo::exit): Set final exit state here. Call sigproc_terminate if invoked with 'norecord'. Clear any residual _cygtls stuff. * winsup.h (exit_states): Define ES_FINAL. * spawn.cc (spawn_guts): Don't call proc_terminate specifically when execing. Let _pinfo::exit handle that case. * sigproc.cc (wait_subproc): Always exit loop early when proc_loop_wait. * init.cc (munge_threadfunc): Eliminate unused argument. (dll_entry): Reflect above change in call to munge_threadfunc.
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/ChangeLog30
-rw-r--r--winsup/cygwin/Makefile.in7
-rw-r--r--winsup/cygwin/cygtls.h1
-rw-r--r--winsup/cygwin/dll_init.cc9
-rw-r--r--winsup/cygwin/exceptions.cc4
-rwxr-xr-xwinsup/cygwin/gendef5
-rw-r--r--winsup/cygwin/init.cc6
-rw-r--r--winsup/cygwin/pinfo.cc8
-rw-r--r--winsup/cygwin/sigproc.cc62
-rw-r--r--winsup/cygwin/spawn.cc3
-rw-r--r--winsup/cygwin/tlsoffsets.h96
-rw-r--r--winsup/cygwin/winsup.h3
12 files changed, 134 insertions, 100 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index ef35a3976..20c8c3ebb 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,31 @@
+2004-02-13 Christopher Faylor <cgf@redhat.com>
+
+ * Makefile.in (clean): Remove sigfe.s.
+ (sigfe.s): Ensure that sigfe.s will be regenerated if it does not exist.
+ * dll_init.cc (dll_dllcrt0): Simplify initializing tests.
+
+ * exceptions.cc (setup_handler): Detect when stub caller is either
+ spinning or has acquired the lock after being suspended to avoid
+ windows problems with suspending a win32 API call.
+
+ * cygtls.h (_cygtls::spinning): Declare new element.
+ * gendef: Remove unused _siglist_index and _siglist declaration.
+ (_sigfe): Set spinning element when potentially looping, waiting for lock.
+ (_sigbe): Ditto.
+ (_cygtls::lock): Ditto.
+ (_longjmp): Ditto.
+ * tlsoffsets.h: Regenerate.
+ * pinfo.cc (_pinfo::exit): Set final exit state here. Call sigproc_terminate if
+ invoked with 'norecord'. Clear any residual _cygtls stuff.
+ * winsup.h (exit_states): Define ES_FINAL.
+ * spawn.cc (spawn_guts): Don't call proc_terminate specifically when
+ execing. Let _pinfo::exit handle that case.
+
+ * sigproc.cc (wait_subproc): Always exit loop early when proc_loop_wait.
+
+ * init.cc (munge_threadfunc): Eliminate unused argument.
+ (dll_entry): Reflect above change in call to munge_threadfunc.
+
2004-02-11 Christopher Faylor <cgf@redhat.com>
* gendef (_sigbe): Zero location on pop.
@@ -88,7 +116,7 @@
(_sigbe): Ditto.
(_threadinfo::lock): Ditto.
(_threadinfo::pop): Eliminate left-over stack unlock.
- * sigproc.cc (proc_subproc): Chnage debugging output to printed
+ * sigproc.cc (proc_subproc): Change debugging output to printed
warning.
2004-02-08 Christopher Faylor <cgf@redhat.com>
diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in
index 54ae6e991..887ab1e44 100644
--- a/winsup/cygwin/Makefile.in
+++ b/winsup/cygwin/Makefile.in
@@ -224,6 +224,7 @@ cygthread_CFLAGS:=-fomit-frame-pointer
cygtls_CFLAGS:=-fomit-frame-pointer
devices_CFLAGS:=-fomit-frame-pointer -Os
dir_CFLAGS:=-fomit-frame-pointer
+dll_init_CFLAGS:=-fomit-frame-pointer
fcntl_CFLAGS:=-fomit-frame-pointer
fhandler_CFLAGS:=-fomit-frame-pointer
fhandler_clipboard_CFLAGS:=-fomit-frame-pointer
@@ -346,7 +347,7 @@ uninstall-man:
done
clean:
- -rm -f *.o *.dll *.a *.exp junk *.base version.cc regexp/*.o winver_stamp *.exe *.d *stamp* *_magic.h
+ -rm -f *.o *.dll *.a *.exp junk *.base version.cc regexp/*.o winver_stamp *.exe *.d *stamp* *_magic.h sigfe.s
maintainer-clean realclean: clean
@echo "This command is intended for maintainers to use;"
@@ -437,7 +438,9 @@ $(srcdir)/tlsoffsets.h: gentls_offsets cygtls.h
$^ $@ $(COMPILE_CXX)
sigfe.s: $(DEF_FILE)
- @touch $@
+ @[ -s $@ ] || \
+ { rm -f $(DEF_FILE); $(MAKE) -s -j1 $(DEF_FILE); }; \
+ [ -s $@ ] && touch $@
sigfe.o: sigfe.s
$(CC) -c -o $@ $?
diff --git a/winsup/cygwin/cygtls.h b/winsup/cygwin/cygtls.h
index 78f61242b..444da265c 100644
--- a/winsup/cygwin/cygtls.h
+++ b/winsup/cygwin/cygtls.h
@@ -112,6 +112,7 @@ struct _cygtls
__stack_t *stackptr;
int sig;
unsigned stacklock;
+ unsigned spinning;
__stack_t stack[TLS_STACK_SIZE];
unsigned padding[0];
diff --git a/winsup/cygwin/dll_init.cc b/winsup/cygwin/dll_init.cc
index a1901a02d..a3817d76e 100644
--- a/winsup/cygwin/dll_init.cc
+++ b/winsup/cygwin/dll_init.cc
@@ -23,7 +23,7 @@ extern void __stdcall check_sanity_and_sync (per_process *);
dll_list NO_COPY dlls;
-static NO_COPY int in_forkee = 0;
+static int NO_COPY in_forkee;
static int dll_global_dtors_recorded;
/* Run destructors for all DLLs on exit. */
@@ -183,7 +183,7 @@ dll_list::alloc (HINSTANCE h, per_process *p, dll_type type)
void
dll_list::detach (void *retaddr)
{
- if (!myself || myself->process_state == PID_EXITED)
+ if (!myself || exit_state)
return;
MEMORY_BASIC_INFORMATION m;
if (!VirtualQuery (retaddr, &m, sizeof m))
@@ -358,6 +358,7 @@ dll_dllcrt0 (HMODULE h, per_process *p)
p = &__cygwin_user_data;
else
*(p->impure_ptr_ptr) = __cygwin_user_data.impure_ptr;
+ bool initializing = in_forkee || cygwin_finished_initializing;
/* Partially initialize Cygwin guts for non-cygwin apps. */
if (dynamically_loaded && user_data->magic_biscuit == 0)
@@ -371,7 +372,7 @@ dll_dllcrt0 (HMODULE h, per_process *p)
initializing, then the DLL must be a cygwin-aware DLL
that was explicitly linked into the program rather than
a dlopened DLL. */
- if (!in_forkee && !cygwin_finished_initializing)
+ if (!initializing)
type = DLL_LINK;
else
{
@@ -387,7 +388,7 @@ dll_dllcrt0 (HMODULE h, per_process *p)
initialize the DLL. If we haven't finished initializing,
it may not be safe to call the dll's "main" since not
all of cygwin's internal structures may have been set up. */
- if (!d || ((in_forkee || cygwin_finished_initializing) && !d->init ()))
+ if (!d || (initializing && !d->init ()))
return -1;
return (DWORD) d;
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index 490756544..118223e03 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -788,12 +788,12 @@ setup_handler (int sig, void *handler, struct sigaction& siga, _cygtls *tls)
#endif
res = SuspendThread (hth);
/* Just set pending if thread is already suspended */
- if (res)
+ if (res || tls->stackptr > tls->stack)
{
(void) ResumeThread (hth);
break;
}
- if (!tls->locked ())
+ if (!tls->locked () && !tls->spinning)
{
cx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
if (!GetThreadContext (hth, &cx))
diff --git a/winsup/cygwin/gendef b/winsup/cygwin/gendef
index 4395ac6de..22acf87df 100755
--- a/winsup/cygwin/gendef
+++ b/winsup/cygwin/gendef
@@ -76,8 +76,6 @@ sub fefunc {
my $fe = '_' . shift;
my $extra;
my $res = <<EOF;
- .extern _siglist_index
- .extern _siglist
.extern $func
.global $fe
$fe:
@@ -96,6 +94,7 @@ __sigfe:
1: movl %fs:4,%edx # location of bottom of stack
movl \$1,%eax # potential lock value
lock xchgl %eax,$tls::stacklock(%edx) # see if we can grab it
+ movl %eax,$tls::spinning(%edx) # flag if we are waiting for lock
orl %eax,%eax # it will be zero
jz 2f # if so
xorl %eax,%eax # nope. It was not zero
@@ -120,6 +119,7 @@ __sigbe:
1: movl %fs:4,%edx # address of bottom of tls
movl \$1,%eax # potential lock value
lock xchgl %eax,$tls::stacklock(%edx) # see if we can grab it
+ movl %eax,$tls::spinning(%edx) # flag if we are waiting for lock
orl %eax,%eax # it will be zero
jz 2f # if so
xorl %eax,%eax # nope. not zero
@@ -242,6 +242,7 @@ _longjmp:
1: movl %fs:4,%edx
movl \$1,%eax
lock xchgl %eax,$tls::stacklock(%edx)
+ movl %eax,$tls::spinning(%edx) # flag if we are waiting for lock
orl %eax,%eax
jz 2f
xorl %eax,%eax
diff --git a/winsup/cygwin/init.cc b/winsup/cygwin/init.cc
index 8bbc89bfb..b6d187328 100644
--- a/winsup/cygwin/init.cc
+++ b/winsup/cygwin/init.cc
@@ -56,7 +56,7 @@ prime_threads ()
/* If possible, redirect the thread entry point to a cygwin routine which
adds tls stuff to the stack. */
static void
-munge_threadfunc (HANDLE cygwin_hmodule)
+munge_threadfunc ()
{
char **ebp = (char **) __builtin_frame_address (0);
if (!threadfunc_ix)
@@ -67,7 +67,7 @@ munge_threadfunc (HANDLE cygwin_hmodule)
threadfunc_ix = peb - ebp;
goto foundit;
}
-#ifdef DEBUGGING
+#ifdef DEBUGGING_HARD
system_printf ("non-fatal warning: unknown thread! search_for %p, cygthread::stub %p, calibration_thread %p, possible func offset %p",
search_for, cygthread::stub, calibration_thread, ebp[137]);
#endif
@@ -102,7 +102,7 @@ dll_entry (HANDLE h, DWORD reason, void *static_load)
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
- munge_threadfunc (h);
+ munge_threadfunc ();
break;
case DLL_THREAD_DETACH:
_my_tls.remove (0);
diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc
index a9a0b80e7..0dd465ae4 100644
--- a/winsup/cygwin/pinfo.cc
+++ b/winsup/cygwin/pinfo.cc
@@ -31,6 +31,7 @@ details. */
#include "cygheap.h"
#include "fhandler.h"
#include "cygmalloc.h"
+#include "cygtls.h"
static char NO_COPY pinfo_dummy[sizeof (_pinfo)] = {0};
@@ -104,6 +105,10 @@ pinfo_init (char **envp, int envc)
void
_pinfo::exit (UINT n, bool norecord)
{
+ exit_state = ES_FINAL;
+ cygthread::terminate ();
+ if (norecord)
+ sigproc_terminate ();
if (this)
{
if (!norecord)
@@ -116,8 +121,9 @@ _pinfo::exit (UINT n, bool norecord)
add_rusage (&rusage_self, &r);
}
- cygthread::terminate ();
sigproc_printf ("Calling ExitProcess %d", n);
+ _my_tls.stacklock = 0;
+ _my_tls.stackptr = _my_tls.stack;
ExitProcess (n);
}
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index c013e0d20..5d7e049be 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -70,26 +70,6 @@ static pending_signals sigqueue;
struct sigaction *global_sigs;
-void __stdcall
-sigalloc ()
-{
- cygheap->sigs = global_sigs =
- (struct sigaction *) ccalloc (HEAP_SIGS, NSIG, sizeof (struct sigaction));
-}
-
-void __stdcall
-signal_fixup_after_exec ()
-{
- global_sigs = cygheap->sigs;
- /* Set up child's signal handlers */
- for (int i = 0; i < NSIG; i++)
- {
- global_sigs[i].sa_mask = 0;
- if (global_sigs[i].sa_handler != SIG_IGN)
- global_sigs[i].sa_handler = SIG_DFL;
- }
-}
-
/*
* Global variables
*/
@@ -101,19 +81,15 @@ char NO_COPY myself_nowait_dummy[1] = {'0'};// Flag to sig_send that signal goes
HANDLE NO_COPY signal_arrived; // Event signaled when a signal has
// resulted in a user-specified
// function call
-/*
- * Common variables
- */
+#define Static static NO_COPY
/* How long to wait for message/signals. Normally this is infinite.
- * On termination, however, these are set to zero as a flag to exit.
- */
-
-#define Static static NO_COPY
+ On termination, however, these are set to zero as a flag to exit. */
Static DWORD proc_loop_wait = 1000; // Wait for subprocesses to exit
+Static HANDLE sendsig_tome;
HANDLE NO_COPY sigCONT; // Used to "STOP" a process
Static cygthread *hwait_sig; // Handle of wait_sig thread
Static cygthread *hwait_subproc; // Handle of sig_subproc thread
@@ -149,6 +125,26 @@ static DWORD WINAPI wait_sig (VOID *arg);
static int __stdcall stopped_or_terminated (waitq *, _pinfo *);
static DWORD WINAPI wait_subproc (VOID *);
+void __stdcall
+sigalloc ()
+{
+ cygheap->sigs = global_sigs =
+ (struct sigaction *) ccalloc (HEAP_SIGS, NSIG, sizeof (struct sigaction));
+}
+
+void __stdcall
+signal_fixup_after_exec ()
+{
+ global_sigs = cygheap->sigs;
+ /* Set up child's signal handlers */
+ for (int i = 0; i < NSIG; i++)
+ {
+ global_sigs[i].sa_mask = 0;
+ if (global_sigs[i].sa_handler != SIG_IGN)
+ global_sigs[i].sa_handler = SIG_DFL;
+ }
+}
+
/* Determine if the parent process is alive.
*/
@@ -1215,17 +1211,13 @@ wait_subproc (VOID *)
{
DWORD rc = WaitForMultipleObjects (nchildren + 1, events, FALSE,
proc_loop_wait);
+ if (!proc_loop_wait)
+ break;
if (rc == WAIT_TIMEOUT)
- if (!proc_loop_wait)
- break; // Exiting
- else
- continue;
+ continue;
if (rc == WAIT_FAILED)
{
- if (!proc_loop_wait)
- break;
-
/* It's ok to get an ERROR_INVALID_HANDLE since another thread may have
closed a handle in the children[] array. So, we try looping a couple
of times to stabilize. FIXME - this is not foolproof. Probably, this
@@ -1274,8 +1266,6 @@ wait_subproc (VOID *)
si.si_stime = 0;
#endif
rc = proc_subproc (PROC_CHILDTERMINATED, rc);
- if (!proc_loop_wait) // Don't bother if wait_subproc is
- break; // exiting
/* Send a SIGCHLD to myself. We do this here, rather than in proc_subproc
to avoid the proc_subproc lock since the signal thread will eventually
diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc
index 7f6231e14..992bad1ab 100644
--- a/winsup/cygwin/spawn.cc
+++ b/winsup/cygwin/spawn.cc
@@ -745,7 +745,7 @@ spawn_guts (const char * prog_arg, const char *const *argv,
(void) sigprocmask (SIG_BLOCK, &child_block, &cleanup.oldmask);
}
- /* Fixup the parent datastructure if needed and resume the child's
+ /* Fixup the parent data structures if needed and resume the child's
main thread. */
if (!cygheap->fdtab.need_fixup_before ())
cygheap_setup_for_child_cleanup (newheap, &ciresrv, 0);
@@ -908,7 +908,6 @@ spawn_guts (const char * prog_arg, const char *const *argv,
{
case _P_OVERLAY:
ForceCloseHandle1 (pi.hProcess, childhProc);
- proc_terminate ();
myself->exit (res, 1);
break;
case _P_WAIT:
diff --git a/winsup/cygwin/tlsoffsets.h b/winsup/cygwin/tlsoffsets.h
index e1da0395a..af55081dc 100644
--- a/winsup/cygwin/tlsoffsets.h
+++ b/winsup/cygwin/tlsoffsets.h
@@ -1,96 +1,100 @@
//;# autogenerated: Do not edit.
-//; $tls::func = -3740;
+//; $tls::func = -3744;
//; $tls::pfunc = 0;
-//; $tls::saved_errno = -3736;
+//; $tls::saved_errno = -3740;
//; $tls::psaved_errno = 4;
-//; $tls::sa_flags = -3732;
+//; $tls::sa_flags = -3736;
//; $tls::psa_flags = 8;
-//; $tls::oldmask = -3728;
+//; $tls::oldmask = -3732;
//; $tls::poldmask = 12;
-//; $tls::newmask = -3724;
+//; $tls::newmask = -3728;
//; $tls::pnewmask = 16;
-//; $tls::event = -3720;
+//; $tls::event = -3724;
//; $tls::pevent = 20;
-//; $tls::errno_addr = -3716;
+//; $tls::errno_addr = -3720;
//; $tls::perrno_addr = 24;
-//; $tls::initialized = -3712;
+//; $tls::initialized = -3716;
//; $tls::pinitialized = 28;
-//; $tls::sigmask = -3708;
+//; $tls::sigmask = -3712;
//; $tls::psigmask = 32;
-//; $tls::sigwait_mask = -3704;
+//; $tls::sigwait_mask = -3708;
//; $tls::psigwait_mask = 36;
-//; $tls::sigwait_info = -3700;
+//; $tls::sigwait_info = -3704;
//; $tls::psigwait_info = 40;
-//; $tls::threadkill = -3696;
+//; $tls::threadkill = -3700;
//; $tls::pthreadkill = 44;
-//; $tls::infodata = -3692;
+//; $tls::infodata = -3696;
//; $tls::pinfodata = 48;
-//; $tls::tid = -3544;
+//; $tls::tid = -3548;
//; $tls::ptid = 196;
-//; $tls::local_clib = -3540;
+//; $tls::local_clib = -3544;
//; $tls::plocal_clib = 200;
-//; $tls::locals = -2612;
+//; $tls::locals = -2616;
//; $tls::plocals = 1128;
-//; $tls::prev = -1044;
+//; $tls::prev = -1048;
//; $tls::pprev = 2696;
-//; $tls::next = -1040;
+//; $tls::next = -1044;
//; $tls::pnext = 2700;
-//; $tls::stackptr = -1036;
+//; $tls::stackptr = -1040;
//; $tls::pstackptr = 2704;
-//; $tls::sig = -1032;
+//; $tls::sig = -1036;
//; $tls::psig = 2708;
-//; $tls::stacklock = -1028;
+//; $tls::stacklock = -1032;
//; $tls::pstacklock = 2712;
+//; $tls::spinning = -1028;
+//; $tls::pspinning = 2716;
//; $tls::stack = -1024;
-//; $tls::pstack = 2716;
+//; $tls::pstack = 2720;
//; $tls::padding = 0;
-//; $tls::ppadding = 3740;
+//; $tls::ppadding = 3744;
//; __DATA__
-#define tls_func (-3740)
+#define tls_func (-3744)
#define tls_pfunc (0)
-#define tls_saved_errno (-3736)
+#define tls_saved_errno (-3740)
#define tls_psaved_errno (4)
-#define tls_sa_flags (-3732)
+#define tls_sa_flags (-3736)
#define tls_psa_flags (8)
-#define tls_oldmask (-3728)
+#define tls_oldmask (-3732)
#define tls_poldmask (12)
-#define tls_newmask (-3724)
+#define tls_newmask (-3728)
#define tls_pnewmask (16)
-#define tls_event (-3720)
+#define tls_event (-3724)
#define tls_pevent (20)
-#define tls_errno_addr (-3716)
+#define tls_errno_addr (-3720)
#define tls_perrno_addr (24)
-#define tls_initialized (-3712)
+#define tls_initialized (-3716)
#define tls_pinitialized (28)
-#define tls_sigmask (-3708)
+#define tls_sigmask (-3712)
#define tls_psigmask (32)
-#define tls_sigwait_mask (-3704)
+#define tls_sigwait_mask (-3708)
#define tls_psigwait_mask (36)
-#define tls_sigwait_info (-3700)
+#define tls_sigwait_info (-3704)
#define tls_psigwait_info (40)
-#define tls_threadkill (-3696)
+#define tls_threadkill (-3700)
#define tls_pthreadkill (44)
-#define tls_infodata (-3692)
+#define tls_infodata (-3696)
#define tls_pinfodata (48)
-#define tls_tid (-3544)
+#define tls_tid (-3548)
#define tls_ptid (196)
-#define tls_local_clib (-3540)
+#define tls_local_clib (-3544)
#define tls_plocal_clib (200)
-#define tls_locals (-2612)
+#define tls_locals (-2616)
#define tls_plocals (1128)
-#define tls_prev (-1044)
+#define tls_prev (-1048)
#define tls_pprev (2696)
-#define tls_next (-1040)
+#define tls_next (-1044)
#define tls_pnext (2700)
-#define tls_stackptr (-1036)
+#define tls_stackptr (-1040)
#define tls_pstackptr (2704)
-#define tls_sig (-1032)
+#define tls_sig (-1036)
#define tls_psig (2708)
-#define tls_stacklock (-1028)
+#define tls_stacklock (-1032)
#define tls_pstacklock (2712)
+#define tls_spinning (-1028)
+#define tls_pspinning (2716)
#define tls_stack (-1024)
-#define tls_pstack (2716)
+#define tls_pstack (2720)
#define tls_padding (0)
-#define tls_ppadding (3740)
+#define tls_ppadding (3744)
diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h
index d8930f9c6..93cdceed2 100644
--- a/winsup/cygwin/winsup.h
+++ b/winsup/cygwin/winsup.h
@@ -197,7 +197,8 @@ enum exit_states
ES_TITLE,
ES_HUP_PGRP,
ES_HUP_SID,
- ES_TTY_TERMINATE
+ ES_TTY_TERMINATE,
+ ES_FINAL
};
extern exit_states exit_state;