Subversion Repositories Kolibri OS

Rev

Rev 5217 | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /* rename.c -- rename a file, preserving symlinks.
  2.    Copyright (C) 1999-2015 Free Software Foundation, Inc.
  3.  
  4.    This file is part of GNU Binutils.
  5.  
  6.    This program is free software; you can redistribute it and/or modify
  7.    it under the terms of the GNU General Public License as published by
  8.    the Free Software Foundation; either version 3 of the License, or
  9.    (at your option) any later version.
  10.  
  11.    This program is distributed in the hope that it will be useful,
  12.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.    GNU General Public License for more details.
  15.  
  16.    You should have received a copy of the GNU General Public License
  17.    along with this program; if not, write to the Free Software
  18.    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
  19.    02110-1301, USA.  */
  20.  
  21. #include "sysdep.h"
  22. #include "bfd.h"
  23. #include "bucomm.h"
  24.  
  25. #ifdef HAVE_GOOD_UTIME_H
  26. #include <utime.h>
  27. #else /* ! HAVE_GOOD_UTIME_H */
  28. #ifdef HAVE_UTIMES
  29. #include <sys/time.h>
  30. #endif /* HAVE_UTIMES */
  31. #endif /* ! HAVE_GOOD_UTIME_H */
  32.  
  33. #if ! defined (_WIN32) || defined (__CYGWIN32__)
  34. static int simple_copy (const char *, const char *);
  35.  
  36. /* The number of bytes to copy at once.  */
  37. #define COPY_BUF 8192
  38.  
  39. /* Copy file FROM to file TO, performing no translations.
  40.    Return 0 if ok, -1 if error.  */
  41.  
  42. static int
  43. simple_copy (const char *from, const char *to)
  44. {
  45.   int fromfd, tofd, nread;
  46.   int saved;
  47.   char buf[COPY_BUF];
  48.  
  49.   fromfd = open (from, O_RDONLY | O_BINARY);
  50.   if (fromfd < 0)
  51.     return -1;
  52. #ifdef O_CREAT
  53.   tofd = open (to, O_CREAT | O_WRONLY | O_TRUNC | O_BINARY, 0777);
  54. #else
  55.   tofd = creat (to, 0777);
  56. #endif
  57.   if (tofd < 0)
  58.     {
  59.       saved = errno;
  60.       close (fromfd);
  61.       errno = saved;
  62.       return -1;
  63.     }
  64.   while ((nread = read (fromfd, buf, sizeof buf)) > 0)
  65.     {
  66.       if (write (tofd, buf, nread) != nread)
  67.         {
  68.           saved = errno;
  69.           close (fromfd);
  70.           close (tofd);
  71.           errno = saved;
  72.           return -1;
  73.         }
  74.     }
  75.   saved = errno;
  76.   close (fromfd);
  77.   close (tofd);
  78.   if (nread < 0)
  79.     {
  80.       errno = saved;
  81.       return -1;
  82.     }
  83.   return 0;
  84. }
  85. #endif /* __CYGWIN32__ or not _WIN32 */
  86.  
  87. /* Set the times of the file DESTINATION to be the same as those in
  88.    STATBUF.  */
  89.  
  90. void
  91. set_times (const char *destination, const struct stat *statbuf)
  92. {
  93.   int result;
  94.  
  95.   {
  96. #ifdef HAVE_GOOD_UTIME_H
  97.     struct utimbuf tb;
  98.  
  99.     tb.actime = statbuf->st_atime;
  100.     tb.modtime = statbuf->st_mtime;
  101. //    result = utime (destination, &tb);
  102. #else /* ! HAVE_GOOD_UTIME_H */
  103. #ifndef HAVE_UTIMES
  104.     long tb[2];
  105.  
  106.     tb[0] = statbuf->st_atime;
  107.     tb[1] = statbuf->st_mtime;
  108.     result = utime (destination, tb);
  109. #else /* HAVE_UTIMES */
  110.     struct timeval tv[2];
  111.  
  112.     tv[0].tv_sec = statbuf->st_atime;
  113.     tv[0].tv_usec = 0;
  114.     tv[1].tv_sec = statbuf->st_mtime;
  115.     tv[1].tv_usec = 0;
  116.     result = utimes (destination, tv);
  117. #endif /* HAVE_UTIMES */
  118. #endif /* ! HAVE_GOOD_UTIME_H */
  119.   }
  120.  
  121.   if (result != 0)
  122.     non_fatal (_("%s: cannot set time: %s"), destination, strerror (errno));
  123. }
  124.  
  125. #ifndef S_ISLNK
  126. #ifdef S_IFLNK
  127. #define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
  128. #else
  129. #define S_ISLNK(m) 0
  130. #define lstat stat
  131. #endif
  132. #endif
  133.  
  134. /* Rename FROM to TO, copying if TO is a link.
  135.    Return 0 if ok, -1 if error.  */
  136.  
  137. int
  138. smart_rename (const char *from, const char *to, int preserve_dates ATTRIBUTE_UNUSED)
  139. {
  140.   bfd_boolean exists;
  141.   struct stat s;
  142.   int ret = 0;
  143.  
  144.   exists = lstat (to, &s) == 0;
  145.  
  146. #if 1
  147.   /* Win32, unlike unix, will not erase `to' in `rename(from, to)' but
  148.      fail instead.  Also, chown is not present.  */
  149.  
  150.   if (exists)
  151.     remove (to);
  152.  
  153.   ret = rename (from, to);
  154.   if (ret != 0)
  155.     {
  156.       /* We have to clean up here.  */
  157.       non_fatal (_("unable to rename '%s'; reason: %s"), to, strerror (errno));
  158.       unlink (from);
  159.     }
  160. #else
  161.   /* Use rename only if TO is not a symbolic link and has
  162.      only one hard link, and we have permission to write to it.  */
  163.   if (! exists
  164.       || (!S_ISLNK (s.st_mode)
  165.           && S_ISREG (s.st_mode)
  166.           && (s.st_mode & S_IWUSR)
  167.           && s.st_nlink == 1)
  168.       )
  169.     {
  170.       ret = rename (from, to);
  171.       if (ret == 0)
  172.         {
  173.           if (exists)
  174.             {
  175.               /* Try to preserve the permission bits and ownership of
  176.                  TO.  First get the mode right except for the setuid
  177.                  bit.  Then change the ownership.  Then fix the setuid
  178.                  bit.  We do the chmod before the chown because if the
  179.                  chown succeeds, and we are a normal user, we won't be
  180.                  able to do the chmod afterward.  We don't bother to
  181.                  fix the setuid bit first because that might introduce
  182.                  a fleeting security problem, and because the chown
  183.                  will clear the setuid bit anyhow.  We only fix the
  184.                  setuid bit if the chown succeeds, because we don't
  185.                  want to introduce an unexpected setuid file owned by
  186.                  the user running objcopy.  */
  187. //         chmod (to, s.st_mode & 0777);
  188. //         if (chown (to, s.st_uid, s.st_gid) >= 0)
  189. //       chmod (to, s.st_mode & 07777);
  190.             }
  191.         }
  192.       else
  193.         {
  194.           /* We have to clean up here.  */
  195.           non_fatal (_("unable to rename '%s'; reason: %s"), to, strerror (errno));
  196.           unlink (from);
  197.         }
  198.     }
  199.   else
  200.     {
  201.       ret = simple_copy (from, to);
  202.       if (ret != 0)
  203.         non_fatal (_("unable to copy file '%s'; reason: %s"), to, strerror (errno));
  204.  
  205.       if (preserve_dates)
  206.         set_times (to, &s);
  207.       unlink (from);
  208.     }
  209. #endif /* _WIN32 && !__CYGWIN32__ */
  210.  
  211.   return ret;
  212. }
  213.