unix/main: Ignore SIGPIPE signal, instead make EPIPE arrive.
Do not raise SIGPIPE, instead return EPIPE. Otherwise, e.g. writing to peer-closed socket will lead to sudden termination of MicroPython process. SIGPIPE is particularly nasty, because unix shell doesn't print anything for it, so the above looks like completely sudden and silent termination for unknown reason. Ignoring SIGPIPE is also what CPython does. Note that this may lead to problems using MicroPython scripts as pipe filters, but again, that's what CPython does. So, scripts which want to follow unix shell pipe semantics (where SIGPIPE means "pipe was requested to terminate, it's not an error"), should catch EPIPE themselves.
This commit is contained in:
parent
5db55e63f3
commit
11bc21dfa8
15
unix/main.c
15
unix/main.c
|
@ -35,6 +35,7 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
#include "py/mpstate.h"
|
#include "py/mpstate.h"
|
||||||
#include "py/nlr.h"
|
#include "py/nlr.h"
|
||||||
|
@ -414,6 +415,20 @@ int main(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
MP_NOINLINE int main_(int argc, char **argv) {
|
MP_NOINLINE int main_(int argc, char **argv) {
|
||||||
|
#ifdef SIGPIPE
|
||||||
|
// Do not raise SIGPIPE, instead return EPIPE. Otherwise, e.g. writing
|
||||||
|
// to peer-closed socket will lead to sudden termination of MicroPython
|
||||||
|
// process. SIGPIPE is particularly nasty, because unix shell doesn't
|
||||||
|
// print anything for it, so the above looks like completely sudden and
|
||||||
|
// silent termination for unknown reason. Ignoring SIGPIPE is also what
|
||||||
|
// CPython does. Note that this may lead to problems using MicroPython
|
||||||
|
// scripts as pipe filters, but again, that's what CPython does. So,
|
||||||
|
// scripts which want to follow unix shell pipe semantics (where SIGPIPE
|
||||||
|
// means "pipe was requested to terminate, it's not an error"), should
|
||||||
|
// catch EPIPE themselves.
|
||||||
|
signal(SIGPIPE, SIG_IGN);
|
||||||
|
#endif
|
||||||
|
|
||||||
mp_stack_set_limit(40000 * (BYTES_PER_WORD / 4));
|
mp_stack_set_limit(40000 * (BYTES_PER_WORD / 4));
|
||||||
|
|
||||||
pre_process_options(argc, argv);
|
pre_process_options(argc, argv);
|
||||||
|
|
Loading…
Reference in New Issue