Changeset 1617


Ignore:
Timestamp:
Nov 7, 2004, 10:33:03 AM (21 years ago)
Author:
bird
Message:

Debugging signals.

Location:
trunk/src/emx
Files:
3 added
1 deleted
23 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/emx/include/InnoTekLIBC/backend.h

    • Property cvs2svn:cvs-rev changed from 1.8 to 1.9
    r1616 r1617  
    3030#include <sys/cdefs.h>
    3131#include <sys/types.h>
     32#include <signal.h>
    3233#include <emx/io.h>
     34
    3335
    3436__BEGIN_DECLS
     
    446448
    447449
     450/** @defgroup   __libc_Back_signal      LIBC Backend - Signals
     451 * @{
     452 */
     453
     454/** @defgroup __libc_Back_signalRaise_return    __libc_back_signalRaise() returns.
     455 * These are only valid for positive return values.
     456 * @{ */
     457/** Try restart any interrupted system call. */
     458#define __LIBC_BSRR_RESTART     0x01
     459/** Go ahead interrupt system call in progress. */
     460#define __LIBC_BSRR_INTERRUPT   0x02
     461/** If set execution should be resumed. */
     462#define __LIBC_BSRR_CONTINUE    0x10
     463/** If set execution should not be resumed but the signal should be passed
     464 * on to the system. */
     465#define __LIBC_BSRR_PASSITON    0x20
     466/** If set the passed in SIGQUEUED structure was used. */
     467#define __LIBC_BSRR_USED_QUEUED 0x40
     468/** @} */
     469
     470/** @defgroup __libc_back_signalRaise_flags     __libc_back_signalRaise() flags.
     471 * @{ */
     472/** The signal is thread specific and must be delivered to the current thread. */
     473#define __LIBC_BSRF_THREAD      0x01
     474/** The signal was send from an unknown process. */
     475#define __LIBC_BSRF_EXTERNAL    0x02
     476/** The signal was generated by the hardware (i.e. CPUs and such). */
     477#define __LIBC_BSRF_HARDWARE    0x04
     478/** The signal should be queued. */
     479#define __LIBC_BSRF_QUEUED      0x08
     480/** @} */
     481
     482
     483/**
     484 * Raises a signal in the current process.
     485 *
     486 * @returns On success a flag mask out of the __LIBC_BSRR_* #defines is returned.
     487 * @returns On failure a negative error code (errno.h) is returned.
     488 * @param   iSignalNo           Signal to raise.
     489 * @param   pSigInfo            Pointer to signal info for this signal.
     490 *                              NULL is allowed.
     491 * @param   pvXcptOrQueued      Exception handler parameter list.
     492 *                              Or if __LIBC_BSRF_QUEUED is set, a pointer to locally malloced
     493 *                              SIGQUEUED node.
     494 * @param   fFlags              Flags of the #defines __LIBC_BSRF_* describing how to
     495 *                              deliver the signal.
     496 *
     497 * @remark  This Backend Signal API does NOT require the caller to own the signal semaphore.
     498 */
     499int __libc_Back_signalRaise(int iSignalNo, siginfo_t *pSigInfo, void *pvXcptOrQueued, unsigned fFlags);
     500
     501/**
     502 * Worker called after __libc_Back_signalRaise() was called with a
     503 * preallocated signal queue entry. This function will make sure
     504 * we're not ending up with too many heap allocated packets in the
     505 * free list.
     506 */
     507void __libc_Back_signalFreeWorker(void);
     508
     509/**
     510 * Send a signal to a process.
     511 *
     512 * @returns 0 on if signal sent.
     513 * @returns -errno on failure.
     514 *
     515 * @param   pid         Process Id of the process which the signal is to be sent to.
     516 * @param   iSignalNo   The signal to send.
     517 * @remark  This Backend Signal API does NOT require the caller to own the signal semaphore.
     518 */
     519int __libc_Back_signalSendPid(pid_t pid, int iSignalNo);
     520
     521/**
     522 * Verify the existance of another process and that the current process
     523 * is allowed to signal it.
     524 *
     525 * @return 0 on success.
     526 * @return -ESRCH if pid doesn't exist.
     527 * @return -EPERM if we aren't allowed to signal the pid.
     528 * @param   pid     Process Id for the process which we wanna signal.
     529 * @todo    Do EPERM check, no ideas here yet.
     530 * @remark  This Backend Signal API does NOT require the caller to own the signal semaphore.
     531 */
     532int __libc_Back_signalVerifyPid(pid_t pid);
     533
     534/**
     535 * Not implemented.
     536 *
     537 * @returns -ENOSYS.
     538 * @param   pgrp        Process group (positive).
     539 *                      0 means the process group of this process.
     540 *                      1 means all process in the system.
     541 * @param   iSignalNo   Signal to send to all the processes in the group.
     542 */
     543int __libc_Back_signalSendPGrp(pid_t pgrp, int iSignalNo);
     544
     545/**
     546 * Verify the existance of a process group and that the current process
     547 * is allowed to signal it.
     548 *
     549 * @return 0 on success.
     550 * @return -ESRCH if pgid doesn't exist.
     551 * @return -EPERM if we aren't allowed to signal the pgid.
     552 * @param   pgid    Process group id which the current process intend to signal.
     553 * @todo    Do EPERM check, no ideas here yet.
     554 * @remark  This Backend Signal API does NOT require the caller to own the signal semaphore.
     555 */
     556int __libc_Back_signalVerifyPGrp(pid_t pgid);
     557
     558/**
     559 * sigaction worker; queries and/or sets the action for a signal.
     560 *
     561 * @returns 0 on success.
     562 * @returns -Negative errno on failure.
     563 * @param   iSignalNo   Signal number.
     564 * @param   pSigAct     Pointer to new signal action.
     565 *                      If NULL no update is done.
     566 * @param   pSigActOld  Where to store the old signal action.
     567 *                      If NULL nothing is attempted stored.
     568 */
     569int __libc_Back_signalAction(int iSignalNo, const struct sigaction *pSigAct, struct sigaction *pSigActOld);
     570
     571/**
     572 * Changes and/or queries the alternative signal stack settings of a thread.
     573 *
     574 * @returns 0 on success.
     575 * @returns Negative error number (errno.h) on failure.
     576 * @param   pThrd       Thread which signal stack to change and/or query.
     577 * @param   pStack      New stack settings. (Optional)
     578 * @param   pOldStack   Old stack settings. (Optional)
     579 */
     580int __libc_Back_signalStack(__LIBC_PTHREAD pThrd, const stack_t *pStack, stack_t *pOldStack);
     581
     582/**
     583 * Block or unblock signal deliveries of a thread.
     584 *
     585 * @returns 0 on success.
     586 * @returns -1 and errno set to EINVAL on failure.
     587 * @param   pThrd       Thread to apply this to.
     588 * @param   iHow        Describes the action taken if pSigSetNew not NULL. Recognized
     589 *                      values are SIG_BLOCK, SIG_UNBLOCK or SIG_SETMASK.
     590 *
     591 *                      SIG_BLOCK means to or the sigset pointed to by pSigSetNew with
     592 *                          the signal mask for the current thread.
     593 *                      SIG_UNBLOCK means to and the 0 complement of the sigset pointed
     594 *                          to by pSigSetNew with the signal mask of the current thread.
     595 *                      SIG_SETMASK means to set the signal mask of the current thread
     596 *                          to the sigset pointed to by pSigSetNew.
     597 *
     598 * @param   pSigSetNew  Pointer to signal set which will be applied to the current
     599 *                      threads signal mask according to iHow. If NULL no change
     600 *                      will be made the the current threads signal mask.
     601 * @param   pSigSetOld  Where to store the current threads signal mask prior to applying
     602 *                      pSigSetNew to it. This parameter can be NULL.
     603 */
     604int __libc_Back_signalMask(__LIBC_PTHREAD pThrd, int iHow, const sigset_t * __restrict pSigSetNew, sigset_t * __restrict pSigSetOld);
     605
     606/** @} */
     607
    448608__END_DECLS
    449609
  • trunk/src/emx/include/InnoTekLIBC/logstrict.h

    • Property cvs2svn:cvs-rev changed from 1.9 to 1.10
    r1616 r1617  
    177177/** Mutex Semaphores. */
    178178#define __LIBC_LOG_GRP_MUTEX        13
    179 /** Signal APIs and events. */
     179/** Signal APIs and Events. */
    180180#define __LIBC_LOG_GRP_SIGNAL       14
    181181/** Environment APIs. */
     
    184184#define __LIBC_LOG_GRP_MMAN         16
    185185
     186/** Backend Signal APIs and Events. */
     187#define __LIBC_LOG_GRP_BACK_SIGNAL  20
    186188/** Backend Memory Mananger APIs. */
    187189#define __LIBC_LOG_GRP_BACK_MMAN    21
  • trunk/src/emx/include/InnoTekLIBC/sharedpm.h

    • Property cvs2svn:cvs-rev changed from 1.12 to 1.13
    r1616 r1617  
    279279    /** Creation timestamp. */
    280280    unsigned                    uTimestamp;
    281     /** Incoming signal queue.
    282      * This is a LIFO for speed and size. The receiving process will
    283      * process them in the correct order of course.
     281    /** Incoming signal queue (FIFO).
    284282     * For signals which aren't queable only one signal can be queued.
    285283     */
     
    289287     */
    290288    volatile unsigned           cSigsSent;
     289    /** Indicates that the process is a full featured LIBC process.
     290     * Untill this flag is set (atomically) it's not a good idea to
     291     * queue signals on the process since it won't have a signal handler
     292     * installed, and thus won't get to know about them.
     293     */
     294    volatile unsigned           fExeInited;
    291295
    292296    /** Reserved pool pointer field with default value 0. */
     
    649653
    650654/**
     655 * Marks the process as a full LIBC process.
     656 *
     657 * Up to this point it was just a process which LIBC happend to be loaded into.
     658 *
     659 * @returns 0 on success.
     660 * @returns Negative error code (errno.h) on failure.
     661 * @param   pSignal     Signal to queue.
     662 * @param   pid         Pid to queue it on.
     663 * @param   fQueued     Set if the signal type is queued.
     664 */
     665void    __libc_spmExeInited(void);
     666
     667/**
    651668 * Queues a signal on another process.
    652669 *
  • trunk/src/emx/include/sys/_sigset.h

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1616 r1617  
    3535 * @{
    3636 */
     37#define __SIGSET_CLONGS     2           /** Space for 64 signals. */
    3738#if __BSD_VISIBLE
    38 #define __SIGSET_CLONGS     2           /** Space for 64 signals. */
    3939#define __SIGSET_MAXSIGNALS 64          /** Maximum signals. */
    4040/** Check if the signal is valid. */
     
    7070        (result)->__bitmap[1] = (set1)->__bitmap[1] | (set2)->__bitmap[1]; \
    7171    } while (0)
    72 #endif
    7372/** @} */
     73#endif /* BSD_VISIBLE */
    7474
    7575/**
     
    8383
    8484#endif
     85
  • trunk/src/emx/include/sys/cdefs.h

    • Property cvs2svn:cvs-rev changed from 1.9 to 1.10
    r1616 r1617  
    1414 *    notice, this list of conditions and the following disclaimer in the
    1515 *    documentation and/or other materials provided with the distribution.
    16  * 3. All advertising materials mentioning features or use of this software
    17  *    must display the following acknowledgement:
    18  *      This product includes software developed by the University of
    19  *      California, Berkeley and its contributors.
    2016 * 4. Neither the name of the University nor the names of its contributors
    2117 *    may be used to endorse or promote products derived from this software
     
    3531 *
    3632 *      @(#)cdefs.h     8.8 (Berkeley) 1/9/95
    37  * $FreeBSD: src/sys/sys/cdefs.h,v 1.69 2003/04/18 18:59:34 bde Exp $
     33 * $FreeBSD: src/sys/sys/cdefs.h,v 1.81 2004/04/07 04:19:49 imp Exp $
    3834 */
    3935
    4036/** @file
    41  * FreeBSD 5.1
     37 * FreeBSD 5.2
    4238 *
    4339 * @changed bird: Toolkit compatibility (_CDEFS_H_ and __TCPROTO()).
     
    5854#define __BEGIN_DECLS
    5955#define __END_DECLS
     56#endif
     57
     58/*
     59 * Macro to test if we're using a specific version of gcc or later.
     60 */
     61#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
     62#define __GNUC_PREREQ__(ma, mi) \
     63        (__GNUC__ > (ma) || __GNUC__ == (ma) && __GNUC_MINOR__ >= (mi))
     64#else
     65#define __GNUC_PREREQ__(ma, mi) 0
    6066#endif
    6167
     
    8591#define __inline        inline          /* convert to C++ keyword */
    8692#else
    87 #ifndef __GNUC__
     93#if !(defined(__GNUC__) || defined(__INTEL_COMPILER))
    8894#define __inline                        /* delete GCC keyword */
    89 #endif /* !__GNUC__ */
     95#endif /* !(__GNUC__ || __INTEL_COMPILER) */
    9096#endif /* !__cplusplus */
    9197
     
    95101#define __STRING(x)     "x"
    96102
    97 #ifndef __GNUC__
     103#if !(defined(__GNUC__) || defined(__INTEL_COMPILER))
    98104#define __const                         /* delete pseudo-ANSI C keywords */
    99105#define __inline
     
    114120#define volatile
    115121#endif  /* !NO_ANSI_KEYWORDS */
    116 #endif  /* !__GNUC__ */
     122#endif  /* !(__GNUC__ || __INTEL_COMPILER) */
    117123#endif  /* !(__STDC__ || __cplusplus) */
    118124
     
    134140#define __section(x)
    135141#else
    136 #if __GNUC__ < 2 || __GNUC__ == 2 && __GNUC_MINOR__ < 5
     142#if !__GNUC_PREREQ__(2, 5) && !defined(__INTEL_COMPILER)
    137143#define __dead2
    138144#define __pure2
    139145#define __unused
    140146#endif
    141 #if __GNUC__ == 2 && __GNUC_MINOR__ >= 5 && __GNUC_MINOR__ < 7
     147#if __GNUC__ == 2 && __GNUC_MINOR__ >= 5 && __GNUC_MINOR__ < 7 && !defined(__INTEL_COMPILER)
    142148#define __dead2         __attribute__((__noreturn__))
    143149#define __pure2         __attribute__((__const__))
     
    145151/* XXX Find out what to do for __packed, __aligned and __section */
    146152#endif
    147 #if __GNUC__ == 2 && __GNUC_MINOR__ >= 7 || __GNUC__ == 3
     153#if __GNUC_PREREQ__(2, 7)
    148154#define __dead2         __attribute__((__noreturn__))
    149155#define __pure2         __attribute__((__const__))
     
    153159#define __section(x)    __attribute__((__section__(x)))
    154160#endif
     161#if defined(__INTEL_COMPILER)
     162#define __dead2         __attribute__((__noreturn__))
     163#define __pure2         __attribute__((__const__))
     164#define __unused        __attribute__((__unused__))
     165#define __packed        __attribute__((__packed__))
     166#define __aligned(x)    __attribute__((__aligned__(x)))
     167#define __section(x)    __attribute__((__section__(x)))
     168#endif
     169#endif
     170
     171#if __GNUC_PREREQ__(3, 1) || (defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 800)
     172#define __always_inline __attribute__((__always_inline__))
     173#else
     174#define __always_inline
     175#endif
     176
     177#if __GNUC_PREREQ__(3, 3)
     178#define __nonnull(x)    __attribute__((__nonnull__(x)))
     179#else
     180#define __nonnull(x)
    155181#endif
    156182
    157183/* XXX: should use `#if __STDC_VERSION__ < 199901'. */
    158 #if !(__GNUC__ == 2 && __GNUC_MINOR__ >= 7 || __GNUC__ >= 3)
     184#if !__GNUC_PREREQ__(2, 7) && !defined(__INTEL_COMPILER)
    159185#define __func__        NULL
    160186#endif
    161187
    162 #if __GNUC__ >= 2 && !defined(__STRICT_ANSI__) || __STDC_VERSION__ >= 199901
     188#if (defined(__INTEL_COMPILER) || (defined(__GNUC__) && __GNUC__ >= 2)) && !defined(__STRICT_ANSI__) || __STDC_VERSION__ >= 199901
    163189#define __LONG_LONG_SUPPORTED
    164190#endif
     
    171197 */
    172198#if !(__GNUC__ == 2 && __GNUC_MINOR__ == 95)
    173 #if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901 /* bird: check if not defined. (-pedantic) */
     199#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901
    174200#define __restrict
    175201#else
    176202#define __restrict      restrict
    177203#endif
     204#endif
     205
     206/*
     207 * GNU C version 2.96 adds explicit branch prediction so that
     208 * the CPU back-end can hint the processor and also so that
     209 * code blocks can be reordered such that the predicted path
     210 * sees a more linear flow, thus improving cache behavior, etc.
     211 *
     212 * The following two macros provide us with a way to utilize this
     213 * compiler feature.  Use __predict_true() if you expect the expression
     214 * to evaluate to true, and __predict_false() if you expect the
     215 * expression to evaluate to false.
     216 *
     217 * A few notes about usage:
     218 *
     219 *      * Generally, __predict_false() error condition checks (unless
     220 *        you have some _strong_ reason to do otherwise, in which case
     221 *        document it), and/or __predict_true() `no-error' condition
     222 *        checks, assuming you want to optimize for the no-error case.
     223 *
     224 *      * Other than that, if you don't know the likelihood of a test
     225 *        succeeding from empirical or other `hard' evidence, don't
     226 *        make predictions.
     227 *
     228 *      * These are meant to be used in places that are run `a lot'.
     229 *        It is wasteful to make predictions in code that is run
     230 *        seldomly (e.g. at subsystem initialization time) as the
     231 *        basic block reordering that this affects can often generate
     232 *        larger code.
     233 */
     234#if __GNUC_PREREQ__(2, 96)
     235#define __predict_true(exp)     __builtin_expect((exp), 1)
     236#define __predict_false(exp)    __builtin_expect((exp), 0)
     237#else
     238#define __predict_true(exp)     (exp)
     239#define __predict_false(exp)    (exp)
    178240#endif
    179241
     
    190252 * didn't permit keeping the keywords out of the application namespace).
    191253 */
    192 #if __GNUC__ < 2 || __GNUC__ == 2 && __GNUC_MINOR__ < 7
     254#if !__GNUC_PREREQ__(2, 7) && !defined(__INTEL_COMPILER)
    193255#define __printflike(fmtarg, firstvararg)
    194256#define __scanflike(fmtarg, firstvararg)
     
    201263
    202264/* Compiler-dependent macros that rely on FreeBSD-specific extensions. */
    203 #if defined(__FreeBSD_cc_version) && __FreeBSD_cc_version >= 300001 /* bird: check if defined to avoid -Wundef messages */
     265#if defined(__FreeBSD_cc_version) && __FreeBSD_cc_version >= 300001 && defined(__GNUC__) && !defined(__INTEL_COMPILER) /* bird: check if defined to avoid -Wundef messages */
    204266#define __printf0like(fmtarg, firstvararg) \
    205267            __attribute__((__format__ (__printf0__, fmtarg, firstvararg)))
     
    208270#endif
    209271
    210 #if 0 /* def __GNUC__ - bird: ELF specific, so skip everything */
     272#if 0 /* defined(__GNUC__) || defined(__INTEL_COMPILER) - bird: ELF specific, so skip everything */
     273#ifndef __INTEL_COMPILER
    211274#define __strong_reference(sym,aliassym)        \
    212275        extern __typeof (sym) aliassym __attribute__ ((__alias__ (#sym)));
     276#endif
    213277#ifdef __STDC__
    214278#define __weak_reference(sym,alias)     \
     
    228292        __asm__(".previous")
    229293#endif  /* __STDC__ */
    230 #endif  /* __GNUC__ */
    231 
    232 #if 0 /*def __GNUC__ - ELF specific. */
     294#endif  /* __GNUC__ || __INTEL_COMPILER */
     295
     296#if 0 /* defined(__GNUC__) || defined(__INTEL_COMPILER) - ELF specific. */
    233297#define __IDSTRING(name,string) __asm__(".ident\t\"" string "\"")
    234298#else
    235299/*
    236  * This doesn't work in header files. But it may be better than nothing.
    237  * The alternative is: #define __IDSTRING(name,string)  [nothing]
     300 * The following definition might not work well if used in header files,
     301 * but it should be better than nothing.  If you want a "do nothing"
     302 * version, then it should generate some harmless declaration, such as:
     303 *    #define __IDSTRING(name,string)   struct __hack
    238304 */
    239305#define __IDSTRING(name,string) static const char name[] __unused = string
     
    244310 * more recent ELF binutils, we use .ident allowing the ID to be stripped.
    245311 * Usage:
    246  *      __FBSDID("$FreeBSD: src/sys/sys/cdefs.h,v 1.69 2003/04/18 18:59:34 bde Exp $");
     312 *      __FBSDID("$FreeBSD: src/sys/sys/cdefs.h,v 1.81 2004/04/07 04:19:49 imp Exp $");
    247313 */
    248314#ifndef __FBSDID
     
    258324#define __RCSID(s)      __IDSTRING(__CONCAT(__rcsid_,__LINE__),s)
    259325#else
    260 #define __RCSID(s)
     326#define __RCSID(s)      struct __hack
    261327#endif
    262328#endif
     
    266332#define __RCSID_SOURCE(s)       __IDSTRING(__CONCAT(__rcsid_source_,__LINE__),s)
    267333#else
    268 #define __RCSID_SOURCE(s)
     334#define __RCSID_SOURCE(s)       struct __hack
    269335#endif
    270336#endif
     
    274340#define __SCCSID(s)     __IDSTRING(__CONCAT(__sccsid_,__LINE__),s)
    275341#else
    276 #define __SCCSID(s)
     342#define __SCCSID(s)     struct __hack
    277343#endif
    278344#endif
     
    282348#define __COPYRIGHT(s)  __IDSTRING(__CONCAT(__copyright_,__LINE__),s)
    283349#else
    284 #define __COPYRIGHT(s)
     350#define __COPYRIGHT(s)  struct __hack
    285351#endif
    286352#endif
     
    321387
    322388/* Deal with IEEE Std. 1003.1-1990, in which _POSIX_C_SOURCE == 1. */
    323 #if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE == 1 /* bird: check if defined to avoid -Wundef message. */
     389#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE == 1
    324390#undef _POSIX_C_SOURCE          /* Probably illegal, but beyond caring now. */
    325391#define _POSIX_C_SOURCE         199009
     
    327393
    328394/* Deal with IEEE Std. 1003.2-1992, in which _POSIX_C_SOURCE == 2. */
    329 #if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE == 2 /* bird: check if defined to avoid -Wundef message. */
     395#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE == 2
    330396#undef _POSIX_C_SOURCE
    331397#define _POSIX_C_SOURCE         199209
  • trunk/src/emx/include/sys/signal.h

    • Property cvs2svn:cvs-rev changed from 1.7 to 1.8
    r1616 r1617  
    5252#endif
    5353#define SIGILL    4     /** ANSI: Illegal instruction */
    54 #if __XSI_VISIBLE
     54#if __XSI_VISIBLE  || __POSIX_VISIBLE >= 200112
    5555#define SIGTRAP   5     /** POSIX: Single step (debugging) */
    5656#endif
     
    6868#endif
    6969#define SIGSEGV  11     /** ANSI: Segmentation fault */
    70 #if __BSD_VISIBLE
     70#if __BSD_VISIBLE || __POSIX_VISIBLE >= 200112
    7171#define SIGSYS   12     /** Invalid argument to system call */
    7272#endif
     
    9292#endif
    9393#if __XSI_VISIBLE
     94#define SIGPOLL  23     /** ??: Input/output possible signal. (Same as SIGIO.) */
     95#endif
     96#if __XSI_VISIBLE || __POSIX_VISIBLE >= 200112
    9497#define SIGXCPU  24     /** BSD 4.2: Exceeded CPU time limit. */
    9598#define SIGXFSZ  25     /** BSD 4.2: Exceeded file size limit. */
     99#endif
     100#if __XSI_VISIBLE
    96101#define SIGVTALRM 26    /** BSD 4.2: Virtual time alarm. */
     102#endif
     103#if __XSI_VISIBLE || __POSIX_VISIBLE >= 200112
    97104#define SIGPROF  27     /** BSD 4.2: Profiling time alarm. */
    98105#endif
     
    188195 * @{
    189196 */
    190 /** Deliver signal on alternate stack. */
     197/** Current on alternative stack. */
    191198#define SS_ONSTACK          0x00000001
    192199/** Do not take signal on alternate stack. */
     
    422429/** If set the signal was queue. */
    423430#define __LIBC_SI_QUEUED        0x00000001
     431/** Internal signal generated by LIBC. */
     432#define __LIBC_SI_INTERNAL      0x00000002
    424433/** @} */
    425434#endif
     
    452461};
    453462#define sa_handler      __sigaction_u.__sa_handler
     463#define sa_sigaction    __sigaction_u.__sa_sigaction
    454464#endif
    455465
  • trunk/src/emx/src/lib/libc.def

    • Property cvs2svn:cvs-rev changed from 1.74 to 1.75
    r1616 r1617  
    12351235    "___libc_Back_signalSendPGrp" @1257
    12361236    "___libc_Back_signalSendPid" @1258
     1237    "___libc_Back_signalAction" @1259
     1238    "___libc_Back_signalFreeWorker" @1260
     1239    "___libc_Back_signalStack" @1261
     1240    "___libc_Back_signalMask" @1262
  • trunk/src/emx/src/lib/process/kill.c

    • Property cvs2svn:cvs-rev changed from 1.4 to 1.5
    r1616 r1617  
    3131#include <signal.h>
    3232#include <errno.h>
    33 #include <InnoTekLIBC/signals.h>
     33#include <InnoTekLIBC/backend.h>
    3434#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_SIGNAL
    3535#include <InnoTekLIBC/logstrict.h>
  • trunk/src/emx/src/lib/process/raise.c

    • Property cvs2svn:cvs-rev changed from 1.3 to 1.4
    r1616 r1617  
    4242 * According to the standards this should only raise the signal in the
    4343 * current thread, however, FreeBSD libc and GLIBC both forwards this
    44  * call to kill(). We do the same to be compatible.
     44 * call to kill(). We do the same to be compatible. :-)
    4545 *
    4646 * @returns 0 on success.
  • trunk/src/emx/src/lib/process/sigaction.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1616 r1617  
    3232#include <signal.h>
    3333#include <errno.h>
    34 #include <InnoTekLIBC/signals.h>
     34#include <string.h>
     35#include <InnoTekLIBC/backend.h>
    3536#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_SIGNAL
    3637#include <InnoTekLIBC/logstrict.h>
     
    6061    struct sigaction    SigAct;
    6162    struct sigaction    SigActOld = {{0}};
    62     int                 rc;
    6363
    6464    /*
     
    8282        }
    8383        if (    SigAct.__sigaction_u.__sa_handler == SIG_ERR
    84             ||  SigAct.__sigaction_u.__sa_handler == SIG_ACK)
     84            ||  SigAct.__sigaction_u.__sa_handler == SIG_ACK
     85            ||  SigAct.__sigaction_u.__sa_handler == SIG_HOLD)
    8586        {
    8687            LIBC_ASSERTM_FAILED("Invalid sa_handler=%p\n", (void*)SigAct.__sigaction_u.__sa_handler);
     
    8990        }
    9091
    91         rc = 0;
     92        /*
     93         * Check if the address is around.
     94         */
    9295        if (    SigAct.__sigaction_u.__sa_handler != SIG_IGN
    93             &&  SigAct.__sigaction_u.__sa_handler != SIG_DFL
    94             &&  SigAct.__sigaction_u.__sa_handler != SIG_HOLD)
     96            &&  SigAct.__sigaction_u.__sa_handler != SIG_DFL)
    9597        {
    96             rc += *(char *)SigAct.__sigaction_u.__sa_handler; /* check if executable address */
     98            char ach[1];
     99            memcpy(&ach, (void *)SigAct.__sigaction_u.__sa_handler, sizeof(ach));  /* check if address is around. */
    97100        }
    98101    }
    99 
    100 
    101     /*
    102      * Gain exclusive access to the signal stuff.
    103      */
    104     if (__libc_back_signalSemRequest())
    105         LIBCLOG_RETURN_INT(-1);
    106102
    107103    /*
    108104     * Call backend worker.
    109105     */
    110     rc = __libc_back_signalAction(iSignalNo, pSigAct ? &SigAct : NULL, &SigActOld);
     106    int rc = __libc_Back_signalAction(iSignalNo, pSigAct ? &SigAct : NULL, &SigActOld);
     107    if (!rc)
     108    {
     109        if (pSigActOld)
     110            *pSigActOld = SigActOld;
    111111
    112     /*
    113      * Release semaphore.
    114      */
    115     __libc_back_signalSemRelease();
    116 
    117     /*
    118      * Check for errors, store result and return.
    119      */
    120     if (rc)
    121         LIBCLOG_RETURN_INT(-1);
    122 
    123     if (pSigActOld)
    124         *pSigActOld = SigActOld;
    125 
    126     LIBCLOG_RETURN_MSG(0, "ret 0 (*pSigActOld=%p {sa_handler=%p, sa_mask={%#08lx%#08lx}, sa_flags=%#x}\n",
    127                        (void *)pSigActOld,
    128                        (void *)SigActOld.__sigaction_u.__sa_sigaction,
    129                        SigActOld.sa_mask.__bitmap[0],
    130                        SigActOld.sa_mask.__bitmap[1],
    131                        SigActOld.sa_flags);
     112        LIBCLOG_RETURN_MSG(0, "ret 0 (*pSigActOld=%p {sa_handler=%p, sa_mask={%#08lx%#08lx}, sa_flags=%#x}\n",
     113                           (void *)pSigActOld,
     114                           (void *)SigActOld.__sigaction_u.__sa_sigaction,
     115                           SigActOld.sa_mask.__bitmap[0],
     116                           SigActOld.sa_mask.__bitmap[1],
     117                           SigActOld.sa_flags);
     118    }
     119    errno = -rc;
     120    LIBCLOG_RETURN_INT(-1);
    132121}
    133122
  • trunk/src/emx/src/lib/process/sigaltstack.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1616 r1617  
    3131#include <signal.h>
    3232#include <errno.h>
    33 #include <InnoTekLIBC/signals.h>
    3433#include <InnoTekLIBC/thread.h>
     34#include <InnoTekLIBC/backend.h>
    3535#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_SIGNAL
    3636#include <InnoTekLIBC/logstrict.h>
     
    3838
    3939
     40/**
     41 * Changes and/or queries the alternative signal stack
     42 * settings of the current thread.
     43 *
     44 * @returns 0 on success.
     45 * @returns Negative error number (errno.h) on failure.
     46 * @param   pThrd       Thread which signal stack to change and/or query.
     47 * @param   pStack      New stack settings. (Optional)
     48 * @param   pOldStack   Old stack settings. (Optional)
     49 */
    4050int _STD(sigaltstack)(const stack_t *pStack, stack_t *pOldStack)
    4151{
     
    4656                  pStack ? pStack->ss_size  : 0,
    4757                  (void *)pOldStack);
    48     __LIBC_THREAD  *pThrd = __libc_threadCurrent();
    49     stack_t         OldStack = {0};
    50     stack_t         Stack;
    51     int             rc = 0;
    5258
    5359    /*
    54      * Validate input.
     60     * Perform operation and return.
    5561     */
    56     if (pStack)
     62    stack_t OldStack;
     63    int rc = __libc_Back_signalStack(__libc_threadCurrent(), pStack, &OldStack);
     64    if (!rc)
    5765    {
    58         if (pStack->ss_flags & ~SS_DISABLE)
    59         {
    60             LIBC_ASSERTM_FAILED("ss_flags=%#x is invalid\n", pStack->ss_flags);
    61             errno = EINVAL;
    62             LIBCLOG_RETURN_INT(-1);
    63         }
    64         if (pStack->ss_flags != SS_DISABLE)
    65         {
    66             if (!pStack->ss_sp)
    67             {
    68                 LIBC_ASSERTM_FAILED("ss_sp=%p is NULL when SS_DISABLE is not set\n", pStack->ss_sp);
    69                 errno = EINVAL;
    70                 LIBCLOG_RETURN_INT(-1);
    71             }
    72             if (!pStack->ss_size < MINSIGSTKSZ)
    73             {
    74                 LIBC_ASSERTM_FAILED("ss_size=%d is too small. minimum size is %d\n", pStack->ss_size, MINSIGSTKSZ);
    75                 errno = ENOMEM;
    76                 LIBCLOG_RETURN_INT(-1);
    77             }
    78         }
     66        if (pOldStack)
     67            *pOldStack = OldStack;
     68        LIBCLOG_RETURN_MSG(0, "ret 0 (*pOldStack {ss_flags=%#x, ss_sp=%p, ss_size=%d}\n",
     69                           OldStack.ss_flags, OldStack.ss_sp, OldStack.ss_size);
    7970    }
    8071
    81     /*
    82      * Copy input.
    83      */
    84     if (pStack)
    85         Stack = *pStack;
     72    errno = -rc;
     73    LIBCLOG_RETURN_INT(-1);
     74}
    8675
    87     /*
    88      * Gain exclusive access to the signal stuff.
    89      */
    90     if (__libc_back_signalSemRequest())
    91         LIBCLOG_RETURN_INT(-1);
    92 
    93     /*
    94      * Get the old stack.
    95      */
    96     OldStack.ss_flags = pThrd->pvSigStack ? 0 : SS_DISABLE;
    97     if (pThrd->fSigStackActive)
    98         OldStack.ss_flags |= SS_ONSTACK;
    99     OldStack.ss_sp    = pThrd->pvSigStack;
    100     OldStack.ss_size  = pThrd->cbSigStack;
    101 
    102     /*
    103      * Change the stack.
    104      */
    105     if (pStack)
    106     {
    107         if (!pThrd->fSigStackActive)
    108         {
    109             if (Stack.ss_flags == SS_ONSTACK)
    110             {
    111                 pThrd->pvSigStack = Stack.ss_sp;
    112                 pThrd->cbSigStack = Stack.ss_size;
    113             }
    114             else
    115             {
    116                 pThrd->pvSigStack = NULL;
    117                 pThrd->cbSigStack = 0;
    118             }
    119         }
    120         else
    121             rc = EPERM;
    122     }
    123 
    124     /*
    125      * Release semaphore.
    126      */
    127     __libc_back_signalSemRelease();
    128 
    129 
    130     /*
    131      * Check for failure and return.
    132      */
    133     if (rc)
    134     {
    135         LIBC_ASSERTM_FAILED("Stack is in use\n");
    136         errno = rc;
    137         LIBCLOG_RETURN_INT(-1);
    138     }
    139 
    140     if (pOldStack)
    141         *pOldStack = OldStack;
    142 
    143     LIBCLOG_RETURN_MSG(0, "ret 0 (*pOldStack {ss_flags=%#x, ss_sp=%p, ss_size=%d}\n",
    144                        OldStack.ss_flags, OldStack.ss_sp, OldStack.ss_size);
    145 }
  • trunk/src/emx/src/lib/process/sigprocmask.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1616 r1617  
    3333#include <sys/_sigset.h>
    3434#include <errno.h>
    35 #include <InnoTekLIBC/signals.h>
    3635#include <InnoTekLIBC/thread.h>
     36#include <InnoTekLIBC/backend.h>
    3737#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_SIGNAL
    3838#include <InnoTekLIBC/logstrict.h>
     
    7070                  pSigSetNew ? pSigSetNew->__bitmap[1] : 0, pSigSetNew ? pSigSetNew->__bitmap[0] : 0,
    7171                  (void *)pSigSetOld);
    72     __LIBC_THREAD  *pThrd = __libc_threadCurrent();
    73     sigset_t        SigSetNew;
    74     sigset_t        SigSetOld;
    75     sigset_t        SigSet;
    7672
    7773    /*
    78      * Validate input.
    79      * ASSUMES SIG_BLOCK 1 and SIG_SETMASK 3.
     74     * Perform operation.
    8075     */
    81     if (iHow < SIG_BLOCK || iHow > SIG_SETMASK)
     76    sigset_t        SigSetOld;
     77    int rc = __libc_Back_signalMask(__libc_threadCurrent(), iHow, pSigSetNew, &SigSetOld);
     78    if (!rc)
    8279    {
    83         LIBC_ASSERTM_FAILED("iHow=%d is wrong\n", iHow);
    84         errno = EINVAL;
    85         LIBCLOG_RETURN_INT(-1);
     80        if (pSigSetOld)
     81            *pSigSetOld = SigSetOld;
     82
     83        LIBCLOG_RETURN_MSG(0, "ret 0 old={%08lx%08lx} new={%08lx%08lx}\n",
     84                           SigSetOld.__bitmap[1], SigSetOld.__bitmap[0],
     85                           SigSetNew.__bitmap[1], SigSetNew.__bitmap[0]);
    8686    }
     87    errno = -rc;
     88    LIBCLOG_RETURN_INT(-1);
     89}
    8790
    88 
    89     /*
    90      * Prepare action.
    91      * We make copies on the stack so we will not crash accessing
    92      * bogus stuff inside the signal mutex.
    93      */
    94     __SIGSET_EMPTY(&SigSetOld);         /* touch it. (paranoia) */
    95     if (pSigSetNew)
    96         SigSetNew = *pSigSetNew;
    97     else
    98         __SIGSET_EMPTY(&SigSetNew);
    99 
    100     /*
    101      * Gain exclusive access to the signal stuff.
    102      */
    103     if (__libc_back_signalSemRequest())
    104         LIBCLOG_RETURN_INT(-1);
    105 
    106     /*
    107      * Save old set of blocked signals and apply any changes.
    108      */
    109     SigSetOld = pThrd->SigSetBlocked;
    110     if (pSigSetNew)
    111     {
    112         switch (iHow)
    113         {
    114             case SIG_BLOCK:
    115                 __SIGSET_OR(&pThrd->SigSetBlocked, &pThrd->SigSetBlocked, &SigSetNew);
    116                 break;
    117 
    118             case SIG_UNBLOCK:
    119                 __SIGSET_NOT(&SigSetNew);
    120                 __SIGSET_AND(&pThrd->SigSetBlocked, &pThrd->SigSetBlocked, &SigSetNew);
    121                 break;
    122 
    123             case SIG_SETMASK:
    124                 pThrd->SigSetBlocked = SigSetNew;
    125                 break;
    126         }
    127 
    128         /*
    129          * Check if we've unblocked anything and thus made it possible for
    130          * pending signals to be delivered.
    131          */
    132         SigSetNew = pThrd->SigSetBlocked;
    133         __SIGSET_AND(&SigSet, &SigSetOld, &SigSetNew);
    134         if (!__SIGSET_ISEMPTY(&SigSetNew))
    135         {
    136             sigset_t    SigSetPending;
    137             __SIGSET_OR(&SigSetPending, &pThrd->SigSetPending, &__libc_gSignalPending);
    138             __SIGSET_AND(&SigSetPending, &SigSetPending, &SigSetNew);
    139             if (!__SIGSET_ISEMPTY(&SigSetPending))
    140                 __libc_back_signalPokeThread(0);
    141         }
    142     }
    143 
    144     /*
    145      * Release semaphore.
    146      */
    147     __libc_back_signalSemRelease();
    148 
    149     /*
    150      * Copy old signal set if requested.
    151      */
    152     if (pSigSetOld)
    153         *pSigSetOld = SigSetOld;
    154 
    155     LIBCLOG_MSG("old={%08lx%08lx} new={%08lx%08lx}\n",
    156                 SigSetOld.__bitmap[1], SigSetOld.__bitmap[0],
    157                 SigSetNew.__bitmap[1], SigSetNew.__bitmap[0]);
    158     LIBCLOG_RETURN_INT(0);
    159 }
  • trunk/src/emx/src/lib/sys/386/signal16bit.asm

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1616 r1617  
    7676
    7777    ; call 32-bit worker
    78     movzx   eax, word ptr [esp + (4 * 5) + (2 * 4) + 4] ; sig_arg
    79     movzx   edx, word ptr [esp + (4 * 5) + (2 * 4) + 6] ; sig_num
     78    movzx   eax, word ptr [esp + (4 * 5) + (2 * 4) + 6] ; sig_arg
     79    movzx   edx, word ptr [esp + (4 * 5) + (2 * 4) + 4] ; sig_num
    8080    push    eax
    8181    push    edx
  • trunk/src/emx/src/lib/sys/__init.c

    • Property cvs2svn:cvs-rev changed from 1.16 to 1.17
    r1616 r1617  
    171171        char **                       envp;
    172172        /** Exception handler registration record (*_sys_xreg). */
    173         EXCEPTIONREGISTRATIONRECORD   ExcpRegReg;
     173        EXCEPTIONREGISTRATIONRECORD   ExcpRegRec;
    174174        /** Argument vector. */
    175175        char *                        apszArg[1];
     
    180180    PPIB      ppib;
    181181    int       cb;
    182     ULONG     times;
    183182
    184183    /*
     
    225224
    226225    /*
    227      * Install exception handler.
    228      */
    229     pStackFrame->ExcpRegReg.prev_structure   = END_OF_CHAIN;
    230     pStackFrame->ExcpRegReg.ExceptionHandler = __libc_Back_exceptionHandler;
    231     rc = DosSetExceptionHandler(&pStackFrame->ExcpRegReg);
    232     if (rc != 0)
    233         goto failure;
    234 
    235     /* DosSetSignalExceptionFocus fails for PM programs, error code 303 */
    236     DosSetSignalExceptionFocus(SIG_SETFOCUS, &times);
    237 
    238     /*
    239      * Install 16-bit signal handler.
    240      */
    241     rc = DosSetSigHandler((PFNSIGHANDLER)__libc_back_signalOS2V1Handler16bit, NULL, NULL, SIGA_ACCEPT, SIG_PFLG_C);
     226     * Install exception handler, 16-bit signal handler and set signal focus.
     227     */
     228    rc = __libc_back_signalInitExe(&pStackFrame->ExcpRegRec);
    242229    if (rc)
    243     {
    244         LIBC_ASSERTM_FAILED("DosSetSigHandler failed with rc=%d\n", rc);
    245         goto failure;
    246     }
    247 
     230        goto failure;
     231
     232    /*
     233     * Mark the process as a completely inited LIBC process.
     234     */
     235    __libc_spmExeInited();
    248236
    249237    /* Return to the program. */
  • trunk/src/emx/src/lib/sys/__select.c

    • Property cvs2svn:cvs-rev changed from 1.5 to 1.6
    r1616 r1617  
    3838#include "syscalls.h"
    3939
     40
     41static int __select_wait(struct timeval *tv)
     42{
     43    /*
     44     * Wait.
     45     */
     46    FS_VAR();
     47    FS_SAVE_LOAD();
     48    int rc;
     49    if (!tv)
     50        rc = DosSleep(~0);
     51    else
     52    {
     53        ULONG cMillies = tv->tv_sec * 1000 + tv->tv_usec / 1000;
     54        if (!cMillies && tv->tv_usec)
     55            cMillies = 1;
     56        rc = DosSleep(cMillies);
     57    }
     58    FS_RESTORE();
     59
     60    /*
     61     * Return.
     62     */
     63    if (!rc)
     64        return 0;
     65    errno = __libc_native2errno(rc);
     66    return -1;
     67}
     68
    4069int __select(int nfds, struct fd_set *readfds, struct fd_set *writefds,
    4170             struct fd_set *exceptfds, struct timeval *tv)
     
    4877    int rc2 = -1;
    4978    int i;
     79
     80    /*
     81     * Wait operation?
     82     */
     83    if (!readfds && !writefds && !exceptfds)
     84        return __select_wait(tv);
     85
    5086
    5187    /*
  • trunk/src/emx/src/lib/sys/b_signalSendPGrp.c

    • Property cvs2svn:cvs-rev changed from 1.2 to 1.3
    r1616 r1617  
    3737#include <signal.h>
    3838#include <errno.h>
    39 #include <InnoTekLIBC/signals.h>
     39#include <InnoTekLIBC/backend.h>
     40#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_BACK_SIGNAL
     41#include <InnoTekLIBC/logstrict.h>
    4042#include "syscalls.h"
    41 #define __LIBC_LOG_GROUP __LIBC_LOG_GRP_SIGNAL
    42 #include <InnoTekLIBC/logstrict.h>
    4343
    4444
  • trunk/src/emx/src/lib/sys/b_signalSendPid.c

    • Property cvs2svn:cvs-rev changed from 1.2 to 1.3
    r1616 r1617  
    3737#include <signal.h>
    3838#include <errno.h>
    39 #include <InnoTekLIBC/signals.h>
     39#include <InnoTekLIBC/backend.h>
     40#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_BACK_SIGNAL
     41#include <InnoTekLIBC/logstrict.h>
    4042#include "syscalls.h"
    41 #define __LIBC_LOG_GROUP __LIBC_LOG_GRP_SIGNAL
    42 #include <InnoTekLIBC/logstrict.h>
    4343
    4444
     
    7676     */
    7777    if (_sys_pid != pid)
    78         rc = __libc_back_signalSendPidOther(pid, iSignalNo);
     78        rc = __libc_back_signalSendPidOther(pid, iSignalNo, NULL);
    7979    else
    8080    {
  • trunk/src/emx/src/lib/sys/b_signalVerifyPGrp.c

    • Property cvs2svn:cvs-rev changed from 1.2 to 1.3
    r1616 r1617  
    2929*   Header Files                                                               *
    3030*******************************************************************************/
     31#include "libc-alias.h"
    3132#define INCL_BASE
    3233#define INCL_FSMACROS
     
    3536#include <signal.h>
    3637#include <errno.h>
    37 #include <InnoTekLIBC/signals.h>
    38 #define __LIBC_LOG_GROUP __LIBC_LOG_GRP_SIGNAL
     38#include <InnoTekLIBC/backend.h>
     39#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_BACK_SIGNAL
    3940#include <InnoTekLIBC/logstrict.h>
    4041
  • trunk/src/emx/src/lib/sys/b_signalVerifyPid.c

    • Property cvs2svn:cvs-rev changed from 1.2 to 1.3
    r1616 r1617  
    2929*   Header Files                                                               *
    3030*******************************************************************************/
     31#include "libc-alias.h"
    3132#define INCL_BASE
    3233#define INCL_FSMACROS
     
    3536#include <signal.h>
    3637#include <errno.h>
    37 #include <InnoTekLIBC/signals.h>
    38 #define __LIBC_LOG_GROUP __LIBC_LOG_GRP_SIGNAL
     38#include <InnoTekLIBC/backend.h>
     39#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_BACK_SIGNAL
    3940#include <InnoTekLIBC/logstrict.h>
    4041
  • trunk/src/emx/src/lib/sys/libcfork.c

    • Property cvs2svn:cvs-rev changed from 1.7 to 1.8
    r1616 r1617  
    10681068     */
    10691069    _fmutex_release(&__libc_gmtxExec);
     1070    __libc_spmExeInited();
    10701071    LIBCLOG_RETURN_INT(0);
    10711072}
  • trunk/src/emx/src/lib/sys/logstrict.c

    • Property cvs2svn:cvs-rev changed from 1.17 to 1.18
    r1616 r1617  
    448448            { 1, "future" },            /* 18 */
    449449            { 1, "future" },            /* 19 */
    450             { 1, "future" },            /* 20 */
     450            { 1, "BACK_SIGNAL" },       /* 20 */
    451451            { 1, "BACK_MMAN" },         /* 21 */
    452452            { 1, "BACK_LDR" },          /* 22 */
  • trunk/src/emx/src/lib/sys/sharedpm.c

    • Property cvs2svn:cvs-rev changed from 1.13 to 1.14
    r1616 r1617  
    879879
    880880/**
    881  * Queues a signal on another process.
     881 * Marks the process as a full LIBC process.
     882 *
     883 * Up to this point it was just a process which LIBC happend to be loaded into.
    882884 *
    883885 * @returns 0 on success.
     
    887889 * @param   fQueued     Set if the signal type is queued.
    888890 */
     891void    __libc_spmExeInited(void)
     892{
     893    __atomic_xchg(&gpSPMSelf->fExeInited, 1);
     894    return 0;
     895}
     896
     897
     898/**
     899 * Queues a signal on another process.
     900 *
     901 * @returns 0 on success.
     902 * @returns Negative error code (errno.h) on failure.
     903 * @param   pSignal     Signal to queue.
     904 * @param   pid         Pid to queue it on.
     905 * @param   fQueued     Set if the signal type is queued.
     906 */
    889907int     __libc_spmSigQueue(siginfo_t *pSignal, pid_t pid, int fQueued)
    890908{
     
    915933
    916934    /*
    917      * Find pid.
     935     * Find pid and check that it's capable of catching signals.
    918936     */
    919937    __LIBC_PSPMPROCESS pProcess = spmQueryProcessInState(pid, __LIBC_PROCSTATE_ALIVE);
    920     if (pProcess)
     938    if (pProcess && pProcess->fExeInited)
    921939    {
    922940        /*
     
    948966                    __LIBC_PSPMSIGNAL pPrev = NULL;
    949967                    for (pSig = gpSPMHdr->pSigFreeHead; pSig; pPrev = pSig, pSig = pSig->pNext)
     968                    {
    950969                        if (pSig->cb == sizeof(*pSig))
    951970                        {
     
    957976                            break;
    958977                        }
     978                    }
    959979                }
    960980                if (!pSig)
     
    964984                        pSig->cb = sizeof(*pSig);
    965985                }
     986
    966987                /*
    967988                 * Copy the data and insert it into the queue.
     
    972993                    pSig->pidSender = gpSPMSelf->pid;
    973994                    pSig->Info      = *pSignal;
    974 
    975                     /* insert */
     995                    if (fQueued)
     996                        pSig->Info.si_flags |= __LIBC_SI_QUEUED;
     997                    else
     998                        pSig->Info.si_flags &= ~__LIBC_SI_QUEUED;
     999
     1000                    /* insert (FIFO) */
    9761001                    if (!pProcess->pSigHead)
    9771002                        pProcess->pSigHead = pSig;
     
    10431068
    10441069    /*
    1045      * De-queue signals one-by-one.
     1070     * Walk thru the queued signals creating the pending signal set
     1071     * and signal count.
    10461072     */
    10471073    __LIBC_PSPMSIGNAL pSig = gpSPMSelf->pSigHead;
     
    10751101     * Validate input.
    10761102     */
    1077     if (sizeof(siginfo_t) > cbSignal)
     1103    if (cbSignal < sizeof(siginfo_t))
    10781104    {
    10791105        LIBC_ASSERTM_FAILED("Invalid siginfo_t size: cbSignal=%d sizeof(siginfo_t)=%d\n", cbSignal, sizeof(siginfo_t));
     
    10981124    {
    10991125        /*
    1100          * Find it.
     1126         * Walk to the next signal of the right sort (if any).
    11011127         */
    11021128        while (pSig && pSig->Info.si_signo != iSignalNo)
     
    11291155
    11301156        /* unlink */
     1157        __LIBC_PSPMSIGNAL pSigNext = pSig->pNext;
    11311158        if (pSigPrev)
    1132             pSigPrev->pNext = pSig->pNext;
     1159            pSigPrev->pNext = pSigNext;
    11331160        else
    1134             gpSPMSelf->pSigHead = pSig->pNext;
     1161            gpSPMSelf->pSigHead = pSigNext;
    11351162
    11361163        /* free */
    1137         __LIBC_PSPMSIGNAL pSigNext = pSig->pNext;
    11381164        if (gpSPMHdr->cSigFree < 32)
    11391165        {
  • trunk/src/emx/src/lib/sys/signals.c

    • Property cvs2svn:cvs-rev changed from 1.3 to 1.4
    r1616 r1617  
    7777#include <string.h>
    7878#include <malloc.h>
     79#include <386/builtin.h>
     80#include <InnoTekLIBC/thread.h>
     81#include <InnoTekLIBC/fork.h>
     82#include <InnoTekLIBC/backend.h>
     83#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_BACK_SIGNAL
     84#include <InnoTekLIBC/logstrict.h>
    7985#include "syscalls.h"
    80 #include <386/builtin.h>
    81 #include <InnoTekLIBC/signals.h>
    82 #include <InnoTekLIBC/thread.h>
    83 #define __LIBC_LOG_GROUP __LIBC_LOG_GRP_SIGNAL
    84 #include <InnoTekLIBC/logstrict.h>
     86#include "signals.h"
    8587
    8688
     
    128130/** Property: Anything can service this signal. */
    129131#define SPP_ANYTHRD     0x0400
     132/** Property: Only thread 1 can service this signal. */
     133#define SPP_THRDONE     0x0800
    130134/** Property: This signal can be queued. */
    131 #define SPP_QUEUED      0x0800
     135#define SPP_QUEUED      0x1000
    132136/** Property: Signal action cannot be automatically reset in SysV fashion. */
    133 #define SPP_NORESET     0x1000
     137#define SPP_NORESET     0x2000
    134138/** @} */
    135139
     
    222226static HEV              ghevWait;
    223227
     228static const char gaszSignalNames[__SIGSET_MAXSIGNALS][12] =
     229{
     230    "SIG0",                             /* SIG0 */
     231    "SIGHUP",                           /* SIGHUP    1     /-- POSIX: Hangup */
     232    "SIGINT",                           /* SIGINT    2     /-- ANSI: Interrupt (Ctrl-C) */
     233    "SIGQUIT",                          /* SIGQUIT   3     /-- POSIX: Quit */
     234    "SIGILL",                           /* SIGILL    4     /-- ANSI: Illegal instruction */
     235    "SIGTRAP",                          /* SIGTRAP   5     /-- POSIX: Single step (debugging) */
     236    "SIGABRT",                          /* SIGABRT   6     /-- ANSI: abort () */
     237    "SIGEMT",                           /* SIGEMT    7     /-- BSD: EMT instruction */
     238    "SIGFPE",                           /* SIGFPE    8     /-- ANSI: Floating point */
     239    "SIGKILL",                          /* SIGKILL   9     /-- POSIX: Kill process */
     240    "SIGBUS",                           /* SIGBUS   10     /-- BSD 4.2: Bus error */
     241    "SIGSEGV",                          /* SIGSEGV  11     /-- ANSI: Segmentation fault */
     242    "SIGSYS",                           /* SIGSYS   12     /-- Invalid argument to system call */
     243    "SIGPIPE",                          /* SIGPIPE  13     /-- POSIX: Broken pipe. */
     244    "SIGALRM",                          /* SIGALRM  14     /-- POSIX: Alarm. */
     245    "SIGTERM",                          /* SIGTERM  15     /-- ANSI: Termination, process killed */
     246    "SIGURG",                           /* SIGURG   16     /-- POSIX/BSD: urgent condition on IO channel */
     247    "SIGSTOP",                          /* SIGSTOP  17     /-- POSIX: Sendable stop signal not from tty. unblockable. */
     248    "SIGTSTP",                          /* SIGTSTP  18     /-- POSIX: Stop signal from tty. */
     249    "SIGCONT",                          /* SIGCONT  19     /-- POSIX: Continue a stopped process. */
     250    "SIGCHLD",                          /* SIGCHLD  20     /-- POSIX: Death or stop of a child process. (EMX: 18) */
     251    "SIGTTIN",                          /* SIGTTIN  21     /-- POSIX: To readers pgrp upon background tty read. */
     252    "SIGTTOU",                          /* SIGTTOU  22     /-- POSIX: To readers pgrp upon background tty write. */
     253    "SIGIO",                            /* SIGIO    23     /-- BSD: Input/output possible signal. */
     254    "SIGXCPU",                          /* SIGXCPU  24     /-- BSD 4.2: Exceeded CPU time limit. */
     255    "SIGXFSZ",                          /* SIGXFSZ  25     /-- BSD 4.2: Exceeded file size limit. */
     256    "SIGVTALRM",                        /* SIGVTALRM 26    /-- BSD 4.2: Virtual time alarm. */
     257    "SIGPROF",                          /* SIGPROF  27     /-- BSD 4.2: Profiling time alarm. */
     258    "SIGWINCH",                         /* SIGWINCH 28     /-- BSD 4.3: Window size change (not implemented). */
     259    "SIGBREAK",                         /* SIGBREAK 29     /-- OS/2: Break (Ctrl-Break). (EMX: 21) */
     260    "SIGUSR1",                          /* SIGUSR1  30     /-- POSIX: User-defined signal #1 */
     261    "SIGUSR2",                          /* SIGUSR2  31     /-- POSIX: User-defined signal #2 */
     262    "SIGBREAK",                         /* SIGBREAK 32     /-- OS/2: Break (Ctrl-Break). (EMX: 21) */
     263
     264    "SIGRT0",                           /* SIGRTMIN +  0 */
     265    "SIGRT1",                           /* SIGRTMIN +  1 */
     266    "SIGRT2",                           /* SIGRTMIN +  2 */
     267    "SIGRT3",                           /* SIGRTMIN +  3 */
     268    "SIGRT4",                           /* SIGRTMIN +  4 */
     269    "SIGRT5",                           /* SIGRTMIN +  5 */
     270    "SIGRT6",                           /* SIGRTMIN +  6 */
     271    "SIGRT7",                           /* SIGRTMIN +  7 */
     272    "SIGRT8",                           /* SIGRTMIN +  8 */
     273    "SIGRT9",                           /* SIGRTMIN +  9 */
     274    "SIGRT10",                          /* SIGRTMIN + 10 */
     275    "SIGRT11",                          /* SIGRTMIN + 11 */
     276    "SIGRT12",                          /* SIGRTMIN + 12 */
     277    "SIGRT13",                          /* SIGRTMIN + 13 */
     278    "SIGRT14",                          /* SIGRTMIN + 14 */
     279    "SIGRT15",                          /* SIGRTMIN + 15 */
     280    "SIGRT16",                          /* SIGRTMIN + 16 */
     281    "SIGRT17",                          /* SIGRTMIN + 17 */
     282    "SIGRT18",                          /* SIGRTMIN + 18 */
     283    "SIGRT19",                          /* SIGRTMIN + 19 */
     284    "SIGRT20",                          /* SIGRTMIN + 20 */
     285    "SIGRT21",                          /* SIGRTMIN + 21 */
     286    "SIGRT22",                          /* SIGRTMIN + 22 */
     287    "SIGRT23",                          /* SIGRTMIN + 23 */
     288    "SIGRT24",                          /* SIGRTMIN + 24 */
     289    "SIGRT25",                          /* SIGRTMIN + 25 */
     290    "SIGRT26",                          /* SIGRTMIN + 26 */
     291    "SIGRT27",                          /* SIGRTMIN + 27 */
     292    "SIGRT28",                          /* SIGRTMIN + 28 */
     293    "SIGRT29",                          /* SIGRTMIN + 29 */
     294    "SIGRT30",                          /* SIGRTMIN + 30 == SIGRTMAX */
     295};
     296
    224297/** Signal Properties.
    225298 * Describes the default actions of a signal.
     
    234307    SPR_CONTINUE | SPA_NEXT_CORE | SPP_NORESET,                         /* SIGILL    4     /-- ANSI: Illegal instruction */
    235308    SPR_CONTINUE | SPA_NEXT_KILL | SPP_NORESET,                         /* SIGTRAP   5     /-- POSIX: Single step (debugging) */
    236     SPR_KILL    | SPA_CORE,                                            /* SIGABRT   6     /-- ANSI: abort () */
     309    SPR_CONTINUE | SPA_CORE,                                            /* SIGABRT   6     /-- ANSI: abort () */
    237310    SPR_CONTINUE | SPA_CORE    | SPP_ANYTHRD,                           /* SIGEMT    7     /-- BSD: EMT instruction */
    238311    SPR_CONTINUE | SPA_NEXT_CORE,                                       /* SIGFPE    8     /-- ANSI: Floating point */
     
    245318    SPR_CONTINUE | SPA_NEXT_KILL | SPP_ANYTHRD,                         /* SIGTERM  15     /-- ANSI: Termination, process killed */
    246319    SPR_CONTINUE | SPA_IGNORE,                                          /* SIGURG   16     /-- POSIX/BSD: urgent condition on IO channel */
    247     SPR_CONTINUE | SPA_STOP | SPP_ANYTHRD | SPP_NOBLOCK | SPP_NOCATCH,  /* SIGSTOP  17     /-- POSIX: Sendable stop signal not from tty. unblockable. */
    248     SPR_CONTINUE | SPA_STOPTTY | SPP_ANYTHRD,                           /* SIGTSTP  18     /-- POSIX: Stop signal from tty. */
    249     SPR_CONTINUE | SPA_RESUME  | SPP_ANYTHRD,                           /* SIGCONT  19     /-- POSIX: Continue a stopped process. */
     320    SPR_CONTINUE | SPA_STOP | SPP_THRDONE | SPP_NOBLOCK | SPP_NOCATCH,  /* SIGSTOP  17     /-- POSIX: Sendable stop signal not from tty. unblockable. */
     321    SPR_CONTINUE | SPA_STOPTTY | SPP_THRDONE,                           /* SIGTSTP  18     /-- POSIX: Stop signal from tty. */
     322    SPR_CONTINUE | SPA_RESUME  | SPP_THRDONE,                           /* SIGCONT  19     /-- POSIX: Continue a stopped process. */
    250323    SPR_CONTINUE | SPA_IGNORE  | SPP_ANYTHRD | SPP_QUEUED,              /* SIGCHLD  20     /-- POSIX: Death or stop of a child process. (EMX: 18) */
    251     SPR_CONTINUE | SPA_STOPTTY | SPP_ANYTHRD,                           /* SIGTTIN  21     /-- POSIX: To readers pgrp upon background tty read. */
    252     SPR_CONTINUE | SPA_STOPTTY | SPP_ANYTHRD,                           /* SIGTTOU  22     /-- POSIX: To readers pgrp upon background tty write. */
     324    SPR_CONTINUE | SPA_STOPTTY | SPP_THRDONE,                           /* SIGTTIN  21     /-- POSIX: To readers pgrp upon background tty read. */
     325    SPR_CONTINUE | SPA_STOPTTY | SPP_THRDONE,                           /* SIGTTOU  22     /-- POSIX: To readers pgrp upon background tty write. */
    253326    SPR_CONTINUE | SPA_IGNORE  | SPP_ANYTHRD,                           /* SIGIO    23     /-- BSD: Input/output possible signal. */
    254327    SPR_CONTINUE | SPA_KILL,                                            /* SIGXCPU  24     /-- BSD 4.2: Exceeded CPU time limit. */
     
    294367    SPR_CONTINUE | SPA_CORE | SPP_ANYTHRD | SPP_QUEUED,                 /* SIGRTMIN + 30 == SIGRTMAX */
    295368};
     369
    296370
    297371/** The signal actions for all signals in the system.
     
    459533static unsigned     gcSigQueuedFree = sizeof(gpaSigQueuedPreAlloced) / sizeof(gpaSigQueuedPreAlloced[0]);
    460534
     535/** Flag indicating that this LIBC instance have installed the signal handler.
     536 * This is used during fork so that the child will behave like the parent. */
     537static int gfOS2V1Handler = 0;
     538
    461539
    462540/*******************************************************************************
     
    473551static int              signalDeliver(__LIBC_PTHREAD pThrd, int iSignalNo, void *pvXcptParams);
    474552static void             signalTerminate(int iSignalNo) __dead2;
     553static void             signalTerminateAbnormal(int iSignalNo) __dead2;
     554static int              signalTerminateHex(char *pszBuf, unsigned u);
    475555static int              signalJobStop(int iSignalNo);
    476556static int              signalJobResume(void);
    477 static void             signalPokeThread(__LIBC_PTHREAD pThrdPoke);
    478557static int              signalActionWorker(__LIBC_PTHREAD pCur, void *pvParam);
    479558static unsigned         signalTimestamp(void);
     559static int              signalForkChild(__LIBC_PFORKHANDLE pForkHandle, __LIBC_FORKOP enmOperation);
    480560
    481561
     
    521601    FS_RESTORE();
    522602    LIBCLOG_RETURN_INT(-1);
     603}
     604
     605
     606/**
     607 * Main/exe init - install exception and signals handlers, and set signal focus.
     608 *
     609 * @returns 0 on success.
     610 * @returns Negative error code (errno.h) on failure.
     611 * @param   pvRegRec    Pointer to the exception registartion record to use.
     612 */
     613int __libc_back_signalInitExe(void *pvRegRec)
     614{
     615    LIBCLOG_ENTER("\n");
     616
     617    /*
     618     * Exception handler.
     619     */
     620    PEXCEPTIONREGISTRATIONRECORD pRegRec = (PEXCEPTIONREGISTRATIONRECORD)pvRegRec;
     621    pRegRec->prev_structure   = END_OF_CHAIN;
     622    pRegRec->ExceptionHandler = __libc_Back_exceptionHandler;
     623    int rc = DosSetExceptionHandler(pRegRec);
     624
     625    /*
     626     * Signal handling.
     627     */
     628    rc = DosSetSigHandler((PFNSIGHANDLER)__libc_back_signalOS2V1Handler16bit, NULL, NULL, SIGA_ACCEPT, SIG_PFLG_A);
     629    if (!rc)
     630    {
     631        gfOS2V1Handler = 1;
     632        ULONG cTimes = 0;
     633        DosSetSignalExceptionFocus(SIG_SETFOCUS, &cTimes); /* (Will fail with rc 303 for PM apps - which we ignore.) */
     634        LIBCLOG_RETURN_INT(0);
     635    }
     636    LIBC_ASSERTM_FAILED("DosSetSigHandler failed with rc=%d\n", rc);
     637    rc = -__libc_native2errno(rc);
     638    LIBCLOG_RETURN_INT(rc);
    523639}
    524640
     
    665781
    666782/**
     783 * Worker called after __libc_Back_signalRaise() was called with a
     784 * preallocated signal queue entry. This function will make sure
     785 * we're not ending up with too many heap allocated packets in the
     786 * free list.
     787 */
     788void __libc_Back_signalFreeWorker(void)
     789{
     790    LIBCLOG_ENTER("\n");
     791    if (gcSigQueuedFree > sizeof(gpaSigQueuedPreAlloced) * 2 / sizeof(gpaSigQueuedPreAlloced[0]))
     792    {
     793        if (!__libc_back_signalSemRequest())
     794        {
     795            /*
     796             * Free nodes which was allocated from the heap until we're below the water line.
     797             */
     798            PSIGQUEUED pSigPrev = NULL;
     799            PSIGQUEUED pSig = gpSigQueuedFree;
     800            int cToMany = gcSigQueuedFree - sizeof(gpaSigQueuedPreAlloced) * 2 / sizeof(gpaSigQueuedPreAlloced[0]);
     801            while (cToMany > 0)
     802            {
     803                if (pSig->enmHowFree == enmHowFree_HeapFree)
     804                {
     805                    /* unlink */
     806                    PSIGQUEUED pSigNext = pSig->pNext;
     807                    if (pSigPrev)
     808                        pSigPrev->pNext = pSigNext;
     809                    else
     810                        gpSigQueuedFree = pSigNext;
     811
     812                    /* free */
     813                    free(pSig);
     814
     815                    /* next */
     816                    pSig = pSigNext;
     817                }
     818                else
     819                {
     820                    pSigPrev = pSig;
     821                    pSig = pSig->pNext;
     822                }
     823            }
     824            __libc_back_signalSemRelease();
     825        }
     826    }
     827    LIBCLOG_RETURN_VOID();
     828}
     829
     830
     831/**
    667832 * Raises a signal in the current process.
    668833 *
     
    682847int __libc_Back_signalRaise(int iSignalNo, siginfo_t *pSigInfo, void *pvXcptOrQueued, unsigned fFlags)
    683848{
    684     LIBCLOG_ENTER("iSignalNo=%d pSigInfo=%p pvXcptOrQueued=%p fFlags=%#x\n",
    685                   iSignalNo, (void *)pSigInfo, (void *)pvXcptOrQueued, fFlags);
     849    LIBCLOG_ENTER("iSignalNo=%d pSigInfo=%p{.si_signo=%d, .si_errno=%d, .si_code=%#x, .si_timestamp=%#x, .si_flags=%#x .si_pid=%#x, .si_tid=%#x, .si_uid=%d, .si_status=%d, .si_addr=%p, .si_value=%p, .si_band=%ld, .si_fd=%d} pvXcptOrQueued=%p fFlags=%#x\n",
     850                  iSignalNo, (void *)pSigInfo,
     851                  pSigInfo ? pSigInfo->si_signo : 0,
     852                  pSigInfo ? pSigInfo->si_errno : 0,
     853                  pSigInfo ? pSigInfo->si_code : 0,
     854                  pSigInfo ? pSigInfo->si_timestamp : 0,
     855                  pSigInfo ? pSigInfo->si_flags : 0,
     856                  pSigInfo ? pSigInfo->si_pid : 0,
     857                  pSigInfo ? pSigInfo->si_tid : 0,
     858                  pSigInfo ? pSigInfo->si_uid : 0,
     859                  pSigInfo ? pSigInfo->si_status : 0,
     860                  pSigInfo ? pSigInfo->si_addr : 0,
     861                  pSigInfo ? pSigInfo->si_value.sigval_ptr : 0,
     862                  pSigInfo ? pSigInfo->si_band : 0,
     863                  pSigInfo ? pSigInfo->si_fd : 0,
     864                  (void *)pvXcptOrQueued, fFlags);
    686865
    687866    /*
     
    689868     */
    690869    LIBC_ASSERTM(!__libc_back_signalSemIsOwner(), "Thread owns the signal semaphore!!! Bad boy!!\n");
    691     if (__SIGSET_SIG_VALID(iSignalNo) || iSignalNo == 0)
     870    if (!__SIGSET_SIG_VALID(iSignalNo) || iSignalNo == 0)
    692871    {
    693872        LIBC_ASSERTM_FAILED("Invalid signal %d\n", iSignalNo);
     
    740919        LIBCLOG_MSG("we're toast!\n");
    741920        DosWrite(HFILE_STDERR, szMsg, sizeof(szMsg) - 1, &cb);
    742         signalTerminate(iSignalNo);
     921        signalTerminateAbnormal(iSignalNo);
    743922    }
    744923
     
    793972        ||  (   gaSignalActions[iSignalNo].__sigaction_u.__sa_handler == SIG_DFL
    794973             && (gafSignalProperties[iSignalNo] & SPA_MASK) == SPA_IGNORE)
     974        ||  (   iSignalNo == SIGCHLD
     975             && pSigInfo
     976             && (gaSignalActions[SIGCHLD].sa_flags & SA_NOCLDSTOP)
     977             && (pSigInfo->si_flags & __LIBC_SI_INTERNAL)
     978             && (pSigInfo->si_code == CLD_STOPPED || pSigInfo->si_code == CLD_CONTINUED))
    795979        )
    796980    {
     
    8191003         */
    8201004        pThrdSig = pThrd;
     1005    }
     1006    else if (gafSignalProperties[iSignalNo] & SPP_THRDONE)
     1007    {
     1008        /*
     1009         * Must schedule this signal on thread one.
     1010         */
     1011        pThrdSig = __libc_threadLookup(1);
    8211012    }
    8221013    else
     
    8511042            pThrdSig->enmStatus = enmLIBCThreadStatus_unknown;
    8521043            if (pThrdSig != pThrd)
    853                 signalPokeThread(pThrdSig);
     1044                __libc_back_signalPokeThread(pThrdSig);
    8541045            LIBCLOG_MSG("wokeup sigwait in thread %d on signal %d.\n", pThrdSig->tid, iSignalNo);
    8551046        }
     
    8591050             * Not waited for, so just queue it if possible and mark it pending.
    8601051             */
    861             if (    (fFlags & __LIBC_BSRF_QUEUED)
     1052            if (    pSigInfo
     1053                ||  (fFlags & __LIBC_BSRF_QUEUED)
    8621054                ||  (gafSignalProperties[iSignalNo] & SPP_QUEUED))
    8631055            {
     
    8841076                    if (    (fFlags & __LIBC_BSRF_HARDWARE)
    8851077                        ||  iSignalNo == SIGKILL)
    886                     {
     1078                    {   /* insert at head */
    8871079                        pSigQueued->pPrev = NULL;
    8881080                        pSigQueued->pNext = pThrdSig->SigQueue.pHead;
    8891081                        if (pThrdSig->SigQueue.pHead)
    890                             pThrdSig->SigQueue.pHead = pThrdSig->SigQueue.pHead->pPrev = pSigQueued;
     1082                            pThrdSig->SigQueue.pHead->pPrev = pSigQueued;
    8911083                        else
    892                             pThrdSig->SigQueue.pHead = pThrdSig->SigQueue.pTail = pSigQueued;
     1084                            pThrdSig->SigQueue.pTail = pSigQueued;
     1085                        pThrdSig->SigQueue.pHead = pSigQueued;
    8931086                    }
    8941087                    else
    895                     {
     1088                    {   /* insert at tail */
    8961089                        pSigQueued->pNext = NULL;
    8971090                        pSigQueued->pPrev = pThrdSig->SigQueue.pTail;
    8981091                        if (pThrdSig->SigQueue.pTail)
    899                             pThrdSig->SigQueue.pTail = pThrdSig->SigQueue.pTail->pNext = pSigQueued;
     1092                            pThrdSig->SigQueue.pTail->pNext = pSigQueued;
    9001093                        else
    901                             pThrdSig->SigQueue.pTail = pThrdSig->SigQueue.pHead = pSigQueued;
     1094                            pThrdSig->SigQueue.pHead = pSigQueued;
     1095                        pThrdSig->SigQueue.pTail = pSigQueued;
    9021096                    }
    9031097                    LIBCLOG_MSG("enqueued signal %d.\n", iSignalNo);
    9041098                }
    905                 else
    906                 {   /* arg! out of nodes :/ */
     1099                /*
     1100                 * No available nodes - ignore this situation if queueing isn't compulsory.
     1101                 */
     1102                else if (   (fFlags & __LIBC_BSRF_QUEUED)
     1103                         || (gafSignalProperties[iSignalNo] & SPP_QUEUED))
     1104                {
    9071105                    LIBC_ASSERTM_FAILED("Out of queue nodes! iSignalNo=%d\n", iSignalNo);
    9081106                    rc = -EAGAIN;
     
    9171115                __SIGSET_SET(&pThrd->SigSetPending, iSignalNo);
    9181116                if (pThrdSig != pThrd)
    919                     signalPokeThread(pThrdSig);
     1117                    __libc_back_signalPokeThread(pThrdSig);
    9201118                LIBCLOG_MSG("setting %d pending on thread %d's and poking it.\n", pThrdSig->tid, iSignalNo);
    9211119            }
     
    9281126         * Queue it if required and then mark it pending.
    9291127         */
    930         if (    (fFlags & __LIBC_BSRF_QUEUED)
     1128        if (    pSigInfo
     1129            ||  (fFlags & __LIBC_BSRF_QUEUED)
    9311130            ||  (gafSignalProperties[iSignalNo] & SPP_QUEUED))
    9321131        {
     
    9591158                LIBCLOG_MSG("enqueued signal %d.\n", iSignalNo);
    9601159            }
    961             else
    962             {   /* arg! out of nodes :/ */
     1160            /*
     1161             * No available nodes - ignore this situation if queueing isn't compulsory.
     1162             */
     1163            else if (   (fFlags & __LIBC_BSRF_QUEUED)
     1164                     || (gafSignalProperties[iSignalNo] & SPP_QUEUED))
     1165            {
    9631166                rc = -EAGAIN;
    9641167                LIBC_ASSERTM_FAILED("Out of queue nodes! iSignalNo=%d\n", iSignalNo);
     
    10611264     * Process queued signals first (to get a more correct order).
    10621265     */
    1063     sigset_t    SigDone;
    1064     __SIGSET_EMPTY(&SigDone);
     1266    sigset_t    SigSetDone;
     1267    __SIGSET_EMPTY(&SigSetDone);
    10651268    PSIGQUEUED pSig = gpSigQueueHead;
    10661269    while (pSig)
    10671270    {
    10681271        int iSignalNo = pSig->SigInfo.si_signo;
    1069         if (!__SIGSET_ISSET(&SigDone, iSignalNo))
     1272        if (!__SIGSET_ISSET(&SigSetDone, iSignalNo))
    10701273        {
    10711274            __LIBC_PTHREAD pThrdSig = signalScheduleThread(iSignalNo, pThrd);
    10721275            if (!pThrdSig)
    1073                 __SIGSET_SET(&SigDone, iSignalNo);
     1276                __SIGSET_SET(&SigSetDone, iSignalNo);
    10741277            else
    10751278            {
     
    10771280                PSIGQUEUED pSigNext = pSig->pNext;
    10781281                if (pSig->pPrev)
    1079                     pSig->pPrev->pNext = pSig->pNext;
     1282                    pSig->pPrev->pNext = pSigNext;
    10801283                else
    1081                     gpSigQueueHead     = pSig->pNext;
    1082                 if (pSig->pNext)
     1284                    gpSigQueueHead     = pSigNext;
     1285                if (pSigNext)
    10831286                    pSig->pNext->pPrev = pSig->pPrev;
    10841287                else
     
    11031306     * Process pending signals (which was not queued).
    11041307     */
    1105     int iSignalNo = 0;
    1106     while (iSignalNo++ < __SIGSET_MAXSIGNALS)
    1107     {
    1108         if (    !__SIGSET_ISSET(&SigDone, iSignalNo)
    1109             &&  __SIGSET_ISSET(&__libc_gSignalPending, iSignalNo))
    1110         {
    1111             __LIBC_PTHREAD pThrdSig = signalScheduleThread(iSignalNo, pThrd);
    1112             if (pThrdSig)
     1308    sigset_t    SigSetTodo = __libc_gSignalPending;
     1309    if (!__SIGSET_ISEMPTY(&SigSetTodo))
     1310    {
     1311        __SIGSET_NOT(&SigSetDone);
     1312        __SIGSET_AND(&SigSetTodo, &SigSetTodo, &SigSetDone);
     1313        if (!__SIGSET_ISEMPTY(&SigSetTodo))
     1314        {
     1315            int iSignalNo = 0;
     1316            while (++iSignalNo < __SIGSET_MAXSIGNALS)
    11131317            {
    1114                 signalScheduleToThread(pThrd, pThrdSig, iSignalNo, NULL);
    1115                 __SIGSET_CLEAR(&__libc_gSignalPending, iSignalNo);
    1116                 __libc_threadDereference(pThrdSig);
     1318                if (__SIGSET_ISSET(&SigSetTodo, iSignalNo))
     1319                {
     1320                    __LIBC_PTHREAD pThrdSig = signalScheduleThread(iSignalNo, pThrd);
     1321                    if (pThrdSig)
     1322                    {
     1323                        signalScheduleToThread(pThrd, pThrdSig, iSignalNo, NULL);
     1324                        __SIGSET_CLEAR(&__libc_gSignalPending, iSignalNo);
     1325                        __libc_threadDereference(pThrdSig);
     1326                    }
     1327                }
    11171328            }
    11181329        }
     
    11381349{
    11391350    LIBCLOG_ENTER("pThrd=%p pThrdSig=%p {.tid=%#x} iSignalNo=%d pSig=%p\n", (void *)pThrd, (void *)pThrdSig, pThrdSig->tid, iSignalNo, (void *)pSig);
     1351
    11401352    /*
    11411353     * If we've got a queue node, queue it.
     
    11481360            pThrdSig->SigQueue.pTail->pNext = pSig;
    11491361        else
    1150             pThrdSig->SigQueue.pTail = pThrdSig->SigQueue.pHead = pSig;
     1362            pThrdSig->SigQueue.pHead = pSig;
     1363        pThrdSig->SigQueue.pTail = pSig;
    11511364    }
    11521365
     
    11561369    __SIGSET_SET(&pThrd->SigSetPending, iSignalNo);
    11571370    if (pThrdSig != pThrd)
    1158         signalPokeThread(pThrdSig);
     1371        __libc_back_signalPokeThread(pThrdSig);
    11591372    LIBCLOG_MSG("setting %d pending on thread %d's and poking it.\n", pThrdSig->tid, iSignalNo);
    11601373    LIBCLOG_RETURN_VOID();
     
    12881501     */
    12891502    if (    pCur->fSigBeingPoked
    1290         ||  pCur != (__LIBC_PTHREAD)pvParam)
     1503        ||  pCur == (__LIBC_PTHREAD)pvParam)
    12911504        return 0;
    12921505
     
    12941507     * See if there are pending signals that can be delivered.
    12951508     */
    1296     sigset_t    SigSet = pCur->SigSetPending;
    1297     __SIGSET_AND(&SigSet, &SigSet, &pCur->SigSetBlocked);
    1298     if (!__SIGSET_EMPTY(&SigSet))
    1299         __libc_back_signalPokeThread(pCur->tid);
     1509    sigset_t    SigSetPending = pCur->SigSetBlocked;
     1510    __SIGSET_NOT(&SigSetPending);
     1511    __SIGSET_AND(&SigSetPending, &SigSetPending, &pCur->SigSetPending);
     1512    if (!__SIGSET_ISEMPTY(&SigSetPending))
     1513        __libc_back_signalPokeThread(pCur);
    13001514
    13011515    return 0;
     
    13311545         * Anything pending?
    13321546         */
    1333         __sigset_t  SigDeliver = pThrd->SigSetPending;
    1334         __SIGSET_AND(&SigDeliver, &SigDeliver, &pThrd->SigSetBlocked);
     1547        sigset_t    SigDeliver = pThrd->SigSetBlocked;
     1548        __SIGSET_NOT(&SigDeliver);
     1549        __SIGSET_AND(&SigDeliver, &SigDeliver, &pThrd->SigSetPending);
    13351550        if (__SIGSET_ISEMPTY(&SigDeliver))
    13361551            break;
     
    13411556         *   1. SIGKILL
    13421557         *   2. Realtime signals. (queued)
    1343          *   3. SIGCHLD
    1344          *   4. SIGCONT
    1345          *   5. Ascending from pending mask.
     1558         *   3. SIGTERM
     1559         *   4. SIGABRT
     1560         *   5. SIGCHLD
     1561         *   6. SIGCONT
     1562         *   7. Ascending from pending mask.
    13461563         *
    13471564         * Note that 0 and 1 may be violating the POSIX specs.
     
    13571574                if (iSignalNo > SIGRTMAX)
    13581575                {
    1359                     iSignalNo = SIGCHLD;
    1360                     if (!__SIGSET_ISSET(&SigDeliver, SIGCHLD))
     1576                    iSignalNo = SIGTERM;
     1577                    if (!__SIGSET_ISSET(&SigDeliver, SIGTERM))
    13611578                    {
    1362                         iSignalNo = SIGCONT;
    1363                         if (!__SIGSET_ISSET(&SigDeliver, SIGCONT))
     1579                        iSignalNo = SIGABRT;
     1580                        if (!__SIGSET_ISSET(&SigDeliver, SIGABRT))
    13641581                        {
    1365                             iSignalNo = 1;
    1366                             while (iSignalNo < SIGRTMIN && !__SIGSET_ISSET(&SigDeliver, iSignalNo))
    1367                                 iSignalNo++;
    1368                             if (iSignalNo >= SIGRTMIN)
     1582                            iSignalNo = SIGCHLD;
     1583                            if (!__SIGSET_ISSET(&SigDeliver, SIGCHLD))
    13691584                            {
    1370                                 LIBC_ASSERTM_FAILED("Internal error!!!\n");
    1371                                 LIBCLOG_RETURN_INT(__LIBC_BSRR_CONTINUE);
     1585                                iSignalNo = SIGCONT;
     1586                                if (!__SIGSET_ISSET(&SigDeliver, SIGCONT))
     1587                                {
     1588                                    iSignalNo = 1;
     1589                                    while (iSignalNo < SIGRTMIN && !__SIGSET_ISSET(&SigDeliver, iSignalNo))
     1590                                        iSignalNo++;
     1591                                    if (iSignalNo >= SIGRTMIN)
     1592                                    {
     1593                                        LIBC_ASSERTM_FAILED("Internal error!!!\n");
     1594                                        LIBCLOG_RETURN_INT(__LIBC_BSRR_CONTINUE);
     1595                                    }
     1596                                }
    13721597                            }
    13731598                        }
     
    14131638                break;
    14141639            }
     1640            /* next */
     1641            pSig = pSig->pNext;
    14151642        }
    14161643
     
    14571684                 */
    14581685                case SPA_NEXT_KILL:
     1686                case SPA_KILL:
     1687                    signalTerminate(iSignalNo);
     1688                case SPA_CORE:
    14591689                case SPA_NEXT_CORE:
    1460                 case SPA_KILL:
    1461                 case SPA_CORE:
    1462                     signalTerminate(iSignalNo);
     1690                    signalTerminateAbnormal(iSignalNo);
    14631691                    break;
    14641692
     
    15451773                *pStack-- = (uintptr_t)pvCtx;
    15461774                *pStack-- = (uintptr_t)&SigInfo;
    1547                 *pStack-- = iSignalNo;
     1775                *pStack  = iSignalNo;
    15481776                pTib->tib_pstack      = pThrd->pvSigStack;
    15491777                pTib->tib_pstacklimit = (char *)pThrd->pvSigStack + pThrd->cbSigStack;
     
    15521780                __libc_back_signalSemRelease();
    15531781                __asm__ __volatile__ (
    1554                     "movl %%esp, %0\n\t"
     1782                    "mov  %%esp, %0\n\t"
    15551783                    "movl %1, %%esp\n\t"
    15561784                    "call *%2\n\t"
    1557                     "movl 12(%%esp), %%esp\n\t"
     1785                    "mov 12(%%esp), %%esp\n\t"
    15581786                    : "=m" (*(uintptr_t *)((char *)pThrd->pvSigStack + pThrd->cbSigStack - sizeof(uintptr_t)))
    1559                     : "a" (pStack),
     1787                    : "c" (pStack),
    15601788                      "d" (SigAction.__sigaction_u.__sa_sigaction)
    1561                     : "ecx" );
     1789                    : "eax" );
    15621790
    15631791                /* Restore tib and release the stack. */
     
    16011829    } /* forever */
    16021830
     1831    LIBC_ASSERT(__libc_back_signalSemIsOwner());
     1832    __libc_back_signalSemRelease();
    16031833    LIBCLOG_RETURN_INT(rcRet);
    16041834}
    16051835
    1606 
    16071836/**
    16081837 * Cause immediate process termination because of the given signal.
     
    16121841static void signalTerminate(int iSignalNo)
    16131842{
    1614     /** @todo implement process termination by signal properly! */
     1843    LIBCLOG_ENTER("iSignalNo=%d\n", iSignalNo);
     1844
     1845    /*
     1846     * Set the exit reason in SPM and exit process.
     1847     */
     1848    __libc_spmTerm(__LIBC_EXIT_REASON_SIGNAL_BASE + iSignalNo, 127);
     1849    LIBCLOG_MSG("Calling DosExit(,127)\n");
     1850    for (;;)
     1851        DosExit(EXIT_THREAD, 127);
     1852}
     1853
     1854/**
     1855 * Cause immediate process termination because of the given signal.
     1856 *
     1857 * @param   iSignalNo   Signal causing the termination.
     1858 */
     1859static void signalTerminateAbnormal(int iSignalNo)
     1860{
     1861    LIBCLOG_ENTER("iSignalNo=%d\n", iSignalNo);
     1862    /*
     1863     * Set the exit reason in SPM.
     1864     */
     1865    __libc_spmTerm(__LIBC_EXIT_REASON_SIGNAL_BASE + iSignalNo, 127);
     1866
    16151867    /*
    16161868     * Before we go crazy here, let's release the semaphore.
     
    16231875    //    DosReleaseMutexSem(ghmtxSignals);
    16241876
     1877    /*
     1878     * Terminate the exception handler chain to avoid recursive trouble.
     1879     */
     1880    FS_VAR();
     1881    FS_SAVE_LOAD();
     1882    PTIB pTib;
     1883    PPIB pPib;
     1884    DosGetInfoBlocks(&pTib, &pPib);
     1885    pTib->tib_pexchain = END_OF_CHAIN;
     1886
     1887    /*
     1888     * Write message to stderr.
     1889     */
     1890    ULONG   cb;
     1891    if (iSignalNo == SIGABRT)
     1892    {
     1893        static const char szMsg[] = "\n\rAbnormal program termination";
     1894        DosWrite(HFILE_STDERR, szMsg, sizeof(szMsg) - 1, &cb);
     1895    }
     1896    else
     1897    {
     1898        static const char szMsg[] = "\n\rProcess terminated by ";
     1899        DosWrite(HFILE_STDERR, szMsg, sizeof(szMsg) - 1, &cb);
     1900
     1901        const char *psz = "unknown signal";
     1902        if (iSignalNo < sizeof(gaszSignalNames) / sizeof(gaszSignalNames[0]))
     1903            psz = gaszSignalNames[iSignalNo];
     1904        for (cb = 0; psz[cb];)
     1905            cb++;
     1906        DosWrite(HFILE_STDERR, psz, cb, &cb);
     1907    }
     1908
     1909    /* pid */
     1910    static const char szMsgPid[] = " - pid=0x";
     1911    DosWrite(HFILE_STDERR, szMsgPid, sizeof(szMsgPid) - 1, &cb);
     1912    char szHexNum[12];
     1913    cb = signalTerminateHex(szHexNum, pPib->pib_ulpid);
     1914    DosWrite(HFILE_STDERR, szHexNum, cb, &cb);
     1915
     1916    /* tid */
     1917    static const char szMsgTid[] = " - tid=0x";
     1918    DosWrite(HFILE_STDERR, szMsgTid, sizeof(szMsgTid) - 1, &cb);
     1919    cb = signalTerminateHex(szHexNum, pTib->tib_ptib2->tib2_ultid);
     1920    DosWrite(HFILE_STDERR, szHexNum, cb, &cb);
     1921
     1922    /* executable name. */
     1923    static char szExeName[CCHMAXPATH];
     1924    if (!DosQueryModuleName(pPib->pib_hmte, sizeof(szExeName), &szExeName[0]))
     1925    {
     1926        static const char szHypen[] = " - ";
     1927        DosWrite(HFILE_STDERR, szHypen, sizeof(szHypen) - 1, &cb);
     1928
     1929        for (cb = 0; szExeName[cb];)
     1930            cb++;
     1931        DosWrite(HFILE_STDERR, szExeName, cb, &cb);
     1932    }
     1933
     1934    /* final newline */
     1935    static const char szNewLine[] = "\r\n";
     1936    DosWrite(HFILE_STDERR, szNewLine, sizeof(szNewLine) - 1, &cb);
     1937
     1938    /*
     1939     * Terminate the process.
     1940     */
     1941    LIBCLOG_MSG("Calling DosExit(,127)\n");
    16251942    for (;;)
    16261943        DosExit(EXIT_THREAD, 127);
     
    16281945
    16291946/**
     1947 * Termination time hex formatter.
     1948 *
     1949 * @returns number of bytes formatted.
     1950 * @param   pszBuf  Where to store the formatted number.
     1951 * @param   u       Number to format.
     1952 */
     1953static int signalTerminateHex(char *pszBuf, unsigned u)
     1954{
     1955    static const char szHex[17] = "0123456789abcdef";
     1956    if (u <= 0xff)
     1957    {
     1958        pszBuf[0] = szHex[u >> 4];
     1959        pszBuf[1] = szHex[u & 0xf];
     1960        pszBuf[2] = '\0';
     1961        return 2;
     1962    }
     1963    else if (u <= 0xffff)
     1964    {
     1965        pszBuf[0] = szHex[u >> 12];
     1966        pszBuf[1] = szHex[(u >> 8) & 0xf];
     1967        pszBuf[2] = szHex[(u >> 4) & 0xf];
     1968        pszBuf[3] = szHex[u & 0xf];
     1969        pszBuf[4] = '\0';
     1970        return 4;
     1971    }
     1972    else
     1973    {
     1974        pszBuf[0] = szHex[u >> 28];
     1975        pszBuf[1] = szHex[(u >> 24) & 0xf];
     1976        pszBuf[2] = szHex[(u >> 20) & 0xf];
     1977        pszBuf[3] = szHex[(u >> 16) & 0xf];
     1978        pszBuf[4] = szHex[(u >> 12) & 0xf];
     1979        pszBuf[5] = szHex[(u >>  8) & 0xf];
     1980        pszBuf[6] = szHex[(u >>  4) & 0xf];
     1981        pszBuf[7] = szHex[u & 0xf];
     1982        pszBuf[8] = '\0';
     1983        return 8;
     1984    }
     1985}
     1986
     1987/**
    16301988 * Stop the process (job control emulation).
    16311989 *
     
    16341992static int signalJobStop(int iSignalNo)
    16351993{
    1636     /** @todo Job control: tell parent and ensure that thread 1 is frozen and unfrozen. */
     1994    LIBC_ASSERTM(__libc_threadCurrent()->tid == 1, "Invalid thread %d\n", __libc_threadCurrent()->tid);
     1995
     1996    /*
     1997     * Signal parent.
     1998     */
     1999    siginfo_t   SigInfo = {0};
     2000    SigInfo.si_signo    = SIGCHLD;
     2001    SigInfo.si_pid      = _sys_pid;
     2002    SigInfo.si_code     = CLD_STOPPED;
     2003    SigInfo.si_flags    = __LIBC_SI_INTERNAL;
     2004    __libc_back_signalSendPidOther(_sys_ppid, SIGCHLD, &SigInfo);
     2005
     2006    /*
     2007     * Wait for interruption (outside semaphores of course).
     2008     */
     2009    __libc_back_signalSemRelease();
    16372010    DosWaitEventSem(ghevWait, SEM_INDEFINITE_WAIT);
    1638     return 0;
     2011    return __libc_back_signalSemRequest();
    16392012}
    16402013
     
    16462019static int signalJobResume(void)
    16472020{
    1648     /** @todo Job control: tell parent and ensure that thread 1 is unfrozen. */
     2021    LIBC_ASSERTM(__libc_threadCurrent()->tid == 1, "Invalid thread %d\n", __libc_threadCurrent()->tid);
     2022
     2023    /*
     2024     * Signal parent.
     2025     */
     2026    siginfo_t   SigInfo = {0};
     2027    SigInfo.si_signo    = SIGCHLD;
     2028    SigInfo.si_pid      = _sys_pid;
     2029    SigInfo.si_code     = CLD_CONTINUED;
     2030    SigInfo.si_flags    = __LIBC_SI_INTERNAL;
     2031    __libc_back_signalSendPidOther(_sys_ppid, SIGCHLD, &SigInfo);
    16492032    return 0;
    16502033}
     
    16582041 * @return 0 on success.
    16592042 * @return -errno on failure.
     2043 * @param   pid         Target pid.
    16602044 * @param   iSignalNo   Signal number to send.
    1661  */
    1662 int __libc_back_signalSendPidOther(pid_t pid, int iSignalNo)
    1663 {
    1664     LIBCLOG_ENTER("pid=%d iSignalNo=%d\n", pid, iSignalNo);
     2045 * @param   pSigInfo    Signal info (optional).
     2046 */
     2047int __libc_back_signalSendPidOther(pid_t pid, int iSignalNo, siginfo_t *pSigInfo)
     2048{
     2049    LIBCLOG_ENTER("pid=%d iSignalNo=%d pSigInfo=%p\n", pid, iSignalNo, (void *)pSigInfo);
    16652050    int     rc;
    16662051    int     rcOS2;
     
    16702055     * Send the signal.
    16712056     */
    1672     switch (iSignalNo)
    1673     {
    1674         /*
    1675          * SIGKILL means kill process.
    1676          */
    1677         case SIGKILL:
    1678             FS_SAVE_LOAD();
    1679             rcOS2 = DosKillProcess(DKP_PROCESS, pid);
    1680             FS_RESTORE();
    1681             switch (rcOS2)
    1682             {
    1683                 case NO_ERROR:
    1684                     LIBCLOG_RETURN_INT(0);
    1685 
    1686                 case ERROR_INVALID_PROCID:
    1687                     rc = -ESRCH;
    1688                     break;
    1689                 default:
    1690                     rc = -EPERM;
    1691                     break;
    1692             }
    1693             LIBCLOG_RETURN_MSG(rc, "ret %d (DosKillProcess rcOS2=%d)\n", rc, rcOS2);
    1694 
    1695         /*
    1696          * We can send these the normal way to decentants.
    1697          */
    1698         case SIGINT:
    1699         case SIGBREAK:
    1700             FS_SAVE_LOAD();
    1701             rcOS2 = DosSendSignalException(pid, iSignalNo == SIGINT ? XCPT_SIGNAL_INTR : XCPT_SIGNAL_BREAK);
    1702             FS_RESTORE();
    1703             switch (rcOS2)
    1704             {
    1705                 case NO_ERROR:
    1706                     LIBCLOG_RETURN_INT(0);
    1707 
    1708                 case ERROR_INVALID_PROCID:
    1709                     LIBCLOG_RETURN_INT(-ESRCH);
    1710             }
    1711             /* try flag it */
    1712             break;
    1713 
    1714         default:
    1715             break;
     2057    if (pSigInfo)
     2058    {
     2059        switch (iSignalNo)
     2060        {
     2061            /*
     2062             * SIGKILL means kill process.
     2063             */
     2064            case SIGKILL:
     2065                FS_SAVE_LOAD();
     2066                rcOS2 = DosKillProcess(DKP_PROCESS, pid);
     2067                FS_RESTORE();
     2068                switch (rcOS2)
     2069                {
     2070                    case NO_ERROR:
     2071                        LIBCLOG_RETURN_INT(0);
     2072
     2073                    case ERROR_INVALID_PROCID:
     2074                        rc = -ESRCH;
     2075                        break;
     2076                    default:
     2077                        rc = -EPERM;
     2078                        break;
     2079                }
     2080                LIBCLOG_RETURN_MSG(rc, "ret %d (DosKillProcess rcOS2=%d)\n", rc, rcOS2);
     2081
     2082            /*
     2083             * We can send these the normal way to decentants.
     2084             */
     2085            case SIGINT:
     2086            case SIGBREAK:
     2087                FS_SAVE_LOAD();
     2088                rcOS2 = DosSendSignalException(pid, iSignalNo == SIGINT ? XCPT_SIGNAL_INTR : XCPT_SIGNAL_BREAK);
     2089                FS_RESTORE();
     2090                switch (rcOS2)
     2091                {
     2092                    case NO_ERROR:
     2093                        LIBCLOG_RETURN_INT(0);
     2094
     2095                    case ERROR_INVALID_PROCID:
     2096                        LIBCLOG_RETURN_INT(-ESRCH);
     2097                }
     2098                /* try flag it */
     2099                break;
     2100
     2101            default:
     2102                break;
     2103        }
    17162104    }
    17172105
     
    17232111     */
    17242112    siginfo_t SigInfo = {0};
    1725     SigInfo.si_signo    = iSignalNo;
    1726     SigInfo.si_pid      = _sys_pid;
    1727     __LIBC_PTHREAD pThrd = __libc_threadCurrentNoAuto();
     2113    if (pSigInfo)
     2114        SigInfo = *pSigInfo;
     2115    SigInfo.si_signo        = iSignalNo;
     2116    if (SigInfo.si_pid)
     2117        SigInfo.si_pid      = _sys_pid;
     2118    __LIBC_PTHREAD pThrd    = __libc_threadCurrentNoAuto();
    17282119    if (pThrd)
    1729         SigInfo.si_tid  = pThrd->tid;
    1730     SigInfo.si_timestamp= signalTimestamp();
     2120        SigInfo.si_tid      = pThrd->tid;
     2121    if (SigInfo.si_timestamp)
     2122        SigInfo.si_timestamp= signalTimestamp();
    17312123    if (gafSignalProperties[iSignalNo] & SPP_QUEUED)
    1732         SigInfo.si_flags |= __LIBC_SI_QUEUED;
     2124        SigInfo.si_flags   |= __LIBC_SI_QUEUED;
    17332125
    17342126    rc = __libc_spmSigQueue(&SigInfo, pid, SigInfo.si_flags & __LIBC_SI_QUEUED);
     
    18952287 * evaluate pending signals.
    18962288 *
    1897  * @param   tid     Thread to poke. 0 means current thread.
    1898  */
    1899 void        __libc_back_signalPokeThread(int tid)
    1900 {
    1901     LIBC_ASSERTM(__libc_back_signalSemIsOwner(), "Thread must own signal sem!\n");
    1902 
    1903     /*
    1904      * Get thread structure of target thread.
    1905      */
    1906     __LIBC_PTHREAD pThrdPoke = __libc_threadLookup(tid);
    1907     if (pThrdPoke)
    1908     {
    1909         signalPokeThread(pThrdPoke);
    1910         __libc_threadDereference(pThrdPoke);
    1911     }
    1912 }
    1913 
    1914 
    1915 /**
    1916  * Pokes a thread in the current process, forcing it to
    1917  * evaluate pending signals.
    1918  *
    19192289 * @param   pThrdPoke       Thread to poke.
    19202290 */
    1921 static void     signalPokeThread(__LIBC_PTHREAD pThrdPoke)
    1922 {
     2291void     __libc_back_signalPokeThread(__LIBC_PTHREAD pThrdPoke)
     2292{
     2293    LIBCLOG_ENTER("pThrdPoke=%p {.tid=%#x}\n", (void *)pThrdPoke, pThrdPoke->tid);
    19232294    LIBC_ASSERTM(__libc_back_signalSemIsOwner(), "Thread must own signal sem!\n");
    19242295
     
    19332304            LIBC_ASSERTM_FAILED("DosKillThread(%d) -> rc=%d\n", pThrdPoke->tid, rc);
    19342305    }
     2306
     2307    LIBCLOG_RETURN_VOID();
    19352308}
    19362309
     
    19842357 * sigaction worker; queries and/or sets the action for a signal.
    19852358 *
     2359 * @returns 0 on success.
     2360 * @returns -Negative errno on failure.
     2361 * @param   iSignalNo   Signal number.
     2362 * @param   pSigAct     Pointer to new signal action.
     2363 *                      If NULL no update is done.
     2364 * @param   pSigActOld  Where to store the old signal action.
     2365 *                      If NULL nothing is attempted stored.
     2366 */
     2367int         __libc_Back_signalAction(int iSignalNo, const struct sigaction *pSigAct, struct sigaction *pSigActOld)
     2368{
     2369    LIBCLOG_ENTER("iSignalNo=%d pSigAct=%p {sa_handler=%p, sa_mask={%#08lx %#08lx}, sa_flags=%#x} pSigActOld=%p\n",
     2370                  iSignalNo, (void *)pSigAct,
     2371                  pSigAct ? (void*)pSigAct->__sigaction_u.__sa_sigaction : NULL,
     2372                  pSigAct ? pSigAct->sa_mask.__bitmap[0] : 0,
     2373                  pSigAct ? pSigAct->sa_mask.__bitmap[1] : 0,
     2374                  pSigAct ? pSigAct->sa_flags : 0,
     2375                  (void *)pSigActOld);
     2376
     2377    /*
     2378     * Take the semaphore
     2379     */
     2380    LIBC_ASSERT(!__libc_back_signalSemIsOwner());
     2381    int rc = __libc_back_signalSemRequest();
     2382    if (!rc)
     2383    {
     2384        rc = __libc_back_signalAction(iSignalNo, pSigAct, pSigActOld);
     2385        __libc_back_signalSemRelease();
     2386    }
     2387
     2388    LIBCLOG_RETURN_INT(rc);
     2389}
     2390
     2391
     2392/**
     2393 * sigaction worker; queries and/or sets the action for a signal.
     2394 *
    19862395 * The caller MUST own the signal semaphore when calling this function.
    19872396 *
    19882397 * @returns 0 on success.
    1989  * @returns -1 on failure, errno set.
     2398 * @returns Negative error code (errno.h) on failure.
    19902399 * @param   iSignalNo   Signal number.
    19912400 * @param   pSigAct     Pointer to new signal action.
     
    20032412                  pSigAct ? pSigAct->sa_flags : 0,
    20042413                  (void *)pSigActOld);
     2414
     2415    /*
     2416     * Assert state.
     2417     */
     2418    LIBC_ASSERTM(__libc_back_signalSemIsOwner(), "Thread does not own the signal semaphore!!!\n");
     2419
     2420    /*
     2421     * Check input.
     2422     */
     2423    if (!__SIGSET_SIG_VALID(iSignalNo))
     2424        LIBCLOG_RETURN_INT(-EINVAL);
     2425
     2426    /*
     2427     * Query.
     2428     */
     2429    if (pSigActOld)
     2430        *pSigActOld = gaSignalActions[iSignalNo];
     2431
     2432    /*
     2433     * Set.
     2434     */
    20052435    int rc = 0;
    2006 
    2007     /*
    2008      * Assert state.
    2009      */
    2010     LIBC_ASSERTM(__libc_back_signalSemIsOwner(), "Thread does not own the signal semaphore!!!\n");
    2011 
    2012     /*
    2013      * Check input.
    2014      */
    2015     if (!__SIGSET_SIG_VALID(iSignalNo))
    2016     {
    2017         errno = EINVAL;
    2018         LIBCLOG_RETURN_INT(-1);
    2019     }
    2020 
    2021     /*
    2022      * Query.
    2023      */
    2024     if (pSigActOld)
    2025     {
    2026         *pSigActOld = gaSignalActions[iSignalNo];
    2027     }
    2028 
    2029     /*
    2030      * Set.
    2031      */
    20322436    if (pSigAct)
    20332437    {
     
    20392443        {
    20402444            if (    pSigAct->__sigaction_u.__sa_handler != SIG_ERR
    2041                 &&  pSigAct->__sigaction_u.__sa_handler != SIG_ACK)
     2445                &&  pSigAct->__sigaction_u.__sa_handler != SIG_ACK
     2446                &&  pSigAct->__sigaction_u.__sa_handler != SIG_HOLD
     2447                &&  pSigAct->__sigaction_u.__sa_handler != NULL)
    20422448            {
    20432449                /*
     
    20452451                 */
    20462452                gaSignalActions[iSignalNo] = *pSigAct;
     2453                __SIGSET_CLEAR(&gaSignalActions[iSignalNo].sa_mask, SIGKILL);
     2454                __SIGSET_CLEAR(&gaSignalActions[iSignalNo].sa_mask, SIGSTOP);
    20472455
    20482456                /*
     
    20592467            {
    20602468                LIBC_ASSERTM_FAILED("Invalid sa_handler=%p\n", (void *)pSigAct->__sigaction_u.__sa_handler);
    2061                 errno = EINVAL;
     2469                rc = -EINVAL;
    20622470            }
    20632471        }
     
    20652473        {
    20662474            LIBC_ASSERTM_FAILED("Invalid sa_flags=%#x\n", pSigAct->sa_flags);
    2067             errno = EINVAL;
    2068         }
    2069 
     2475            rc = -EINVAL;
     2476        }
    20702477    }
    20712478
     
    21682575}
    21692576
     2577
     2578
     2579_FORK_CHILD1(0x0000000f, signalForkChild)
     2580
     2581/**
     2582 * Fork callback which initializes 16-bit signal handler in the child process.
     2583 *
     2584 * @returns 0 on success.
     2585 * @returns -errno on failure.
     2586 * @param   pForkHandle     Pointer to fork handle.
     2587 * @param   enmOperation    Fork operation.
     2588 */
     2589static int signalForkChild(__LIBC_PFORKHANDLE pForkHandle, __LIBC_FORKOP enmOperation)
     2590{
     2591    LIBCLOG_ENTER("pForkHandle=%p enmOperation=%d\n", (void *)pForkHandle, enmOperation);
     2592    int     rc;
     2593    switch (enmOperation)
     2594    {
     2595        /*
     2596         * Install the 16-bit signal handler if we were the LIBC having that installed
     2597         * in the parent process.
     2598         */
     2599        case __LIBC_FORK_OP_FORK_CHILD:
     2600            rc = 0;
     2601            if (gfOS2V1Handler)
     2602            {
     2603                rc = DosSetSigHandler((PFNSIGHANDLER)__libc_back_signalOS2V1Handler16bit, NULL, NULL, SIGA_ACCEPT, SIG_PFLG_A);
     2604                if (rc)
     2605                {
     2606                    LIBC_ASSERTM_FAILED("DosSetSigHandler failed with rc=%d\n", rc);
     2607                    rc = -__libc_native2errno(rc);
     2608                }
     2609                ULONG cTimes = 0;
     2610                DosSetSignalExceptionFocus(SIG_SETFOCUS, &cTimes);
     2611            }
     2612            break;
     2613
     2614        default:
     2615            rc = 0;
     2616            break;
     2617    }
     2618
     2619    LIBCLOG_RETURN_INT(rc);
     2620}
     2621
     2622
Note: See TracChangeset for help on using the changeset viewer.