diff options
Diffstat (limited to 'apps/examples/nxflat/tests/signal')
-rw-r--r-- | apps/examples/nxflat/tests/signal/Makefile | 78 | ||||
-rw-r--r-- | apps/examples/nxflat/tests/signal/signal.c | 308 |
2 files changed, 386 insertions, 0 deletions
diff --git a/apps/examples/nxflat/tests/signal/Makefile b/apps/examples/nxflat/tests/signal/Makefile new file mode 100644 index 000000000..d967fbf09 --- /dev/null +++ b/apps/examples/nxflat/tests/signal/Makefile @@ -0,0 +1,78 @@ +############################################################################ +# examples/nxflat/tests/signal/Makefile +# +# Copyright (C) 2009 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt <spudmonkey@racsa.co.cr> +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +-include $(TOPDIR)/.config # Current configuration +-include $(TOPDIR)/Make.defs # Basic make info + +BIN = signal + +R1SRCS = $(BIN).c +R1OBJS = $(R1SRCS:.c=.o) + +R2SRC = $(BIN)-thunk.S +R2OBJ = $(R2SRC:.S=.o) + +all: $(BIN) + +$(R1OBJS): %.o: %.c + @echo "CC: $<" + @$(CC) -c $(CPICFLAGS) $< -o $@ + +$(R2OBJ): %.o: %.S + @echo "AS: $<" + @$(CC) -c $(CPICFLAGS) $< -o $@ + +$(BIN).r1: $(R1OBJS) + @echo "LD: $<" + @$(LD) $(NXFLATLDFLAGS1) -o $@ $^ + +$(R2SRC): $(BIN).r1 + @echo "MK: $<" + @$(MKNXFLAT) -o $@ $^ + +$(BIN).r2: $(R2OBJ) + @echo "LD: $<" + @$(LD) $(NXFLATLDFLAGS2) -o $@ $(R1OBJS) $(R2OBJ) + +$(BIN): $(BIN).r2 + @echo "LD: $<" + @$(LDNXFLAT) $(LDNXFLATFLAGS) -o $@ $^ + +clean: + @rm -f $(BIN) $(R2SRC) *.o *.r1 *.r2 *~ .*.swp core + +install: + @install -D $(BIN) $(ROMFS_DIR)/$(BIN) + diff --git a/apps/examples/nxflat/tests/signal/signal.c b/apps/examples/nxflat/tests/signal/signal.c new file mode 100644 index 000000000..ff1c58305 --- /dev/null +++ b/apps/examples/nxflat/tests/signal/signal.c @@ -0,0 +1,308 @@ +/**************************************************************************** + * examples/nxflat/tests/signal/signal.c + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <sys/types.h> +#include <stdio.h> +#include <stdlib.h> +#include <signal.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +#define USEC_PER_MSEC 1000 +#define MSEC_PER_SEC 1000 +#define USEC_PER_SEC (USEC_PER_MSEC * MSEC_PER_SEC) +#define SHORT_DELAY (USEC_PER_SEC / 3) + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static int sigusr1_rcvd = 0; +static int sigusr2_rcvd = 0; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sigusr1_sighandler + ****************************************************************************/ + +/* NOTE: it is necessary for functions that are referred to by function pointers + * pointer to be declared with global scope (at least for ARM). Otherwise, + * a relocation type that is not supported by NXFLAT is generated by GCC. + */ + +void sigusr1_sighandler(int signo) +{ + printf("sigusr1_sighandler: Received SIGUSR1, signo=%d\n", signo); + sigusr1_rcvd = 1; +} + +/**************************************************************************** + * Name: sigusr2_sigaction + ***************************************************************************/ + +/* NOTE: it is necessary for functions that are referred to by function pointers + * pointer to be declared with global scope (at least for ARM). Otherwise, + * a relocation type that is not supported by NXFLAT is generated by GCC. + */ + +#ifdef __USE_POSIX199309 +void sigusr2_sigaction(int signo, siginfo_t *siginfo, void *arg) +{ + printf("sigusr2_sigaction: Received SIGUSR2, signo=%d siginfo=%p arg=%p\n", + signo, siginfo, arg); + +#ifdef HAVE_SIGQUEUE + if (siginfo) + { + printf(" si_signo = %d\n", siginfo->si_signo); + printf(" si_errno = %d\n", siginfo->si_errno); + printf(" si_code = %d\n", siginfo->si_code); + printf(" si_pid = %d\n", siginfo->si_pid); + printf(" si_uid = %d\n", siginfo->si_uid); + printf(" si_status = %d\n", siginfo->si_status); + printf(" si_utime = %ld\n", (long)siginfo->si_utime); + printf(" si_stime = %ld\n", (long)siginfo->si_stime); + printf(" si_value = %d\n", siginfo->si_value.sival_int); + printf(" si_int = %d\n", siginfo->si_int); + printf(" si_ptr = %p\n", siginfo->si_ptr); + printf(" si_addr = %p\n", siginfo->si_addr); + printf(" si_band = %ld\n", siginfo->si_band); + printf(" si_fd = %d\n", siginfo->si_fd); + } +#endif + sigusr2_rcvd = 1; +} +#else +void sigusr2_sigaction(int signo) +{ + printf("sigusr2_sigaction: Received SIGUSR2, signo=%d\n", signo); + sigusr2_rcvd = 1; +} + +#endif + +/**************************************************************************** + * Name: sigusr2_sighandler + ****************************************************************************/ + +static void sigusr2_sighandler(int signo) +{ + printf("sigusr2_sighandler: Received SIGUSR2, signo=%d\n", signo); + sigusr2_rcvd = 1; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: main + ****************************************************************************/ + +int main(int argc, char **argv) +{ + struct sigaction act; + struct sigaction oact; + void (*old_sigusr1_sighandler)(int signo); + void (*old_sigusr2_sighandler)(int signo); + pid_t mypid = getpid(); +#if defined(__USE_POSIX199309) && defined(HAVE_SIGQUEUE) + sigval_t sigval; +#endif + int status; + + printf("Setting up signal handlers from pid=%d\n", mypid); + + /* Set up so that sigusr1_sighandler will respond to SIGUSR1 */ + + old_sigusr1_sighandler = signal(SIGUSR1, sigusr1_sighandler); + if (old_sigusr1_sighandler == SIG_ERR) + { + fprintf(stderr, "Failed to install SIGUSR1 handler, errno=%d\n", + errno); + exit(1); + } + + printf("Old SIGUSR1 sighandler at %p\n", old_sigusr1_sighandler); + printf("New SIGUSR1 sighandler at %p\n", sigusr1_sighandler); + + /* Set up so that sigusr2_sigaction will respond to SIGUSR2 */ + + memset(&act, 0, sizeof(struct sigaction)); + act.sa_sigaction = sigusr2_sigaction; + act.sa_flags = SA_SIGINFO; + + (void)sigemptyset(&act.sa_mask); + + status = sigaction(SIGUSR2, &act, &oact); + if (status != 0) + { + fprintf(stderr, "Failed to install SIGUSR2 handler, errno=%d\n", + errno); + exit(2); + } + + printf("Old SIGUSR2 sighandler at %p\n", oact.sa_handler); + printf("New SIGUSR2 sighandler at %p\n", sigusr2_sigaction); + printf("Raising SIGUSR1 from pid=%d\n", mypid); + + fflush(stdout); usleep(SHORT_DELAY); + + /* Send SIGUSR1 to ourselves via raise() */ + + status = raise(SIGUSR1); + if (status != 0) + { + fprintf(stderr, "Failed to raise SIGUSR1, errno=%d\n", errno); + exit(3); + } + + usleep(SHORT_DELAY); + printf("SIGUSR1 raised from pid=%d\n", mypid); + + /* Verify that we received SIGUSR1 */ + + if (sigusr1_rcvd == 0) + { + fprintf(stderr, "SIGUSR1 not received\n"); + exit(4); + } + sigusr1_rcvd = 0; + + /* Send SIGUSR2 to ourselves */ + + printf("Killing SIGUSR2 from pid=%d\n", mypid); + fflush(stdout); usleep(SHORT_DELAY); + +#if defined(__USE_POSIX199309) && defined(HAVE_SIGQUEUE) + /* Send SIGUSR2 to ourselves via sigqueue() */ + + sigval.sival_int = 87; + status = sigqueue(mypid, SIGUSR2, sigval); + if (status != 0) + { + fprintf(stderr, "Failed to queue SIGUSR2, errno=%d\n", errno); + exit(5); + } + + usleep(SHORT_DELAY); + printf("SIGUSR2 queued from pid=%d, sigval=97\n", mypid); +#else + /* Send SIGUSR2 to ourselves via kill() */ + + status = kill(mypid, SIGUSR2); + if (status != 0) + { + fprintf(stderr, "Failed to kill SIGUSR2, errno=%d\n", errno); + exit(5); + } + + usleep(SHORT_DELAY); + printf("SIGUSR2 killed from pid=%d\n", mypid); +#endif + /* Verify that SIGUSR2 was received */ + + if (sigusr2_rcvd == 0) + { + fprintf(stderr, "SIGUSR2 not received\n"); + exit(6); + } + sigusr2_rcvd = 0; + + /* Remove the sigusr2_sigaction handler and replace the SIGUSR2 + * handler with sigusr2_sighandler. + */ + + printf("Resetting SIGUSR2 signal handler from pid=%d\n", mypid); + + old_sigusr2_sighandler = signal(SIGUSR2, sigusr2_sighandler); + if (old_sigusr2_sighandler == SIG_ERR) + { + fprintf(stderr, "Failed to install SIGUSR2 handler, errno=%d\n", + errno); + exit(7); + } + + printf("Old SIGUSR2 sighandler at %p\n", old_sigusr2_sighandler); + printf("New SIGUSR2 sighandler at %p\n", sigusr2_sighandler); + + /* Verify that the handler that was removed was sigusr2_sigaction */ + + if ((void*)old_sigusr2_sighandler != (void*)sigusr2_sigaction) + { + fprintf(stderr, + "Old SIGUSR2 signhanlder (%p) is not sigusr2_sigation (%p)\n", + old_sigusr2_sighandler, sigusr2_sigaction); + exit(8); + } + + /* Send SIGUSR2 to ourselves via kill() */ + + printf("Killing SIGUSR2 from pid=%d\n", mypid); + fflush(stdout); usleep(SHORT_DELAY); + + status = kill(mypid, SIGUSR2); + if (status != 0) + { + fprintf(stderr, "Failed to kill SIGUSR2, errno=%d\n", errno); + exit(9); + } + + usleep(SHORT_DELAY); + printf("SIGUSR2 killed from pid=%d\n", mypid); + + /* Verify that SIGUSR2 was received */ + + if (sigusr2_rcvd == 0) + { + fprintf(stderr, "SIGUSR2 not received\n"); + exit(10); + } + sigusr2_rcvd = 0; + + return 0; +} |