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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [uClibc/] [libc/] [stdlib/] [realpath.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1325 phoenix
/*
2
 * realpath.c -- canonicalize pathname by removing symlinks
3
 * Copyright (C) 1993 Rick Sladkey <jrs@world.std.com>
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU Library Public License as published by
7
 * the Free Software Foundation; either version 2, or (at your option)
8
 * any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU Library Public License for more details.
14
 */
15
 
16
#ifdef HAVE_CONFIG_H
17
#include <config.h>
18
#endif
19
 
20
#include <sys/types.h>
21
#include <unistd.h>
22
#include <stdio.h>
23
#include <string.h>
24
#include <strings.h>
25
#include <limits.h>                             /* for PATH_MAX */
26
#include <sys/param.h>                  /* for MAXPATHLEN */
27
#include <errno.h>
28
 
29
#include <sys/stat.h>                   /* for S_IFLNK */
30
 
31
#ifndef PATH_MAX
32
#ifdef _POSIX_VERSION
33
#define PATH_MAX _POSIX_PATH_MAX
34
#else
35
#ifdef MAXPATHLEN
36
#define PATH_MAX MAXPATHLEN
37
#else
38
#define PATH_MAX 1024
39
#endif
40
#endif
41
#endif
42
 
43
#define MAX_READLINKS 32
44
 
45
#ifdef __STDC__
46
char *realpath(const char *path, char resolved_path[])
47
#else
48
char *realpath(path, resolved_path)
49
const char *path;
50
char resolved_path[];
51
#endif
52
{
53
        char copy_path[PATH_MAX];
54
        char link_path[PATH_MAX];
55
        char got_path[PATH_MAX];
56
        char *new_path = got_path;
57
        char *max_path;
58
        int readlinks = 0;
59
        int n;
60
 
61
        /* Make a copy of the source path since we may need to modify it. */
62
        if (strlen(path) >= PATH_MAX - 2) {
63
                __set_errno(ENAMETOOLONG);
64
                return NULL;
65
        }
66
        strcpy(copy_path, path);
67
        path = copy_path;
68
        max_path = copy_path + PATH_MAX - 2;
69
        /* If it's a relative pathname use getwd for starters. */
70
        if (*path != '/') {
71
                /* Ohoo... */
72
#define HAVE_GETCWD
73
#ifdef HAVE_GETCWD
74
                getcwd(new_path, PATH_MAX - 1);
75
#else
76
                getwd(new_path);
77
#endif
78
                new_path += strlen(new_path);
79
                if (new_path[-1] != '/')
80
                        *new_path++ = '/';
81
        } else {
82
                *new_path++ = '/';
83
                path++;
84
        }
85
        /* Expand each slash-separated pathname component. */
86
        while (*path != '\0') {
87
                /* Ignore stray "/". */
88
                if (*path == '/') {
89
                        path++;
90
                        continue;
91
                }
92
                if (*path == '.') {
93
                        /* Ignore ".". */
94
                        if (path[1] == '\0' || path[1] == '/') {
95
                                path++;
96
                                continue;
97
                        }
98
                        if (path[1] == '.') {
99
                                if (path[2] == '\0' || path[2] == '/') {
100
                                        path += 2;
101
                                        /* Ignore ".." at root. */
102
                                        if (new_path == got_path + 1)
103
                                                continue;
104
                                        /* Handle ".." by backing up. */
105
                                        while ((--new_path)[-1] != '/');
106
                                        continue;
107
                                }
108
                        }
109
                }
110
                /* Safely copy the next pathname component. */
111
                while (*path != '\0' && *path != '/') {
112
                        if (path > max_path) {
113
                                __set_errno(ENAMETOOLONG);
114
                                return NULL;
115
                        }
116
                        *new_path++ = *path++;
117
                }
118
#ifdef S_IFLNK
119
                /* Protect against infinite loops. */
120
                if (readlinks++ > MAX_READLINKS) {
121
                        __set_errno(ELOOP);
122
                        return NULL;
123
                }
124
                /* See if latest pathname component is a symlink. */
125
                *new_path = '\0';
126
                n = readlink(got_path, link_path, PATH_MAX - 1);
127
                if (n < 0) {
128
                        /* EINVAL means the file exists but isn't a symlink. */
129
                        if (errno != EINVAL) {
130
                                /* Make sure it's null terminated. */
131
                                *new_path = '\0';
132
                                strcpy(resolved_path, got_path);
133
                                return NULL;
134
                        }
135
                } else {
136
                        /* Note: readlink doesn't add the null byte. */
137
                        link_path[n] = '\0';
138
                        if (*link_path == '/')
139
                                /* Start over for an absolute symlink. */
140
                                new_path = got_path;
141
                        else
142
                                /* Otherwise back up over this component. */
143
                                while (*(--new_path) != '/');
144
                        /* Safe sex check. */
145
                        if (strlen(path) + n >= PATH_MAX - 2) {
146
                                __set_errno(ENAMETOOLONG);
147
                                return NULL;
148
                        }
149
                        /* Insert symlink contents into path. */
150
                        strcat(link_path, path);
151
                        strcpy(copy_path, link_path);
152
                        path = copy_path;
153
                }
154
#endif                                                  /* S_IFLNK */
155
                *new_path++ = '/';
156
        }
157
        /* Delete trailing slash but don't whomp a lone slash. */
158
        if (new_path != got_path + 1 && new_path[-1] == '/')
159
                new_path--;
160
        /* Make sure it's null terminated. */
161
        *new_path = '\0';
162
        strcpy(resolved_path, got_path);
163
        return resolved_path;
164
}

powered by: WebSVN 2.1.0

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