Talk:C signal handling
This is the talk page for discussing improvements to the C signal handling article. This is not a forum for general discussion of the article's subject. |
Article policies
|
Find sources: Google (books · news · scholar · free images · WP refs) · FENS · JSTOR · TWL |
This article is rated Start-class on Wikipedia's content assessment scale. It is of interest to the following WikiProjects: | ||||||||||||||
|
POSIX vs Standard C
editSome POSIX functions are mentioned without it being clear that they are not part of the C standard library. kill
and sigaction
are part of POSIX (but POSIX prescribes that they be defined in signal.h
).
I'm not sure whether POSIX-specific C signal handling should be in scope for this article. I am not aware of an existing article which covers it. Maybe it would be more relevant in Signal (IPC)#POSIX Signals. If not, we should at least split POSIX-specific information into its own section within this article.
Correct code in "Example usage"
editIn the "Example usage" the following code is found:
#include <signal.h> #include <stdio.h> #include <stdlib.h> static void catch_function(int signo) { puts("Interactive attention signal caught."); }
However, this goes against security guidelines, as well as the C standard. For example, SEI's "SIG30-C. Call only asynchronous-safe functions within signal handlers" rule.
The C Standard, 7.14.1.1, paragraph 5 (ISO/IEC 9899:2011), states that if the signal occurs other than as the result of calling the abort() or raise() function, the behavior is undefined if:
"...the signal handler calls any function in the standard library other than the abort function, the _Exit function, the quick_exit function, or the signal function with the first argument equal to the signal number corresponding to the signal that caused the invocation of the handler."
The function `puts` is part of the C standard library and is not asynchronous safe. It is not safe to use within a signal handler.
According to the C Rationale, 7.14.1.1 [C99 Rationale 2003], "When a signal occurs, the normal flow of control of a program is interrupted. If a signal occurs that is being trapped by a signal handler, that handler is invoked. When it is finished, execution continues at the point at which the signal occurred. This arrangement can cause problems if the signal handler invokes a library function that was being executed at the time of the signal."
It is better for the software to set a volatile atomic flag when a signal is trapped, and part of the normal flow control of the software should check that flag and respond appropriately.
A compliant example from the SEI wikipage (see above):
#include <signal.h> #include <stdio.h> #include <stdlib.h> enum { MAXLINE = 1024 }; volatile sig_atomic_t eflag = 0; char *info = NULL; void log_message(void) { fputs(info, stderr); } void handler(int signum) { eflag = 1; } int main(void) { if (signal(SIGINT, handler) == SIG_ERR) { /* Handle error */ } info = (char *)malloc(MAXLINE); if (info == NULL) { /* Handle error */ } while (!eflag) { /* Main loop program code */ log_message(); /* More program code */ } log_message(); free(info); info = NULL; return 0; }
Note that the fputs and free aren't called within the signal handler, the signal handler adjusts a flag, and then the flag change is detected in normal flow control. This provides correct behaviour. The given example on the wiki page does not conform with the C standard nor security recommendations - as such, it should not be used as an example. It is problematic code.
2A02:AB88:C80:C080:E5D2:4890:F705:A0C5 (talk) 07:03, 8 April 2022 (UTC) Raphael Krausz
- I agree that the example needs to change, for the reasons outlined above. I suggest replacing the current example with this one (if colons precede each line as shown in the preview, I apologize, as it seems I don't know how to use a syntaxhighlight tag. They aren't there in the actual code. Spacing may be a bit off too):
- 169.236.78.22 (talk) 01:47, 6 November 2023 (UTC)
#include <signal.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> static void handler(int signo) { static const char msg[] = "Interactive attention signal caught.\n"; const size_t msg_len = sizeof msg - 1; // Do not include null terminator write(STDOUT_FILENO, msg, msg_len); } int main(void) { // Set above function as signal handler for the SIGINT signal: struct sigaction sa; sa.sa_handler = handler; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; if (sigaction(SIGINT, &sa, NULL) != 0) { fputs("An error occurred while setting a signal handler.\n", stderr); return EXIT_FAILURE; } puts("Raising the interactive attention signal."); fflush(stdout); if (raise(SIGINT) != 0) { fputs("Error raising the signal.\n", stderr); return EXIT_FAILURE; } puts("Exiting."); return EXIT_SUCCESS; }
India Education Program course assignment
editThis article was the subject of an educational assignment supported by Wikipedia Ambassadors through the India Education Program.
The above message was substituted from {{IEP assignment}}
by PrimeBOT (talk) on 20:07, 1 February 2023 (UTC)