Ticket #2695: siginfo_2009-11-17.diff
File siginfo_2009-11-17.diff, 5.5 KB (added by , 14 years ago) |
---|
-
headers/posix/signal.h
diff --git a/headers/posix/signal.h b/headers/posix/signal.h index 97703c8..bd002e4 100644
a b typedef void (*__signal_func_ptr)(int); 28 28 /* TODO: Support this structure, or more precisely the SA_SIGINFO flag. To do 29 29 * this properly we need real-time signal support. Both are commented out for 30 30 * the time being to not make "configure" scripts think we do support them. */ 31 #if 032 31 typedef struct { 33 32 int si_signo; /* signal number */ 34 33 int si_code; /* signal code */ … … typedef struct { 39 38 int si_status; /* exit value or signal */ 40 39 long si_band; /* band event for SIGPOLL */ 41 40 } siginfo_t; 42 #endif /* 0 */43 41 44 42 /* 45 43 * structure used by sigaction() … … typedef struct { 48 46 * See the documentation for more info on this. 49 47 */ 50 48 struct sigaction { 51 sighandler_t sa_handler; 49 union { 50 sighandler_t sa_handler; 51 void (*sa_sigaction)(int, siginfo_t *, void *); 52 }; 52 53 sigset_t sa_mask; 53 54 int sa_flags; 54 55 void *sa_userdata; /* will be passed to the signal handler */ … … struct sigaction { 61 62 #define SA_NODEFER 0x08 62 63 #define SA_RESTART 0x10 63 64 #define SA_ONSTACK 0x20 64 /* #define SA_SIGINFO 0x40 */ 65 #define SA_SIGINFO 0x40 65 66 #define SA_NOMASK SA_NODEFER 66 67 #define SA_STACK SA_ONSTACK 67 68 #define SA_ONESHOT SA_RESETHAND -
new file headers/posix/ucontext.h
diff --git a/headers/posix/ucontext.h b/headers/posix/ucontext.h new file mode 100644 index 0000000..6900401
- + 1 /* 2 * Copyright 2008, Haiku Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT license. 4 */ 5 #ifndef _UCONTEXT_H_ 6 #define _UCONTEXT_H_ 7 8 #include <signal.h> 9 10 11 typedef struct vregs mcontext_t; 12 13 14 typedef struct ucontext_t { 15 ucontext_t *uc_link; 16 sigset_t uc_sigmask; 17 stack_t uc_stack; 18 mcontext_t uc_mcontext; 19 } ucontext_t; 20 21 22 #endif /* _UCONTEXT_H_ */ -
src/system/kernel/arch/x86/arch_thread.cpp
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 b 23 23 #include <tracing.h> 24 24 #include <vm_address_space.h> 25 25 #include <vm_types.h> 26 #include <ucontext.h> 26 27 27 28 #include "x86_paging.h" 28 29 … … arch_setup_signal_frame(struct thread *thread, struct sigaction *action, 485 486 } 486 487 487 488 uint32 *signalCode; 488 uint32 *userRegs; 489 struct vregs regs; 489 uint32 *userRegs, *userSiginfo, *userContext; 490 siginfo_t siginfo; 491 ucontext_t ucontext; 490 492 uint32 buffer[6]; 491 493 status_t status; 492 494 … … arch_setup_signal_frame(struct thread *thread, struct sigaction *action, 506 508 if (status < B_OK) 507 509 return status; 508 510 511 if (action->sa_flags & SA_SIGINFO) { 512 // store the signal info 513 memset(&siginfo, 0, sizeof(siginfo)); 514 siginfo.si_signo = signal; 515 //TODO fill in other members 516 517 userStack -= (sizeof(siginfo_t) + 3) / 4; 518 userSiginfo = userStack; 519 status = user_memcpy(userSiginfo, &siginfo, sizeof(siginfo)); 520 if (status < B_OK) 521 return status; 522 } 523 509 524 // store the saved regs onto the user stack 510 regs.eip = frame->eip; 511 regs.eflags = frame->flags; 512 regs.eax = frame->eax; 513 regs.ecx = frame->ecx; 514 regs.edx = frame->edx; 515 regs.ebp = frame->ebp; 516 regs.esp = frame->esp; 517 regs._reserved_1 = frame->user_esp; 518 regs._reserved_2[0] = frame->edi; 519 regs._reserved_2[1] = frame->esi; 520 regs._reserved_2[2] = frame->ebx; 521 i386_fnsave((void *)(®s.xregs)); 522 523 userStack -= (sizeof(struct vregs) + 3) / 4; 524 userRegs = userStack; 525 status = user_memcpy(userRegs, ®s, sizeof(regs)); 525 ucontext.uc_mcontext.eip = frame->eip; 526 ucontext.uc_mcontext.eflags = frame->flags; 527 ucontext.uc_mcontext.eax = frame->eax; 528 ucontext.uc_mcontext.ecx = frame->ecx; 529 ucontext.uc_mcontext.edx = frame->edx; 530 ucontext.uc_mcontext.ebp = frame->ebp; 531 ucontext.uc_mcontext.esp = frame->esp; 532 ucontext.uc_mcontext._reserved_1 = frame->user_esp; 533 ucontext.uc_mcontext._reserved_2[0] = frame->edi; 534 ucontext.uc_mcontext._reserved_2[1] = frame->esi; 535 ucontext.uc_mcontext._reserved_2[2] = frame->ebx; 536 i386_fnsave((void *)(&ucontext.uc_mcontext.xregs)); 537 538 if (action->sa_flags & SA_SIGINFO) { 539 userStack -= (sizeof(ucontext_t) + 3) / 4; 540 userContext = userStack; 541 userRegs = userContext + offsetof(ucontext_t, uc_mcontext); 542 status = user_memcpy(userContext, &ucontext, sizeof(ucontext)); 543 } else { 544 userStack -= (sizeof(struct vregs) + 3) / 4; 545 userRegs = userStack; 546 status = user_memcpy(userRegs, &ucontext.uc_mcontext, sizeof(struct vregs)); 547 } 526 548 if (status < B_OK) 527 549 return status; 528 550 … … arch_setup_signal_frame(struct thread *thread, struct sigaction *action, 539 561 // now set up the final part 540 562 buffer[0] = (uint32)signalCode; // return address when sa_handler done 541 563 buffer[1] = signal; // arguments to sa_handler 542 buffer[2] = (uint32)action->sa_userdata; 543 buffer[3] = (uint32)userRegs; 564 if (action->sa_flags & SA_SIGINFO) { 565 buffer[2] = (uint32)userSiginfo; 566 buffer[3] = (uint32)userContext; 567 } else { 568 buffer[2] = (uint32)action->sa_userdata; 569 buffer[3] = (uint32)userRegs; 570 } 544 571 545 572 buffer[4] = signalMask; // Old signal mask to restore 546 573 buffer[5] = (uint32)userRegs; // Int frame + extra regs to restore … … arch_setup_signal_frame(struct thread *thread, struct sigaction *action, 552 579 return status; 553 580 554 581 frame->user_esp = (uint32)userStack; 555 frame->eip = ( uint32)action->sa_handler;582 frame->eip = (action->sa_flags & SA_SIGINFO) ? (uint32)action->sa_sigaction : (uint32)action->sa_handler; 556 583 557 584 return B_OK; 558 585 }