continue calling waitpid() while still reapingchildren (patch from
[rsync/rsync.git] / receiver.c
index 378364c..6361d21 100644 (file)
@@ -83,7 +83,7 @@ static void add_delete_entry(struct file_struct *file)
 static void delete_one(struct file_struct *f)
 {
        if (!S_ISDIR(f->mode)) {
-               if (do_unlink(f_name(f)) != 0) {
+               if (robust_unlink(f_name(f)) != 0) {
                        rprintf(FERROR,"unlink %s : %s\n",f_name(f),strerror(errno));
                } else if (verbose) {
                        rprintf(FINFO,"deleting %s\n",f_name(f));
@@ -412,14 +412,18 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
                   setuid/setgid bits to ensure that there is no race
                   condition. They are then correctly updated after
                   the lchown. Thanks to snabb@epipe.fi for pointing
-                  this out */
+                  this out.  We also set it initially without group
+                  access because of a similar race condition. */
                fd2 = do_open(fnametmp,O_WRONLY|O_CREAT|O_EXCL,
-                             file->mode & ACCESSPERMS);
+                             file->mode & INITACCESSPERMS);
 
+               /* in most cases parent directories will already exist
+                  because their information should have been previously
+                  transferred, but that may not be the case with -R */
                if (fd2 == -1 && relative_paths && errno == ENOENT && 
                    create_directory_path(fnametmp) == 0) {
                        fd2 = do_open(fnametmp,O_WRONLY|O_CREAT|O_EXCL,
-                                     file->mode & ACCESSPERMS);
+                                     file->mode & INITACCESSPERMS);
                }
                if (fd2 == -1) {
                        rprintf(FERROR,"cannot create %s : %s\n",fnametmp,strerror(errno));
@@ -473,7 +477,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
        for (i = 0; i < flist->count; i++) {
                file = flist->files[i];
                if (!file->basename || !S_ISDIR(file->mode)) continue;
-               recv_generator(f_name(file),flist,i,-1);
+               recv_generator(local_name?local_name:f_name(file),flist,i,-1);
        }
 
        if (verbose > 2)