/* -*- c-file-style: "linux"; -*-
- Copyright (C) 1998-2001 by Andrew Tridgell <mbp@samba.org>
+ Copyright (C) 1998-2001 by Andrew Tridgell <tridge@samba.org>
Copyright (C) 2000-2001 by Martin Pool <mbp@samba.org>
This program is free software; you can redistribute it and/or modify
/*
Logging and utility functions.
+ tridge, May 1998
Mapping to human-readable messages added by Martin Pool
<mbp@samba.org>, Oct 2000.
return NULL;
}
+struct err_list {
+ struct err_list *next;
+ char *buf;
+ int len;
+ int written; /* how many bytes we have written so far */
+};
+
+static struct err_list *err_list_head;
+static struct err_list *err_list_tail;
+
+/* add an error message to the pending error list */
+static void err_list_add(int code, char *buf, int len)
+{
+ struct err_list *el;
+ el = (struct err_list *)malloc(sizeof(*el));
+ if (!el) exit_cleanup(RERR_MALLOC);
+ el->next = NULL;
+ el->buf = malloc(len+4);
+ if (!el->buf) exit_cleanup(RERR_MALLOC);
+ memcpy(el->buf+4, buf, len);
+ SIVAL(el->buf, 0, ((code+MPLEX_BASE)<<24) | len);
+ el->len = len+4;
+ el->written = 0;
+ if (err_list_tail) {
+ err_list_tail->next = el;
+ } else {
+ err_list_head = el;
+ }
+ err_list_tail = el;
+}
+
+
+/* try to push errors off the error list onto the wire */
+void err_list_push(void)
+{
+ if (log_error_fd == -1) return;
+
+ while (err_list_head) {
+ struct err_list *el = err_list_head;
+ int n = write(log_error_fd, el->buf+el->written, el->len - el->written);
+ if (n == -1) break;
+ if (n > 0) {
+ el->written += n;
+ }
+ if (el->written == el->len) {
+ free(el->buf);
+ err_list_head = el->next;
+ if (!err_list_head) err_list_tail = NULL;
+ free(el);
+ }
+ }
+}
+
static void logit(int priority, char *buf)
{
void set_error_fd(int fd)
{
log_error_fd = fd;
+ set_nonblocking(log_error_fd);
}
/* this is the underlying (unformatted) rsync debugging function. Call
return;
}
- /* first try to pass it off the our sibling */
- if (am_server && io_error_write(log_error_fd, code, buf, len)) {
+ /* first try to pass it off to our sibling */
+ if (am_server && log_error_fd != -1) {
+ err_list_add(code, buf, len);
+ err_list_push();
return;
}