1/*
2 * rename - rename a file
3 */
4
5/* Copyright (C) 1999 Free Software Foundation, Inc.
6
7   This file is part of GNU Bash, the Bourne Again SHell.
8
9   Bash is free software: you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation, either version 3 of the License, or
12   (at your option) any later version.
13
14   Bash is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18
19   You should have received a copy of the GNU General Public License
20   along with Bash.  If not, see <http://www.gnu.org/licenses/>.
21*/
22
23#include <config.h>
24
25#if !defined (HAVE_RENAME)
26
27#include <bashtypes.h>
28#include <posixstat.h>
29
30#if defined (HAVE_UNISTD_H)
31#  include <unistd.h>
32#endif
33#include <errno.h>
34
35#include <stdc.h>
36
37#ifndef errno
38extern int errno;
39#endif
40
41int
42rename (from, to)
43     const char *from, *to;
44{
45  struct stat fb, tb;
46
47  if (stat (from, &fb) < 0)
48    return -1;
49
50  if (stat (to, &tb) < 0)
51    {
52      if (errno != ENOENT)
53	return -1;
54    }
55  else
56    {
57      if (fb.st_dev == tb.st_dev && fb.st_ino == tb.st_ino)
58        return 0;		/* same file */
59      if (unlink (to) < 0 && errno != ENOENT)
60        return -1;
61    }
62
63  if (link (from, to) < 0)
64    return (-1);
65
66  if (unlink (from) < 0 && errno != ENOENT)
67    {
68      int e = errno;
69      unlink (to);
70      errno = e;
71      return (-1);
72    }
73
74  return (0);
75}
76#endif /* !HAVE_RENAME */
77