mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-16 22:37:30 +08:00
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
This commit is contained in:
@@ -425,19 +425,22 @@ static ssize_t uv__fs_scandir(uv_fs_t* req) {
|
|||||||
return n;
|
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) {
|
static ssize_t uv__fs_pathmax_size(const char* path) {
|
||||||
ssize_t pathmax;
|
ssize_t pathmax;
|
||||||
|
|
||||||
pathmax = pathconf(path, _PC_PATH_MAX);
|
pathmax = pathconf(path, _PC_PATH_MAX);
|
||||||
|
|
||||||
if (pathmax == -1) {
|
if (pathmax == -1)
|
||||||
#if defined(PATH_MAX)
|
pathmax = UV__FS_PATH_MAX;
|
||||||
return PATH_MAX;
|
|
||||||
#else
|
|
||||||
#error "PATH_MAX undefined in the current platform"
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
return pathmax;
|
return pathmax;
|
||||||
}
|
}
|
||||||
@@ -446,7 +449,28 @@ static ssize_t uv__fs_readlink(uv_fs_t* req) {
|
|||||||
ssize_t len;
|
ssize_t len;
|
||||||
char* buf;
|
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);
|
len = uv__fs_pathmax_size(req->path);
|
||||||
|
#else
|
||||||
|
len = uv__fs_pathmax_size(req->path);
|
||||||
|
#endif
|
||||||
|
|
||||||
buf = uv__malloc(len + 1);
|
buf = uv__malloc(len + 1);
|
||||||
|
|
||||||
if (buf == NULL) {
|
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) {
|
static ssize_t uv__fs_realpath(uv_fs_t* req) {
|
||||||
ssize_t len;
|
|
||||||
char* buf;
|
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);
|
len = uv__fs_pathmax_size(req->path);
|
||||||
buf = uv__malloc(len + 1);
|
buf = uv__malloc(len + 1);
|
||||||
|
|
||||||
@@ -488,6 +518,7 @@ static ssize_t uv__fs_realpath(uv_fs_t* req) {
|
|||||||
uv__free(buf);
|
uv__free(buf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
req->ptr = buf;
|
req->ptr = buf;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user