git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1723 a95241bf-73f2-0310-859d-f6bbb57e9c96
123 lines
2.4 KiB
C
123 lines
2.4 KiB
C
/*
|
|
** Small test for signals handling
|
|
*/
|
|
|
|
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <signal.h>
|
|
#include <syscalls.h>
|
|
|
|
|
|
typedef void (*beos_signal_func_ptr)(int, void *, struct vregs *);
|
|
|
|
|
|
void sig_handler(int, void *data, struct vregs *regs);
|
|
void alarm_handler(int, void *data, struct vregs *regs);
|
|
void install_handler(int, beos_signal_func_ptr);
|
|
int32 thread(void *);
|
|
void usage(void);
|
|
|
|
|
|
void
|
|
sig_handler(int sig, void *data, struct vregs *regs)
|
|
{
|
|
int i;
|
|
char buffer[10];
|
|
|
|
memcpy(buffer, data, 10);
|
|
buffer[9] = '\0';
|
|
printf("sig_test (sig_handler): Received signal #%d...\n", sig);
|
|
printf("User data at %p (contents: \"%s\"), vregs at %p\n", data, buffer, regs);
|
|
printf("Counting for fun: ");
|
|
for (i=0; i<10; i++)
|
|
printf("%d ", i);
|
|
printf("\n");
|
|
}
|
|
|
|
|
|
void
|
|
alarm_handler(int sig, void *data, struct vregs *regs)
|
|
{
|
|
printf("Alarm!\n");
|
|
}
|
|
|
|
|
|
void
|
|
install_handler(int sig, beos_signal_func_ptr handler)
|
|
{
|
|
struct sigaction newa;
|
|
struct sigaction olda;
|
|
|
|
memset(&newa, 0, sizeof(newa));
|
|
|
|
newa.sa_handler = (__signal_func_ptr)handler;
|
|
newa.sa_flags = SA_NOMASK | SA_RESTART;
|
|
newa.sa_userdata = "test!";
|
|
|
|
if (sys_sigaction(sig, &newa, &olda) < 0) {
|
|
printf("Failed installing handler for sig #%d!\n", sig);
|
|
}
|
|
}
|
|
|
|
|
|
int32
|
|
thread(void *data)
|
|
{
|
|
printf("Started snoozing thread...\n");
|
|
while (1) {
|
|
if (snooze(1000000000L) == B_INTERRUPTED)
|
|
printf("sig_test (thread): snooze was interrupted!\n");
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
void
|
|
usage()
|
|
{
|
|
printf("usage: sig_test <mode>\n"
|
|
"where `mode' is one of:\n"
|
|
"\t1\tInstalls one handler for all signals and spawns 5 threads\n"
|
|
"\t2\tSame as 1 but does not spawn additional threads\n"
|
|
"\t3\tSets an alarm via set_alarm\n"
|
|
"\n");
|
|
exit(1);
|
|
}
|
|
|
|
|
|
int
|
|
main(int argc, char **argv)
|
|
{
|
|
int i;
|
|
|
|
if (argc != 2)
|
|
usage();
|
|
|
|
switch (argv[1][0]) {
|
|
case '1':
|
|
printf("Spawning some threads...\n");
|
|
for (i=0; i<5; i++)
|
|
resume_thread(spawn_thread(thread, "sig_test aux thread", B_NORMAL_PRIORITY, NULL));
|
|
case '2':
|
|
printf("Installing signal handlers...\n");
|
|
for (i=1; i<=NSIG; i++)
|
|
install_handler(i, sig_handler);
|
|
break;
|
|
case '3':
|
|
install_handler(SIGALRM, alarm_handler);
|
|
sys_set_alarm(5000000, B_PERIODIC_ALARM);
|
|
break;
|
|
}
|
|
printf("Done. Entering sleep mode...\n");
|
|
while (1) {
|
|
if (snooze(1000000000L) == B_INTERRUPTED)
|
|
// this never gets called as the syscall is always restarted
|
|
printf("sig_test (main): snooze was interrupted!\n");
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|