source: trunk/third/patch/rename.c @ 11119

Revision 11119, 2.8 KB checked in by ghudson, 27 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r11118, which included commits to RCS files with non-trunk default branches.
Line 
1/* BSD compatible rename and directory rename function for System V.
2   Copyright (C) 1988, 1990 Free Software Foundation, Inc.
3
4   This program is free software; you can redistribute it and/or modify
5   it under the terms of the GNU General Public License as published by
6   the Free Software Foundation; either version 2, or (at your option)
7   any later version.
8
9   This program is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   GNU General Public License for more details.
13
14   You should have received a copy of the GNU General Public License
15   along with this program; if not, write to the Free Software Foundation,
16   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
17
18#if HAVE_CONFIG_H
19# include <config.h>
20#endif
21
22#include <sys/types.h>
23#include <sys/stat.h>
24#include <errno.h>
25#ifndef errno
26extern int errno;
27#endif
28
29#if STAT_MACROS_BROKEN
30# undef S_ISDIR
31#endif
32
33#if !defined(S_ISDIR) && defined(S_IFDIR)
34# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
35#endif
36
37/* Rename file FROM to file TO.
38   Return 0 if successful, -1 if not. */
39
40int
41rename (from, to)
42     char *from;
43     char *to;
44{
45  struct stat from_stats, to_stats;
46  int pid, status;
47
48  if (stat (from, &from_stats))
49    return -1;
50
51  /* Be careful not to unlink `from' if it happens to be equal to `to' or
52     (on filesystems that silently truncate filenames after 14 characters)
53     if `from' and `to' share the significant characters. */
54  if (stat (to, &to_stats))
55    {
56      if (errno != ENOENT)
57        return -1;
58    }
59  else
60    {
61      if ((from_stats.st_dev == to_stats.st_dev)
62          && (from_stats.st_ino == to_stats.st_ino))
63        /* `from' and `to' designate the same file on that filesystem. */
64        return 0;
65
66      if (unlink (to) && errno != ENOENT)
67        return -1;
68    }
69
70#ifdef MVDIR
71
72/* If MVDIR is defined, it should be the full filename of a setuid root
73   program able to link and unlink directories.  If MVDIR is not defined,
74   then the capability of renaming directories may be missing.  */
75
76  if (S_ISDIR (from_stats.st_mode))
77    {
78      /* Need a setuid root process to link and unlink directories. */
79      pid = fork ();
80      switch (pid)
81        {
82        case -1:                /* Error. */
83          error (1, errno, "cannot fork");
84
85        case 0:                 /* Child. */
86          execl (MVDIR, "mvdir", from, to, (char *) 0);
87          error (255, errno, "cannot run `%s'", MVDIR);
88
89        default:                /* Parent. */
90          while (wait (&status) != pid)
91            /* Do nothing. */ ;
92
93          errno = 0;            /* mvdir printed the system error message. */
94          if (status)
95            return -1;
96        }
97    }
98  else
99
100#endif /* MVDIR */
101
102    {
103      if (link (from, to))
104        return -1;
105      if (unlink (from) && errno != ENOENT)
106        {
107          unlink (to);
108          return -1;
109        }
110    }
111  return 0;
112}
Note: See TracBrowser for help on using the repository browser.