OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [binutils/] [rename.c] - Blame information for rev 146

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 15 khays
/* rename.c -- rename a file, preserving symlinks.
2
   Copyright 1999, 2002, 2003, 2005, 2007, 2008 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
#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
 
35
#if ! defined (_WIN32) || defined (__CYGWIN32__)
36
static int simple_copy (const char *, const char *);
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
 
44
static int
45
simple_copy (const char *from, const char *to)
46
{
47
  int fromfd, tofd, nread;
48
  int saved;
49
  char buf[COPY_BUF];
50
 
51
  fromfd = open (from, O_RDONLY | O_BINARY);
52
  if (fromfd < 0)
53
    return -1;
54
#ifdef O_CREAT
55
  tofd = open (to, O_CREAT | O_WRONLY | O_TRUNC | O_BINARY, 0777);
56
#else
57
  tofd = creat (to, 0777);
58
#endif
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
}
87
#endif /* __CYGWIN32__ or not _WIN32 */
88
 
89
/* Set the times of the file DESTINATION to be the same as those in
90
   STATBUF.  */
91
 
92
void
93
set_times (const char *destination, const struct stat *statbuf)
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
 
139
int
140
smart_rename (const char *from, const char *to, int preserve_dates ATTRIBUTE_UNUSED)
141
{
142
  bfd_boolean exists;
143
  struct stat s;
144
  int ret = 0;
145
 
146
  exists = lstat (to, &s) == 0;
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
 
152
  if (exists)
153
    remove (to);
154
 
155
  ret = rename (from, to);
156
  if (ret != 0)
157
    {
158
      /* We have to clean up here.  */
159
      non_fatal (_("unable to rename '%s'; reason: %s"), to, strerror (errno));
160
      unlink (from);
161
    }
162
#else
163
  /* Use rename only if TO is not a symbolic link and has
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
      )
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
        {
196
          /* We have to clean up here.  */
197
          non_fatal (_("unable to rename '%s'; reason: %s"), to, strerror (errno));
198
          unlink (from);
199
        }
200
    }
201
  else
202
    {
203
      ret = simple_copy (from, to);
204
      if (ret != 0)
205
        non_fatal (_("unable to copy file '%s'; reason: %s"), to, strerror (errno));
206
 
207
      if (preserve_dates)
208
        set_times (to, &s);
209
      unlink (from);
210
    }
211
#endif /* _WIN32 && !__CYGWIN32__ */
212
 
213
  return ret;
214
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.