From 2e3e0d8b920fb4e2da32814597bb04da950ca14e Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Fri, 8 Nov 2019 07:56:47 -0600 Subject: psx_sigint: Add new example of POSIX signal and default mask --- posix_api/Makefile | 1 + posix_api/psx_sigint/Makefile | 20 ++++++++ posix_api/psx_sigint/main.c | 99 +++++++++++++++++++++++++++++++++++++ posix_api/psx_sigint/rtems_config.c | 48 ++++++++++++++++++ posix_api/psx_sigint/wscript | 15 ++++++ posix_api/wscript | 1 + 6 files changed, 184 insertions(+) create mode 100644 posix_api/psx_sigint/Makefile create mode 100644 posix_api/psx_sigint/main.c create mode 100644 posix_api/psx_sigint/rtems_config.c create mode 100644 posix_api/psx_sigint/wscript diff --git a/posix_api/Makefile b/posix_api/Makefile index 601246c..586758a 100644 --- a/posix_api/Makefile +++ b/posix_api/Makefile @@ -14,5 +14,6 @@ ifeq ($(RTEMS_HAS_POSIX_API),yes) SUBDIRS += psx_pthread_report SUBDIRS += psx_rwlock_report SUBDIRS += psx_sched_report + SUBDIRS += psx_sigint SUBDIRS += livermore endif diff --git a/posix_api/psx_sigint/Makefile b/posix_api/psx_sigint/Makefile new file mode 100644 index 0000000..0720473 --- /dev/null +++ b/posix_api/psx_sigint/Makefile @@ -0,0 +1,20 @@ +# +# RTEMS_MAKEFILE_PATH is typically set in an environment variable +# + +PGM=${ARCH}/psx_sigint.exe + +# C source names +CSRCS = main.c rtems_config.c +COBJS = $(CSRCS:%.c=${ARCH}/%.o) + +include $(RTEMS_MAKEFILE_PATH)/Makefile.inc +include $(RTEMS_CUSTOM) +include $(PROJECT_ROOT)/make/leaf.cfg + +OBJS= $(COBJS) $(CXXOBJS) $(ASOBJS) + +all: ${ARCH} $(PGM) + +$(PGM): $(OBJS) + $(make-exe) diff --git a/posix_api/psx_sigint/main.c b/posix_api/psx_sigint/main.c new file mode 100644 index 0000000..3793650 --- /dev/null +++ b/posix_api/psx_sigint/main.c @@ -0,0 +1,99 @@ +/* + * A C program that does not terminate when SIGINT is generated. + * Normally, SIGINT is generated with ctrl-c is pressed. + */ +#include +#include +#include +#include +#include +#include +#include + +/* + * This program can be conditionally compiled to install the signal + * handler with signal() or sigaction(). The distinction is that + * using signal() only stays within the confines of the Standard + * C Library and does not assume any POSIX APIs or behavior. + */ + +/* #define USE_SIGNAL */ +#define USE_SIGACTION + +/* Signal Handler for SIGINT */ +void sigintHandler(int signo) +{ + if (signo != SIGINT) { + fprintf( + stderr, + "signalHandler: signal != SIGINT (%d != %d)\n", + signo, + SIGINT + ); + exit(1); + } +#ifdef USE_SIGNAL + /* Reset handler to catch SIGINT next time. + * Refer http://en.cppreference.com/w/c/program/signal + */ + signal(SIGINT, sigintHandler); +#endif + + printf("\n Cannot be terminated using Ctrl+C \n"); + fflush(stdout); +} + +int main(int argc, char **argv) +{ + /* + * POSIX does not appear to define the default signal mask. It discusses + * a forked process and created thread inheriting a mask from the creating + * process/thread, but not the default initial signal mask. + * + * On RTEMS 4.11 and older, all signals are masked by default for both POSIX + * threads and Classic API tasks. With version 5, they are enabled by + * default for POSIX threads and disabled by default for Classic API tasks. + * On Linux, all signals are unmasked by default. + * + * The following code unmasks the signal of interest. + */ +#if __rtems__ && (__RTEMS_MAJOR__ < 5) + sigset_t old_set,new_set; + sigprocmask(SIG_SETMASK, NULL, &old_set); + /* printf( "mask=0x%08lx\n", old_set); */ + + sigemptyset(&new_set); + sigaddset(&new_set,SIGINT); + sigprocmask(SIG_UNBLOCK, &new_set, NULL); +#endif + +#ifdef USE_SIGNAL + /* Set the SIGINT (Ctrl-C) signal handler to sigintHandler + Refer http://en.cppreference.com/w/c/program/signal */ + signal(SIGINT, sigintHandler); +#endif + +#ifdef USE_SIGACTION + struct sigaction new_action; + int rc; + + new_action.sa_handler = sigintHandler; + new_action.sa_flags = 0; + rc = sigaction(SIGINT, &new_action, NULL); + if (rc != 0) { + fprintf(stderr, "sigaction -> %s\n", strerror(errno)); + } +#endif + + int sent_signal = 0; + + while(1) + { + if (sent_signal == 0) { + kill(getpid(), SIGINT); + sent_signal = 1; + } + } + return 0; +} + diff --git a/posix_api/psx_sigint/rtems_config.c b/posix_api/psx_sigint/rtems_config.c new file mode 100644 index 0000000..fd0a0f8 --- /dev/null +++ b/posix_api/psx_sigint/rtems_config.c @@ -0,0 +1,48 @@ +/* + * This file contains the RTEMS Configuration for this example. + */ + +/* + * Copyright 2018 Joel Sherrill (joel@rtems.org) + * + * This file's license is 2-clause BSD as in this distribution's LICENSE.2 file. + */ + +#include + +int main(int argc, char **argv); + +static char *argv_list[] = { + "report", + "" +}; +static void *POSIX_Init(void *arg) +{ + (void) arg; /* deliberately ignored */ + + /* + * Initialize optional services + */ + + /* + * Could get arguments from command line or have a static set. + */ + (void) main(1, argv_list); + + return NULL; +} + +#include /* for device driver prototypes */ + +/* NOTICE: the clock driver is explicitly disabled */ +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER + +#define CONFIGURE_POSIX_INIT_THREAD_TABLE + +#define CONFIGURE_UNLIMITED_OBJECTS +#define CONFIGURE_UNIFIED_WORK_AREAS +#define CONFIGURE_MINIMUM_TASK_STACK_SIZE (64 * 1024) + +#define CONFIGURE_INIT +#include diff --git a/posix_api/psx_sigint/wscript b/posix_api/psx_sigint/wscript new file mode 100644 index 0000000..e09594c --- /dev/null +++ b/posix_api/psx_sigint/wscript @@ -0,0 +1,15 @@ +# Copyright 2013 Gedare Bloom (gedare@rtems.org) +# +# This file's license is 2-clause BSD as in this distribution's LICENSE.2 file. +# + +import rtems_waf.rtems as rtems + +def build(bld): + rtems.build(bld) + + bld(features = 'c cprogram', + target = 'psx_sigint.exe', + source = ['main.c','rtems_config.c'], + lib = ['c']) + diff --git a/posix_api/wscript b/posix_api/wscript index 912063b..19b6e3e 100644 --- a/posix_api/wscript +++ b/posix_api/wscript @@ -17,4 +17,5 @@ def build(bld): bld.recurse('psx_pthread_report') bld.recurse('psx_rwlock_report') bld.recurse('psx_sched_report') + bld.recurse('psx_sigint') bld.recurse('livermore') -- cgit v1.2.3