extern Int VG_(nanosleep)( const struct vki_timespec *req,
struct vki_timespec *rem );
-extern Int VG_(write_socket)( Int sd, void *msg, Int count );
+extern Int VG_(write_socket)( Int sd, void *msg, Int count );
/* --- Connecting over the network --- */
extern Int VG_(connect_via_socket)( UChar* str );
+
+/* ---------------------------------------------------------------------
+ Exports of vg_message.c
+ ------------------------------------------------------------------ */
+
+/* Low-level -- send bytes directly to the message sink. Do not
+ use. */
+extern void VG_(send_bytes_to_logging_sink) ( Char* msg, Int nbytes );
+
+
/* ---------------------------------------------------------------------
Definitions for the JITter (vg_translate.c, vg_to_ucode.c,
vg_from_ucode.c).
}
if (eventually_logfile_fd == -2) {
VG_(message)(Vg_UserMsg,
- "Failed to connect to logging server `%s'; giving up",
+ "valgrind: failed to connect to logging server `%s'.",
VG_(clo_logfile_name) );
- VG_(bad_option)(
- "--logsocket= (timeout during connect)");
- }
- vg_assert(eventually_logfile_fd > 0);
- VG_(clo_logfile_fd) = eventually_logfile_fd;
- VG_(logging_to_filedes) = False;
+ VG_(message)(Vg_UserMsg,
+ "Log messages will sent to stderr instead." );
+ VG_(message)(Vg_UserMsg,
+ "" );
+ /* We don't change anything here. */
+ } else {
+ vg_assert(eventually_logfile_fd > 0);
+ VG_(clo_logfile_fd) = eventually_logfile_fd;
+ VG_(logging_to_filedes) = False;
+ }
break;
}
{
if (VG_(clo_logfile_fd) >= 0) {
add_to_buf('\n');
- if (VG_(logging_to_filedes))
- VG_(write)(
- VG_(clo_logfile_fd), vg_mbuf, VG_(strlen)(vg_mbuf));
- else
- VG_(write_socket)(
- VG_(clo_logfile_fd), vg_mbuf, VG_(strlen)(vg_mbuf));
+ VG_(send_bytes_to_logging_sink) (
+ vg_mbuf, VG_(strlen)(vg_mbuf) );
+ }
+}
+
+
+/* Do the low-level send of a message to the logging sink. */
+void VG_(send_bytes_to_logging_sink) ( Char* msg, Int nbytes )
+{
+ Int rc;
+ if (VG_(logging_to_filedes)) {
+ VG_(write)( VG_(clo_logfile_fd), msg, nbytes );
+ } else {
+ rc = VG_(write_socket)( VG_(clo_logfile_fd), msg, nbytes );
+ if (rc == -1) {
+ /* for example, the listener process died. Switch back to
+ stderr. */
+ VG_(logging_to_filedes) = True;
+ VG_(clo_log_to) = VgLogTo_Fd;
+ VG_(clo_logfile_fd) = 2;
+ VG_(write)( VG_(clo_logfile_fd), msg, nbytes );
+ }
}
}
{
if (n_myprintf_buf >= 100-10 /*paranoia*/ ) {
if (VG_(clo_logfile_fd) >= 0) {
- if (VG_(logging_to_filedes))
- VG_(write)
- (VG_(clo_logfile_fd), myprintf_buf, VG_(strlen)(myprintf_buf));
- else
- VG_(write_socket)
- (VG_(clo_logfile_fd), myprintf_buf, VG_(strlen)(myprintf_buf));
+ VG_(send_bytes_to_logging_sink)(
+ myprintf_buf, VG_(strlen)(myprintf_buf) );
}
n_myprintf_buf = 0;
myprintf_buf[n_myprintf_buf] = 0;
ret = VG_(vprintf) ( add_to_myprintf_buf, format, vargs );
if (n_myprintf_buf > 0 && VG_(clo_logfile_fd) >= 0) {
- if (VG_(logging_to_filedes))
- VG_(write)
- ( VG_(clo_logfile_fd), myprintf_buf, n_myprintf_buf);
- else
- VG_(write_socket)
- ( VG_(clo_logfile_fd), myprintf_buf, n_myprintf_buf);
+ VG_(send_bytes_to_logging_sink)( myprintf_buf, n_myprintf_buf );
}
va_end(vargs);
/* kernel, include/linux/socket.h */
typedef unsigned short vki_sa_family_t;
#define AF_INET 2 /* Internet IP Protocol */
+#define MSG_NOSIGNAL 0x4000 /* Do not generate SIGPIPE */
/* kernel, ./include/asm-i386/socket.h */
#define SOCK_STREAM 1 /* stream (connection) socket */
Int VG_(write_socket)( Int sd, void *msg, Int count )
{
/* This is actually send(). */
- Int flags = 0;
+
+ /* Requests not to send SIGPIPE on errors on stream oriented
+ sockets when the other end breaks the connection. The EPIPE
+ error is still returned. */
+ Int flags = MSG_NOSIGNAL;
+
Int res;
UInt args[4];
args[0] = sd;