X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=libbb%2Fxreadlink.c;h=ec95af2229f1d94243e9071fce2d9d69276cad86;hb=0b170e6a096b0d5010e29a39f3b270c3a7bc4945;hp=a5f7eb8bef5fac5e35076696e707f93eda9b4438;hpb=599bbfbd9be0073c262319a120174fad5a60113e;p=oweals%2Fbusybox.git diff --git a/libbb/xreadlink.c b/libbb/xreadlink.c index a5f7eb8be..ec95af222 100644 --- a/libbb/xreadlink.c +++ b/libbb/xreadlink.c @@ -1,16 +1,18 @@ /* vi: set sw=4 ts=4: */ /* - * xreadlink.c - safe implementation of readlink. - * Returns a NULL on failure... + * xreadlink.c - safe implementation of readlink. + * Returns a NULL on failure... + * + * Licensed under GPLv2, see file LICENSE in this source tree. */ #include "libbb.h" /* * NOTE: This function returns a malloced char* that you will have to free - * yourself. You have been warned. + * yourself. */ -char *xmalloc_readlink(const char *path) +char* FAST_FUNC xmalloc_readlink(const char *path) { enum { GROWBY = 80 }; /* how large we will grow strings by */ @@ -33,16 +35,16 @@ char *xmalloc_readlink(const char *path) } /* - * this routine is not the same as realpath(), which - * canonicalizes the given path completely. this routine only - * follows trailing symlinks until a real file is reached, and - * returns its name. if the path ends in a dangling link, or if - * the target doesn't exist, the path is returned in any case. - * intermediate symlinks in the path are not expanded -- only + * This routine is not the same as realpath(), which + * canonicalizes the given path completely. This routine only + * follows trailing symlinks until a real file is reached and + * returns its name. If the path ends in a dangling link or if + * the target doesn't exist, the path is returned in any case. + * Intermediate symlinks in the path are not expanded -- only * those at the tail. - * a malloced char* is returned, which must be freed by the caller. + * A malloced char* is returned, which must be freed by the caller. */ -char *xmalloc_follow_symlinks(const char *path) +char* FAST_FUNC xmalloc_follow_symlinks(const char *path) { char *buf; char *lpc; @@ -54,18 +56,17 @@ char *xmalloc_follow_symlinks(const char *path) goto jump_in; while (1) { - linkpath = xmalloc_readlink(buf); if (!linkpath) { /* not a symlink, or doesn't exist */ if (errno == EINVAL || errno == ENOENT) return buf; - free(buf); - return NULL; - } + goto free_buf_ret_null; + } if (!--looping) { free(linkpath); + free_buf_ret_null: free(buf); return NULL; } @@ -85,28 +86,30 @@ char *xmalloc_follow_symlinks(const char *path) } } -char *xmalloc_readlink_or_warn(const char *path) +char* FAST_FUNC xmalloc_readlink_or_warn(const char *path) { char *buf = xmalloc_readlink(path); if (!buf) { /* EINVAL => "file: Invalid argument" => puzzled user */ - bb_error_msg("%s: cannot read link (not a symlink?)", path); + const char *errmsg = "not a symlink"; + int err = errno; + if (err != EINVAL) + errmsg = strerror(err); + bb_error_msg("%s: cannot read link: %s", path, errmsg); } return buf; } -/* UNUSED */ -#if 0 -char *xmalloc_realpath(const char *path) +char* FAST_FUNC xmalloc_realpath(const char *path) { #if defined(__GLIBC__) && !defined(__UCLIBC__) /* glibc provides a non-standard extension */ + /* new: POSIX.1-2008 specifies this behavior as well */ return realpath(path, NULL); #else char buf[PATH_MAX+1]; - /* on error returns NULL (xstrdup(NULL) ==NULL) */ + /* on error returns NULL (xstrdup(NULL) == NULL) */ return xstrdup(realpath(path, buf)); #endif } -#endif