Select one of the symbols to view example projects that use it.
 
Outline
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <dirent.h>
#include <sys/param.h>
realpath(const char *, char *)
getcwd(char *, size_t)
chdir(const char *)
chmod(const char *, mode_t)
dirfd(DIR *)
Files
loading...
SourceVuESP-IDF Framework and ExamplesESP-IDFcomponents/newlib/realpath.c
 
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
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
/* * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 *//* ... */ #include <unistd.h> #include <errno.h> #include <string.h> #include <stdlib.h> #include <assert.h> #include <dirent.h> #include <sys/param.h>7 includes /* realpath logic: * 1. prepend CWD (/) * 2. iterate over components (search until next '/' or end of line) * - empty, skip the component * - if it is '.', skip the component * - if it is '..' * - and out_level == 0, ??? ('/..') * - otherwise, reverse-search for '/', set out_pos to that - 1, decrement out_level * - otherwise, add the component to output, increment out_level *//* ... */ char * realpath(const char *file_name, char *resolved_name) { char * out_path = resolved_name; if (out_path == NULL) { /* allowed as an extension, allocate memory for the output path */ out_path = malloc(PATH_MAX); if (out_path == NULL) { errno = ENOMEM; return NULL; }{...} }{...} /* canonical path starts with / */ strlcpy(out_path, "/", PATH_MAX); /* pointers moving over the input and output path buffers */ const char* in_ptr = file_name; char* out_ptr = out_path + 1; /* number of path components in the output buffer */ size_t out_depth = 0; while (*in_ptr) { /* "path component" is the part between two '/' path separators. * locate the next path component in the input path: *//* ... */ const char* end_of_path_component = strchrnul(in_ptr, '/'); size_t path_component_len = end_of_path_component - in_ptr; if (path_component_len == 0 || (path_component_len == 1 && in_ptr[0] == '.')) { /* empty path component or '.' - nothing to do */ }{...} else if (path_component_len == 2 && in_ptr[0] == '.' && in_ptr[1] == '.') { /* '..' - remove one path component from the output */ if (out_depth == 0) { /* nothing to remove */ }{...} else if (out_depth == 1) { /* there is only one path component in output; * remove it, but keep the leading separator *//* ... */ out_ptr = out_path + 1; *out_ptr = '\0'; out_depth = 0; }{...} else { /* remove last path component and the separator preceding it */ char * prev_sep = strrchr(out_path, '/'); assert(prev_sep > out_path); /* this shouldn't be the leading separator */ out_ptr = prev_sep; *out_ptr = '\0'; --out_depth; }{...} }{...} else { /* copy path component to output; +1 is for the separator */ if (out_ptr - out_path + 1 + path_component_len > PATH_MAX - 1) { /* output buffer insufficient */ errno = E2BIG; goto fail; }{...} else { /* add separator if necessary */ if (out_depth > 0) { *out_ptr = '/'; ++out_ptr; }{...} memcpy(out_ptr, in_ptr, path_component_len); out_ptr += path_component_len; *out_ptr = '\0'; ++out_depth; }{...} }{...} /* move input pointer to separator right after this path component */ in_ptr += path_component_len; if (*in_ptr != '\0') { /* move past it unless already at the end of the input string */ ++in_ptr; }{...} }{...} return out_path; fail: if (resolved_name == NULL) { /* out_path was allocated, free it */ free(out_path); }{...} return NULL; }{ ... } char * getcwd(char *buf, size_t size) { if (buf == NULL) { return strdup("/"); }{...} strlcpy(buf, "/", size); return buf; }{ ... } int chdir(const char *path) { (void) path; errno = ENOSYS; return -1; }{ ... } /* std::filesystem functions call chmod and exit with an exception if it fails, * so not failing with ENOSYS seems a better solution. *//* ... */ int chmod(const char *path, mode_t mode) { return 0; }{ ... } /* As a workaround for libstdc++ being built with _GLIBCXX_HAVE_DIRFD, * we have to provide at least a stub for dirfd function. *//* ... */ int dirfd(DIR *dirp) { errno = ENOSYS; return -1; }{ ... }
Details
Show:
from
Types: Columns:
This file uses the notable symbols shown below. Click anywhere in the file to view more details.