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