diff options
author | Brad King <brad.king@kitware.com> | 2018-09-28 16:41:12 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2018-10-01 12:22:38 (GMT) |
commit | 3c0bfb596fa53596b16c2f6ed0868f15475b5bf7 (patch) | |
tree | cd95ed8e5d43ff87e8e46f76db2b9c4f3bbe3b57 | |
parent | f478fa633daeb1432805821adddc40730ffd283d (diff) | |
download | CMake-3c0bfb596fa53596b16c2f6ed0868f15475b5bf7.zip CMake-3c0bfb596fa53596b16c2f6ed0868f15475b5bf7.tar.gz CMake-3c0bfb596fa53596b16c2f6ed0868f15475b5bf7.tar.bz2 |
libuv: do not require PATH_MAX to be defined
Some platforms (e.g. GNU/Hurd) do not define PATH_MAX. Add a few other
variants and a fallback constant. Also use alternatives where possible:
* For readlink(), use lstat() to read the length of the link first.
If it is not a symlink, report EINVAL before trying to allocate.
If the size reports as zero, fall back one of the PATH_MAX variants.
* For realpath(), POSIX 2008 allows us to pass a NULL buffer
to tell it to malloc() internally.
This patch was inspired by downstream patches in Debian packaging
for issues 897061 and 909011.
Issue: #18337
-rw-r--r-- | Utilities/cmlibuv/src/unix/fs.c | 47 |
1 files changed, 39 insertions, 8 deletions
diff --git a/Utilities/cmlibuv/src/unix/fs.c b/Utilities/cmlibuv/src/unix/fs.c index 4545168..a6cc6db 100644 --- a/Utilities/cmlibuv/src/unix/fs.c +++ b/Utilities/cmlibuv/src/unix/fs.c @@ -425,19 +425,22 @@ static ssize_t uv__fs_scandir(uv_fs_t* req) { return n; } +#if defined(_POSIX_PATH_MAX) +# define UV__FS_PATH_MAX _POSIX_PATH_MAX +#elif defined(PATH_MAX) +# define UV__FS_PATH_MAX PATH_MAX +#else +# define UV__FS_PATH_MAX_FALLBACK 8192 +# define UV__FS_PATH_MAX UV__FS_PATH_MAX_FALLBACK +#endif static ssize_t uv__fs_pathmax_size(const char* path) { ssize_t pathmax; pathmax = pathconf(path, _PC_PATH_MAX); - if (pathmax == -1) { -#if defined(PATH_MAX) - return PATH_MAX; -#else -#error "PATH_MAX undefined in the current platform" -#endif - } + if (pathmax == -1) + pathmax = UV__FS_PATH_MAX; return pathmax; } @@ -446,7 +449,28 @@ static ssize_t uv__fs_readlink(uv_fs_t* req) { ssize_t len; char* buf; +#if defined(UV__FS_PATH_MAX_FALLBACK) + /* We may not have a real PATH_MAX. Read size of link. */ + struct stat st; + int ret; + ret = lstat(req->path, &st); + if (ret != 0) + return -1; + if (!S_ISLNK(st.st_mode)) { + errno = EINVAL; + return -1; + } + + len = st.st_size; + + /* According to readlink(2) lstat can report st_size == 0 + for some symlinks, such as those in /proc or /sys. */ + if (len == 0) + len = uv__fs_pathmax_size(req->path); +#else len = uv__fs_pathmax_size(req->path); +#endif + buf = uv__malloc(len + 1); if (buf == NULL) { @@ -473,9 +497,15 @@ static ssize_t uv__fs_readlink(uv_fs_t* req) { } static ssize_t uv__fs_realpath(uv_fs_t* req) { - ssize_t len; char* buf; +#if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L + buf = realpath(req->path, NULL); + if (buf == NULL) + return -1; +#else + ssize_t len; + len = uv__fs_pathmax_size(req->path); buf = uv__malloc(len + 1); @@ -488,6 +518,7 @@ static ssize_t uv__fs_realpath(uv_fs_t* req) { uv__free(buf); return -1; } +#endif req->ptr = buf; |