File: rename.c

package info (click to toggle)
patch 2.6-2
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 1,592 kB
  • ctags: 955
  • sloc: ansic: 11,238; sh: 3,354; makefile: 382; sed: 54
file content (165 lines) | stat: -rw-r--r-- 4,053 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/* Work around rename bugs in some systems.  On SunOS 4.1.1_U1
   and mips-dec-ultrix4.4, rename fails when the source file has
   a trailing slash.  On mingw, rename fails when the destination
   exists.

   Copyright (C) 2001, 2002, 2003, 2005, 2006, 2009 Free Software Foundation, Inc.

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

/* written by Volker Borchert */

#include <config.h>
#undef rename

#if RENAME_DEST_EXISTS_BUG
/* This replacement must come first, otherwise when cross
 * compiling to Windows we will guess that it has the trailing
 * slash bug and entirely miss this one. */
#include <errno.h>

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

/* Rename the file SRC to DST.  This replacement is necessary on
   Windows, on which the system rename function will not replace
   an existing DST.  */
int
rpl_rename (char const *src, char const *dst)
{
  int error;

  /* MoveFileEx works if SRC is a directory without any flags,
     but fails with MOVEFILE_REPLACE_EXISTING, so try without
     flags first. */
  if (MoveFileEx (src, dst, 0))
    return 0;

  /* Retry with MOVEFILE_REPLACE_EXISTING if the move failed
   * due to the destination already existing. */
  error = GetLastError ();
  if (error == ERROR_FILE_EXISTS || error == ERROR_ALREADY_EXISTS)
    {
      if (MoveFileEx (src, dst, MOVEFILE_REPLACE_EXISTING))
        return 0;

      error = GetLastError ();
    }

  switch (error)
    {
    case ERROR_FILE_NOT_FOUND:
    case ERROR_PATH_NOT_FOUND:
    case ERROR_BAD_PATHNAME:
    case ERROR_DIRECTORY:
      errno = ENOENT;
      break;

    case ERROR_ACCESS_DENIED:
    case ERROR_SHARING_VIOLATION:
      errno = EACCES;
      break;

    case ERROR_OUTOFMEMORY:
      errno = ENOMEM;
      break;

    case ERROR_CURRENT_DIRECTORY:
      errno = EBUSY;
      break;

    case ERROR_NOT_SAME_DEVICE:
      errno = EXDEV;
      break;

    case ERROR_WRITE_PROTECT:
      errno = EROFS;
      break;

    case ERROR_WRITE_FAULT:
    case ERROR_READ_FAULT:
    case ERROR_GEN_FAILURE:
      errno = EIO;
      break;

    case ERROR_HANDLE_DISK_FULL:
    case ERROR_DISK_FULL:
    case ERROR_DISK_TOO_FRAGMENTED:
      errno = ENOSPC;
      break;

    case ERROR_FILE_EXISTS:
    case ERROR_ALREADY_EXISTS:
      errno = EEXIST;
      break;

    case ERROR_BUFFER_OVERFLOW:
    case ERROR_FILENAME_EXCED_RANGE:
      errno = ENAMETOOLONG;
      break;

    case ERROR_INVALID_NAME:
    case ERROR_DELETE_PENDING:
      errno = EPERM;        /* ? */
      break;

#ifndef ERROR_FILE_TOO_LARGE
/* This value is documented but not defined in all versions of windows.h. */
#define ERROR_FILE_TOO_LARGE 223
#endif
    case ERROR_FILE_TOO_LARGE:
      errno = EFBIG;
      break;

    default:
      errno = EINVAL;
      break;
    }

  return -1;
}
#elif RENAME_TRAILING_SLASH_BUG
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "dirname.h"
#include "xalloc.h"

/* Rename the file SRC to DST, removing any trailing
   slashes from SRC.  Needed for SunOS 4.1.1_U1.  */

int
rpl_rename (char const *src, char const *dst)
{
  char *src_temp;
  int ret_val;
  size_t s_len = strlen (src);

  if (s_len && src[s_len - 1] == '/')
    {
      src_temp = xstrdup (src);
      strip_trailing_slashes (src_temp);
    }
  else
    src_temp = (char *) src;

  ret_val = rename (src_temp, dst);

  if (src_temp != src)
    free (src_temp);

  return ret_val;
}
#endif /* RENAME_TRAILING_SLASH_BUG */