diff options
author | J.W. Schultz <jw@samba.org> | 2003-09-16 02:49:59 +0000 |
---|---|---|
committer | J.W. Schultz <jw@samba.org> | 2003-09-16 02:49:59 +0000 |
commit | 6a7cc46cb279b9dbf12977177330aeebb912aa34 (patch) | |
tree | 6e3b7760f73eb3610228467999714af25378f3d4 | |
parent | aa6dc37ccb73c83f652e72ed1ca7700934a52331 (diff) | |
download | android_external_rsync-6a7cc46cb279b9dbf12977177330aeebb912aa34.tar.gz android_external_rsync-6a7cc46cb279b9dbf12977177330aeebb912aa34.tar.bz2 android_external_rsync-6a7cc46cb279b9dbf12977177330aeebb912aa34.zip |
Detect and report when open or opendir succeed but read and
readdir fail caused by network filesystems issues and
truncated files.
Thanks to David Norwood and Michael Brown
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | fileio.c | 14 | ||||
-rw-r--r-- | flist.c | 11 | ||||
-rw-r--r-- | rsync.c | 18 | ||||
-rw-r--r-- | rsync.h | 14 | ||||
-rw-r--r-- | sender.c | 12 |
6 files changed, 58 insertions, 15 deletions
@@ -92,6 +92,10 @@ Changes since version 2.5.6: same path. A directory still cannot be replaced by a regular file unless --delete specified. (J.W. Schultz) + * Detect and report when open or opendir succeed but read and + readdir fail caused by network filesystems issues and truncated + files. (David Norwood, Michael Brown, J.W. Schultz) + INTERNAL: * Eliminated vestigial support for old versions that we stopped @@ -115,6 +115,7 @@ struct map_struct *map_file(int fd,OFF_T len) map->p_offset = 0; map->p_fd_offset = 0; map->p_len = 0; + map->status = 0; return map; } @@ -191,7 +192,11 @@ char *map_ptr(struct map_struct *map,OFF_T offset,int len) } if ((nread=read(map->fd,map->p + read_offset,read_size)) != read_size) { - if (nread < 0) nread = 0; + if (nread < 0) { + nread = 0; + if (!map->status) + map->status = errno; + } /* the best we can do is zero the buffer - the file has changed mid transfer! */ memset(map->p+read_offset+nread, 0, read_size - nread); @@ -206,13 +211,18 @@ char *map_ptr(struct map_struct *map,OFF_T offset,int len) } -void unmap_file(struct map_struct *map) +int unmap_file(struct map_struct *map) { + int ret; + if (map->p) { free(map->p); map->p = NULL; } + ret = map->status; memset(map, 0, sizeof(*map)); free(map); + + return ret; } @@ -877,14 +877,19 @@ static void send_directory(int f, struct file_list *flist, char *dir) } } - for (di = readdir(d); di; di = readdir(d)) { + for (errno = 0, di = readdir(d); di; errno = 0, di = readdir(d)) { char *dname = d_name(di); - if (dname[0] == '.' && (dname[1] == '\0' || - (dname[1] == '.' && dname[2] == '\0'))) + if (dname[0] == '.' && (dname[1] == '\0' + || (dname[1] == '.' && dname[2] == '\0'))) continue; strlcpy(p, dname, MAXPATHLEN - l); send_file_name(f, flist, fname, recurse, 0); } + if (errno) { + io_error = 1; + rprintf(FERROR, "readdir(%s): (%d) %s\n", + dir, errno, strerror(errno)); + } if (local_exclude_list) free_exclude_list(&local_exclude_list); /* Zeros pointer too */ @@ -88,10 +88,10 @@ int delete_file(char *fname) return -1; } - for (di=readdir(d); di; di=readdir(d)) { + for (errno = 0, di = readdir(d); di; errno = 0, di = readdir(d)) { char *dname = d_name(di); - if (strcmp(dname,".")==0 || - strcmp(dname,"..")==0) + if (strcmp(dname,".") == 0 + || strcmp(dname,"..") == 0) continue; snprintf(buf, sizeof(buf), "%s/%s", fname, dname); if (verbose > 0) @@ -101,6 +101,12 @@ int delete_file(char *fname) return -1; } } + if (errno) { + rprintf(FERROR, "delete_file: readdir(%s): (%d) %s\n", + fname, errno, strerror(errno)); + closedir(d); + return -1; + } closedir(d); @@ -148,7 +154,7 @@ static int is_in_group(gid_t gid) } int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st, - int report) + int report) { int updated = 0; STRUCT_STAT st2; @@ -218,7 +224,7 @@ int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st, } } #endif - + if (verbose > 1 && report) { if (updated) rprintf(FINFO,"%s\n",fname); @@ -245,7 +251,7 @@ void finish_transfer(char *fname, char *fnametmp, struct file_struct *file) /* move tmp file over real file */ if (robust_rename(fnametmp,fname) != 0) { if (errno == EXDEV) { - /* rename failed on cross-filesystem link. + /* rename failed on cross-filesystem link. Copy the file instead. */ if (copy_file(fnametmp,fname, file->mode & INITACCESSPERMS)) { rprintf(FERROR, "copy %s -> \"%s\": %s\n", @@ -416,9 +416,17 @@ struct sum_struct { }; struct map_struct { - char *p; - int fd,p_size,p_len; - OFF_T file_size, p_offset, p_fd_offset; + char *p; /* Window pointer */ + int fd; /* File Descriptor */ + int p_size; /* Window size at allocation */ + int p_len; /* Window size after fill */ + /* p_size and p_len could be + * consolodated by using a local + * variable in map_ptr() */ + int status; /* first errno from read errors */ + OFF_T file_size; /* File size (from stat) */ + OFF_T p_offset; /* Window start */ + OFF_T p_fd_offset; /* offset of cursor in fd ala lseek */ }; #define MATCHFLG_WILD 0x0001 /* pattern has '*', '[', and/or '?' */ @@ -277,7 +277,17 @@ void send_files(struct file_list *flist, int f_out, int f_in) } if (!read_batch) { /* dw */ - if (buf) unmap_file(buf); + if (buf) { + j = unmap_file(buf); + if (j) { + io_error = 1; + rprintf(FERROR, + "read errors mapping %s: (%d) %s\n", + full_fname(fname), + j, + strerror(j)); + } + } close(fd); } |