* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "rsync.h"
+extern int am_server;
+extern int am_daemon;
extern int io_error;
extern int keep_partial;
extern int log_got_error;
extern char *partial_dir;
+extern char *logfile_name;
#ifdef HAVE_SIGACTION
static struct sigaction sigact;
pid_t cleanup_child_pid = -1;
+int in_exit_cleanup = 0;
+
/**
* Eventually calls exit(), passing @p code, therefore does not return.
*
* @param code one of the RERR_* codes from errcode.h.
**/
-void _exit_cleanup(int code, const char *file, int line)
+NORETURN void _exit_cleanup(int code, const char *file, int line)
{
int ocode = code;
- static int inside_cleanup = 0;
-
- if (inside_cleanup > 10) {
- /* prevent the occasional infinite recursion */
- return;
- }
- inside_cleanup++;
SIGACTION(SIGUSR1, SIG_IGN);
SIGACTION(SIGUSR2, SIG_IGN);
+ in_exit_cleanup = 1;
+
if (verbose > 3) {
rprintf(FINFO,"_exit_cleanup(code=%d, file=%s, line=%d): entered\n",
code, file, line);
if (cleanup_child_pid != -1) {
int status;
- if (wait_process(cleanup_child_pid, &status, WNOHANG)
- == cleanup_child_pid) {
+ if (wait_process(cleanup_child_pid, &status, WNOHANG) == cleanup_child_pid) {
status = WEXITSTATUS(status);
if (status > code)
code = status;
}
}
- if (cleanup_got_literal && cleanup_fname && keep_partial
+ if (cleanup_got_literal && cleanup_new_fname && keep_partial
&& handle_partial_dir(cleanup_new_fname, PDIR_CREATE)) {
char *fname = cleanup_fname;
cleanup_fname = NULL;
code = RERR_PARTIAL;
}
- if (code)
+ if (code || am_daemon || (logfile_name && (am_server || !verbose)))
log_exit(code, file, line);
if (verbose > 2) {
void cleanup_disable(void)
{
- cleanup_fname = NULL;
+ cleanup_fname = cleanup_new_fname = NULL;
cleanup_got_literal = 0;
}
void cleanup_set(char *fnametmp, char *fname, struct file_struct *file,
int fd_r, int fd_w)
{
- cleanup_fname = fname ? fnametmp : NULL;
- cleanup_new_fname = fname;
+ cleanup_fname = fnametmp;
+ cleanup_new_fname = fname; /* can be NULL on a partial-dir failure */
cleanup_file = file;
cleanup_fd_r = fd_r;
cleanup_fd_w = fd_w;