mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-02-18 15:09:32 +08:00
libc: Added implementation for sig2str/str2sig.
Added implementations for sig2str() and str2sig() in libc/signal in order to improve POSIX compliance. Added fucntion prototypes in libc/include/sys/signal.h.
This commit is contained in:
parent
38965159df
commit
2b50ec0cd2
@ -12,6 +12,7 @@ extern "C" {
|
||||
#include <sys/types.h>
|
||||
#include <sys/_sigset.h>
|
||||
#include <sys/_timespec.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if !defined(_SIGSET_T_DECLARED)
|
||||
#define _SIGSET_T_DECLARED
|
||||
@ -238,6 +239,22 @@ int sigqueue (pid_t, int, const union sigval);
|
||||
|
||||
#endif /* __POSIX_VISIBLE >= 199309 */
|
||||
|
||||
/* Using __MISC_VISIBLE until POSIX Issue 8 is officially released */
|
||||
#if __MISC_VISIBLE
|
||||
|
||||
/* POSIX Issue 8 adds sig2str() and str2sig() */
|
||||
|
||||
#if __STDINT_EXP(INT_MAX) > 0x7fff
|
||||
#define SIG2STR_MAX (sizeof("RTMAX+") + sizeof("4294967295") - 1)
|
||||
#else
|
||||
#define SIG2STR_MAX (sizeof("RTMAX+") + sizeof("65535") - 1)
|
||||
#endif
|
||||
|
||||
int sig2str(int, char *);
|
||||
int str2sig(const char *__restrict, int *__restrict);
|
||||
|
||||
#endif /* __MISC_VISIBLE */
|
||||
|
||||
#if defined(___AM29K__)
|
||||
/* These all need to be defined for ANSI C, but I don't think they are
|
||||
meaningful. */
|
||||
|
@ -4,7 +4,7 @@ AUTOMAKE_OPTIONS = cygnus
|
||||
|
||||
INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS)
|
||||
|
||||
LIB_SOURCES = psignal.c raise.c signal.c
|
||||
LIB_SOURCES = psignal.c raise.c signal.c sig2str.c
|
||||
|
||||
libsignal_la_LDFLAGS = -Xcompiler -nostdlib
|
||||
|
||||
@ -21,6 +21,6 @@ endif # USE_LIBTOOL
|
||||
|
||||
include $(srcdir)/../../Makefile.shared
|
||||
|
||||
CHEWOUT_FILES = psignal.def raise.def signal.def
|
||||
CHEWOUT_FILES = psignal.def raise.def signal.def sig2str.def
|
||||
|
||||
CHAPTERS = signal.tex
|
||||
|
@ -73,12 +73,12 @@ ARFLAGS = cru
|
||||
lib_a_AR = $(AR) $(ARFLAGS)
|
||||
lib_a_LIBADD =
|
||||
am__objects_1 = lib_a-psignal.$(OBJEXT) lib_a-raise.$(OBJEXT) \
|
||||
lib_a-signal.$(OBJEXT)
|
||||
lib_a-signal.$(OBJEXT) lib_a-sig2str.$(OBJEXT)
|
||||
@USE_LIBTOOL_FALSE@am_lib_a_OBJECTS = $(am__objects_1)
|
||||
lib_a_OBJECTS = $(am_lib_a_OBJECTS)
|
||||
LTLIBRARIES = $(noinst_LTLIBRARIES)
|
||||
libsignal_la_LIBADD =
|
||||
am__objects_2 = psignal.lo raise.lo signal.lo
|
||||
am__objects_2 = psignal.lo raise.lo signal.lo sig2str.lo
|
||||
@USE_LIBTOOL_TRUE@am_libsignal_la_OBJECTS = $(am__objects_2)
|
||||
libsignal_la_OBJECTS = $(am_libsignal_la_OBJECTS)
|
||||
libsignal_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
@ -253,7 +253,7 @@ top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
AUTOMAKE_OPTIONS = cygnus
|
||||
INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS)
|
||||
LIB_SOURCES = psignal.c raise.c signal.c
|
||||
LIB_SOURCES = psignal.c raise.c signal.c sig2str.c
|
||||
libsignal_la_LDFLAGS = -Xcompiler -nostdlib
|
||||
@USE_LIBTOOL_TRUE@noinst_LTLIBRARIES = libsignal.la
|
||||
@USE_LIBTOOL_TRUE@libsignal_la_SOURCES = $(LIB_SOURCES)
|
||||
@ -272,7 +272,7 @@ DOCBOOK_CHEW = ${top_srcdir}/../doc/makedocbook.py
|
||||
DOCBOOK_OUT_FILES = $(CHEWOUT_FILES:.def=.xml)
|
||||
DOCBOOK_CHAPTERS = $(CHAPTERS:.tex=.xml)
|
||||
CLEANFILES = $(CHEWOUT_FILES) $(DOCBOOK_OUT_FILES)
|
||||
CHEWOUT_FILES = psignal.def raise.def signal.def
|
||||
CHEWOUT_FILES = psignal.def raise.def signal.def sig2str.def
|
||||
CHAPTERS = signal.tex
|
||||
all: all-am
|
||||
|
||||
@ -361,6 +361,12 @@ lib_a-signal.o: signal.c
|
||||
lib_a-signal.obj: signal.c
|
||||
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-signal.obj `if test -f 'signal.c'; then $(CYGPATH_W) 'signal.c'; else $(CYGPATH_W) '$(srcdir)/signal.c'; fi`
|
||||
|
||||
lib_a-sig2str.o: sig2str.c
|
||||
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-sig2str.o `test -f 'sig2str.c' || echo '$(srcdir)/'`sig2str.c
|
||||
|
||||
lib_a-sig2str.obj: sig2str.c
|
||||
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-sig2str.obj `if test -f 'sig2str.c'; then $(CYGPATH_W) 'sig2str.c'; else $(CYGPATH_W) '$(srcdir)/sig2str.c'; fi`
|
||||
|
||||
mostlyclean-libtool:
|
||||
-rm -f *.lo
|
||||
|
||||
|
297
newlib/libc/signal/sig2str.c
Normal file
297
newlib/libc/signal/sig2str.c
Normal file
@ -0,0 +1,297 @@
|
||||
/* SPDX-License-Identifier: BSD-2-Clause */
|
||||
/*
|
||||
* Copyright (C) 2021 Matthew Joyce
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
<<sig2str>>, <<str2sig>>---Translate between signal number and name
|
||||
|
||||
INDEX
|
||||
sig2str
|
||||
INDEX
|
||||
str2sig
|
||||
|
||||
SYNOPSIS
|
||||
#include <signal.h>
|
||||
int sig2str(int <[signum]>, char *<[str]>);
|
||||
|
||||
int str2sig(const char *restrict <[str]>, int *restrict <[pnum]>);
|
||||
|
||||
DESCRIPTION
|
||||
The <<sig2str>> function translates the signal number specified by <[signum]> to
|
||||
a signal name and stores this string in the location specified by <[str]>. The
|
||||
application must ensure that <[str]> points to a location that can store the
|
||||
string including the terminating null byte. The symbolic constant
|
||||
<[SIG2STR_MAX]> defined in `<<signal.h>>' gives the maximum number of bytes
|
||||
required.
|
||||
|
||||
The <<str2sig>> function translates the signal name in the string pointed to by
|
||||
<[str]> to a signal number and stores this value in the location specified by
|
||||
<[pnum]>.
|
||||
|
||||
RETURNS
|
||||
<<sig2str>> returns <<0>> if <[signum]>> is a valid, supported signal number.
|
||||
Otherwise, it returns <<-1>>.
|
||||
|
||||
<<str2sig>> returns <<0>> if it stores a value in the location pointed to by
|
||||
<[pnum]>. Otherwise it returns <<-1>>.
|
||||
*/
|
||||
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define SPACES_TO_N 6 /* Allows indexing to RT Signal number in str2sig */
|
||||
#define NUM_OF_SIGS (sizeof(sig_array) / sizeof(sig_name_and_num))
|
||||
|
||||
typedef struct sig_name_and_num {
|
||||
const char *sig_name;
|
||||
const int sig_num;
|
||||
} sig_name_and_num;
|
||||
|
||||
static const sig_name_and_num sig_array[] = {
|
||||
{ "EXIT", 0 },
|
||||
#ifdef SIGHUP
|
||||
{ "HUP", SIGHUP },
|
||||
#endif
|
||||
#ifdef SIGINT
|
||||
{ "INT", SIGINT },
|
||||
#endif
|
||||
#ifdef SIGQUIT
|
||||
{ "QUIT", SIGQUIT },
|
||||
#endif
|
||||
#ifdef SIGILL
|
||||
{ "ILL", SIGILL },
|
||||
#endif
|
||||
#ifdef SIGTRAP
|
||||
{ "TRAP", SIGTRAP },
|
||||
#endif
|
||||
#ifdef SIGABRT
|
||||
{ "ABRT", SIGABRT },
|
||||
#endif
|
||||
#ifdef SIGIOT
|
||||
{ "IOT", SIGIOT},
|
||||
#endif
|
||||
#ifdef SIGEMT
|
||||
{ "EMT", SIGEMT },
|
||||
#endif
|
||||
#ifdef SIGFPE
|
||||
{ "FPE", SIGFPE },
|
||||
#endif
|
||||
#ifdef SIGKILL
|
||||
{ "KILL", SIGKILL },
|
||||
#endif
|
||||
#ifdef SIGBUS
|
||||
{ "BUS", SIGBUS },
|
||||
#endif
|
||||
#ifdef SIGSEGV
|
||||
{ "SEGV", SIGSEGV },
|
||||
#endif
|
||||
#ifdef SIGSYS
|
||||
{ "SYS", SIGSYS },
|
||||
#endif
|
||||
#ifdef SIGPIPE
|
||||
{ "PIPE", SIGPIPE },
|
||||
#endif
|
||||
#ifdef SIGALRM
|
||||
{ "ALRM", SIGALRM },
|
||||
#endif
|
||||
#ifdef SIGTERM
|
||||
{ "TERM", SIGTERM },
|
||||
#endif
|
||||
#ifdef SIGURG
|
||||
{ "URG", SIGURG },
|
||||
#endif
|
||||
#ifdef SIGSTOP
|
||||
{ "STOP", SIGSTOP },
|
||||
#endif
|
||||
#ifdef SIGTSTP
|
||||
{ "TSTP", SIGTSTP },
|
||||
#endif
|
||||
#ifdef SIGCONT
|
||||
{ "CONT", SIGCONT },
|
||||
#endif
|
||||
#ifdef SIGCHLD
|
||||
{ "CHLD", SIGCHLD },
|
||||
#endif
|
||||
#ifdef SIGCLD
|
||||
{ "CLD", SIGCLD },
|
||||
#endif
|
||||
#ifdef SIGTTIN
|
||||
{ "TTIN", SIGTTIN },
|
||||
#endif
|
||||
#ifdef SIGTTOU
|
||||
{ "TTOU", SIGTTOU },
|
||||
#endif
|
||||
#ifdef SIGIO
|
||||
{ "IO", SIGIO },
|
||||
#endif
|
||||
#ifdef SIGPOLL
|
||||
{ "POLL", SIGPOLL },
|
||||
#endif
|
||||
#ifdef SIGWINCH
|
||||
{ "WINCH", SIGWINCH },
|
||||
#endif
|
||||
#ifdef SIGUSR1
|
||||
{ "USR1", SIGUSR1 },
|
||||
#endif
|
||||
#ifdef SIGUSR2
|
||||
{ "USR2", SIGUSR2 },
|
||||
#endif
|
||||
#ifdef SIGPWR
|
||||
{ "PWR", SIGPWR },
|
||||
#endif
|
||||
#ifdef SIGXCPU
|
||||
{ "XCPU", SIGXCPU },
|
||||
#endif
|
||||
#ifdef SIGXFSZ
|
||||
{ "XFSZ", SIGXFSZ },
|
||||
#endif
|
||||
#ifdef SIGVTALRM
|
||||
{ "VTALRM", SIGVTALRM },
|
||||
#endif
|
||||
#ifdef SIGPROF
|
||||
{ "PROF", SIGPROF },
|
||||
#endif
|
||||
#ifdef SIGLOST
|
||||
{ "LOST", SIGLOST },
|
||||
#endif
|
||||
/* The Issue 8 standard requires that SIGRTMIN and SIGRTMAX be included
|
||||
* as valid results to be saved from calls to sig2str/str2sig. */
|
||||
#ifdef SIGRTMIN
|
||||
{ "RTMIN", SIGRTMIN },
|
||||
#endif
|
||||
#ifdef SIGRTMAX
|
||||
{ "RTMAX", SIGRTMAX }
|
||||
#endif
|
||||
};
|
||||
|
||||
int
|
||||
sig2str(int signum, char *str)
|
||||
{
|
||||
const sig_name_and_num *sptr;
|
||||
|
||||
/* If signum falls in lower half of the real time signals range, define
|
||||
* the saved str value as "RTMIN+n" according to the Issue 8 standard */
|
||||
if ((SIGRTMIN + 1) <= signum &&
|
||||
signum <= (SIGRTMIN + SIGRTMAX) / 2) {
|
||||
sprintf(str, "RTMIN+%d", (signum-SIGRTMIN));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If signum falls in upper half of the real time signals range, define
|
||||
* the saved str value as "RTMAX-m" according to the Issue 8 standard */
|
||||
if ((((SIGRTMIN + SIGRTMAX) / 2) + 1) <= signum &&
|
||||
signum <= (SIGRTMAX - 1)) {
|
||||
sprintf(str, "RTMAX-%d", (SIGRTMAX - signum));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Otherwise, search for signal matching signum in sig_array. If found,
|
||||
* save its string value in str. */
|
||||
for (sptr = sig_array; sptr < &sig_array[NUM_OF_SIGS]; sptr++) {
|
||||
if (sptr->sig_num == signum) {
|
||||
strcpy(str, sptr->sig_name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* If signum is not a recognized signal number, return -1 */
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
str2sig(const char *restrict str, int *restrict pnum)
|
||||
{
|
||||
unsigned long j = 0;
|
||||
char *endp;
|
||||
const sig_name_and_num *sptr;
|
||||
unsigned long is_valid_decimal;
|
||||
|
||||
/* i686 Cygwin only supports one RT signal. For this case, skip checks
|
||||
* for "RTMIN+n" and "RTMAX-m". */
|
||||
if (SIGRTMIN != SIGRTMAX) {
|
||||
|
||||
/* If str is in RT signal range, get number of of RT signal, save it as an
|
||||
* integer. */
|
||||
if (strncmp(str, "RTMIN+", SPACES_TO_N) == 0) {
|
||||
j = strtoul(&str[SPACES_TO_N], &endp, 10);
|
||||
|
||||
/* If number is valid, save it in pnum. */
|
||||
if (*endp == '\0') {
|
||||
if (1 <= j &&
|
||||
j <= ((SIGRTMAX - SIGRTMIN)-1)) {
|
||||
*pnum = (SIGRTMIN + j);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* If str is in RT signal range, get number of of RT signal, save it as an
|
||||
* integer. */
|
||||
if (strncmp(str, "RTMAX-", SPACES_TO_N) == 0) {
|
||||
j = strtoul(&str[SPACES_TO_N], &endp, 10); // and endptr null check
|
||||
|
||||
/* If number is valid, save it in pnum. */
|
||||
if (*endp == '\0') {
|
||||
if (1 <= j &&
|
||||
j <= ((SIGRTMAX - SIGRTMIN)-1)) {
|
||||
*pnum = (SIGRTMAX - j);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*If str is a valid signal name, save its corresponding number in pnum. */
|
||||
for (sptr = sig_array; sptr < &sig_array[NUM_OF_SIGS]; sptr++) {
|
||||
if (strcmp(sptr->sig_name, str) == 0) {
|
||||
*pnum = sptr->sig_num;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* str was not found in sig_array. Check whether str is a string
|
||||
* representation of a valid integer. */
|
||||
is_valid_decimal = strtoul(str, &endp, 10);
|
||||
|
||||
if (*endp != '\0') {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* If str is a representation of a decimal value, save its integer value
|
||||
* in pnum. */
|
||||
if (1 <= is_valid_decimal &&
|
||||
is_valid_decimal <= SIGRTMAX) {
|
||||
*pnum = is_valid_decimal;
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
@ -61,6 +61,7 @@ reliable from signal handlers.)
|
||||
@menu
|
||||
* psignal:: Print a signal message to standard error
|
||||
* raise:: Send a signal
|
||||
* sig2str:: Translate between signal number and name
|
||||
* signal:: Specify handler subroutine for a signal
|
||||
@end menu
|
||||
|
||||
@ -70,5 +71,8 @@ reliable from signal handlers.)
|
||||
@page
|
||||
@include signal/raise.def
|
||||
|
||||
@page
|
||||
@include signal/sig2str.def
|
||||
|
||||
@page
|
||||
@include signal/signal.def
|
||||
|
Loading…
x
Reference in New Issue
Block a user