1 /* Copyright 2013 The Chromium Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file. */
14 #include "sdk_util/macros.h"
18 #if defined(__native_client__)
20 // TODO(binji): glibc has realpath, but it fails for all tests. Investigate.
22 char* realpath(const char* path
, char* resolved_path
) {
29 if (resolved_path
== NULL
) {
30 resolved_path
= (char*)malloc(PATH_MAX
);
35 const char* in
= path
;
36 char* out
= resolved_path
;
37 char* out_end
= resolved_path
+ PATH_MAX
- 1;
49 if (getcwd(out
, out_end
- out
) == NULL
)
55 if (stat(resolved_path
, &statbuf
) != 0)
59 const char* next_slash
= strchr(in
, '/');
63 namelen
= next_slash
- in
;
64 next_in
= next_slash
+ 1;
67 next_in
= in
+ namelen
; // Move to the '\0'
72 // Empty name, do nothing.
73 } else if (namelen
== 1 && strncmp(in
, ".", 1) == 0) {
74 // Current directory, do nothing.
75 } else if (namelen
== 2 && strncmp(in
, "..", 2) == 0) {
76 // Parent directory, find previous slash in resolved_path.
77 char* prev_slash
= strrchr(resolved_path
, '/');
78 assert(prev_slash
!= NULL
);
81 if (prev_slash
== resolved_path
) {
82 // Moved to the root. Keep the slash.
88 // Append a slash if not at root.
89 if (out
!= resolved_path
+ 1) {
90 if (out
+ 1 > out_end
) {
95 strncat(out
, "/", namelen
);
99 if (out
+ namelen
> out_end
) {
100 errno
= ENAMETOOLONG
;
104 strncat(out
, in
, namelen
);
110 if (stat(resolved_path
, &statbuf
) != 0)
113 // If there is more to the path, then the current path must be a directory.
114 if (!done
&& !S_ISDIR(statbuf
.st_mode
)) {
120 return resolved_path
;
131 #endif // defined(__native_client__)