diff --git a/src/ChangeLog b/src/ChangeLog index 3cf1b82cb..35a34fa86 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,27 @@ +Sun May 24 02:45:03 1998 Norbert Warmuth + + * utilunix.c, util.h (errno_dir_not_empty): deleted + +Sat May 23 22:29:57 1998 Norbert Warmuth + + * file.c (check_dir_is_empty): New function which takes a path and + returns -1 on error, 1 if there are no entries besides "." and + ".." in the directory path points to, 0 else. This function + actually opens and reads the directory and doesn't do tricks we + used to do with rmdir. + + * file.c (erase_dir, erase_dir_iff_empty): Use check_dir_is_empty + to detect non empty directories. The old code tried to remove the + directory and decided on errno whether the failure of rmdir was + caused by a non empty directory or whether there was a different + error. + Unfortunatly not every filesystem sets errno to EDIRNOTEMPTY if + you try to delete a non empty directory. Namely the linux user + space nfs server sets errno to EIO, Suns nfs server sets it to + EEXIST and the AIX nfs server sets it to ??? (Steve reported + problems on AIX so I guess AIX sets errno to a value we currently + don't check). + 1998-maj-18 Tamasi Gyorgy (gt_cosy@usa.net) * lib/mc.menu: 'Z' on 'tar.Z' and 'tar.z' files: '%f' -> '$1'. diff --git a/src/file.c b/src/file.c index e83af881b..b689ff1f8 100644 --- a/src/file.c +++ b/src/file.c @@ -1801,6 +1801,31 @@ recursive_erase (char *s) return FILE_CONT; } +/* Return -1 on error, 1 if there are no entries besides "." and ".." + in the directory path points to, 0 else. */ +static int +check_dir_is_empty(char *path) +{ + DIR *dir; + struct dirent *d; + int i; + + dir = mc_opendir (path); + if (!dir) + return -1; + + for (i = 1, d = mc_readdir (dir); d; d = mc_readdir (dir)) { + if (d->d_name[0] == '.' && (d->d_name[1] == '\0' || + (d->d_name[1] == '.' && d->d_name[2] == '\0'))) + continue; /* "." or ".." */ + i = 0; + break; + } + + mc_closedir (dir); + return i; +} + int erase_dir (char *s) { @@ -1816,16 +1841,25 @@ erase_dir (char *s) return FILE_ABORT; mc_refresh (); - retry_rmdir: - error = my_rmdir (s); - if (error && errno_dir_not_empty (errno)){ + /* The old way to detect a non empty directory was: + error = my_rmdir (s); + if (error && (errno == ENOTEMPTY || errno == EEXIST))) { + For the linux user space nfs server (nfs-server-2.2beta29-2) + we would have to check also for EIO. I hope the new way is + fool proof. (Norbert) + */ + error = check_dir_is_empty (s); + if (error == 0) { /* not empty */ error = query_recursive (s); if (error == FILE_CONT) return recursive_erase (s); else return error; } - if (error){ + + retry_rmdir: + error = my_rmdir (s); + if (error == -1){ error = file_error (_(" Cannot remove directory \"%s\" \n %s "), s); if (error == FILE_RETRY) goto retry_rmdir; @@ -1849,9 +1883,12 @@ erase_dir_iff_empty (char *s) return FILE_ABORT; mc_refresh (); + if (1 != check_dir_is_empty (s)) /* not empty or error */ + return FILE_CONT; + retry_rmdir: error = my_rmdir (s); - if (error && !errno_dir_not_empty (errno)) { + if (error) { error = file_error (_(" Cannot remove directory \"%s\" \n %s "), s); if (error == FILE_RETRY) goto retry_rmdir; diff --git a/src/util.h b/src/util.h index 32bb75d63..fdd579039 100644 --- a/src/util.h +++ b/src/util.h @@ -124,9 +124,6 @@ char *get_current_wd (char *buffer, int size); int my_mkdir (char *s, mode_t mode); int my_rmdir (char *s); -/* Returns true if the err means the directory is not empty */ -int errno_dir_not_empty (int err); - /* Filesystem status */ struct my_statfs { int type; diff --git a/src/utilunix.c b/src/utilunix.c index c28d142ea..91eb79917 100644 --- a/src/utilunix.c +++ b/src/utilunix.c @@ -832,14 +832,6 @@ int gettimeofday (struct timeval *tp, void *tzp) } #endif -int -errno_dir_not_empty (int err) -{ - if (err == ENOTEMPTY || err == EEXIST) - return 1; - return 0; -} - #ifdef SCO_FLAVOR /* Define this only for SCO */ #ifdef USE_NETCODE