67
#endif
68
69
/*
70
- * Return the real path (i.e., absolute path, with symlinks resolved
71
- * and extra slashes removed) equivalent to the specified path. (If
72
- * you want an absolute path but don't mind links, use
73
- * absolute_path().) Places the resolved realpath in the provided strbuf.
74
- *
75
- * The directory part of path (i.e., everything up to the last
76
- * dir_sep) must denote a valid, existing directory, but the last
77
- * component need not exist. If die_on_error is set, then die with an
78
- * informative error message if there is a problem. Otherwise, return
79
- * NULL on errors (without generating any output).
70
+ * If set, any number of trailing components may be missing; otherwise, only one
71
+ * may be.
72
*/
81
-char *strbuf_realpath(struct strbuf *resolved, const char *path,
82
- int die_on_error)
73
+#define REALPATH_MANY_MISSING (1 << 0)
74
+/* Should we die if there's an error? */
75
+#define REALPATH_DIE_ON_ERROR (1 << 1)
76
+
77
+static char *strbuf_realpath_1(struct strbuf *resolved, const char *path,
78
+ int flags)
79
{
80
struct strbuf remaining = STRBUF_INIT;
81
struct strbuf next = STRBUF_INIT;
85
struct stat st;
86
87
if (!*path) {
92
- if (die_on_error)
88
+ if (flags & REALPATH_DIE_ON_ERROR)
89
die("The empty string is not a valid path");
90
else
91
goto error_out;
97
if (!resolved->len) {
98
/* relative path; can use CWD as the initial resolved path */
99
if (strbuf_getcwd(resolved)) {
104
- if (die_on_error)
100
+ if (flags & REALPATH_DIE_ON_ERROR)
101
die_errno("unable to get current working directory");
102
else
103
goto error_out;
125
126
if (lstat(resolved->buf, &st)) {
127
/* error out unless this was the last component */
132
- if (errno != ENOENT || remaining.len) {
133
- if (die_on_error)
128
+ if (errno != ENOENT ||
129
+ (!(flags & REALPATH_MANY_MISSING) && remaining.len)) {
130
+ if (flags & REALPATH_DIE_ON_ERROR)
131
die_errno("Invalid path '%s'",
132
resolved->buf);
133
else
140
if (num_symlinks++ > MAXSYMLINKS) {
141
errno = ELOOP;
142
146
- if (die_on_error)
143
+ if (flags & REALPATH_DIE_ON_ERROR)
144
die("More than %d nested symlinks "
145
"on path '%s'", MAXSYMLINKS, path);
146
else
150
len = strbuf_readlink(&symlink, resolved->buf,
151
st.st_size);
152
if (len < 0) {
156
- if (die_on_error)
153
+ if (flags & REALPATH_DIE_ON_ERROR)
154
die_errno("Invalid symlink '%s'",
155
resolved->buf);
156
else
199
return retval;
200
}
201
202
+/*
203
+ * Return the real path (i.e., absolute path, with symlinks resolved
204
+ * and extra slashes removed) equivalent to the specified path. (If
205
+ * you want an absolute path but don't mind links, use
206
+ * absolute_path().) Places the resolved realpath in the provided strbuf.
207
+ *
208
+ * The directory part of path (i.e., everything up to the last
209
+ * dir_sep) must denote a valid, existing directory, but the last
210
+ * component need not exist. If die_on_error is set, then die with an
211
+ * informative error message if there is a problem. Otherwise, return
212
+ * NULL on errors (without generating any output).
213
+ */
214
+char *strbuf_realpath(struct strbuf *resolved, const char *path,
215
+ int die_on_error)
216
+{
217
+ return strbuf_realpath_1(resolved, path,
218
+ die_on_error ? REALPATH_DIE_ON_ERROR : 0);
219
+}
220
+
221
+/*
222
+ * Just like strbuf_realpath, but allows an arbitrary number of path
223
+ * components to be missing.
224
+ */
225
+char *strbuf_realpath_forgiving(struct strbuf *resolved, const char *path,
226
+ int die_on_error)
227
+{
228
+ return strbuf_realpath_1(resolved, path,
229
+ ((die_on_error ? REALPATH_DIE_ON_ERROR : 0) |
230
+ REALPATH_MANY_MISSING));
231
+}
232
+
233
char *real_pathdup(const char *path, int die_on_error)
234
{
235
struct strbuf realpath = STRBUF_INIT;