source: rtems/cpukit/libcsupport/src/_rename_r.c @ 98b785e

4.115
Last change on this file since 98b785e was ce92a825, checked in by Chris Johns <chrisj@…>, on 05/20/10 at 03:10:41

2010-05-20 Bharath Suri <bharath.s.jois@…>

  • libcsupport/src/_rename_r.c: Avoid overwriting of errno by _rename_r to invalid values.
  • Property mode set to 100644
File size: 3.9 KB
Line 
1/*
2 *  _rename_r() - POSIX 1003.1b - 5.3.4 - Rename a file
3 *
4 *  COPYRIGHT (c) 1989-2007.
5 *  On-Line Applications Research Corporation (OAR).
6 *
7 *  The license and distribution terms for this file may be
8 *  found in the file LICENSE in this distribution or at
9 *  http://www.rtems.com/license/LICENSE.
10 *
11 *  $Id$
12 */
13
14#if HAVE_CONFIG_H
15#include "config.h"
16#endif
17
18#if defined(RTEMS_NEWLIB) && !defined(HAVE__RENAME_R)
19#include <sys/types.h>
20#include <sys/stat.h>
21#include <unistd.h>
22
23#include <rtems/libio_.h>
24#include <rtems/seterr.h>
25
26int _rename_r(
27  struct _reent *ptr __attribute__((unused)),
28  const char    *old,
29  const char    *new
30)
31{
32  int                                 old_parent_pathlen;
33  rtems_filesystem_location_info_t    old_loc;
34  rtems_filesystem_location_info_t    old_parent_loc;
35  rtems_filesystem_location_info_t    new_parent_loc;
36  int                                 i;
37  int                                 result;
38  const char                         *name;
39  bool                                free_old_parentloc = false;
40
41  /*
42   *  Get the parent node of the old path to be renamed. Find the parent path.
43   */
44
45  old_parent_pathlen = rtems_filesystem_dirname ( old );
46
47  if ( old_parent_pathlen == 0 )
48    rtems_filesystem_get_start_loc( old, &i, &old_parent_loc );
49  else {
50    result = rtems_filesystem_evaluate_path( old, old_parent_pathlen,
51                                             RTEMS_LIBIO_PERMS_WRITE,
52                                             &old_parent_loc,
53                                             false );
54    if ( result != 0 )
55      return -1;
56
57    free_old_parentloc = true;
58  }
59
60  /*
61   * Start from the parent to find the node that should be under it.
62   */
63
64  old_loc = old_parent_loc;
65  name = old + old_parent_pathlen;
66  name += rtems_filesystem_prefix_separators( name, strlen( name ) );
67
68  result = rtems_filesystem_evaluate_relative_path( name , strlen( name ),
69                                                    0, &old_loc, false );
70  if ( result != 0 ) {
71    if ( free_old_parentloc )
72      rtems_filesystem_freenode( &old_parent_loc );
73    return -1;
74  }
75 
76  /*
77   * Get the parent of the new node we are renaming to.
78   */
79
80  rtems_filesystem_get_start_loc( new, &i, &new_parent_loc );
81
82  if ( !new_parent_loc.ops->evalformake_h ) {
83    if ( free_old_parentloc )
84      rtems_filesystem_freenode( &old_parent_loc );
85    rtems_filesystem_freenode( &old_loc );
86    rtems_set_errno_and_return_minus_one( ENOTSUP );
87  }
88
89  result = (*new_parent_loc.ops->evalformake_h)( &new[i], &new_parent_loc, &name );
90  if ( result != 0 ) {
91    rtems_filesystem_freenode( &new_parent_loc );
92    if ( free_old_parentloc )
93      rtems_filesystem_freenode( &old_parent_loc );
94    rtems_filesystem_freenode( &old_loc );
95    return -1;
96  }
97
98  /*
99   *  Check to see if the caller is trying to rename across file system
100   *  boundaries.
101   */
102
103  if ( old_parent_loc.mt_entry != new_parent_loc.mt_entry ) {
104    rtems_filesystem_freenode( &new_parent_loc );
105    if ( free_old_parentloc )
106      rtems_filesystem_freenode( &old_parent_loc );
107    rtems_filesystem_freenode( &old_loc );
108    rtems_set_errno_and_return_minus_one( EXDEV );
109  }
110
111  if ( !new_parent_loc.ops->rename_h ) {
112    rtems_filesystem_freenode( &new_parent_loc );
113    if ( free_old_parentloc )
114      rtems_filesystem_freenode( &old_parent_loc );
115    rtems_filesystem_freenode( &old_loc );
116    rtems_set_errno_and_return_minus_one( ENOTSUP );
117  }
118
119  result = (*new_parent_loc.ops->rename_h)( &old_parent_loc, &old_loc, &new_parent_loc, name );
120
121  rtems_filesystem_freenode( &new_parent_loc );
122  if ( free_old_parentloc )
123    rtems_filesystem_freenode( &old_parent_loc );
124  rtems_filesystem_freenode( &old_loc );
125
126  return result;
127}
128
129#if 0
130  struct stat sb;
131  int s;
132
133  s = stat( old, &sb);
134  if ( s < 0 )
135    return s;
136  s = link( old, new );
137  if ( s < 0 )
138    return s;
139  return S_ISDIR(sb.st_mode) ? rmdir( old ) : unlink( old );
140#endif
141                                           
142#endif
Note: See TracBrowser for help on using the repository browser.