The ELF loader is basically functional (needs more testing)
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5265 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
f863b72ced
commit
603f1f0317
@ -383,4 +383,5 @@
|
|||||||
* apps/Makefile: Small change that reduces the number of shell invocations
|
* apps/Makefile: Small change that reduces the number of shell invocations
|
||||||
by one (Mike Smith).
|
by one (Mike Smith).
|
||||||
* apps/examples/elf: Test example for the ELF loader.
|
* apps/examples/elf: Test example for the ELF loader.
|
||||||
|
* apps/examples/elf: The ELF module test example appears fully functional.
|
||||||
|
|
||||||
|
@ -318,7 +318,12 @@ examples/elf
|
|||||||
|
|
||||||
NOTES:
|
NOTES:
|
||||||
|
|
||||||
1. Your top-level nuttx/Make.defs file must include an approproate definition,
|
1. CFLAGS should be provided in CELFFLAGS. RAM and FLASH memory regions
|
||||||
|
may require long allcs. For ARM, this might be:
|
||||||
|
|
||||||
|
CELFFLAGS = $(CFLAGS) -mlong-calls
|
||||||
|
|
||||||
|
2. Your top-level nuttx/Make.defs file must alos include an approproate definition,
|
||||||
LDELFFLAGS, to generate a relocatable ELF object. With GNU LD, this should
|
LDELFFLAGS, to generate a relocatable ELF object. With GNU LD, this should
|
||||||
include '-r' and '-e main' (or _main on some platforms).
|
include '-r' and '-e main' (or _main on some platforms).
|
||||||
|
|
||||||
@ -327,24 +332,24 @@ examples/elf
|
|||||||
If you use GCC to link, you make also need to include '-nostdlib' or
|
If you use GCC to link, you make also need to include '-nostdlib' or
|
||||||
'-nostartfiles' and '-nodefaultlibs'.
|
'-nostartfiles' and '-nodefaultlibs'.
|
||||||
|
|
||||||
2. This example also requires genromfs. genromfs can be build as part of the
|
3. This example also requires genromfs. genromfs can be build as part of the
|
||||||
nuttx toolchain. Or can built from the genromfs sources that can be found
|
nuttx toolchain. Or can built from the genromfs sources that can be found
|
||||||
at misc/tools/genromfs-0.5.2.tar.gz. In any event, the PATH variable must
|
at misc/tools/genromfs-0.5.2.tar.gz. In any event, the PATH variable must
|
||||||
include the path to the genromfs executable.
|
include the path to the genromfs executable.
|
||||||
|
|
||||||
3. ELF size: The ELF files in this example are, be default, quite large
|
4. ELF size: The ELF files in this example are, be default, quite large
|
||||||
because they include a lot of "build garbage". You can greatly reduce the
|
because they include a lot of "build garbage". You can greatly reduce the
|
||||||
size of the ELF binaries are using the 'objcopy --strip-unneeded' command to
|
size of the ELF binaries are using the 'objcopy --strip-unneeded' command to
|
||||||
remove un-necessary information from the ELF files.
|
remove un-necessary information from the ELF files.
|
||||||
|
|
||||||
4. Simulator. You cannot use this example with the the NuttX simulator on
|
5. Simulator. You cannot use this example with the the NuttX simulator on
|
||||||
Cygwin. That is because the Cygwin GCC does not generate ELF file but
|
Cygwin. That is because the Cygwin GCC does not generate ELF file but
|
||||||
rather some Windows-native binary format.
|
rather some Windows-native binary format.
|
||||||
|
|
||||||
If you really want to do this, you can create a NuttX x86 buildroot toolchain
|
If you really want to do this, you can create a NuttX x86 buildroot toolchain
|
||||||
and use that be build the ELF executables for the ROMFS file system.
|
and use that be build the ELF executables for the ROMFS file system.
|
||||||
|
|
||||||
5. Linker scripts. You might also want to use a linker scripts to combine
|
6. Linker scripts. You might also want to use a linker scripts to combine
|
||||||
sections better. An example linker script is at nuttx/binfmt/libelf/gnu-elf.ld.
|
sections better. An example linker script is at nuttx/binfmt/libelf/gnu-elf.ld.
|
||||||
That example might have to be tuned for your particular linker output to
|
That example might have to be tuned for your particular linker output to
|
||||||
position additional sections correctly. The GNU LD LDELFFLAGS then might
|
position additional sections correctly. The GNU LD LDELFFLAGS then might
|
||||||
|
@ -39,29 +39,29 @@ include $(APPDIR)/Make.defs
|
|||||||
|
|
||||||
# ELF Example
|
# ELF Example
|
||||||
|
|
||||||
ASRCS =
|
ASRCS =
|
||||||
CSRCS = elf_main.c
|
CSRCS = elf_main.c symtab.c
|
||||||
|
|
||||||
AOBJS = $(ASRCS:.S=$(OBJEXT))
|
AOBJS = $(ASRCS:.S=$(OBJEXT))
|
||||||
COBJS = $(CSRCS:.c=$(OBJEXT))
|
COBJS = $(CSRCS:.c=$(OBJEXT))
|
||||||
|
|
||||||
SRCS = $(ASRCS) $(CSRCS)
|
SRCS = $(ASRCS) $(CSRCS)
|
||||||
OBJS = $(AOBJS) $(COBJS)
|
OBJS = $(AOBJS) $(COBJS)
|
||||||
|
|
||||||
ifeq ($(WINTOOL),y)
|
ifeq ($(WINTOOL),y)
|
||||||
BIN = "${shell cygpath -w $(APPDIR)/libapps$(LIBEXT)}"
|
BIN = "${shell cygpath -w $(APPDIR)/libapps$(LIBEXT)}"
|
||||||
else
|
else
|
||||||
BIN = "$(APPDIR)/libapps$(LIBEXT)"
|
BIN = "$(APPDIR)/libapps$(LIBEXT)"
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ROOTDEPPATH = --dep-path .
|
ROOTDEPPATH = --dep-path . --dep-path tests
|
||||||
|
|
||||||
# Common build
|
# Build targets
|
||||||
|
|
||||||
VPATH =
|
VPATH = tests
|
||||||
|
|
||||||
all: .built
|
all: .built
|
||||||
.PHONY: headers clean_tests clean depend disclean
|
.PHONY: really_build clean_tests clean depend disclean
|
||||||
|
|
||||||
$(AOBJS): %$(OBJEXT): %.S
|
$(AOBJS): %$(OBJEXT): %.S
|
||||||
$(call ASSEMBLE, $<, $@)
|
$(call ASSEMBLE, $<, $@)
|
||||||
@ -69,15 +69,21 @@ $(AOBJS): %$(OBJEXT): %.S
|
|||||||
$(COBJS): %$(OBJEXT): %.c
|
$(COBJS): %$(OBJEXT): %.c
|
||||||
$(call COMPILE, $<, $@)
|
$(call COMPILE, $<, $@)
|
||||||
|
|
||||||
headers:
|
# This is a little messy. The build is broken into two pieces: (1) the
|
||||||
@$(MAKE) -C tests TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" CROSSDEV=$(CROSSDEV)
|
# tests/ subdir build that auto-generates several files, and (2) the real
|
||||||
|
# build. This is done because we need a fresh build context after auto-
|
||||||
|
# generating the source files.
|
||||||
|
|
||||||
.built: headers $(OBJS)
|
really_build: $(OBJS)
|
||||||
@( for obj in $(OBJS) ; do \
|
@( for obj in $(OBJS) ; do \
|
||||||
$(call ARCHIVE, $(BIN), $${obj}); \
|
$(call ARCHIVE, $(BIN), $${obj}); \
|
||||||
done ; )
|
done ; )
|
||||||
@touch .built
|
@touch .built
|
||||||
|
|
||||||
|
.built:
|
||||||
|
@$(MAKE) -C tests TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" CROSSDEV=$(CROSSDEV)
|
||||||
|
@$(MAKE) TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" really_build
|
||||||
|
|
||||||
context:
|
context:
|
||||||
|
|
||||||
# We can't make dependencies in this directory because the required
|
# We can't make dependencies in this directory because the required
|
||||||
|
@ -52,10 +52,10 @@
|
|||||||
#include <nuttx/ramdisk.h>
|
#include <nuttx/ramdisk.h>
|
||||||
#include <nuttx/binfmt/binfmt.h>
|
#include <nuttx/binfmt/binfmt.h>
|
||||||
#include <nuttx/binfmt/elf.h>
|
#include <nuttx/binfmt/elf.h>
|
||||||
|
#include <nuttx/binfmt/symtab.h>
|
||||||
|
|
||||||
#include "tests/romfs.h"
|
#include "tests/romfs.h"
|
||||||
#include "tests/dirlist.h"
|
#include "tests/dirlist.h"
|
||||||
#include "tests/symtab.h"
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Definitions
|
* Definitions
|
||||||
@ -134,6 +134,13 @@ static const char delimiter[] =
|
|||||||
|
|
||||||
static char path[128];
|
static char path[128];
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Symbols from Auto-Generated Code
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
extern const struct symtab_s exports[];
|
||||||
|
extern const int nexports;
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -207,7 +214,7 @@ int elf_main(int argc, char *argv[])
|
|||||||
|
|
||||||
bin.filename = path;
|
bin.filename = path;
|
||||||
bin.exports = exports;
|
bin.exports = exports;
|
||||||
bin.nexports = NEXPORTS;
|
bin.nexports = nexports;
|
||||||
|
|
||||||
ret = load_module(&bin);
|
ret = load_module(&bin);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
@ -34,35 +34,53 @@
|
|||||||
############################################################################
|
############################################################################
|
||||||
|
|
||||||
# Most of these do no build yet
|
# Most of these do no build yet
|
||||||
SUBDIRS = errno hello hello++ longjmp mutex pthread signal task struct
|
|
||||||
|
ALL_SUBDIRS = errno hello hello++ longjmp mutex pthread signal task struct
|
||||||
|
BUILD_SUBDIRS = errno hello task struct
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_HAVE_CXX),y)
|
||||||
|
BUILD_SUBDIRS += hello++
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_EXAMPLES_ELF_LONGJMP),y)
|
||||||
|
BUILD_SUBDIRS += longjmp
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq ($(CONFIG_DISABLE_PTHREAD),y)
|
||||||
|
BUILD_SUBDIRS += mutex pthread
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq ($(CONFIG_DISABLE_SIGNALS),y)
|
||||||
|
BUILD_SUBDIRS += signal
|
||||||
|
endif
|
||||||
|
|
||||||
ELF_DIR = $(APPDIR)/examples/elf
|
ELF_DIR = $(APPDIR)/examples/elf
|
||||||
TESTS_DIR = $(ELF_DIR)/tests
|
TESTS_DIR = $(ELF_DIR)/tests
|
||||||
ROMFS_DIR = $(TESTS_DIR)/romfs
|
ROMFS_DIR = $(TESTS_DIR)/romfs
|
||||||
ROMFS_IMG = $(TESTS_DIR)/romfs.img
|
ROMFS_IMG = $(TESTS_DIR)/romfs.img
|
||||||
ROMFS_HDR = $(TESTS_DIR)/romfs.h
|
ROMFS_HDR = $(TESTS_DIR)/romfs.h
|
||||||
ROMFS_DIRLIST = $(TESTS_DIR)/dirlist.h
|
DIRLIST_HDR = $(TESTS_DIR)/dirlist.h
|
||||||
SYMTAB = $(TESTS_DIR)/symtab.h
|
SYMTAB_SRC = $(TESTS_DIR)/symtab.c
|
||||||
|
|
||||||
define DIR_template
|
define DIR_template
|
||||||
$(1)_$(2):
|
$(1)_$(2):
|
||||||
@$(MAKE) -C $(1) $(3) TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" ROMFS_DIR="$(ROMFS_DIR)" CROSSDEV=$(CROSSDEV)
|
@$(MAKE) -C $(1) $(3) TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" ROMFS_DIR="$(ROMFS_DIR)" CROSSDEV=$(CROSSDEV)
|
||||||
endef
|
endef
|
||||||
|
|
||||||
all: $(ROMFS_HDR) $(ROMFS_DIRLIST) $(SYMTAB)
|
all: $(ROMFS_HDR) $(DIRLIST_HDR) $(SYMTAB_SRC)
|
||||||
.PHONY: all build clean install populate
|
.PHONY: all build clean install populate
|
||||||
|
|
||||||
$(foreach DIR, $(SUBDIRS), $(eval $(call DIR_template,$(DIR),build, all)))
|
$(foreach DIR, $(BUILD_SUBDIRS), $(eval $(call DIR_template,$(DIR),build, all)))
|
||||||
$(foreach DIR, $(SUBDIRS), $(eval $(call DIR_template,$(DIR),clean,clean)))
|
$(foreach DIR, $(ALL_SUBDIRS), $(eval $(call DIR_template,$(DIR),clean,clean)))
|
||||||
$(foreach DIR, $(SUBDIRS), $(eval $(call DIR_template,$(DIR),install,install)))
|
$(foreach DIR, $(BUILD_SUBDIRS), $(eval $(call DIR_template,$(DIR),install,install)))
|
||||||
|
|
||||||
# Build program(s) in each sud-directory
|
# Build program(s) in each sud-directory
|
||||||
|
|
||||||
build: $(foreach DIR, $(SUBDIRS), $(DIR)_build)
|
build: $(foreach DIR, $(BUILD_SUBDIRS), $(DIR)_build)
|
||||||
|
|
||||||
# Install each program in the romfs directory
|
# Install each program in the romfs directory
|
||||||
|
|
||||||
install: $(foreach DIR, $(SUBDIRS), $(DIR)_install)
|
install: $(foreach DIR, $(BUILD_SUBDIRS), $(DIR)_install)
|
||||||
|
|
||||||
# Create the romfs directory
|
# Create the romfs directory
|
||||||
|
|
||||||
@ -85,16 +103,16 @@ $(ROMFS_HDR) : $(ROMFS_IMG)
|
|||||||
|
|
||||||
# Create the dirlist.h header file from the romfs directory
|
# Create the dirlist.h header file from the romfs directory
|
||||||
|
|
||||||
$(ROMFS_DIRLIST) : populate
|
$(DIRLIST_HDR) : populate
|
||||||
@$(TESTS_DIR)/mkdirlist.sh $(ROMFS_DIR) >$@
|
@$(TESTS_DIR)/mkdirlist.sh $(ROMFS_DIR) >$@
|
||||||
|
|
||||||
# Create the exported symbol table list from the derived *-thunk.S files
|
# Create the exported symbol table list from the derived *-thunk.S files
|
||||||
|
|
||||||
$(SYMTAB): build
|
$(SYMTAB_SRC): build
|
||||||
@$(TESTS_DIR)/mksymtab.sh $(TESTS_DIR) >$@
|
@$(TESTS_DIR)/mksymtab.sh -t varlist.tmp $(ROMFS_DIR) >$@
|
||||||
|
|
||||||
# Clean each subdirectory
|
# Clean each subdirectory
|
||||||
|
|
||||||
clean: $(foreach DIR, $(SUBDIRS), $(DIR)_clean)
|
clean: $(foreach DIR, $(ALL_SUBDIRS), $(DIR)_clean)
|
||||||
@rm -f $(ROMFS_HDR) $(ROMFS_IMG) $(SYMTAB)
|
@rm -f $(ROMFS_HDR) $(ROMFS_IMG) $(SYMTAB_SRC) varlist.tmp
|
||||||
@rm -rf $(ROMFS_DIR)
|
@rm -rf $(ROMFS_DIR)
|
||||||
|
@ -45,7 +45,7 @@ all: $(BIN)
|
|||||||
|
|
||||||
$(OBJS): %.o: %.c
|
$(OBJS): %.o: %.c
|
||||||
@echo "CC: $<"
|
@echo "CC: $<"
|
||||||
@$(CC) -c $(CFLAGS) $< -o $@
|
@$(CC) -c $(CELFFLAGS) $< -o $@
|
||||||
|
|
||||||
$(BIN): $(OBJS)
|
$(BIN): $(OBJS)
|
||||||
@echo "LD: $<"
|
@echo "LD: $<"
|
||||||
|
@ -45,7 +45,7 @@ all: $(BIN)
|
|||||||
|
|
||||||
$(OBJS): %.o: %.c
|
$(OBJS): %.o: %.c
|
||||||
@echo "CC: $<"
|
@echo "CC: $<"
|
||||||
@$(CC) -c $(CFLAGS) $< -o $@
|
@$(CC) -c $(CELFFLAGS) $< -o $@
|
||||||
|
|
||||||
$(BIN): $(OBJS)
|
$(BIN): $(OBJS)
|
||||||
@echo "LD: $<"
|
@echo "LD: $<"
|
||||||
|
@ -45,7 +45,7 @@ all: $(BIN)
|
|||||||
|
|
||||||
$(OBJS): %.o: %.c
|
$(OBJS): %.o: %.c
|
||||||
@echo "CC: $<"
|
@echo "CC: $<"
|
||||||
@$(CC) -c $(CFLAGS) $< -o $@
|
@$(CC) -c $(CELFFLAGS) $< -o $@
|
||||||
|
|
||||||
$(BIN): $(OBJS)
|
$(BIN): $(OBJS)
|
||||||
@echo "LD: $<"
|
@echo "LD: $<"
|
||||||
|
@ -1,6 +1,24 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
usage="Usage: %0 <test-dir-path>"
|
usage="Usage: $0 [-t <tmp-file>] <test-dir-path>"
|
||||||
|
|
||||||
|
# Check for the optional tempory file name
|
||||||
|
|
||||||
|
tmpfile=varlist.tmp
|
||||||
|
if [ "X${1}" = "X-t" ]; then
|
||||||
|
shift
|
||||||
|
tmpfile=$1
|
||||||
|
shift
|
||||||
|
|
||||||
|
if [ -z "$tmpfile" ]; then
|
||||||
|
echo "ERROR: Missing <tmpfile>"
|
||||||
|
echo ""
|
||||||
|
echo $usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for the required ROMFS directory path
|
||||||
|
|
||||||
dir=$1
|
dir=$1
|
||||||
if [ -z "$dir" ]; then
|
if [ -z "$dir" ]; then
|
||||||
@ -17,23 +35,33 @@ if [ ! -d "$dir" ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
varlist=`find $dir -name "*-thunk.S"| xargs grep -h asciz | cut -f3 | sort | uniq`
|
# Extract all of the undefined symbols from the ELF files and create a
|
||||||
|
# list of sorted, unique undefined variable names.
|
||||||
|
|
||||||
echo "#ifndef __EXAMPLES_ELF_TESTS_SYMTAB_H"
|
varlist=`find ${dir} -executable -type f | xargs nm | fgrep ' U ' | sed -e "s/^[ ]*//g" | cut -d' ' -f2 | sort | uniq`
|
||||||
echo "#define __EXAMPLES_ELF_TESTS_SYMTAB_H"
|
|
||||||
echo ""
|
# Now output the symbol table as a structure in a C source file. All
|
||||||
|
# undefined symbols are declared as void* types. If the toolchain does
|
||||||
|
# any kind of checking for function vs. data objects, then this could
|
||||||
|
# faile
|
||||||
|
|
||||||
|
echo "#include <nuttx/compiler.h>"
|
||||||
echo "#include <nuttx/binfmt/symtab.h>"
|
echo "#include <nuttx/binfmt/symtab.h>"
|
||||||
echo ""
|
echo ""
|
||||||
echo "static const struct symtab_s exports[] = "
|
|
||||||
|
for var in $varlist; do
|
||||||
|
echo "extern void *${var};"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "const struct symtab_s exports[] = "
|
||||||
echo "{"
|
echo "{"
|
||||||
|
|
||||||
for string in $varlist; do
|
for var in $varlist; do
|
||||||
var=`echo $string | sed -e "s/\"//g"`
|
echo " {\"${var}\", &${var}},"
|
||||||
echo " {$string, $var},"
|
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "};"
|
echo "};"
|
||||||
echo "#define NEXPORTS (sizeof(exports)/sizeof(struct symtab_s))"
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "#endif /* __EXAMPLES_ELF_TESTS_SYMTAB_H */"
|
echo "const int nexports = sizeof(exports) / sizeof(struct symtab_s);"
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ all: $(BIN)
|
|||||||
|
|
||||||
$(OBJS): %.o: %.c
|
$(OBJS): %.o: %.c
|
||||||
@echo "CC: $<"
|
@echo "CC: $<"
|
||||||
@$(CC) -c $(CFLAGS) $< -o $@
|
@$(CC) -c $(CELFFLAGS) $< -o $@
|
||||||
|
|
||||||
$(BIN): $(OBJS)
|
$(BIN): $(OBJS)
|
||||||
@echo "LD: $<"
|
@echo "LD: $<"
|
||||||
|
@ -45,7 +45,7 @@ all: $(BIN)
|
|||||||
|
|
||||||
$(OBJS): %.o: %.c
|
$(OBJS): %.o: %.c
|
||||||
@echo "CC: $<"
|
@echo "CC: $<"
|
||||||
@$(CC) -c $(CFLAGS) $< -o $@
|
@$(CC) -c $(CELFFLAGS) $< -o $@
|
||||||
|
|
||||||
$(BIN): $(OBJS)
|
$(BIN): $(OBJS)
|
||||||
@echo "LD: $<"
|
@echo "LD: $<"
|
||||||
|
@ -45,7 +45,7 @@ all: $(BIN)
|
|||||||
|
|
||||||
$(OBJS): %.o: %.c
|
$(OBJS): %.o: %.c
|
||||||
@echo "CC: $<"
|
@echo "CC: $<"
|
||||||
@$(CC) -c $(CFLAGS) $< -o $@
|
@$(CC) -c $(CELFFLAGS) $< -o $@
|
||||||
|
|
||||||
$(BIN): $(OBJS)
|
$(BIN): $(OBJS)
|
||||||
@echo "LD: $<"
|
@echo "LD: $<"
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
@ -66,22 +67,7 @@ static int sigusr2_rcvd = 0;
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: sigusr1_sighandler
|
* Name: siguser_action
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/* 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 ELF 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
|
/* NOTE: it is necessary for functions that are referred to by function pointers
|
||||||
@ -89,50 +75,33 @@ void sigusr1_sighandler(int signo)
|
|||||||
* a relocation type that is not supported by ELF is generated by GCC.
|
* a relocation type that is not supported by ELF is generated by GCC.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __USE_POSIX199309
|
void siguser_action(int signo, siginfo_t *siginfo, void *arg)
|
||||||
void sigusr2_sigaction(int signo, siginfo_t *siginfo, void *arg)
|
|
||||||
{
|
{
|
||||||
printf("sigusr2_sigaction: Received SIGUSR2, signo=%d siginfo=%p arg=%p\n",
|
printf("siguser_action: Received signo=%d siginfo=%p arg=%p\n",
|
||||||
signo, siginfo, arg);
|
signo, siginfo, arg);
|
||||||
|
|
||||||
#ifdef HAVE_SIGQUEUE
|
if (signo == SIGUSR1)
|
||||||
|
{
|
||||||
|
printf(" SIGUSR1 received\n");
|
||||||
|
sigusr2_rcvd = 1;
|
||||||
|
}
|
||||||
|
else if (signo == SIGUSR2)
|
||||||
|
{
|
||||||
|
printf(" SIGUSR2 received\n");
|
||||||
|
sigusr1_rcvd = 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf(" ERROR: Unexpected signal\n");
|
||||||
|
}
|
||||||
|
|
||||||
if (siginfo)
|
if (siginfo)
|
||||||
{
|
{
|
||||||
|
printf("siginfo:\n");
|
||||||
printf(" si_signo = %d\n", siginfo->si_signo);
|
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_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_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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -146,39 +115,36 @@ static void sigusr2_sighandler(int signo)
|
|||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct sigaction act;
|
struct sigaction act;
|
||||||
struct sigaction oact;
|
struct sigaction oact1;
|
||||||
void (*old_sigusr1_sighandler)(int signo);
|
struct sigaction oact2;
|
||||||
void (*old_sigusr2_sighandler)(int signo);
|
|
||||||
pid_t mypid = getpid();
|
pid_t mypid = getpid();
|
||||||
#if defined(__USE_POSIX199309) && defined(HAVE_SIGQUEUE)
|
union sigval sigval;
|
||||||
sigval_t sigval;
|
|
||||||
#endif
|
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
printf("Setting up signal handlers from pid=%d\n", mypid);
|
printf("Setting up signal handlers from pid=%d\n", mypid);
|
||||||
|
|
||||||
/* Set up so that sigusr1_sighandler will respond to SIGUSR1 */
|
/* Set up so that siguser_action 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));
|
memset(&act, 0, sizeof(struct sigaction));
|
||||||
act.sa_sigaction = sigusr2_sigaction;
|
act.sa_sigaction = siguser_action;
|
||||||
act.sa_flags = SA_SIGINFO;
|
act.sa_flags = SA_SIGINFO;
|
||||||
|
|
||||||
(void)sigemptyset(&act.sa_mask);
|
(void)sigemptyset(&act.sa_mask);
|
||||||
|
|
||||||
status = sigaction(SIGUSR2, &act, &oact);
|
status = sigaction(SIGUSR1, &act, &oact1);
|
||||||
|
if (status != 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Failed to install SIGUSR1 handler, errno=%d\n",
|
||||||
|
errno);
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Old SIGUSR1 sighandler at %p\n", oact1.sa_handler);
|
||||||
|
printf("New SIGUSR1 sighandler at %p\n", siguser_action);
|
||||||
|
|
||||||
|
/* Set up so that siguser_action will respond to SIGUSR2 */
|
||||||
|
|
||||||
|
status = sigaction(SIGUSR2, &act, &oact2);
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Failed to install SIGUSR2 handler, errno=%d\n",
|
fprintf(stderr, "Failed to install SIGUSR2 handler, errno=%d\n",
|
||||||
@ -186,18 +152,19 @@ int main(int argc, char **argv)
|
|||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Old SIGUSR2 sighandler at %p\n", oact.sa_handler);
|
printf("Old SIGUSR2 sighandler at %p\n", oact2.sa_handler);
|
||||||
printf("New SIGUSR2 sighandler at %p\n", sigusr2_sigaction);
|
printf("New SIGUSR2 sighandler at %p\n", siguser_action);
|
||||||
printf("Raising SIGUSR1 from pid=%d\n", mypid);
|
printf("Raising SIGUSR1 from pid=%d\n", mypid);
|
||||||
|
|
||||||
fflush(stdout); usleep(SHORT_DELAY);
|
fflush(stdout); usleep(SHORT_DELAY);
|
||||||
|
|
||||||
/* Send SIGUSR1 to ourselves via raise() */
|
/* Send SIGUSR1 to ourselves via kill() */
|
||||||
|
|
||||||
status = raise(SIGUSR1);
|
printf("Kill-ing SIGUSR1 from pid=%d\n", mypid);
|
||||||
|
status = kill(0, SIGUSR1);
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Failed to raise SIGUSR1, errno=%d\n", errno);
|
fprintf(stderr, "Failed to kill SIGUSR1, errno=%d\n", errno);
|
||||||
exit(3);
|
exit(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,14 +178,14 @@ int main(int argc, char **argv)
|
|||||||
fprintf(stderr, "SIGUSR1 not received\n");
|
fprintf(stderr, "SIGUSR1 not received\n");
|
||||||
exit(4);
|
exit(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
sigusr1_rcvd = 0;
|
sigusr1_rcvd = 0;
|
||||||
|
|
||||||
/* Send SIGUSR2 to ourselves */
|
/* Send SIGUSR2 to ourselves */
|
||||||
|
|
||||||
printf("Killing SIGUSR2 from pid=%d\n", mypid);
|
printf("sigqueue-ing SIGUSR2 from pid=%d\n", mypid);
|
||||||
fflush(stdout); usleep(SHORT_DELAY);
|
fflush(stdout); usleep(SHORT_DELAY);
|
||||||
|
|
||||||
#if defined(__USE_POSIX199309) && defined(HAVE_SIGQUEUE)
|
|
||||||
/* Send SIGUSR2 to ourselves via sigqueue() */
|
/* Send SIGUSR2 to ourselves via sigqueue() */
|
||||||
|
|
||||||
sigval.sival_int = 87;
|
sigval.sival_int = 87;
|
||||||
@ -230,20 +197,8 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
usleep(SHORT_DELAY);
|
usleep(SHORT_DELAY);
|
||||||
printf("SIGUSR2 queued from pid=%d, sigval=97\n", mypid);
|
printf("SIGUSR2 queued from pid=%d, sigval=87\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 */
|
/* Verify that SIGUSR2 was received */
|
||||||
|
|
||||||
if (sigusr2_rcvd == 0)
|
if (sigusr2_rcvd == 0)
|
||||||
@ -251,32 +206,33 @@ int main(int argc, char **argv)
|
|||||||
fprintf(stderr, "SIGUSR2 not received\n");
|
fprintf(stderr, "SIGUSR2 not received\n");
|
||||||
exit(6);
|
exit(6);
|
||||||
}
|
}
|
||||||
|
|
||||||
sigusr2_rcvd = 0;
|
sigusr2_rcvd = 0;
|
||||||
|
|
||||||
/* Remove the sigusr2_sigaction handler and replace the SIGUSR2
|
/* Remove the siguser_action handler and replace the SIGUSR2
|
||||||
* handler with sigusr2_sighandler.
|
* handler with sigusr2_sighandler.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
printf("Resetting SIGUSR2 signal handler from pid=%d\n", mypid);
|
printf("Resetting SIGUSR2 signal handler from pid=%d\n", mypid);
|
||||||
|
|
||||||
old_sigusr2_sighandler = signal(SIGUSR2, sigusr2_sighandler);
|
status = sigaction(SIGUSR2, &oact2, &act);
|
||||||
if (old_sigusr2_sighandler == SIG_ERR)
|
if (status != 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Failed to install SIGUSR2 handler, errno=%d\n",
|
fprintf(stderr, "Failed to install SIGUSR1 handler, errno=%d\n",
|
||||||
errno);
|
errno);
|
||||||
exit(7);
|
exit(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Old SIGUSR2 sighandler at %p\n", old_sigusr2_sighandler);
|
printf("Old SIGUSR1 sighandler at %p\n", act.sa_handler);
|
||||||
printf("New SIGUSR2 sighandler at %p\n", sigusr2_sighandler);
|
printf("New SIGUSR1 sighandler at %p\n", oact1.sa_handler);
|
||||||
|
|
||||||
/* Verify that the handler that was removed was sigusr2_sigaction */
|
/* Verify that the handler that was removed was siguser_action */
|
||||||
|
|
||||||
if ((void*)old_sigusr2_sighandler != (void*)sigusr2_sigaction)
|
if ((void*)act.sa_handler != (void*)siguser_action)
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Old SIGUSR2 signhanlder (%p) is not sigusr2_sigation (%p)\n",
|
"Old SIGUSR2 signal handler (%p) is not siguser_action (%p)\n",
|
||||||
old_sigusr2_sighandler, sigusr2_sigaction);
|
act.sa_handler, siguser_action);
|
||||||
exit(8);
|
exit(8);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,6 +258,7 @@ int main(int argc, char **argv)
|
|||||||
fprintf(stderr, "SIGUSR2 not received\n");
|
fprintf(stderr, "SIGUSR2 not received\n");
|
||||||
exit(10);
|
exit(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
sigusr2_rcvd = 0;
|
sigusr2_rcvd = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
-include $(TOPDIR)/.config
|
-include $(TOPDIR)/.config
|
||||||
-include $(TOPDIR)/Make.defs
|
-include $(TOPDIR)/Make.defs
|
||||||
|
|
||||||
CFLAGS += -I.
|
CELFFLAGS += -I.
|
||||||
|
|
||||||
BIN = struct
|
BIN = struct
|
||||||
SRCS = struct_main.c struct_dummy.c
|
SRCS = struct_main.c struct_dummy.c
|
||||||
@ -46,7 +46,7 @@ all: $(BIN)
|
|||||||
|
|
||||||
$(OBJS): %.o: %.c
|
$(OBJS): %.o: %.c
|
||||||
@echo "CC: $<"
|
@echo "CC: $<"
|
||||||
@$(CC) -c $(CFLAGS) $< -o $@
|
@$(CC) -c $(CELFFLAGS) $< -o $@
|
||||||
|
|
||||||
$(BIN): $(OBJS)
|
$(BIN): $(OBJS)
|
||||||
@echo "LD: $<"
|
@echo "LD: $<"
|
||||||
|
@ -45,7 +45,7 @@ all: $(BIN)
|
|||||||
|
|
||||||
$(OBJS): %.o: %.c
|
$(OBJS): %.o: %.c
|
||||||
@echo "CC: $<"
|
@echo "CC: $<"
|
||||||
@$(CC) -c $(CFLAGS) $< -o $@
|
@$(CC) -c $(CELFFLAGS) $< -o $@
|
||||||
|
|
||||||
$(BIN): $(OBJS)
|
$(BIN): $(OBJS)
|
||||||
@echo "LD: $<"
|
@echo "LD: $<"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
usage="Usage: %0 <test-dir-path>"
|
usage="Usage: $0 <test-dir-path>"
|
||||||
|
|
||||||
dir=$1
|
dir=$1
|
||||||
if [ -z "$dir" ]; then
|
if [ -z "$dir" ]; then
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* examples/nxflat/tests/signal/signal.c
|
* examples/nxflat/tests/signal/signal.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2009, 2012 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -67,73 +67,41 @@ static int sigusr2_rcvd = 0;
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: sigusr1_sighandler
|
* Name: siguser_action
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/* 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
|
/* 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,
|
* 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.
|
* a relocation type that is not supported by ELF is generated by GCC.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __USE_POSIX199309
|
void siguser_action(int signo, siginfo_t *siginfo, void *arg)
|
||||||
void sigusr2_sigaction(int signo, siginfo_t *siginfo, void *arg)
|
|
||||||
{
|
{
|
||||||
printf("sigusr2_sigaction: Received SIGUSR2, signo=%d siginfo=%p arg=%p\n",
|
printf("siguser_action: Received signo=%d siginfo=%p arg=%p\n",
|
||||||
signo, siginfo, arg);
|
signo, siginfo, arg);
|
||||||
|
|
||||||
#ifdef HAVE_SIGQUEUE
|
if (signo == SIGUSR1)
|
||||||
|
{
|
||||||
|
printf(" SIGUSR1 received\n");
|
||||||
|
sigusr2_rcvd = 1;
|
||||||
|
}
|
||||||
|
else if (signo == SIGUSR2)
|
||||||
|
{
|
||||||
|
printf(" SIGUSR2 received\n");
|
||||||
|
sigusr1_rcvd = 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf(" ERROR: Unexpected signal\n");
|
||||||
|
}
|
||||||
|
|
||||||
if (siginfo)
|
if (siginfo)
|
||||||
{
|
{
|
||||||
|
printf("siginfo:\n");
|
||||||
printf(" si_signo = %d\n", siginfo->si_signo);
|
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_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_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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -147,39 +115,36 @@ static void sigusr2_sighandler(int signo)
|
|||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct sigaction act;
|
struct sigaction act;
|
||||||
struct sigaction oact;
|
struct sigaction oact1;
|
||||||
void (*old_sigusr1_sighandler)(int signo);
|
struct sigaction oact2;
|
||||||
void (*old_sigusr2_sighandler)(int signo);
|
|
||||||
pid_t mypid = getpid();
|
pid_t mypid = getpid();
|
||||||
#if defined(__USE_POSIX199309) && defined(HAVE_SIGQUEUE)
|
union sigval sigval;
|
||||||
sigval_t sigval;
|
|
||||||
#endif
|
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
printf("Setting up signal handlers from pid=%d\n", mypid);
|
printf("Setting up signal handlers from pid=%d\n", mypid);
|
||||||
|
|
||||||
/* Set up so that sigusr1_sighandler will respond to SIGUSR1 */
|
/* Set up so that siguser_action 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));
|
memset(&act, 0, sizeof(struct sigaction));
|
||||||
act.sa_sigaction = sigusr2_sigaction;
|
act.sa_sigaction = siguser_action;
|
||||||
act.sa_flags = SA_SIGINFO;
|
act.sa_flags = SA_SIGINFO;
|
||||||
|
|
||||||
(void)sigemptyset(&act.sa_mask);
|
(void)sigemptyset(&act.sa_mask);
|
||||||
|
|
||||||
status = sigaction(SIGUSR2, &act, &oact);
|
status = sigaction(SIGUSR1, &act, &oact1);
|
||||||
|
if (status != 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Failed to install SIGUSR1 handler, errno=%d\n",
|
||||||
|
errno);
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Old SIGUSR1 sighandler at %p\n", oact1.sa_handler);
|
||||||
|
printf("New SIGUSR1 sighandler at %p\n", siguser_action);
|
||||||
|
|
||||||
|
/* Set up so that siguser_action will respond to SIGUSR2 */
|
||||||
|
|
||||||
|
status = sigaction(SIGUSR2, &act, &oact2);
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Failed to install SIGUSR2 handler, errno=%d\n",
|
fprintf(stderr, "Failed to install SIGUSR2 handler, errno=%d\n",
|
||||||
@ -187,18 +152,19 @@ int main(int argc, char **argv)
|
|||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Old SIGUSR2 sighandler at %p\n", oact.sa_handler);
|
printf("Old SIGUSR2 sighandler at %p\n", oact2.sa_handler);
|
||||||
printf("New SIGUSR2 sighandler at %p\n", sigusr2_sigaction);
|
printf("New SIGUSR2 sighandler at %p\n", siguser_action);
|
||||||
printf("Raising SIGUSR1 from pid=%d\n", mypid);
|
printf("Raising SIGUSR1 from pid=%d\n", mypid);
|
||||||
|
|
||||||
fflush(stdout); usleep(SHORT_DELAY);
|
fflush(stdout); usleep(SHORT_DELAY);
|
||||||
|
|
||||||
/* Send SIGUSR1 to ourselves via raise() */
|
/* Send SIGUSR1 to ourselves via kill() */
|
||||||
|
|
||||||
status = raise(SIGUSR1);
|
printf("Kill-ing SIGUSR1 from pid=%d\n", mypid);
|
||||||
|
status = kill(0, SIGUSR1);
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Failed to raise SIGUSR1, errno=%d\n", errno);
|
fprintf(stderr, "Failed to kill SIGUSR1, errno=%d\n", errno);
|
||||||
exit(3);
|
exit(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,14 +178,14 @@ int main(int argc, char **argv)
|
|||||||
fprintf(stderr, "SIGUSR1 not received\n");
|
fprintf(stderr, "SIGUSR1 not received\n");
|
||||||
exit(4);
|
exit(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
sigusr1_rcvd = 0;
|
sigusr1_rcvd = 0;
|
||||||
|
|
||||||
/* Send SIGUSR2 to ourselves */
|
/* Send SIGUSR2 to ourselves */
|
||||||
|
|
||||||
printf("Killing SIGUSR2 from pid=%d\n", mypid);
|
printf("sigqueue-ing SIGUSR2 from pid=%d\n", mypid);
|
||||||
fflush(stdout); usleep(SHORT_DELAY);
|
fflush(stdout); usleep(SHORT_DELAY);
|
||||||
|
|
||||||
#if defined(__USE_POSIX199309) && defined(HAVE_SIGQUEUE)
|
|
||||||
/* Send SIGUSR2 to ourselves via sigqueue() */
|
/* Send SIGUSR2 to ourselves via sigqueue() */
|
||||||
|
|
||||||
sigval.sival_int = 87;
|
sigval.sival_int = 87;
|
||||||
@ -231,20 +197,8 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
usleep(SHORT_DELAY);
|
usleep(SHORT_DELAY);
|
||||||
printf("SIGUSR2 queued from pid=%d, sigval=97\n", mypid);
|
printf("SIGUSR2 queued from pid=%d, sigval=87\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 */
|
/* Verify that SIGUSR2 was received */
|
||||||
|
|
||||||
if (sigusr2_rcvd == 0)
|
if (sigusr2_rcvd == 0)
|
||||||
@ -252,32 +206,33 @@ int main(int argc, char **argv)
|
|||||||
fprintf(stderr, "SIGUSR2 not received\n");
|
fprintf(stderr, "SIGUSR2 not received\n");
|
||||||
exit(6);
|
exit(6);
|
||||||
}
|
}
|
||||||
|
|
||||||
sigusr2_rcvd = 0;
|
sigusr2_rcvd = 0;
|
||||||
|
|
||||||
/* Remove the sigusr2_sigaction handler and replace the SIGUSR2
|
/* Remove the siguser_action handler and replace the SIGUSR2
|
||||||
* handler with sigusr2_sighandler.
|
* handler with sigusr2_sighandler.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
printf("Resetting SIGUSR2 signal handler from pid=%d\n", mypid);
|
printf("Resetting SIGUSR2 signal handler from pid=%d\n", mypid);
|
||||||
|
|
||||||
old_sigusr2_sighandler = signal(SIGUSR2, sigusr2_sighandler);
|
status = sigaction(SIGUSR2, &oact2, &act);
|
||||||
if (old_sigusr2_sighandler == SIG_ERR)
|
if (status != 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Failed to install SIGUSR2 handler, errno=%d\n",
|
fprintf(stderr, "Failed to install SIGUSR1 handler, errno=%d\n",
|
||||||
errno);
|
errno);
|
||||||
exit(7);
|
exit(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Old SIGUSR2 sighandler at %p\n", old_sigusr2_sighandler);
|
printf("Old SIGUSR1 sighandler at %p\n", act.sa_handler);
|
||||||
printf("New SIGUSR2 sighandler at %p\n", sigusr2_sighandler);
|
printf("New SIGUSR1 sighandler at %p\n", oact1.sa_handler);
|
||||||
|
|
||||||
/* Verify that the handler that was removed was sigusr2_sigaction */
|
/* Verify that the handler that was removed was siguser_action */
|
||||||
|
|
||||||
if ((void*)old_sigusr2_sighandler != (void*)sigusr2_sigaction)
|
if ((void*)act.sa_handler != (void*)siguser_action)
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Old SIGUSR2 signhanlder (%p) is not sigusr2_sigation (%p)\n",
|
"Old SIGUSR2 signal handler (%p) is not siguser_action (%p)\n",
|
||||||
old_sigusr2_sighandler, sigusr2_sigaction);
|
act.sa_handler, siguser_action);
|
||||||
exit(8);
|
exit(8);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,6 +258,7 @@ int main(int argc, char **argv)
|
|||||||
fprintf(stderr, "SIGUSR2 not received\n");
|
fprintf(stderr, "SIGUSR2 not received\n");
|
||||||
exit(10);
|
exit(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
sigusr2_rcvd = 0;
|
sigusr2_rcvd = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user