int smart_rename (const char *from, const char *to, int preserve_dates ATTRIBUTE_UNUSED) { bfd_boolean exists; struct stat s; int ret = 0; exists = lstat (to, &s) == 0; #if 1 /* Win32, unlike unix, will not erase `to' in `rename(from, to)' but fail instead. Also, chown is not present. */ if (exists) remove (to); ret = rename (from, to); if (ret != 0) { /* We have to clean up here. */ non_fatal (_("unable to rename '%s'; reason: %s"), to, strerror (errno)); unlink (from); } #else /* Use rename only if TO is not a symbolic link and has only one hard link, and we have permission to write to it. */ if (! exists || (!S_ISLNK (s.st_mode) && S_ISREG (s.st_mode) && (s.st_mode & S_IWUSR) && s.st_nlink == 1) ) { ret = rename (from, to); if (ret == 0) { if (exists) { /* Try to preserve the permission bits and ownership of TO. First get the mode right except for the setuid bit. Then change the ownership. Then fix the setuid bit. We do the chmod before the chown because if the chown succeeds, and we are a normal user, we won't be able to do the chmod afterward. We don't bother to fix the setuid bit first because that might introduce a fleeting security problem, and because the chown will clear the setuid bit anyhow. We only fix the setuid bit if the chown succeeds, because we don't want to introduce an unexpected setuid file owned by the user running objcopy. */ // chmod (to, s.st_mode & 0777); // if (chown (to, s.st_uid, s.st_gid) >= 0) // chmod (to, s.st_mode & 07777); } } else { /* We have to clean up here. */ non_fatal (_("unable to rename '%s'; reason: %s"), to, strerror (errno)); unlink (from); } } else { ret = simple_copy (from, to); if (ret != 0) non_fatal (_("unable to copy file '%s'; reason: %s"), to, strerror (errno)); if (preserve_dates) set_times (to, &s); unlink (from); } #endif /* _WIN32 && !__CYGWIN32__ */ return ret; }
int smart_rename (const char *from, const char *to, int preserve_dates) { bfd_boolean exists; struct stat s; int ret = 0; exists = lstat (to, &s) == 0; #if defined (_WIN32) && !defined (__CYGWIN32__) /* Win32, unlike unix, will not erase `to' in `rename(from, to)' but fail instead. Also, chown is not present. */ if (exists) remove (to); ret = rename (from, to); if (ret != 0) { /* We have to clean up here. */ non_fatal (_("unable to rename '%s' reason: %s"), to, strerror (errno)); unlink (from); } #else /* Use rename only if TO is not a symbolic link and has only one hard link, and we have permission to write to it. */ if (! exists || (!S_ISLNK (s.st_mode) && S_ISREG (s.st_mode) && (s.st_mode & S_IWUSR) && s.st_nlink == 1) ) { ret = rename (from, to); if (ret == 0) { if (exists) { /* Try to preserve the permission bits of TO. Don't * restore special bits. */ chmod (to, s.st_mode & 0777); } } else { /* We have to clean up here. */ non_fatal (_("unable to rename '%s' reason: %s"), to, strerror (errno)); unlink (from); } } else { ret = simple_copy (from, to); if (ret != 0) non_fatal (_("unable to copy file '%s' reason: %s"), to, strerror (errno)); if (preserve_dates) set_times (to, &s); unlink (from); } #endif /* _WIN32 && !__CYGWIN32__ */ return ret; }