{
if (new_size < out->size) {
/* Avoid weird buffer interactions by only outputting this to stderr. */
- if (msgs2stderr && DEBUG_GTE(IO, 4)) {
+ if (msgs2stderr == 1 && DEBUG_GTE(IO, 4)) {
const char *name = out == &iobuf.out ? "iobuf.out"
: out == &iobuf.msg ? "iobuf.msg"
: NULL;
if (IOBUF_WAS_REDUCED(out->size)) {
size_t new_size = IOBUF_RESTORE_SIZE(out->size);
/* Avoid weird buffer interactions by only outputting this to stderr. */
- if (msgs2stderr && DEBUG_GTE(IO, 4)) {
+ if (msgs2stderr == 1 && DEBUG_GTE(IO, 4)) {
const char *name = out == &iobuf.out ? "iobuf.out"
: out == &iobuf.msg ? "iobuf.msg"
: NULL;
exit_cleanup(RERR_PROTOCOL);
}
- if (msgs2stderr && DEBUG_GTE(IO, 3)) {
+ if (msgs2stderr == 1 && DEBUG_GTE(IO, 3)) {
rprintf(FINFO, "[%s] perform_io(%ld, %sinput)\n",
who_am_i(), (long)needed, flags & PIO_CONSUME_INPUT ? "consume&" : "");
}
exit_cleanup(RERR_PROTOCOL);
}
- if (msgs2stderr && DEBUG_GTE(IO, 3)) {
+ if (msgs2stderr == 1 && DEBUG_GTE(IO, 3)) {
rprintf(FINFO, "[%s] perform_io(%ld, outroom) needs to flush %ld\n",
who_am_i(), (long)needed,
iobuf.out.len + needed > iobuf.out.size
exit_cleanup(RERR_PROTOCOL);
}
- if (msgs2stderr && DEBUG_GTE(IO, 3)) {
+ if (msgs2stderr == 1 && DEBUG_GTE(IO, 3)) {
rprintf(FINFO, "[%s] perform_io(%ld, msgroom) needs to flush %ld\n",
who_am_i(), (long)needed,
iobuf.msg.len + needed > iobuf.msg.size
break;
case 0:
- if (msgs2stderr && DEBUG_GTE(IO, 3))
+ if (msgs2stderr == 1 && DEBUG_GTE(IO, 3))
rprintf(FINFO, "[%s] perform_io(%ld, %d)\n", who_am_i(), (long)needed, flags);
break;
SIVAL(iobuf.out.buf + iobuf.raw_data_header_pos, 0,
((MPLEX_BASE + (int)MSG_DATA)<<24) + iobuf.out.len - 4);
- if (msgs2stderr && DEBUG_GTE(IO, 1)) {
+ if (msgs2stderr == 1 && DEBUG_GTE(IO, 1)) {
rprintf(FINFO, "[%s] send_msg(%d, %ld)\n",
who_am_i(), (int)MSG_DATA, (long)iobuf.out.len - 4);
}
exit_cleanup(RERR_SOCKETIO);
}
}
- if (msgs2stderr && DEBUG_GTE(IO, 2))
+ if (msgs2stderr == 1 && DEBUG_GTE(IO, 2))
rprintf(FINFO, "[%s] recv=%ld\n", who_am_i(), (long)n);
if (io_timeout || stop_at_utime) {
exit_cleanup(RERR_SOCKETIO);
}
}
- if (msgs2stderr && DEBUG_GTE(IO, 2)) {
+ if (msgs2stderr == 1 && DEBUG_GTE(IO, 2)) {
rprintf(FINFO, "[%s] %s sent=%ld\n",
who_am_i(), out == &iobuf.out ? "out" : "msg", (long)n);
}
{
char *hdr;
size_t needed, pos;
- BOOL want_debug = DEBUG_GTE(IO, 1) && convert >= 0 && (msgs2stderr || code != MSG_INFO);
+ BOOL want_debug = DEBUG_GTE(IO, 1) && convert >= 0 && (msgs2stderr == 1 || code != MSG_INFO);
if (!OUT_MULTIPLEXED)
return 0;
BOOL io_start_buffering_out(int f_out)
{
- if (msgs2stderr && DEBUG_GTE(IO, 2))
+ if (msgs2stderr == 1 && DEBUG_GTE(IO, 2))
rprintf(FINFO, "[%s] io_start_buffering_out(%d)\n", who_am_i(), f_out);
if (iobuf.out.buf) {
BOOL io_start_buffering_in(int f_in)
{
- if (msgs2stderr && DEBUG_GTE(IO, 2))
+ if (msgs2stderr == 1 && DEBUG_GTE(IO, 2))
rprintf(FINFO, "[%s] io_start_buffering_in(%d)\n", who_am_i(), f_in);
if (iobuf.in.buf) {
void io_end_buffering_in(BOOL free_buffers)
{
- if (msgs2stderr && DEBUG_GTE(IO, 2)) {
+ if (msgs2stderr == 1 && DEBUG_GTE(IO, 2)) {
rprintf(FINFO, "[%s] io_end_buffering_in(IOBUF_%s_BUFS)\n",
who_am_i(), free_buffers ? "FREE" : "KEEP");
}
void io_end_buffering_out(BOOL free_buffers)
{
- if (msgs2stderr && DEBUG_GTE(IO, 2)) {
+ if (msgs2stderr == 1 && DEBUG_GTE(IO, 2)) {
rprintf(FINFO, "[%s] io_end_buffering_out(IOBUF_%s_BUFS)\n",
who_am_i(), free_buffers ? "FREE" : "KEEP");
}
msg_bytes = tag & 0xFFFFFF;
tag = (tag >> 24) - MPLEX_BASE;
- if (DEBUG_GTE(IO, 1) && msgs2stderr)
+ if (msgs2stderr == 1 && DEBUG_GTE(IO, 1))
rprintf(FINFO, "[%s] got msg=%d, len=%ld\n", who_am_i(), (int)tag, (long)msg_bytes);
switch (tag) {
{
io_flush(FULL_FLUSH);
- if (msgs2stderr && DEBUG_GTE(IO, 2))
+ if (msgs2stderr == 1 && DEBUG_GTE(IO, 2))
rprintf(FINFO, "[%s] io_start_multiplex_out(%d)\n", who_am_i(), fd);
if (!iobuf.msg.buf)
/* Setup for multiplexing a MSG_* stream with the data stream. */
void io_start_multiplex_in(int fd)
{
- if (msgs2stderr && DEBUG_GTE(IO, 2))
+ if (msgs2stderr == 1 && DEBUG_GTE(IO, 2))
rprintf(FINFO, "[%s] io_start_multiplex_in(%d)\n", who_am_i(), fd);
iobuf.in_multiplexed = 1; /* See also IN_MULTIPLEXED */
{
int ret = iobuf.in_multiplexed ? iobuf.in_fd : -1;
- if (msgs2stderr && DEBUG_GTE(IO, 2))
+ if (msgs2stderr == 1 && DEBUG_GTE(IO, 2))
rprintf(FINFO, "[%s] io_end_multiplex_in(mode=%d)\n", who_am_i(), mode);
iobuf.in_multiplexed = 0;
{
int ret = iobuf.out_empty_len ? iobuf.out_fd : -1;
- if (msgs2stderr && DEBUG_GTE(IO, 2))
+ if (msgs2stderr == 1 && DEBUG_GTE(IO, 2))
rprintf(FINFO, "[%s] io_end_multiplex_out(mode=%d)\n", who_am_i(), mode);
if (mode != MPLX_TO_BUFFERED)
int implied_dirs = 1;
int missing_args = 0; /* 0 = FERROR_XFER, 1 = ignore, 2 = delete */
int numeric_ids = 0;
-int msgs2stderr = 0;
+int msgs2stderr = -1;
int allow_8bit_chars = 0;
int force_delete = 0;
int io_timeout = 0;
{"no-v", 0, POPT_ARG_VAL, &verbose, 0, 0, 0 },
{"info", 0, POPT_ARG_STRING, 0, OPT_INFO, 0, 0 },
{"debug", 0, POPT_ARG_STRING, 0, OPT_DEBUG, 0, 0 },
- {"msgs2stderr", 0, POPT_ARG_NONE, &msgs2stderr, 0, 0, 0 },
+ {"msgs2stderr", 0, POPT_ARG_VAL, &msgs2stderr, 1, 0, 0 },
{"no-msgs2stderr", 0, POPT_ARG_VAL, &msgs2stderr, 0, 0, 0 },
{"quiet", 'q', POPT_ARG_NONE, 0, 'q', 0, 0 },
{"motd", 0, POPT_ARG_VAL, &output_motd, 1, 0, 0 },
setvbuf(stdout, (char *)NULL, mode, 0);
}
- if (msgs2stderr) {
+ if (msgs2stderr < 0)
+ msgs2stderr = am_daemon > 0 ? 0 : 2;
+ if (msgs2stderr == 1) {
/* Make stderr line buffered for better sharing of the stream. */
fflush(stderr); /* Just in case... */
setvbuf(stderr, (char *)NULL, _IOLBF, 0);
args[ac++] = "--log-format=X";
}
+ if (msgs2stderr == 1)
+ args[ac++] = "--msgs2stderr";
+ else if (msgs2stderr == 0)
+ args[ac++] = "--no-msgs2stderr";
+
if (block_size) {
if (asprintf(&arg, "-B%u", (int)block_size) < 0)
goto oom;
--verbose, -v increase verbosity
--info=FLAGS fine-grained informational verbosity
--debug=FLAGS fine-grained debug verbosity
---msgs2stderr output messages directly to stderr
+--msgs2stderr output all messages directly to stderr
--quiet, -q suppress non-error messages
--no-motd suppress daemon-mode MOTD
--checksum, -c skip based on checksum, not mod-time & size
0. `--msgs2stderr`
- This option changes rsync to send all its output directly to stderr rather
+ This option tells rsync to send all the messages directly to stderr rather
than to send messages to the client side via the protocol. The protocol
allows rsync to output normal messages via stdout and errors via stderr,
but it can delay messages behind a slew of data.
- One case where this is helpful is when sending really large files, since
- errors that happen on a remote receiver tend to get delayed until after the
- file's data is fully sent. It is also helpful for debugging, since it
- helps to avoid overpopulating the protocol data with extra message data.
-
- The option does not affect the remote side of a transfer without using
- `--remote-option`, e.g. `-M--msgs2stderr` or `{-M,}--msgs2stderr`.
+ This option helps to avoid putting a lot of data into the pipe if you are
+ outputting debugging information via several `-v` options or the `--debug`
+ options.
Also keep in mind that connecting to a normal (non-remote-shell) daemon
does not have a stderr channel to send messages back to the client side, so
so that the merging of the output of 3 programs happens in a more readable
manner.
+ Starting with rsync 3.2.3 rsync will send **errors** directly to stderr for
+ a non-daemon transfer, so you no longer need to specify this option just to
+ try to improve rsync's behavior when a remote receiver encounters an error.
+ You can override this new default by specifying `--no-msgs2stderr`.
+
+ Also starting with rsync 3.2.3 rsync will forward the `--msgs2stderr` or
+ `--no-msgs2stderr` option to the remote rsync.
+
0. `--quiet`, `-q`
This option decreases the amount of information you are given during the