diff --git a/headers/posix/signal.h b/headers/posix/signal.h
index 97703c8..bd002e4 100644
--- a/headers/posix/signal.h
+++ b/headers/posix/signal.h
@@ -28,7 +28,6 @@ typedef void (*__signal_func_ptr)(int);
 /* 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
 typedef struct {
 	int		si_signo;	/* signal number */
 	int		si_code;	/* signal code */
@@ -39,7 +38,6 @@ typedef struct {
 	int		si_status;	/* exit value or signal */
 	long	si_band;	/* band event for SIGPOLL */
 } siginfo_t;
-#endif	/* 0 */
 
 /*
  * structure used by sigaction()
@@ -48,7 +46,10 @@ typedef struct {
  * 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 +62,7 @@ struct sigaction {
 #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
diff --git a/headers/posix/ucontext.h b/headers/posix/ucontext.h
new file mode 100644
index 0000000..6900401
--- /dev/null
+++ b/headers/posix/ucontext.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2008, Haiku Inc. All Rights Reserved.
+ * Distributed under the terms of the MIT license.
+ */
+#ifndef _UCONTEXT_H_
+#define _UCONTEXT_H_
+
+#include <signal.h>
+
+
+typedef struct vregs mcontext_t;
+
+
+typedef struct ucontext_t {
+	ucontext_t	*uc_link;
+	sigset_t	uc_sigmask;
+	stack_t		uc_stack;
+	mcontext_t	uc_mcontext;
+} ucontext_t;
+
+
+#endif /* _UCONTEXT_H_ */
diff --git a/src/system/kernel/arch/x86/arch_thread.cpp b/src/system/kernel/arch/x86/arch_thread.cpp
index 60e0a57..9265ebc 100644
--- a/src/system/kernel/arch/x86/arch_thread.cpp
+++ b/src/system/kernel/arch/x86/arch_thread.cpp
@@ -23,6 +23,7 @@
 #include <tracing.h>
 #include <vm_address_space.h>
 #include <vm_types.h>
+#include <ucontext.h>
 
 #include "x86_paging.h"
 
@@ -485,8 +486,9 @@ arch_setup_signal_frame(struct thread *thread, struct sigaction *action,
 	}
 
 	uint32 *signalCode;
-	uint32 *userRegs;
-	struct vregs regs;
+	uint32 *userRegs, *userSiginfo, *userContext;
+	siginfo_t siginfo;
+	ucontext_t ucontext;
 	uint32 buffer[6];
 	status_t status;
 
@@ -506,23 +508,43 @@ arch_setup_signal_frame(struct thread *thread, struct sigaction *action,
 	if (status < B_OK)
 		return status;
 
+	if (action->sa_flags & SA_SIGINFO) {
+		// store the signal info
+		memset(&siginfo, 0, sizeof(siginfo));
+		siginfo.si_signo = signal;
+		//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));
-
-	userStack -= (sizeof(struct vregs) + 3) / 4;
-	userRegs = userStack;
-	status = user_memcpy(userRegs, &regs, sizeof(regs));
+	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));
+
+	if (action->sa_flags & SA_SIGINFO) {
+		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;
 
@@ -539,8 +561,13 @@ arch_setup_signal_frame(struct thread *thread, struct sigaction *action,
 	// now set up the final part
 	buffer[0] = (uint32)signalCode;	// return address when sa_handler done
 	buffer[1] = signal;				// arguments to sa_handler
-	buffer[2] = (uint32)action->sa_userdata;
-	buffer[3] = (uint32)userRegs;
+	if (action->sa_flags & SA_SIGINFO) {
+		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
@@ -552,7 +579,7 @@ arch_setup_signal_frame(struct thread *thread, struct sigaction *action,
 		return status;
 
 	frame->user_esp = (uint32)userStack;
-	frame->eip = (uint32)action->sa_handler;
+	frame->eip = (action->sa_flags & SA_SIGINFO) ? (uint32)action->sa_sigaction : (uint32)action->sa_handler;
 
 	return B_OK;
 }
