[haiku-commits] r41568 - in haiku/branches/developer/bonefish/signals: headers/posix src/system/kernel/arch/x86

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 18 May 2011 18:09:42 +0200 (CEST)

Author: bonefish
Date: 2011-05-18 18:09:42 +0200 (Wed, 18 May 2011)
New Revision: 41568
Changeset: https://dev.haiku-os.org/changeset/41568
Ticket: https://dev.haiku-os.org/ticket/2695

Modified:
   haiku/branches/developer/bonefish/signals/headers/posix/signal.h
   
haiku/branches/developer/bonefish/signals/src/system/kernel/arch/x86/arch_thread.cpp
Log:
Applied partial patch by Andreas Faerber (ticket #2695) with some style
changes:
* <signal.h>: Added/uncommented/extended the structures needed for SA_SIGINFO
  support.
* arch_setup_signal_frame(): Added (partial) support for setting up the signal
  frame for SA_SIGINFO style handlers.


Modified: haiku/branches/developer/bonefish/signals/headers/posix/signal.h
===================================================================
--- haiku/branches/developer/bonefish/signals/headers/posix/signal.h    
2011-05-18 15:21:47 UTC (rev 41567)
+++ haiku/branches/developer/bonefish/signals/headers/posix/signal.h    
2011-05-18 16:09:42 UTC (rev 41568)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2010 Haiku Inc. All Rights Reserved.
+ * Copyright 2002-2011 Haiku, Inc. All Rights Reserved.
  * Distributed under the terms of the MIT License.
  */
 #ifndef _SIGNAL_H_
@@ -25,21 +25,23 @@
 #define SIG_ERR                ((sighandler_t)-1)      /* an error occurred 
during signal processing */
 #define SIG_HOLD       ((sighandler_t)3)       /* the signal was hold */
 
-/* TODO: Support this structure, or more precisely the SA_SIGINFO flag. To do
- * this properly we need real-time signal support. Both are commented out for
- * the time being to not make "configure" scripts think we do support them. */
-#if 0
+union sigval {
+       int             sival_int;
+       void    *sival_ptr;
+};
+
 typedef struct {
-       int             si_signo;       /* signal number */
-       int             si_code;        /* signal code */
-       int             si_errno;       /* if non zero, an error number 
associated with this signal */
-       pid_t   si_pid;         /* sending process ID */
-       uid_t   si_uid;         /* real user ID of sending process */
-       void    *si_addr;       /* address of faulting instruction */
-       int             si_status;      /* exit value or signal */
-       long    si_band;        /* band event for SIGPOLL */
+       int                             si_signo;       /* signal number */
+       int                             si_code;        /* signal code */
+       int                             si_errno;       /* if non zero, an 
error number associated with
+                                                                  this signal 
*/
+       pid_t                   si_pid;         /* sending process ID */
+       uid_t                   si_uid;         /* real user ID of sending 
process */
+       void                    *si_addr;       /* address of faulting 
instruction */
+       int                             si_status;      /* exit value or signal 
*/
+       long                    si_band;        /* band event for SIGPOLL */
+       union sigval    si_value;       /* signal value */
 } siginfo_t;
-#endif /* 0 */
 
 /*
  * structure used by sigaction()
@@ -48,7 +50,10 @@
  * See the documentation for more info on this.
  */
 struct sigaction {
-       sighandler_t sa_handler;
+       union {
+               sighandler_t    sa_handler;
+               void                    (*sa_sigaction)(int, siginfo_t *, void 
*);
+       };
        sigset_t        sa_mask;
        int                     sa_flags;
        void            *sa_userdata;  /* will be passed to the signal handler 
*/
@@ -61,7 +66,7 @@
 #define SA_NODEFER             0x08
 #define SA_RESTART             0x10
 #define SA_ONSTACK             0x20
-/* #define SA_SIGINFO          0x40 */
+#define SA_SIGINFO             0x40
 #define SA_NOMASK              SA_NODEFER
 #define SA_STACK               SA_ONSTACK
 #define SA_ONESHOT             SA_RESETHAND
@@ -251,5 +256,14 @@
 /* include architecture specific definitions */
 #include __HAIKU_ARCH_HEADER(signal.h)
 
+typedef struct vregs mcontext_t;
 
+typedef struct ucontext_t {
+       struct ucontext_t       *uc_link;
+       sigset_t        uc_sigmask;
+       stack_t         uc_stack;
+       mcontext_t      uc_mcontext;
+} ucontext_t;
+
+
 #endif /* _SIGNAL_H_ */

Modified: 
haiku/branches/developer/bonefish/signals/src/system/kernel/arch/x86/arch_thread.cpp
===================================================================
--- 
haiku/branches/developer/bonefish/signals/src/system/kernel/arch/x86/arch_thread.cpp
        2011-05-18 15:21:47 UTC (rev 41567)
+++ 
haiku/branches/developer/bonefish/signals/src/system/kernel/arch/x86/arch_thread.cpp
        2011-05-18 16:09:42 UTC (rev 41568)
@@ -485,7 +485,10 @@
 
        uint32 *signalCode;
        uint32 *userRegs;
-       struct vregs regs;
+       uint32 *userSiginfo = NULL;
+       uint32 *userContext = NULL;
+       siginfo_t siginfo;
+       ucontext_t ucontext;
        uint32 buffer[6];
        status_t status;
 
@@ -505,23 +508,43 @@
        if (status < B_OK)
                return status;
 
+       if ((action->sa_flags & SA_SIGINFO) != 0) {
+               // store the signal info
+               memset(&siginfo, 0, sizeof(siginfo));
+               siginfo.si_signo = signal->Number();
+               // TODO: fill in other members
+
+               userStack -= (sizeof(siginfo_t) + 3) / 4;
+               userSiginfo = userStack;
+               status = user_memcpy(userSiginfo, &siginfo, sizeof(siginfo));
+               if (status < B_OK)
+                       return status;
+       }
+
        // store the saved regs onto the user stack
-       regs.eip = frame->eip;
-       regs.eflags = frame->flags;
-       regs.eax = frame->eax;
-       regs.ecx = frame->ecx;
-       regs.edx = frame->edx;
-       regs.ebp = frame->ebp;
-       regs.esp = frame->esp;
-       regs._reserved_1 = frame->user_esp;
-       regs._reserved_2[0] = frame->edi;
-       regs._reserved_2[1] = frame->esi;
-       regs._reserved_2[2] = frame->ebx;
-       i386_fnsave((void *)(&regs.xregs));
+       ucontext.uc_mcontext.eip = frame->eip;
+       ucontext.uc_mcontext.eflags = frame->flags;
+       ucontext.uc_mcontext.eax = frame->eax;
+       ucontext.uc_mcontext.ecx = frame->ecx;
+       ucontext.uc_mcontext.edx = frame->edx;
+       ucontext.uc_mcontext.ebp = frame->ebp;
+       ucontext.uc_mcontext.esp = frame->esp;
+       ucontext.uc_mcontext._reserved_1 = frame->user_esp;
+       ucontext.uc_mcontext._reserved_2[0] = frame->edi;
+       ucontext.uc_mcontext._reserved_2[1] = frame->esi;
+       ucontext.uc_mcontext._reserved_2[2] = frame->ebx;
+       i386_fnsave((void *)(&ucontext.uc_mcontext.xregs));
 
-       userStack -= (sizeof(struct vregs) + 3) / 4;
-       userRegs = userStack;
-       status = user_memcpy(userRegs, &regs, sizeof(regs));
+       if ((action->sa_flags & SA_SIGINFO) != 0) {
+               userStack -= (sizeof(ucontext_t) + 3) / 4;
+               userContext = userStack;
+               userRegs = userContext + offsetof(ucontext_t, uc_mcontext);
+               status = user_memcpy(userContext, &ucontext, sizeof(ucontext));
+       } else {
+               userStack -= (sizeof(struct vregs) + 3) / 4;
+               userRegs = userStack;
+               status = user_memcpy(userRegs, &ucontext.uc_mcontext, 
sizeof(struct vregs));
+       }
        if (status < B_OK)
                return status;
 
@@ -538,8 +561,13 @@
        // now set up the final part
        buffer[0] = (uint32)signalCode; // return address when sa_handler done
        buffer[1] = signal->Number();   // arguments to sa_handler
-       buffer[2] = (uint32)action->sa_userdata;
-       buffer[3] = (uint32)userRegs;
+       if ((action->sa_flags & SA_SIGINFO) != 0) {
+               buffer[2] = (uint32)userSiginfo;
+               buffer[3] = (uint32)userContext;
+       } else {
+               buffer[2] = (uint32)action->sa_userdata;
+               buffer[3] = (uint32)userRegs;
+       }
 
        buffer[4] = signalMask;                 // Old signal mask to restore
        buffer[5] = (uint32)userRegs;   // Int frame + extra regs to restore
@@ -551,7 +579,8 @@
                return status;
 
        frame->user_esp = (uint32)userStack;
-       frame->eip = (uint32)action->sa_handler;
+       frame->eip = (action->sa_flags & SA_SIGINFO) != 0
+               ? (uint32)action->sa_sigaction : (uint32)action->sa_handler;
 
        return B_OK;
 }


Other related posts:

  • » [haiku-commits] r41568 - in haiku/branches/developer/bonefish/signals: headers/posix src/system/kernel/arch/x86 - ingo_weinhold