summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2018-08-30 00:00:22 -0400
committerRich Felker <dalias@aerifal.cx>2018-08-30 00:05:52 -0400
commitcd8d8309975893736fe03e10b72de9678c5784fb (patch)
tree858d5561059f704f1837d46bc83873c2491c9fd8
parenta43a7b215cf7b71d1371c63927c17bae7177aa95 (diff)
downloadmusl-cd8d8309975893736fe03e10b72de9678c5784fb.tar.gz
prevent psignal/psiginfo from clobbering stderr orientation, errno
these functions are specified to write to stderr but not set its orientation, presumably so that they can be used in programs operating stderr in wide mode. also, they are not allowed to clobber errno on success. save and restore to meet the requirement. psiginfo is reduced to a think wrapper around psignal, since it already behaved the same. if we want to add more detailed siginfo printing at some point this will need refactoring.
-rw-r--r--src/signal/psiginfo.c6
-rw-r--r--src/signal/psignal.c23
2 files changed, 21 insertions, 8 deletions
diff --git a/src/signal/psiginfo.c b/src/signal/psiginfo.c
index 57be34cd..2b15982b 100644
--- a/src/signal/psiginfo.c
+++ b/src/signal/psiginfo.c
@@ -1,10 +1,6 @@
-#include <stdio.h>
-#include <string.h>
#include <signal.h>
void psiginfo(const siginfo_t *si, const char *msg)
{
- char *s = strsignal(si->si_signo);
- if (msg) fprintf(stderr, "%s: %s\n", msg, s);
- else fprintf(stderr, "%s\n", s);
+ psignal(si->si_signo, msg);
}
diff --git a/src/signal/psignal.c b/src/signal/psignal.c
index 02f1c760..138dbe00 100644
--- a/src/signal/psignal.c
+++ b/src/signal/psignal.c
@@ -1,10 +1,27 @@
-#include <stdio.h>
+#include "stdio_impl.h"
#include <string.h>
#include <signal.h>
+#include <errno.h>
void psignal(int sig, const char *msg)
{
+ FILE *f = stderr;
char *s = strsignal(sig);
- if (msg) fprintf(stderr, "%s: %s\n", msg, s);
- else fprintf(stderr, "%s\n", s);
+
+ FLOCK(f);
+
+ /* Save stderr's orientation and encoding rule, since psignal is not
+ * permitted to change them. Save errno and restore it if there is no
+ * error since fprintf might change it even on success but psignal is
+ * not permitted to do so. */
+ void *old_locale = f->locale;
+ int old_mode = f->mode;
+ int old_errno = errno;
+
+ if (fprintf(f, "%s%s%s\n", msg?msg:"", msg?": ":"", s)>=0)
+ errno = old_errno;
+ f->mode = old_mode;
+ f->locale = old_locale;
+
+ FUNLOCK(f);
}