-
Notifications
You must be signed in to change notification settings - Fork 7.4k
posix: signal: APIs implementation #60083
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
095ada1
1617186
8eb2380
98ab04d
ae640f6
c726b14
078d9f7
0170c4c
b1181a1
e1896cf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,57 @@ | |
extern "C" { | ||
#endif | ||
|
||
#ifdef CONFIG_POSIX_SIGNAL | ||
#define SIGHUP 1 /**< Hangup */ | ||
#define SIGINT 2 /**< Interrupt */ | ||
#define SIGQUIT 3 /**< Quit */ | ||
#define SIGILL 4 /**< Illegal instruction */ | ||
#define SIGTRAP 5 /**< Trace/breakpoint trap */ | ||
#define SIGABRT 6 /**< Aborted */ | ||
#define SIGBUS 7 /**< Bus error */ | ||
#define SIGFPE 8 /**< Arithmetic exception */ | ||
#define SIGKILL 9 /**< Killed */ | ||
#define SIGUSR1 10 /**< User-defined signal 1 */ | ||
#define SIGSEGV 11 /**< Invalid memory reference */ | ||
#define SIGUSR2 12 /**< User-defined signal 2 */ | ||
#define SIGPIPE 13 /**< Broken pipe */ | ||
#define SIGALRM 14 /**< Alarm clock */ | ||
#define SIGTERM 15 /**< Terminated */ | ||
/* 16 not used */ | ||
#define SIGCHLD 17 /**< Child status changed */ | ||
#define SIGCONT 18 /**< Continued */ | ||
#define SIGSTOP 19 /**< Stop executing */ | ||
#define SIGTSTP 20 /**< Stopped */ | ||
#define SIGTTIN 21 /**< Stopped (read) */ | ||
#define SIGTTOU 22 /**< Stopped (write) */ | ||
#define SIGURG 23 /**< Urgent I/O condition */ | ||
#define SIGXCPU 24 /**< CPU time limit exceeded */ | ||
#define SIGXFSZ 25 /**< File size limit exceeded */ | ||
#define SIGVTALRM 26 /**< Virtual timer expired */ | ||
#define SIGPROF 27 /**< Profiling timer expired */ | ||
/* 28 not used */ | ||
#define SIGPOLL 29 /**< Pollable event occurred */ | ||
/* 30 not used */ | ||
#define SIGSYS 31 /**< Bad system call */ | ||
|
||
#define SIGRTMIN 32 | ||
#define SIGRTMAX (SIGRTMIN + CONFIG_POSIX_RTSIG_MAX) | ||
#define _NSIG (SIGRTMAX + 1) | ||
|
||
BUILD_ASSERT(CONFIG_POSIX_RTSIG_MAX >= 0); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. POSIX says 8; that could get checked here or Kconfig, or just stick a note in Kconfig indicating what will make the system POSIX compliant. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've added These Kconfigs serve as direct translation when we implement cc @cfriedt There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That sounds perfect -- tell people how to make POSIX compliant systems, but also allow them to reduce resources if desired. |
||
|
||
typedef struct { | ||
ycsin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
unsigned long sig[DIV_ROUND_UP(_NSIG, BITS_PER_LONG)]; | ||
} sigset_t; | ||
ycsin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
char *strsignal(int signum); | ||
int sigemptyset(sigset_t *set); | ||
int sigfillset(sigset_t *set); | ||
int sigaddset(sigset_t *set, int signo); | ||
int sigdelset(sigset_t *set, int signo); | ||
int sigismember(const sigset_t *set, int signo); | ||
#endif /* CONFIG_POSIX_SIGNAL */ | ||
|
||
#ifndef SIGEV_NONE | ||
#define SIGEV_NONE 1 | ||
#endif | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# Copyright (c) 2023 Meta | ||
# | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
if POSIX_SIGNAL | ||
config POSIX_LIMITS_RTSIG_MAX | ||
int "_POSIX_RTSIG_MAX value in limits.h" | ||
default 8 | ||
help | ||
Define the _POSIX_RTSIG_MAX value in limits.h. | ||
IEEE 1003.1 defines this to be 8. | ||
|
||
endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# Copyright (c) 2023 Meta | ||
# | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
config POSIX_SIGNAL | ||
bool "Support for POSIX signal APIs" | ||
default y if POSIX_API | ||
help | ||
Enable support for POSIX signal APIs. | ||
|
||
if POSIX_SIGNAL | ||
config POSIX_RTSIG_MAX | ||
int "Maximum number of realtime signals" | ||
default 31 | ||
help | ||
Define the maximum number of realtime signals (RTSIG_MAX). | ||
The range of realtime signals is [SIGRTMIN .. (SIGRTMIN+RTSIG_MAX)] | ||
|
||
config POSIX_SIGNAL_STRING_DESC | ||
bool "Use full description for the strsignal API" | ||
default y | ||
help | ||
Use full description for the strsignal API. | ||
Will use 256 bytes of ROM. | ||
|
||
endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
/* | ||
* Copyright (c) 2023 Meta | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
#include "posix/strsignal_table.h" | ||
|
||
#include <errno.h> | ||
#include <stdio.h> | ||
|
||
#include <zephyr/posix/signal.h> | ||
|
||
#define SIGNO_WORD_IDX(_signo) (signo / BITS_PER_LONG) | ||
#define SIGNO_WORD_BIT(_signo) (signo & BIT_MASK(LOG2(BITS_PER_LONG))) | ||
|
||
BUILD_ASSERT(CONFIG_POSIX_LIMITS_RTSIG_MAX >= 0); | ||
BUILD_ASSERT(CONFIG_POSIX_RTSIG_MAX >= CONFIG_POSIX_LIMITS_RTSIG_MAX); | ||
|
||
static inline bool signo_valid(int signo) | ||
{ | ||
return ((signo > 0) && (signo < _NSIG)); | ||
} | ||
|
||
static inline bool signo_is_rt(int signo) | ||
{ | ||
return ((signo >= SIGRTMIN) && (signo <= SIGRTMAX)); | ||
} | ||
|
||
int sigemptyset(sigset_t *set) | ||
{ | ||
*set = (sigset_t){0}; | ||
return 0; | ||
} | ||
|
||
int sigfillset(sigset_t *set) | ||
{ | ||
for (int i = 0; i < ARRAY_SIZE(set->sig); i++) { | ||
set->sig[i] = -1; | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
int sigaddset(sigset_t *set, int signo) | ||
{ | ||
if (!signo_valid(signo)) { | ||
errno = EINVAL; | ||
return -1; | ||
} | ||
|
||
WRITE_BIT(set->sig[SIGNO_WORD_IDX(signo)], SIGNO_WORD_BIT(signo), 1); | ||
|
||
return 0; | ||
} | ||
|
||
int sigdelset(sigset_t *set, int signo) | ||
{ | ||
if (!signo_valid(signo)) { | ||
errno = EINVAL; | ||
return -1; | ||
} | ||
|
||
WRITE_BIT(set->sig[SIGNO_WORD_IDX(signo)], SIGNO_WORD_BIT(signo), 0); | ||
|
||
return 0; | ||
} | ||
|
||
int sigismember(const sigset_t *set, int signo) | ||
{ | ||
if (!signo_valid(signo)) { | ||
errno = EINVAL; | ||
return -1; | ||
} | ||
|
||
return 1 & (set->sig[SIGNO_WORD_IDX(signo)] >> SIGNO_WORD_BIT(signo)); | ||
} | ||
|
||
char *strsignal(int signum) | ||
ycsin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
static char buf[sizeof("RT signal " STRINGIFY(SIGRTMAX))]; | ||
|
||
if (!signo_valid(signum)) { | ||
errno = EINVAL; | ||
return "Invalid signal"; | ||
ycsin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
if (signo_is_rt(signum)) { | ||
snprintf(buf, sizeof(buf), "RT signal %d", signum - SIGRTMIN); | ||
return buf; | ||
} | ||
|
||
if (IS_ENABLED(CONFIG_POSIX_SIGNAL_STRING_DESC)) { | ||
if (strsignal_list[signum] != NULL) { | ||
return (char *)strsignal_list[signum]; | ||
} | ||
} | ||
|
||
snprintf(buf, sizeof(buf), "Signal %d", signum); | ||
|
||
return buf; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
#!/usr/bin/env python3 | ||
# | ||
# Copyright (c) 2023 Meta | ||
# | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
import argparse | ||
import os | ||
import re | ||
|
||
|
||
def front_matter(): | ||
return f''' | ||
/* | ||
* This file is generated by {__file__} | ||
*/ | ||
|
||
#include <zephyr/posix/signal.h> | ||
''' | ||
|
||
|
||
def gen_strsignal_table(input, output): | ||
with open(input, 'r') as inf: | ||
|
||
highest_signo = 0 | ||
symbols = [] | ||
msgs = {} | ||
|
||
for line in inf.readlines(): | ||
# Select items of the form below (note: SIGNO is numeric) | ||
# #define SYMBOL SIGNO /**< MSG */ | ||
pat = r'^#define[\s]+(SIG[A-Z_]*)[\s]+([1-9][0-9]*)[\s]+/\*\*<[\s]+(.*)[\s]+\*/[\s]*$' | ||
match = re.match(pat, line) | ||
|
||
if not match: | ||
continue | ||
|
||
symbol = match[1] | ||
signo = int(match[2]) | ||
msg = match[3] | ||
|
||
symbols.append(symbol) | ||
msgs[symbol] = msg | ||
|
||
highest_signo = max(int(signo), highest_signo) | ||
|
||
try: | ||
os.makedirs(os.path.dirname(output)) | ||
except BaseException: | ||
# directory already present | ||
pass | ||
|
||
with open(output, 'w') as outf: | ||
|
||
print(front_matter(), file=outf) | ||
|
||
# Generate string table | ||
print( | ||
f'static const char *const strsignal_list[{highest_signo + 1}] = {{', file=outf) | ||
for symbol in symbols: | ||
print(f'\t[{symbol}] = "{msgs[symbol]}",', file=outf) | ||
|
||
print('};', file=outf) | ||
|
||
|
||
def parse_args(): | ||
parser = argparse.ArgumentParser(allow_abbrev=False) | ||
parser.add_argument( | ||
'-i', | ||
'--input', | ||
dest='input', | ||
required=True, | ||
help='input file (e.g. include/zephyr/posix/signal.h)') | ||
parser.add_argument( | ||
'-o', | ||
'--output', | ||
dest='output', | ||
required=True, | ||
help='output file (e.g. build/zephyr/misc/generated/lib/posix/strsignal_table.h)') | ||
|
||
args = parser.parse_args() | ||
|
||
return args | ||
|
||
|
||
def main(): | ||
args = parse_args() | ||
gen_strsignal_table(args.input, args.output) | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like you should define
RTSIG_MAX
to beCONFIG_POSIX_RTSIG_MAX
in<limits.h>
and that it must be at least 8.https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this Kconfig will make the implementation of
limits.h
a bit easier, but I thinklimits.h
can probably be in another PRThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that sounds like it's getting close to
sysconf()
. There is another PR in draft for that, so I can addRTSIG_MAX
separately.