| 166 | Return true if successful. */ |
| 167 | |
| 168 | static bool |
| 169 | do_move (char const *source, char const *dest, |
| 170 | int dest_dirfd, char const *dest_relname, const struct cp_options *x) |
| 171 | { |
| 172 | bool copy_into_self; |
| 173 | bool rename_succeeded; |
| 174 | bool ok = copy (source, dest, dest_dirfd, dest_relname, 0, x, |
| 175 | ©_into_self, &rename_succeeded); |
| 176 | |
| 177 | if (ok) |
| 178 | { |
| 179 | char const *dir_to_remove; |
| 180 | if (copy_into_self) |
| 181 | { |
| 182 | /* In general, when copy returns with copy_into_self set, SOURCE is |
| 183 | the same as, or a parent of DEST. In this case we know it's a |
| 184 | parent. It doesn't make sense to move a directory into itself, and |
| 185 | besides in some situations doing so would give highly unintuitive |
| 186 | results. Run this 'mkdir b; touch a c; mv * b' in an empty |
| 187 | directory. Here's the result of running echo $(find b -print): |
| 188 | b b/a b/b b/b/a b/c. Notice that only file 'a' was copied |
| 189 | into b/b. Handle this by giving a diagnostic, removing the |
| 190 | copied-into-self directory, DEST ('b/b' in the example), |
| 191 | and failing. */ |
| 192 | |
| 193 | dir_to_remove = NULL; |
| 194 | ok = false; |
| 195 | } |
| 196 | else if (rename_succeeded) |
| 197 | { |
| 198 | /* No need to remove anything. SOURCE was successfully |
| 199 | renamed to DEST. Or the user declined to rename a file. */ |
| 200 | dir_to_remove = NULL; |
| 201 | } |
| 202 | else |
| 203 | { |
| 204 | /* This may mean SOURCE and DEST referred to different devices. |
| 205 | It may also conceivably mean that even though they referred |
| 206 | to the same device, rename wasn't implemented for that device. |
| 207 | |
| 208 | E.g., (from Joel N. Weber), |
| 209 | [...] there might someday be cases where you can't rename |
| 210 | but you can copy where the device name is the same, especially |
| 211 | on Hurd. Consider an ftpfs with a primitive ftp server that |
| 212 | supports uploading, downloading and deleting, but not renaming. |
| 213 | |
| 214 | Also, note that comparing device numbers is not a reliable |
| 215 | check for 'can-rename'. Some systems can be set up so that |
| 216 | files from many different physical devices all have the same |
| 217 | st_dev field. This is a feature of some NFS mounting |
| 218 | configurations. |
| 219 | |
| 220 | We reach this point if SOURCE has been successfully copied |
| 221 | to DEST. Now we have to remove SOURCE. |
| 222 | |
| 223 | This function used to resort to copying only when rename |
| 224 | failed and set errno to EXDEV. */ |
| 225 |
no test coverage detected