Back to index

cell-binutils  2.17cvs20070401
rename.c
Go to the documentation of this file.
00001 /* rename.c -- rename a file, preserving symlinks.
00002    Copyright 1999, 2002, 2003 Free Software Foundation, Inc.
00003 
00004    This file is part of GNU Binutils.
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010 
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014    GNU General Public License for more details.
00015 
00016    You should have received a copy of the GNU General Public License
00017    along with this program; if not, write to the Free Software
00018    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
00019    02110-1301, USA.  */
00020 
00021 #include "bfd.h"
00022 #include "bucomm.h"
00023 
00024 #include <sys/stat.h>
00025 
00026 #ifdef HAVE_GOOD_UTIME_H
00027 #include <utime.h>
00028 #else /* ! HAVE_GOOD_UTIME_H */
00029 #ifdef HAVE_UTIMES
00030 #include <sys/time.h>
00031 #endif /* HAVE_UTIMES */
00032 #endif /* ! HAVE_GOOD_UTIME_H */
00033 
00034 /* We need to open the file in binary modes on system where that makes
00035    a difference.  */
00036 #ifndef O_BINARY
00037 #define O_BINARY 0
00038 #endif
00039 
00040 #if ! defined (_WIN32) || defined (__CYGWIN32__)
00041 static int simple_copy (const char *, const char *);
00042 
00043 /* The number of bytes to copy at once.  */
00044 #define COPY_BUF 8192
00045 
00046 /* Copy file FROM to file TO, performing no translations.
00047    Return 0 if ok, -1 if error.  */
00048 
00049 static int
00050 simple_copy (const char *from, const char *to)
00051 {
00052   int fromfd, tofd, nread;
00053   int saved;
00054   char buf[COPY_BUF];
00055 
00056   fromfd = open (from, O_RDONLY | O_BINARY);
00057   if (fromfd < 0)
00058     return -1;
00059 #ifdef O_CREAT
00060   tofd = open (to, O_CREAT | O_WRONLY | O_TRUNC | O_BINARY, 0777);
00061 #else
00062   tofd = creat (to, 0777);
00063 #endif
00064   if (tofd < 0)
00065     {
00066       saved = errno;
00067       close (fromfd);
00068       errno = saved;
00069       return -1;
00070     }
00071   while ((nread = read (fromfd, buf, sizeof buf)) > 0)
00072     {
00073       if (write (tofd, buf, nread) != nread)
00074        {
00075          saved = errno;
00076          close (fromfd);
00077          close (tofd);
00078          errno = saved;
00079          return -1;
00080        }
00081     }
00082   saved = errno;
00083   close (fromfd);
00084   close (tofd);
00085   if (nread < 0)
00086     {
00087       errno = saved;
00088       return -1;
00089     }
00090   return 0;
00091 }
00092 #endif /* __CYGWIN32__ or not _WIN32 */
00093 
00094 /* Set the times of the file DESTINATION to be the same as those in
00095    STATBUF.  */
00096 
00097 void
00098 set_times (const char *destination, const struct stat *statbuf)
00099 {
00100   int result;
00101 
00102   {
00103 #ifdef HAVE_GOOD_UTIME_H
00104     struct utimbuf tb;
00105 
00106     tb.actime = statbuf->st_atime;
00107     tb.modtime = statbuf->st_mtime;
00108     result = utime (destination, &tb);
00109 #else /* ! HAVE_GOOD_UTIME_H */
00110 #ifndef HAVE_UTIMES
00111     long tb[2];
00112 
00113     tb[0] = statbuf->st_atime;
00114     tb[1] = statbuf->st_mtime;
00115     result = utime (destination, tb);
00116 #else /* HAVE_UTIMES */
00117     struct timeval tv[2];
00118 
00119     tv[0].tv_sec = statbuf->st_atime;
00120     tv[0].tv_usec = 0;
00121     tv[1].tv_sec = statbuf->st_mtime;
00122     tv[1].tv_usec = 0;
00123     result = utimes (destination, tv);
00124 #endif /* HAVE_UTIMES */
00125 #endif /* ! HAVE_GOOD_UTIME_H */
00126   }
00127 
00128   if (result != 0)
00129     non_fatal (_("%s: cannot set time: %s"), destination, strerror (errno));
00130 }
00131 
00132 #ifndef S_ISLNK
00133 #ifdef S_IFLNK
00134 #define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
00135 #else
00136 #define S_ISLNK(m) 0
00137 #define lstat stat
00138 #endif
00139 #endif
00140 
00141 /* Rename FROM to TO, copying if TO is a link.
00142    Return 0 if ok, -1 if error.  */
00143 
00144 int
00145 smart_rename (const char *from, const char *to, int preserve_dates ATTRIBUTE_UNUSED)
00146 {
00147   bfd_boolean exists;
00148   struct stat s;
00149   int ret = 0;
00150 
00151   exists = lstat (to, &s) == 0;
00152 
00153 #if defined (_WIN32) && !defined (__CYGWIN32__)
00154   /* Win32, unlike unix, will not erase `to' in `rename(from, to)' but
00155      fail instead.  Also, chown is not present.  */
00156 
00157   if (exists)
00158     remove (to);
00159 
00160   ret = rename (from, to);
00161   if (ret != 0)
00162     {
00163       /* We have to clean up here.  */
00164       non_fatal (_("unable to rename '%s' reason: %s"), to, strerror (errno));
00165       unlink (from);
00166     }
00167 #else
00168   /* Use rename only if TO is not a symbolic link and has
00169      only one hard link, and we have permission to write to it.  */
00170   if (! exists
00171       || (!S_ISLNK (s.st_mode)
00172          && S_ISREG (s.st_mode)
00173          && (s.st_mode & S_IWUSR)
00174          && s.st_nlink == 1)
00175       )
00176     {
00177       ret = rename (from, to);
00178       if (ret == 0)
00179        {
00180          if (exists)
00181            {
00182              /* Try to preserve the permission bits and ownership of
00183                TO.  First get the mode right except for the setuid
00184                bit.  Then change the ownership.  Then fix the setuid
00185                bit.  We do the chmod before the chown because if the
00186                chown succeeds, and we are a normal user, we won't be
00187                able to do the chmod afterward.  We don't bother to
00188                fix the setuid bit first because that might introduce
00189                a fleeting security problem, and because the chown
00190                will clear the setuid bit anyhow.  We only fix the
00191                setuid bit if the chown succeeds, because we don't
00192                want to introduce an unexpected setuid file owned by
00193                the user running objcopy.  */
00194              chmod (to, s.st_mode & 0777);
00195              if (chown (to, s.st_uid, s.st_gid) >= 0)
00196               chmod (to, s.st_mode & 07777);
00197            }
00198        }
00199       else
00200        {
00201          /* We have to clean up here.  */
00202          non_fatal (_("unable to rename '%s' reason: %s"), to, strerror (errno));
00203          unlink (from);
00204        }
00205     }
00206   else
00207     {
00208       ret = simple_copy (from, to);
00209       if (ret != 0)
00210        non_fatal (_("unable to copy file '%s' reason: %s"), to, strerror (errno));
00211 
00212       if (preserve_dates)
00213        set_times (to, &s);
00214       unlink (from);
00215     }
00216 #endif /* _WIN32 && !__CYGWIN32__ */
00217 
00218   return ret;
00219 }