summaryrefslogtreecommitdiffstats
path: root/Utilities/cmlibuv
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2018-09-28 16:41:12 (GMT)
committerBrad King <brad.king@kitware.com>2018-10-01 12:22:38 (GMT)
commit3c0bfb596fa53596b16c2f6ed0868f15475b5bf7 (patch)
treecd95ed8e5d43ff87e8e46f76db2b9c4f3bbe3b57 /Utilities/cmlibuv
parentf478fa633daeb1432805821adddc40730ffd283d (diff)
downloadCMake-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
Diffstat (limited to 'Utilities/cmlibuv')
-rw-r--r--Utilities/cmlibuv/src/unix/fs.c47
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;