[m-rev.] for review: Thread-safe alternative to strerror.
Peter Wang
novalazy at gmail.com
Tue Jun 24 15:09:29 AEST 2014
Branches: master, 14.01
Add MR_strerror as a thread-safe alternative to strerror.
The current implementation wraps strerror_r(), strerror_s()
or sys_errlist as appropriate for the platform. Bug #340.
configure.ac:
runtime/mercury_conf.h.in:
Check for strerror_r, strerror_s.
Delete irrelevant code in the sockets test for the external debugger.
runtime/mercury_runtime_util.c:
runtime/mercury_runtime_util.h:
Add MR_strerror and use it.
library/io.m:
Use MR_strerror. In particular, mercury_output_error was not
thread-safe.
Pass errno to mercury_output_error explicitly for clarity.
Delete req_lock parameter in ML_maybe_make_err_msg macro which is not
needed any more.
compiler/prog_event.m:
runtime/mercury_deep_profiling.c:
runtime/mercury_misc.c:
runtime/mercury_term_size.c:
runtime/mercury_trace_base.c:
trace/mercury_trace_cmd_developer.c:
trace/mercury_trace_cmd_exp.c:
trace/mercury_trace_cmd_misc.c:
trace/mercury_trace_declarative.c:
trace/mercury_trace_external.c:
trace/mercury_trace_internal.c:
Use MR_strerror.
compiler/notes/coding_standards.html:
Update coding standard.
extras/net/sockets.m:
extras/net/tcp.m:
Use MR_strerror.
NEWS:
Announce change.
diff --git a/NEWS b/NEWS
index c5aacac..5b13316 100644
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,7 @@ This is a bug-fix release.
* We have added workarounds for problems with (arguably broken)
system headers on MinGW and MinGW64 systems.
* The MinGW port now builds in the absence of POSIX threads library.
+* We now use thread-safe alternatives to strerror().
Changes to the Mercury compiler:
diff --git a/compiler/notes/coding_standards.html b/compiler/notes/coding_standards.html
index 94ee830..752a924 100644
--- a/compiler/notes/coding_standards.html
+++ b/compiler/notes/coding_standards.html
@@ -174,7 +174,7 @@ Error messages from the runtime system should begin with the text
If a system call or C library function that sets errno fails,
the error message should be printed with perror()
-or should contain strerror(errno).
+or should contain MR_strerror(errno, errbuf, sizeof(errbuf)).
If it was a function manipulating some file,
the error message should include the filename.
diff --git a/compiler/prog_event.m b/compiler/prog_event.m
index 9546508..eb943de 100644
--- a/compiler/prog_event.m
+++ b/compiler/prog_event.m
@@ -185,6 +185,7 @@ read_specs_file_2(MR_AllocSiteInfoPtr alloc_id, MR_String specs_file_name,
{
int spec_fd;
MR_String problem;
+ char errbuf[MR_STRERROR_SIZE];
/*
** There are race conditions between opening the file, stat'ing the file
@@ -195,7 +196,7 @@ read_specs_file_2(MR_AllocSiteInfoPtr alloc_id, MR_String specs_file_name,
spec_fd = open(specs_file_name, O_RDONLY);
if (spec_fd < 0) {
problem = MR_make_string(alloc_id, ""could not open %s: %s"",
- specs_file_name, strerror(errno));
+ specs_file_name, MR_strerror(errno, errbuf, sizeof(errbuf)));
} else {
problem = read_specs_file_3(alloc_id, specs_file_name,
term_file_name, spec_fd);
@@ -256,11 +257,13 @@ read_specs_file_4(MR_AllocSiteInfoPtr alloc_id, MR_String specs_file_name,
specs_file_name);
} else {
FILE *term_fp;
+ char errbuf[MR_STRERROR_SIZE];
term_fp = fopen(term_file_name, ""w"");
if (term_fp == NULL) {
problem = MR_make_string(alloc_id, ""could not open %s: %s"",
- term_file_name, strerror(errno));
+ term_file_name,
+ MR_strerror(errno, errbuf, sizeof(errbuf)));
} else {
MR_print_event_set(term_fp, event_set);
fclose(term_fp);
diff --git a/configure.ac b/configure.ac
index 720500a..dede274 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1285,7 +1285,8 @@ mercury_check_for_functions \
sysconf getpagesize gethostname \
mprotect memalign posix_memalign memmove \
sigaction siginterrupt setitimer \
- snprintf _snprintf vsnprintf _vsnprintf strerror \
+ snprintf _snprintf vsnprintf _vsnprintf \
+ strerror strerror_r strerror_s \
open close dup dup2 fdopen fileno fstat stat lstat isatty \
getpid setpgid fork execlp wait kill \
grantpt unlockpt ptsname tcgetattr tcsetattr ioctl \
@@ -5107,37 +5108,17 @@ AC_TRY_LINK([
*/
fd = socket(addr_family, SOCK_STREAM, 0);
- if (fd < 0) {
- fprintf(stderr, "Mercury runtime: socket() failed: %s\n",
- strerror(errno));
- fatal_error("cannot open socket for debugger");
- } else if (MR_debug_socket) {
- fprintf(stderr,"Mercury runtime: creation of socket ok\n");
- }
/*
** Connect to the socket
*/
- if (connect(fd, addr, len) < 0) {
- fprintf(stderr, "Mercury runtime: connect() failed: %s\n",
- strerror(errno));
- fatal_error("can't connect to debugger socket");
- } else if (MR_debug_socket) {
- fprintf(stderr, "Mercury runtime: connection to socket: ok\n");
- }
+ connect(fd, addr, len);
/*
** Convert the socket fd to a Mercury stream
*/
file_in = fdopen(fd, "r");
file_out = fdopen(fd, "w");
- if ((file_in == NULL)||(file_out == NULL)) {
- fprintf(stderr, "Mercury runtime: fdopen() failed: %s\n",
- strerror(errno));
- fatal_error("cannot open debugger socket");
- } else if (MR_debug_socket) {
- fprintf(stderr, "Mercury runtime: fdopen(): ok\n");
- }
}
changequote([,])
],[mercury_cv_sockets_work=yes],[mercury_cv_sockets_work=no]))
diff --git a/extras/net/sockets.m b/extras/net/sockets.m
index 6d7acf1..5dc1ce8 100644
--- a/extras/net/sockets.m
+++ b/extras/net/sockets.m
@@ -293,12 +293,14 @@
shutdown(Fd, 2);
").
- % XXX thread safe?
:- pragma foreign_proc("C",
error_message(Err::out, _IO0::di, _IO::uo),
- [will_not_call_mercury, promise_pure, tabled_for_io],
+ [will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
"
- MR_make_aligned_string_copy(Err, strerror(socket_errno));
+ char errbuf[MR_STRERROR_SIZE];
+
+ MR_make_aligned_string_copy(Err,
+ MR_strerror(socket_errno, errbuf, sizeof(errbuf)));
").
%-----------------------------------------------------------------------------%
diff --git a/extras/net/tcp.m b/extras/net/tcp.m
index 4036526..567233c 100644
--- a/extras/net/tcp.m
+++ b/extras/net/tcp.m
@@ -624,8 +624,11 @@ socket_fd(Tcp) = socket_fd_c(Tcp ^ handle).
tcp.get_error(Errno::in, Msg::out),
[will_not_call_mercury, thread_safe, promise_pure],
"
+ char errbuf[MR_STRERROR_SIZE];
+
MR_save_transient_hp();
- MR_make_aligned_string_copy(Msg, strerror(Errno));
+ MR_make_aligned_string_copy(Msg,
+ MR_strerror(Errno, errbuf, sizeof(errbuf)));
MR_restore_transient_hp();
").
@@ -679,9 +682,12 @@ socket_fd(Tcp) = socket_fd_c(Tcp ^ handle).
:- pragma foreign_proc("C",
error_message(Errno::in) = (Err::out),
- [promise_pure, will_not_call_mercury],
+ [promise_pure, will_not_call_mercury, thread_safe],
"
- MR_make_aligned_string_copy(Err, strerror(Errno));
+ char errbuf[MR_STRERROR_SIZE];
+
+ MR_make_aligned_string_copy(Err,
+ MR_strerror(Errno, errbuf, sizeof(errbuf)));
").
:- pred throw_tcp_exception(string::in) is erroneous.
diff --git a/library/io.m b/library/io.m
index 501f1e7..7765dbb 100644
--- a/library/io.m
+++ b/library/io.m
@@ -2546,7 +2546,7 @@ io.check_err(Stream, Res, !IO) :-
}
ML_maybe_make_err_msg(RetVal != 0, errno, ""read failed: "",
- MR_ALLOC_ID, MR_TRUE, RetStr);
+ MR_ALLOC_ID, RetStr);
").
:- pragma foreign_proc("C#",
@@ -2626,10 +2626,10 @@ io.make_err_msg(Msg0, Msg, !IO) :-
:- pragma foreign_proc("C",
make_err_msg(Error::in, Msg0::in, Msg::out, _IO0::di, _IO::uo),
- [will_not_call_mercury, promise_pure, tabled_for_io,
+ [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe,
does_not_affect_liveness, no_sharing],
"
- ML_maybe_make_err_msg(MR_TRUE, Error, Msg0, MR_ALLOC_ID, MR_FALSE, Msg);
+ ML_maybe_make_err_msg(MR_TRUE, Error, Msg0, MR_ALLOC_ID, Msg);
").
:- pragma foreign_proc("C#",
@@ -2849,7 +2849,7 @@ io.file_modification_time(File, Result, !IO) :-
Status = 1;
} else {
ML_maybe_make_err_msg(MR_TRUE, errno, ""stat() failed: "",
- MR_ALLOC_ID, MR_TRUE, Msg);
+ MR_ALLOC_ID, Msg);
Status = 0;
Time = 0; /* Dummy value -- will not be used. */
}
@@ -3948,7 +3948,7 @@ io.file_id(FileName, Result, !IO) :-
Status = 1;
} else {
ML_maybe_make_err_msg(MR_TRUE, errno, ""stat() failed: "",
- MR_ALLOC_ID, MR_TRUE, Msg);
+ MR_ALLOC_ID, Msg);
Status = 0;
}
#else
@@ -5659,6 +5659,7 @@ io.get_io_output_stream_type(Type, !IO) :-
#include ""mercury_file.h""
#include ""mercury_heap.h""
#include ""mercury_misc.h""
+#include ""mercury_runtime_util.h""
#include <stdio.h>
#include <stdlib.h>
@@ -5703,7 +5704,7 @@ int mercury_next_stream_id(void);
MercuryFilePtr mercury_open(const char *filename, const char *openmode,
MR_AllocSiteInfoPtr alloc_id);
void mercury_io_error(MercuryFilePtr mf, const char *format, ...);
-void mercury_output_error(MercuryFilePtr mf);
+void mercury_output_error(MercuryFilePtr mf, int errnum);
void mercury_print_string(MercuryFilePtr mf, const char *s);
int mercury_get_byte(MercuryFilePtr mf);
void mercury_close(MercuryFilePtr mf);
@@ -7069,10 +7070,12 @@ mercury_io_error(MercuryFilePtr mf, const char *format, ...)
:- pragma foreign_code("C", "
void
-mercury_output_error(MercuryFilePtr mf)
+mercury_output_error(MercuryFilePtr mf, int errnum)
{
+ char errbuf[MR_STRERROR_SIZE];
+
mercury_io_error(mf, ""error writing to output file: %s"",
- strerror(errno));
+ MR_strerror(errnum, errbuf, sizeof(errbuf)));
}
").
@@ -7083,7 +7086,7 @@ void
mercury_print_string(MercuryFilePtr mf, const char *s)
{
if (ML_fprintf(mf, ""%s"", s) < 0) {
- mercury_output_error(mf);
+ mercury_output_error(mf, errno);
}
while (*s) {
if (*s++ == '\\n') {
@@ -7342,6 +7345,8 @@ static const MercuryFile MR_closed_stream = {
void
mercury_close(MercuryFilePtr mf)
{
+ char errbuf[MR_STRERROR_SIZE];
+
/*
** On some systems attempting to close a file stream that has been
** previously closed will lead to a segmentation fault. We check
@@ -7353,7 +7358,8 @@ mercury_close(MercuryFilePtr mf)
}
if (MR_CLOSE(*mf) < 0) {
- mercury_io_error(mf, ""error closing file: %s"", strerror(errno));
+ mercury_io_error(mf, ""error closing file: %s"",
+ MR_strerror(errno, errbuf, sizeof(errbuf)));
}
#ifdef MR_NEW_MERCURYFILE_STRUCT
@@ -7760,7 +7766,7 @@ io.putback_byte(binary_input_stream(Stream), Character, !IO) :-
size_t i;
if (Character <= 0x7f) {
if (MR_PUTCH(*out, Character) < 0) {
- mercury_output_error(out);
+ mercury_output_error(out, errno);
}
if (Character == '\\n') {
MR_line_number(*out)++;
@@ -7769,7 +7775,7 @@ io.putback_byte(binary_input_stream(Stream), Character, !IO) :-
len = MR_utf8_encode(buf, Character);
for (i = 0; i < len; i++) {
if (MR_PUTCH(*out, buf[i]) < 0) {
- mercury_output_error(out);
+ mercury_output_error(out, errno);
break;
}
}
@@ -7783,7 +7789,7 @@ io.putback_byte(binary_input_stream(Stream), Character, !IO) :-
"
MercuryFilePtr out = mercury_current_text_output();
if (ML_fprintf(out, ""%"" MR_INTEGER_LENGTH_MODIFIER ""d"", Val) < 0) {
- mercury_output_error(out);
+ mercury_output_error(out, errno);
}
").
@@ -7798,7 +7804,7 @@ io.putback_byte(binary_input_stream(Stream), Character, !IO) :-
MR_sprintf_float(buf, Val);
out = mercury_current_text_output();
if (ML_fprintf(out, ""%s"", buf) < 0) {
- mercury_output_error(out);
+ mercury_output_error(out, errno);
}
").
@@ -7811,7 +7817,7 @@ io.putback_byte(binary_input_stream(Stream), Character, !IO) :-
if (MR_PUTCH(*mercury_current_binary_output(),
(int) ((unsigned char) Byte)) < 0)
{
- mercury_output_error(mercury_current_text_output());
+ mercury_output_error(mercury_current_text_output(), errno);
}
").
@@ -7830,7 +7836,7 @@ io.write_bitmap(Bitmap, Start, NumBytes, !IO) :-
"
MercuryFilePtr out = mercury_current_text_output();
if (MR_FLUSH(*out) < 0) {
- mercury_output_error(out);
+ mercury_output_error(out, errno);
}
").
@@ -7841,7 +7847,7 @@ io.write_bitmap(Bitmap, Start, NumBytes, !IO) :-
"
MercuryFilePtr out = mercury_current_binary_output();
if (MR_FLUSH(*out) < 0) {
- mercury_output_error(out);
+ mercury_output_error(out, errno);
}
").
@@ -8101,7 +8107,7 @@ io.write_char(output_stream(Stream), Character, !IO) :-
"
if (Character <= 0x7f) {
if (MR_PUTCH(*Stream, Character) < 0) {
- mercury_output_error(Stream);
+ mercury_output_error(Stream, errno);
}
if (Character == '\\n') {
MR_line_number(*Stream)++;
@@ -8113,7 +8119,7 @@ io.write_char(output_stream(Stream), Character, !IO) :-
len = MR_utf8_encode(buf, Character);
for (i = 0; i < len; i++) {
if (MR_PUTCH(*Stream, buf[i]) < 0) {
- mercury_output_error(Stream);
+ mercury_output_error(Stream, errno);
break;
}
}
@@ -8130,7 +8136,7 @@ io.write_int(output_stream(Stream), Val, !IO) :-
does_not_affect_liveness, no_sharing],
"
if (ML_fprintf(Stream, ""%"" MR_INTEGER_LENGTH_MODIFIER ""d"", Val) < 0) {
- mercury_output_error(Stream);
+ mercury_output_error(Stream, errno);
}
").
@@ -8146,7 +8152,7 @@ io.write_float(output_stream(Stream), Val, !IO) :-
char buf[MR_SPRINTF_FLOAT_BUF_SIZE];
MR_sprintf_float(buf, Val);
if (ML_fprintf(Stream, ""%s"", buf) < 0) {
- mercury_output_error(Stream);
+ mercury_output_error(Stream, errno);
}
").
@@ -8161,7 +8167,7 @@ io.write_byte(binary_output_stream(Stream), Byte, !IO) :-
"
/* call putc with a strictly non-negative byte-sized integer */
if (MR_PUTCH(*Stream, (int) ((unsigned char) Byte)) < 0) {
- mercury_output_error(Stream);
+ mercury_output_error(Stream, errno);
}
").
@@ -8221,7 +8227,7 @@ io.flush_output(output_stream(Stream), !IO) :-
does_not_affect_liveness, no_sharing],
"
if (MR_FLUSH(*Stream) < 0) {
- mercury_output_error(Stream);
+ mercury_output_error(Stream, errno);
}
").
@@ -8235,7 +8241,7 @@ io.flush_binary_output(binary_output_stream(Stream), !IO) :-
does_not_affect_liveness, no_sharing],
"
if (MR_FLUSH(*Stream) < 0) {
- mercury_output_error(Stream);
+ mercury_output_error(Stream, errno);
}
").
@@ -9694,7 +9700,7 @@ io.close_binary_output(binary_output_stream(Stream), !IO) :-
Status = 127;
ML_maybe_make_err_msg(MR_TRUE, errno,
""error invoking system command: "",
- MR_ALLOC_ID, MR_TRUE, Msg);
+ MR_ALLOC_ID, Msg);
} else {
/* Wait for the spawned process to exit. */
do {
@@ -9704,7 +9710,7 @@ io.close_binary_output(binary_output_stream(Stream), !IO) :-
Status = 127;
ML_maybe_make_err_msg(MR_TRUE, errno,
""error invoking system command: "",
- MR_ALLOC_ID, MR_TRUE, Msg);
+ MR_ALLOC_ID, Msg);
} else {
Status = st;
Msg = MR_make_string_const("""");
@@ -9728,7 +9734,7 @@ io.close_binary_output(binary_output_stream(Stream), !IO) :-
Status = 127;
ML_maybe_make_err_msg(MR_TRUE, errno,
""error invoking system command: "",
- MR_ALLOC_ID, MR_TRUE, Msg);
+ MR_ALLOC_ID, Msg);
} else {
Msg = MR_make_string_const("""");
}
@@ -10267,7 +10273,7 @@ io.make_temp(Dir, Prefix, Name, !IO) :-
if (fd == -1) {
ML_maybe_make_err_msg(MR_TRUE, errno,
""error opening temporary file: "", MR_ALLOC_ID,
- MR_TRUE, ErrorMessage);
+ ErrorMessage);
Error = -1;
} else {
do {
@@ -10275,7 +10281,7 @@ io.make_temp(Dir, Prefix, Name, !IO) :-
} while (err == -1 && MR_is_eintr(errno));
ML_maybe_make_err_msg(err, errno,
""error closing temporary file: "", MR_ALLOC_ID,
- MR_TRUE, ErrorMessage);
+ ErrorMessage);
Error = err;
}
#else
@@ -10324,7 +10330,7 @@ io.make_temp(Dir, Prefix, Name, !IO) :-
if (fd == -1) {
ML_maybe_make_err_msg(MR_TRUE, errno,
""error opening temporary file: "", MR_ALLOC_ID,
- MR_TRUE, ErrorMessage);
+ ErrorMessage);
Error = -1;
} else {
do {
@@ -10332,7 +10338,7 @@ io.make_temp(Dir, Prefix, Name, !IO) :-
} while (err == -1 && MR_is_eintr(errno));
ML_maybe_make_err_msg(err, errno,
""error closing temporary file: "", MR_ALLOC_ID,
- MR_TRUE, ErrorMessage);
+ ErrorMessage);
Error = err;
}
#endif
@@ -10488,11 +10494,9 @@ io.make_temp(Dir, Prefix, Name, !IO) :-
#include <errno.h>
/*
-** ML_maybe_make_err_msg(was_error, errno, msg, alloc_id, req_lock, error_msg):
-** if `was_error' is true, then append `msg' and `strerror(errno)'
+** ML_maybe_make_err_msg(was_error, errnum, msg, alloc_id, error_msg):
+** if `was_error' is true, then append `msg' and a message for errnum
** to give `error_msg'; otherwise, set `error_msg' to "".
-** `req_lock' must be true iff the caller is marked `thread_safe' as the
-** underlying strerror() function is not thread-safe.
**
** WARNING: this must only be called when the `hp' register is valid.
** That means it must only be called from procedures declared
@@ -10503,18 +10507,15 @@ io.make_temp(Dir, Prefix, Name, !IO) :-
** invalidated by the function call.
*/
-#define ML_maybe_make_err_msg(was_error, error, msg, alloc_id, req_lock, \\
- error_msg) \\
+#define ML_maybe_make_err_msg(was_error, errnum, msg, alloc_id, error_msg) \\
do { \\
- char *errno_msg; \\
+ char errbuf[MR_STRERROR_SIZE]; \\
+ const char *errno_msg; \\
size_t total_len; \\
MR_Word tmp; \\
\\
if (was_error) { \\
- if (req_lock) { \\
- MR_OBTAIN_GLOBAL_LOCK(""ML_maybe_make_err_msg""); \\
- } \\
- errno_msg = strerror(error); \\
+ errno_msg = MR_strerror(errnum, errbuf, sizeof(errbuf)); \\
total_len = strlen(msg) + strlen(errno_msg); \\
MR_offset_incr_hp_atomic_msg(tmp, 0, \\
(total_len + sizeof(MR_Word)) / sizeof(MR_Word), \\
@@ -10522,9 +10523,6 @@ io.make_temp(Dir, Prefix, Name, !IO) :-
(error_msg) = (char *) tmp; \\
strcpy((error_msg), msg); \\
strcat((error_msg), errno_msg); \\
- if (req_lock) { \\
- MR_RELEASE_GLOBAL_LOCK(""ML_maybe_make_err_msg""); \\
- } \\
} else { \\
/* \\
** We can't just return NULL here, because otherwise mdb \\
@@ -10625,7 +10623,7 @@ io.remove_file(FileName, Result, !IO) :-
RetVal = remove(FileName);
#endif
ML_maybe_make_err_msg(RetVal != 0, errno, ""remove failed: "",
- MR_ALLOC_ID, MR_TRUE, RetStr);
+ MR_ALLOC_ID, RetStr);
").
:- pragma foreign_proc("C#",
@@ -10768,7 +10766,7 @@ io.rename_file(OldFileName, NewFileName, Result, IO0, IO) :-
RetVal = rename(OldFileName, NewFileName);
#endif
ML_maybe_make_err_msg(RetVal != 0, errno, ""rename failed: "",
- MR_ALLOC_ID, MR_TRUE, RetStr);
+ MR_ALLOC_ID, RetStr);
").
:- pragma foreign_proc("C#",
diff --git a/runtime/mercury_conf.h.in b/runtime/mercury_conf.h.in
index d8b8560..d44ce45 100644
--- a/runtime/mercury_conf.h.in
+++ b/runtime/mercury_conf.h.in
@@ -241,6 +241,8 @@
** MR_HAVE_MEMALIGN we have the memalign() function.
** MR_HAVE_POSIX_MEMALIGN we have the posix_memalign() function.
** MR_HAVE_STRERROR we have the strerror() function.
+** MR_HAVE_STRERROR_R we have the strerror_r() function.
+** MR_HAVE_STRERROR_S we have the strerror_s() function.
** MR_HAVE_SIGINTERRUPT we have the siginterrupt() function.
** MR_HAVE_SETITIMER we have the setitimer() function.
** MR_HAVE_MEMMOVE we have the memmove() function.
@@ -314,6 +316,8 @@
#undef MR_HAVE_POSIX_MEMALIGN
#undef MR_HAVE_MPROTECT
#undef MR_HAVE_STRERROR
+#undef MR_HAVE_STRERROR_R
+#undef MR_HAVE_STRERROR_S
#undef MR_HAVE_SIGINTERRUPT
#undef MR_HAVE_SETITIMER
#undef MR_HAVE_MEMMOVE
diff --git a/runtime/mercury_deep_profiling.c b/runtime/mercury_deep_profiling.c
index 124e378..889a6c8 100644
--- a/runtime/mercury_deep_profiling.c
+++ b/runtime/mercury_deep_profiling.c
@@ -24,7 +24,7 @@
#include "mercury_stack_layout.h"
#include "mercury_timing.h"
#include "mercury_prof_time.h"
-#include "mercury_runtime_util.h" /* for strerror() on some systems */
+#include "mercury_runtime_util.h"
#include "mercury_deep_profiling.h"
#include "mercury_deep_profiling_hand.h"
@@ -387,6 +387,7 @@ MR_write_out_profiling_tree(void)
int ticks_per_sec;
unsigned num_call_seqs;
long table_sizes_offset;
+ char errbuf[MR_STRERROR_SIZE];
#ifdef MR_DEEP_PROFILING_STATISTICS
int i;
@@ -396,13 +397,15 @@ MR_write_out_profiling_tree(void)
deep_fp = fopen(MR_MDPROF_DATA_FILENAME, "wb+");
if (deep_fp == NULL) {
MR_fatal_error("cannot open `%s' for writing: %s",
- MR_MDPROF_DATA_FILENAME, strerror(errno));
+ MR_MDPROF_DATA_FILENAME,
+ MR_strerror(errno, errbuf, sizeof(errbuf)));
}
procrep_fp = fopen(MR_MDPROF_PROCREP_FILENAME, "wb+");
if (procrep_fp == NULL) {
MR_fatal_error("cannot open `%s' for writing: %s",
- MR_MDPROF_PROCREP_FILENAME, strerror(errno));
+ MR_MDPROF_PROCREP_FILENAME,
+ MR_strerror(errno, errbuf, sizeof(errbuf)));
}
#ifdef MR_DEEP_PROFILING_DEBUG
@@ -667,7 +670,10 @@ MR_write_out_profiling_tree(void)
static void
MR_deep_data_output_error(const char *op, const char *filename)
{
- MR_warning("%s %s: %s", op, filename, strerror(errno));
+ char errbuf[MR_STRERROR_SIZE];
+
+ MR_warning("%s %s: %s", op, filename,
+ MR_strerror(errno, errbuf, sizeof(errbuf)));
/*
** An incomplete profiling data file is useless. Removing it prevents
@@ -677,12 +683,14 @@ MR_deep_data_output_error(const char *op, const char *filename)
if (remove(MR_MDPROF_DATA_FILENAME) != 0) {
MR_warning("cannot remove %s: %s",
- MR_MDPROF_DATA_FILENAME, strerror(errno));
+ MR_MDPROF_DATA_FILENAME,
+ MR_strerror(errno, errbuf, sizeof(errbuf)));
}
if (remove(MR_MDPROF_PROCREP_FILENAME) != 0) {
MR_warning("cannot remove %s: %s",
- MR_MDPROF_PROCREP_FILENAME, strerror(errno));
+ MR_MDPROF_PROCREP_FILENAME,
+ MR_strerror(errno, errbuf, sizeof(errbuf)));
}
exit(1);
diff --git a/runtime/mercury_misc.c b/runtime/mercury_misc.c
index 2d78480..ae92889 100644
--- a/runtime/mercury_misc.c
+++ b/runtime/mercury_misc.c
@@ -14,6 +14,7 @@
#include "mercury_string.h"
#include "mercury_misc.h"
#include "mercury_array_macros.h"
+#include "mercury_runtime_util.h"
#include <stdio.h>
#include <stdarg.h>
@@ -87,11 +88,13 @@ MR_fatal_error(const char *fmt, ...)
{
va_list args;
int error = errno;
+ char errbuf[MR_STRERROR_SIZE];
fflush(stdout); /* in case stdout and stderr are the same */
if (error != 0) {
- fprintf(stderr, "Errno = %d: %s\n", error, strerror(error));
+ fprintf(stderr, "Errno = %d: %s\n", error,
+ MR_strerror(error, errbuf, sizeof(errbuf)));
}
fprintf(stderr, "Mercury runtime: ");
va_start(args, fmt);
diff --git a/runtime/mercury_runtime_util.c b/runtime/mercury_runtime_util.c
index 5c565e5..f523c52 100644
--- a/runtime/mercury_runtime_util.c
+++ b/runtime/mercury_runtime_util.c
@@ -3,6 +3,7 @@
*/
/*
** Copyright (C) 2001-2002, 2006 The University of Melbourne.
+** Copyright (C) 2014 The Mercury team.
** This file may only be copied under the terms of the GNU Library General
** Public License - see the file COPYING.LIB in the Mercury distribution.
*/
@@ -24,41 +25,75 @@
#include <errno.h>
-#ifndef MR_HAVE_STRERROR
+static void
+generic_strerror(char *buf, size_t buflen, int errnum)
+{
+#if defined(MR_HAVE_SNPRINTF)
+ snprintf(buf, buflen, "Error %d", errnum);
+#elif defined(MR_HAVE__SNPRINTF)
+ /* _snprintf does not guarantee null termination. */
+ _snprintf(buf, buflen, "Error %d", errnum);
+ if (buflen > 0) {
+ buf[buflen - 1] = '\0';
+ }
+#else
+ #error "generic_error: unable to define"
+#endif
+}
+const char *
+MR_strerror(int errnum, char *buf, size_t buflen)
+{
+#if defined(MR_HAVE_STRERROR_S)
/*
-** Apparently SunOS 4.1.3 doesn't have strerror()
-** (!%^&!^% non-ANSI systems, grumble...)
+ ** MSVC has strerror_s. It also exists in C11 Annex K and is enabled by
+ ** defining a preprocessor macro __STDC_WANT_LIB_EXT1__
+ */
+ if (strerror_s(buf, buflen, errnum) != 0) {
+ generic_strerror(buf, buflen, errnum);
+ }
+ return buf;
+#elif defined(MR_HAVE_STRERROR_R)
+ /*
+ ** The XSI-compliant strerror_r populates buf unless it fails.
+ ** The GNU-specific strerror_r does not always populate buf.
+ */
+ #if (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && ! _GNU_SOURCE
+ if (strerror_r(errnum, buf, buflen) != 0) {
+ generic_strerror(errnum, buf, buflen);
+ }
+ return buf;
+ #else
+ return strerror_r(errnum, buf, buflen);
+ #endif
+#else
+ /*
+ ** Fallback using deprecated variables. This is used on MinGW at least.
+ **
+ ** strerror_l is another thread-safe alternative, specified in POSIX.
+ ** It is locale-sensitive and takes a locale argument so we don't use it
+ ** for now.
*/
-
-extern int sys_nerr;
-extern char *sys_errlist[];
-
-char *
-strerror(int errnum)
-{
if (errnum >= 0 && errnum < sys_nerr && sys_errlist[errnum] != NULL) {
return sys_errlist[errnum];
} else {
- static char buf[30];
-
- sprintf(buf, "Error %d", errnum);
+ generic_strerror(buf, buflen, errnum);
return buf;
}
+#endif
}
-#endif /* MR_HAVE_STRERROR */
-
FILE *
MR_checked_fopen(const char *filename, const char *message, const char *mode)
{
FILE *file;
+ char errbuf[MR_STRERROR_SIZE];
errno = 0;
file = fopen(filename, mode);
if (file == NULL) {
fprintf(stderr, "Mercury runtime: couldn't %s file `%s': %s\n",
- message, filename, strerror(errno));
+ message, filename, MR_strerror(errno, errbuf, sizeof(errbuf)));
exit(EXIT_FAILURE);
}
return file;
@@ -67,10 +102,12 @@ MR_checked_fopen(const char *filename, const char *message, const char *mode)
void
MR_checked_fclose(FILE *file, const char *filename)
{
+ char errbuf[MR_STRERROR_SIZE];
+
errno = 0;
if (fclose(file) != 0) {
fprintf(stderr, "Mercury runtime: error closing file `%s': %s\n",
- filename, strerror(errno));
+ filename, MR_strerror(errno, errbuf, sizeof(errbuf)));
exit(EXIT_FAILURE);
}
}
@@ -78,10 +115,12 @@ MR_checked_fclose(FILE *file, const char *filename)
void
MR_checked_atexit(void (*func)(void))
{
+ char errbuf[MR_STRERROR_SIZE];
+
errno = 0;
if (atexit(func) != 0) {
fprintf(stderr, "Mercury runtime: error in call to atexit: %s\n",
- strerror(errno));
+ MR_strerror(errno, errbuf, sizeof(errbuf)));
exit(EXIT_FAILURE);
}
}
diff --git a/runtime/mercury_runtime_util.h b/runtime/mercury_runtime_util.h
index d40fb2b..9f41283 100644
--- a/runtime/mercury_runtime_util.h
+++ b/runtime/mercury_runtime_util.h
@@ -1,5 +1,6 @@
/*
** Copyright (C) 2001,2006 The University of Melbourne.
+** Copyright (C) 2014 The Mercury team.
** This file may only be copied under the terms of the GNU Library General
** Public License - see the file COPYING.LIB in the Mercury distribution.
*/
@@ -9,9 +10,18 @@
#include <stdio.h>
-#ifndef MR_HAVE_STRERROR
-extern char *strerror(int errnum);
-#endif
+/*
+** An appropriate buffer size for MR_strerror().
+*/
+#define MR_STRERROR_SIZE 256
+
+/*
+** Thread-safe strerror function. Returns a pointer to a null terminated string
+** describing the error number. The returned pointer may be to the provided
+** buffer, or it may be a pointer into static or thread-local memory.
+** errno may be modified by this call.
+*/
+extern const char *MR_strerror(int errnum, char *buf, size_t buflen);
extern FILE *MR_checked_fopen(const char *filename, const char *message,
const char *mode);
diff --git a/runtime/mercury_term_size.c b/runtime/mercury_term_size.c
index 78d558f..5acb7b1 100644
--- a/runtime/mercury_term_size.c
+++ b/runtime/mercury_term_size.c
@@ -399,6 +399,7 @@ MR_write_complexity_proc(MR_ComplexityProc *proc)
int num_slots;
MR_ComplexityPastSlots *past_slots;
char *cmd_buf;
+ char errbuf[MR_STRERROR_SIZE];
full_proc_name_len = strlen(proc->MR_clp_full_proc_name);
full_proc_name = MR_malloc(100 + full_proc_name_len);
@@ -422,7 +423,8 @@ MR_write_complexity_proc(MR_ComplexityProc *proc)
if (! MR_have_printed_complexity_dirs_error) {
fprintf(stderr, "%s: cannot create %s and %s: %s\n",
MR_progname, MR_COMPLEXITY_ARGS_DIR,
- MR_COMPLEXITY_DATA_DIR, strerror(errno));
+ MR_COMPLEXITY_DATA_DIR,
+ MR_strerror(errno, errbuf, sizeof(errbuf)));
/* there is no point in aborting */
MR_have_printed_complexity_dirs_error = MR_TRUE;
return;
@@ -440,7 +442,8 @@ MR_write_complexity_proc(MR_ComplexityProc *proc)
fp = fopen(args_filename, "w");
if (fp == NULL) {
fprintf(stderr, "%s: cannot open %s: %s\n",
- MR_progname, args_filename, strerror(errno));
+ MR_progname, args_filename,
+ MR_strerror(errno, errbuf, sizeof(errbuf)));
/* there is no point in aborting */
return;
}
@@ -458,7 +461,8 @@ MR_write_complexity_proc(MR_ComplexityProc *proc)
fp = fopen(tmp_filename, "w");
if (fp == NULL) {
fprintf(stderr, "%s: cannot open %s: %s\n",
- MR_progname, tmp_filename, strerror(errno));
+ MR_progname, tmp_filename,
+ MR_strerror(errno, errbuf, sizeof(errbuf)));
/* there is no point in aborting */
return;
}
@@ -484,7 +488,8 @@ MR_write_complexity_proc(MR_ComplexityProc *proc)
fp = fopen(data_filename, data_filemode);
if (fp == NULL) {
fprintf(stderr, "%s: cannot open %s: %s\n",
- MR_progname, data_filename, strerror(errno));
+ MR_progname, data_filename,
+ MR_strerror(errno, errbuf, sizeof(errbuf)));
/* there is no point in aborting */
return;
}
diff --git a/runtime/mercury_trace_base.c b/runtime/mercury_trace_base.c
index d5fbe9a..d1933a0 100644
--- a/runtime/mercury_trace_base.c
+++ b/runtime/mercury_trace_base.c
@@ -27,7 +27,7 @@ ENDINIT
#include "mercury_misc.h"
#include "mercury_hash_table.h"
#include "mercury_layout_util.h" /* for MR_generate_proc_name_from_layout */
-#include "mercury_runtime_util.h" /* for strerror() on some systems */
+#include "mercury_runtime_util.h" /* for MR_strerror */
#include "mercury_signal.h" /* for MR_setup_signal() */
#include "mercury_builtin_types.h" /* for type_ctor_infos */
#include "mercury_array_macros.h" /* for type_ctor_infos */
@@ -283,6 +283,7 @@ MR_trace_record_label_exec_counts(void *dummy)
MR_bool keep;
char *slash;
const char *program_name;
+ char errbuf[MR_STRERROR_SIZE];
program_name = MR_copy_string(MR_progname);
slash = strrchr(program_name, '/');
@@ -364,7 +365,8 @@ MR_trace_record_label_exec_counts(void *dummy)
summarize = MR_FALSE;
}
} else {
- fprintf(stderr, "%s: %s\n", name, strerror(errno));
+ fprintf(stderr, "%s: %s\n", name,
+ MR_strerror(errno, errbuf, sizeof(errbuf)));
/*
** You can't summarize a file list if you can't create
** one of its files.
@@ -934,6 +936,7 @@ MR_trace_report(FILE *fp)
#ifdef MR_TRACE_HISTOGRAM
{
FILE *hfp;
+ char errbuf[MR_STRERROR_SIZE];
hfp = fopen(MR_TRACE_HISTOGRAM_FILENAME, "w");
if (hfp != NULL) {
@@ -944,11 +947,13 @@ MR_trace_report(FILE *fp)
MR_TRACE_HISTOGRAM_FILENAME);
} else {
fprintf(fp, "Cannot put event histogram into `%s': %s."
- MR_TRACE_HISTOGRAM_FILENAME, strerror(errno));
+ MR_TRACE_HISTOGRAM_FILENAME,
+ MR_strerror(errno, errbuf, sizeof(errbuf)));
}
} else {
fprintf(fp, "Cannot open `%s': %s.\n"
- MR_TRACE_HISTOGRAM_FILENAME, strerror(errno));
+ MR_TRACE_HISTOGRAM_FILENAME,
+ MR_strerror(errno, errbuf, sizeof(errbuf)));
}
}
#endif /* MR_TRACE_HISTOGRAM */
diff --git a/trace/mercury_trace_cmd_developer.c b/trace/mercury_trace_cmd_developer.c
index 73b7e7b..2099137 100644
--- a/trace/mercury_trace_cmd_developer.c
+++ b/trace/mercury_trace_cmd_developer.c
@@ -26,6 +26,7 @@
#include "mercury_tabling.h"
#include "mercury_trace_base.h"
#include "mercury_regs.h"
+#include "mercury_runtime_util.h"
#include "mercury_trace_internal.h"
#include "mercury_trace_cmds.h"
@@ -647,6 +648,7 @@ MR_trace_cmd_stats(char **words, int word_count, MR_TraceCmdInfo *cmd,
char *filename;
FILE *fp;
MR_bool should_close;
+ char errbuf[MR_STRERROR_SIZE];
filename = NULL;
if (! MR_trace_options_stats(&filename, &words, &word_count)) {
@@ -664,7 +666,7 @@ MR_trace_cmd_stats(char **words, int word_count, MR_TraceCmdInfo *cmd,
if (fp == NULL) {
fflush(MR_mdb_out);
fprintf(MR_mdb_err, "mdb: error opening `%s': %s.\n",
- filename, strerror(errno));
+ filename, MR_strerror(errno, errbuf, sizeof(errbuf)));
return KEEP_INTERACTING;
}
@@ -1248,6 +1250,7 @@ MR_trace_cmd_all_procedures(char **words, int word_count,
MR_bool uci;
FILE *fp;
char *module;
+ char errbuf[MR_STRERROR_SIZE];
MR_register_all_modules_and_procs(MR_mdb_out, MR_TRUE);
@@ -1264,14 +1267,14 @@ MR_trace_cmd_all_procedures(char **words, int word_count,
if (fp == NULL) {
fflush(MR_mdb_out);
fprintf(MR_mdb_err, "mdb: error opening `%s': %s.\n",
- filename, strerror(errno));
+ filename, MR_strerror(errno, errbuf, sizeof(errbuf)));
return KEEP_INTERACTING;
}
MR_dump_module_tables(fp, separate, uci, module);
if (fclose(fp) != 0) {
fprintf(MR_mdb_err, "mdb: error writing to `%s': %s.\n",
- filename, strerror(errno));
+ filename, MR_strerror(errno, errbuf, sizeof(errbuf)));
return KEEP_INTERACTING;
} else {
fprintf(MR_mdb_out, "mdb: wrote table to `%s'.\n", filename);
@@ -1292,6 +1295,7 @@ MR_trace_cmd_ambiguity(char **words, int word_count,
MR_bool print_types;
MR_bool print_functors;
FILE *fp;
+ char errbuf[MR_STRERROR_SIZE];
filename = NULL;
print_procs = MR_FALSE;
@@ -1317,7 +1321,7 @@ MR_trace_cmd_ambiguity(char **words, int word_count,
if (fp == NULL) {
fflush(MR_mdb_out);
fprintf(MR_mdb_err, "mdb: error opening `%s': %s.\n",
- filename, strerror(errno));
+ filename, MR_strerror(errno, errbuf, sizeof(errbuf)));
return KEEP_INTERACTING;
}
}
diff --git a/trace/mercury_trace_cmd_exp.c b/trace/mercury_trace_cmd_exp.c
index 7d7c82b..17ac665 100644
--- a/trace/mercury_trace_cmd_exp.c
+++ b/trace/mercury_trace_cmd_exp.c
@@ -22,6 +22,7 @@
#include "mercury_std.h"
#include "mercury_getopt.h"
+#include "mercury_runtime_util.h"
#include "mercury_trace_internal.h"
#include "mercury_trace_cmds.h"
@@ -65,7 +66,7 @@ MR_trace_cmd_histogram_all(char **words, int word_count,
if (fp == NULL) {
fflush(MR_mdb_out);
fprintf(MR_mdb_err, "mdb: cannot open file `%s' for output: %s.\n",
- words[1], strerror(errno));
+ words[1], MR_strerror(errno, errbuf, sizeof(errbuf)));
} else {
MR_trace_print_histogram(fp, "All-inclusive",
MR_trace_histogram_all,
@@ -73,7 +74,7 @@ MR_trace_cmd_histogram_all(char **words, int word_count,
if (fclose(fp) != 0) {
fflush(MR_mdb_out);
fprintf(MR_mdb_err, "mdb: error closing file `%s': %s.\n",
- words[1], strerror(errno));
+ words[1], MR_strerror(errno, errbuf, sizeof(errbuf)));
}
}
} else {
@@ -103,7 +104,7 @@ MR_trace_cmd_histogram_exp(char **words, int word_count,
if (fp == NULL) {
fflush(MR_mdb_out);
fprintf(MR_mdb_err, "mdb: cannot open file `%s' for output: %s.\n",
- words[1], strerror(errno));
+ words[1], MR_strerror(errno, errbuf, sizeof(errbuf)));
} else {
MR_trace_print_histogram(fp, "Experimental",
MR_trace_histogram_exp,
@@ -111,7 +112,7 @@ MR_trace_cmd_histogram_exp(char **words, int word_count,
if (fclose(fp) != 0) {
fflush(MR_mdb_out);
fprintf(MR_mdb_err, "mdb: error closing file `%s': %s.\n",
- words[1], strerror(errno));
+ words[1], MR_strerror(errno, errbuf, sizeof(errbuf)));
}
}
} else {
@@ -233,6 +234,7 @@ MR_trace_print_dice(char *pass_trace_counts_file,
MR_String aligned_sort_str;
MR_String aligned_module;
FILE *fp;
+ char errbuf[MR_STRERROR_SIZE];
MR_TRACE_USE_HP(
MR_make_aligned_string(aligned_pass_trace_counts_file,
@@ -264,12 +266,12 @@ MR_trace_print_dice(char *pass_trace_counts_file,
if (fclose(fp) != 0) {
fflush(MR_mdb_out);
fprintf(MR_mdb_err, "mdb: Error closing file `%s': %s\n",
- out_file, strerror(errno));
+ out_file, MR_strerror(errno, errbuf, sizeof(errbuf)));
}
} else {
fflush(MR_mdb_out);
fprintf(MR_mdb_err, "mdb: Error opening file `%s': %s\n",
- out_file, strerror(errno));
+ out_file, MR_strerror(errno, errbuf, sizeof(errbuf)));
}
}
} else {
diff --git a/trace/mercury_trace_cmd_misc.c b/trace/mercury_trace_cmd_misc.c
index d0a1ab6..4703001 100644
--- a/trace/mercury_trace_cmd_misc.c
+++ b/trace/mercury_trace_cmd_misc.c
@@ -22,6 +22,7 @@
#include "mercury_std.h"
#include "mercury_getopt.h"
+#include "mercury_runtime_util.h"
#include "mercury_trace_internal.h"
#include "mercury_trace_cmds.h"
@@ -80,12 +81,13 @@ MR_trace_cmd_save(char **words, int word_count, MR_TraceCmdInfo *cmd,
FILE *fp;
MR_bool found_error;
MR_Word path_list;
+ char errbuf[MR_STRERROR_SIZE];
fp = fopen(words[1], "w");
if (fp == NULL) {
fflush(MR_mdb_out);
fprintf(MR_mdb_err, "mdb: error opening `%s': %s.\n",
- words[1], strerror(errno));
+ words[1], MR_strerror(errno, errbuf, sizeof(errbuf)));
return KEEP_INTERACTING;
}
@@ -204,7 +206,7 @@ MR_trace_cmd_save(char **words, int word_count, MR_TraceCmdInfo *cmd,
} else if (fclose(fp) != 0) {
fflush(MR_mdb_out);
fprintf(MR_mdb_err, "mdb: error closing `%s': %s.\n",
- words[1], strerror(errno));
+ words[1], MR_strerror(errno, errbuf, sizeof(errbuf)));
} else {
fprintf(MR_mdb_out, "Debugger state saved to %s.\n", words[1]);
}
diff --git a/trace/mercury_trace_declarative.c b/trace/mercury_trace_declarative.c
index 00c1697..5b81122 100644
--- a/trace/mercury_trace_declarative.c
+++ b/trace/mercury_trace_declarative.c
@@ -120,6 +120,7 @@
#include "mercury_string.h"
#include "mercury_timing.h"
#include "mercury_trace_base.h"
+#include "mercury_runtime_util.h"
#include "mdb.declarative_debugger.mh"
#include "mdb.declarative_execution.mh"
@@ -1712,9 +1713,11 @@ MR_trace_start_decl_debug(MR_DeclMode mode, const char *outfile,
if (mode == MR_DECL_DUMP) {
out = fopen(outfile, "w");
if (out == NULL) {
+ char errbuf[MR_STRERROR_SIZE];
+
fflush(MR_mdb_out);
fprintf(MR_mdb_err, "mdb: cannot open file `%s' for output: %s.\n",
- outfile, strerror(errno));
+ outfile, MR_strerror(errno, errbuf, sizeof(errbuf)));
return MR_FALSE;
} else {
MR_trace_store_file = out;
diff --git a/trace/mercury_trace_external.c b/trace/mercury_trace_external.c
index 5c881ea..3dcda04 100644
--- a/trace/mercury_trace_external.c
+++ b/trace/mercury_trace_external.c
@@ -38,6 +38,7 @@
#include "type_desc.mh"
#include "mercury_deep_copy.h"
+#include "mercury_runtime_util.h"
#include <stdio.h>
#include <errno.h>
@@ -317,6 +318,7 @@ MR_trace_init_external(void)
struct sockaddr *addr;
MR_Word debugger_request;
MR_Integer debugger_request_type;
+ char errbuf[MR_STRERROR_SIZE];
/*
** MR_external_mmc_options contains the options to pass to mmc
@@ -405,7 +407,7 @@ MR_trace_init_external(void)
fd = socket(addr_family, SOCK_STREAM, 0);
if (fd < 0) {
fprintf(stderr, "Mercury runtime: socket() failed: %s\n",
- strerror(errno));
+ MR_strerror(errno, errbuf, sizeof(errbuf)));
MR_fatal_error("cannot open socket for debugger");
} else if (MR_debug_socket) {
fprintf(stderr,"Mercury runtime: creation of socket ok\n");
@@ -417,7 +419,7 @@ MR_trace_init_external(void)
if (connect(fd, addr, len) < 0) {
fprintf(stderr, "Mercury runtime: connect() failed: %s\n",
- strerror(errno));
+ MR_strerror(errno, errbuf, sizeof(errbuf)));
MR_fatal_error("can't connect to debugger socket");
} else if (MR_debug_socket) {
fprintf(stderr, "Mercury runtime: connection to socket: ok\n");
@@ -431,7 +433,7 @@ MR_trace_init_external(void)
file_out = fdopen(fd, "w");
if ((file_in == NULL)||(file_out == NULL)) {
fprintf(stderr, "Mercury runtime: fdopen() failed: %s\n",
- strerror(errno));
+ MR_strerror(errno, errbuf, sizeof(errbuf)));
MR_fatal_error("cannot open debugger socket");
} else if (MR_debug_socket) {
fprintf(stderr, "Mercury runtime: fdopen(): ok\n");
diff --git a/trace/mercury_trace_internal.c b/trace/mercury_trace_internal.c
index 11e041a..57e099c 100644
--- a/trace/mercury_trace_internal.c
+++ b/trace/mercury_trace_internal.c
@@ -22,6 +22,7 @@
#include "mercury_signal.h"
#include "mercury_builtin_types.h"
#include "mercury_deep_profiling.h"
+#include "mercury_runtime_util.h"
#include "mercury_event_spec.h"
@@ -277,12 +278,13 @@ MR_try_fopen(const char *filename, const char *mode, FILE *default_file)
return default_file;
} else {
FILE *f;
+ char errbuf[MR_STRERROR_SIZE];
f = fopen(filename, mode);
if (f == NULL) {
fflush(MR_mdb_out);
fprintf(MR_mdb_err, "mdb: error opening `%s': %s\n",
- filename, strerror(errno));
+ filename, MR_strerror(errno, errbuf, sizeof(errbuf)));
return default_file;
} else {
return f;
@@ -683,6 +685,7 @@ MR_trace_source(const char *filename, MR_bool ignore_errors,
char** args, int num_args)
{
FILE *fp;
+ char errbuf[MR_STRERROR_SIZE];
if ((fp = fopen(filename, "r")) != NULL) {
MR_trace_source_from_open_file(fp, args, num_args);
@@ -692,7 +695,8 @@ MR_trace_source(const char *filename, MR_bool ignore_errors,
if (! ignore_errors) {
fflush(MR_mdb_out);
- fprintf(MR_mdb_err, "%s: %s.\n", filename, strerror(errno));
+ fprintf(MR_mdb_err, "%s: %s.\n",
+ filename, MR_strerror(errno, errbuf, sizeof(errbuf)));
}
return MR_FALSE;
--
1.8.4
More information about the reviews
mailing list