MCPcopy Create free account
hub / github.com/ElementsProject/lightning / path_simplify

Function path_simplify

ccan/ccan/tal/path/path.c:339–423  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

337}
338
339char *path_simplify(const tal_t *ctx, const char *path)
340{
341 size_t i, j, start, len;
342 char *ret;
343 bool ended = false;
344
345 ret = tal_strdup(ctx, path);
346 if (!ret)
347 return NULL;
348
349 /* Always need first / if there is one. */
350 if (ret[0] == PATH_SEP)
351 start = 1;
352 else
353 start = 0;
354
355 for (i = j = start; !ended; i += len) {
356 /* Get length of this segment, including terminator. */
357 for (len = 0; ret[i+len] != PATH_SEP; len++) {
358 if (!ret[i+len]) {
359 ended = true;
360 break;
361 }
362 }
363 len++;
364
365 /* Empty segment is //; ignore first one. */
366 if (len == 1)
367 continue;
368
369 /* Always ignore slashdot. */
370 if (len == 2 && ret[i] == '.')
371 continue;
372
373 /* .. => remove previous if there is one, unless symlink. */
374 if (len == 3 && ret[i] == '.' && ret[i+1] == '.') {
375 struct stat st;
376
377 if (j > start) {
378 /* eg. /foo/, foo/ or foo/bar/ */
379 assert(ret[j-1] == PATH_SEP);
380 ret[j-1] = '\0';
381
382 /* Avoid stepping back over ..! */
383 if (streq(ret, "..")
384 || strends(ret, PATH_SEP_STR"..")) {
385 ret[j-1] = PATH_SEP;
386 goto copy;
387 }
388
389 if (lstat(ret, &st) == 0
390 && !S_ISLNK(st.st_mode)) {
391 char *sep = strrchr(ret, PATH_SEP);
392 if (sep)
393 j = sep - ret + 1;
394 else
395 j = 0;
396 }

Callers 2

mainFunction · 0.85
find_my_pkglibexec_pathFunction · 0.85

Calls 1

strendsFunction · 0.85

Tested by 1

mainFunction · 0.68