1
6
7
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
37
38
39
40
41
42
43
44
45
46
47
48
51
52
53
54
55
94
95
96
100
101
102
103
104
108
109
110
111
119
120
126
127
130
134
135
138
/* ... */
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <dirent.h>
#include <sys/param.h>7 includes
/* ... */
char * realpath(const char *file_name, char *resolved_name)
{
char * out_path = resolved_name;
if (out_path == NULL) {
out_path = malloc(PATH_MAX);
if (out_path == NULL) {
errno = ENOMEM;
return NULL;
}{...}
}{...}
strlcpy(out_path, "/", PATH_MAX);
const char* in_ptr = file_name;
char* out_ptr = out_path + 1;
size_t out_depth = 0;
while (*in_ptr) {
/* ... */
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] == '.')) {
}{...} else if (path_component_len == 2 && in_ptr[0] == '.' && in_ptr[1] == '.') {
if (out_depth == 0) {
}{...} else if (out_depth == 1) {
/* ... */
out_ptr = out_path + 1;
*out_ptr = '\0';
out_depth = 0;
}{...} else {
char * prev_sep = strrchr(out_path, '/');
assert(prev_sep > out_path);
out_ptr = prev_sep;
*out_ptr = '\0';
--out_depth;
}{...}
}{...} else {
if (out_ptr - out_path + 1 + path_component_len > PATH_MAX - 1) {
errno = E2BIG;
goto fail;
}{...} else {
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;
}{...}
}{...}
in_ptr += path_component_len;
if (*in_ptr != '\0') {
++in_ptr;
}{...}
}{...}
return out_path;
fail:
if (resolved_name == NULL) {
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;
}{ ... }
/* ... */
int chmod(const char *path, mode_t mode)
{
return 0;
}{ ... }
/* ... */
int dirfd(DIR *dirp)
{
errno = ENOSYS;
return -1;
}{ ... }