unix: fix uv_pipe_chmod() on macOS
According to its man page, there is a bug in fstat() on macOS related to pipes. This commit replaces a fstat() call in uv_pipe_chmod() with a stat() call in order to get the correct permissions. PR-URL: https://github.com/libuv/libuv/pull/1635 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
This commit is contained in:
parent
9afb013574
commit
19855c03ba
@ -319,21 +319,6 @@ int uv_pipe_chmod(uv_pipe_t* handle, int mode) {
|
|||||||
mode != (UV_WRITABLE | UV_READABLE))
|
mode != (UV_WRITABLE | UV_READABLE))
|
||||||
return UV_EINVAL;
|
return UV_EINVAL;
|
||||||
|
|
||||||
if (fstat(uv__stream_fd(handle), &pipe_stat) == -1)
|
|
||||||
return UV__ERR(errno);
|
|
||||||
|
|
||||||
desired_mode = 0;
|
|
||||||
if (mode & UV_READABLE)
|
|
||||||
desired_mode |= S_IRUSR | S_IRGRP | S_IROTH;
|
|
||||||
if (mode & UV_WRITABLE)
|
|
||||||
desired_mode |= S_IWUSR | S_IWGRP | S_IWOTH;
|
|
||||||
|
|
||||||
/* Exit early if pipe already has desired mode. */
|
|
||||||
if ((pipe_stat.st_mode & desired_mode) == desired_mode)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
pipe_stat.st_mode |= desired_mode;
|
|
||||||
|
|
||||||
/* Unfortunately fchmod does not work on all platforms, we will use chmod. */
|
/* Unfortunately fchmod does not work on all platforms, we will use chmod. */
|
||||||
name_len = 0;
|
name_len = 0;
|
||||||
r = uv_pipe_getsockname(handle, NULL, &name_len);
|
r = uv_pipe_getsockname(handle, NULL, &name_len);
|
||||||
@ -350,6 +335,26 @@ int uv_pipe_chmod(uv_pipe_t* handle, int mode) {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* stat must be used as fstat has a bug on Darwin */
|
||||||
|
if (stat(name_buffer, &pipe_stat) == -1) {
|
||||||
|
uv__free(name_buffer);
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
desired_mode = 0;
|
||||||
|
if (mode & UV_READABLE)
|
||||||
|
desired_mode |= S_IRUSR | S_IRGRP | S_IROTH;
|
||||||
|
if (mode & UV_WRITABLE)
|
||||||
|
desired_mode |= S_IWUSR | S_IWGRP | S_IWOTH;
|
||||||
|
|
||||||
|
/* Exit early if pipe already has desired mode. */
|
||||||
|
if ((pipe_stat.st_mode & desired_mode) == desired_mode) {
|
||||||
|
uv__free(name_buffer);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pipe_stat.st_mode |= desired_mode;
|
||||||
|
|
||||||
r = chmod(name_buffer, pipe_stat.st_mode);
|
r = chmod(name_buffer, pipe_stat.st_mode);
|
||||||
uv__free(name_buffer);
|
uv__free(name_buffer);
|
||||||
|
|
||||||
|
|||||||
@ -27,6 +27,9 @@ TEST_IMPL(pipe_set_chmod) {
|
|||||||
uv_pipe_t pipe_handle;
|
uv_pipe_t pipe_handle;
|
||||||
uv_loop_t* loop;
|
uv_loop_t* loop;
|
||||||
int r;
|
int r;
|
||||||
|
#ifndef _WIN32
|
||||||
|
struct stat stat_buf;
|
||||||
|
#endif
|
||||||
|
|
||||||
loop = uv_default_loop();
|
loop = uv_default_loop();
|
||||||
|
|
||||||
@ -44,12 +47,33 @@ TEST_IMPL(pipe_set_chmod) {
|
|||||||
RETURN_SKIP("Insufficient privileges to alter pipe fmode");
|
RETURN_SKIP("Insufficient privileges to alter pipe fmode");
|
||||||
}
|
}
|
||||||
ASSERT(r == 0);
|
ASSERT(r == 0);
|
||||||
|
#ifndef _WIN32
|
||||||
|
stat(TEST_PIPENAME, &stat_buf);
|
||||||
|
ASSERT(stat_buf.st_mode & S_IRUSR);
|
||||||
|
ASSERT(stat_buf.st_mode & S_IRGRP);
|
||||||
|
ASSERT(stat_buf.st_mode & S_IROTH);
|
||||||
|
#endif
|
||||||
|
|
||||||
r = uv_pipe_chmod(&pipe_handle, UV_WRITABLE);
|
r = uv_pipe_chmod(&pipe_handle, UV_WRITABLE);
|
||||||
ASSERT(r == 0);
|
ASSERT(r == 0);
|
||||||
|
#ifndef _WIN32
|
||||||
|
stat(TEST_PIPENAME, &stat_buf);
|
||||||
|
ASSERT(stat_buf.st_mode & S_IWUSR);
|
||||||
|
ASSERT(stat_buf.st_mode & S_IWGRP);
|
||||||
|
ASSERT(stat_buf.st_mode & S_IWOTH);
|
||||||
|
#endif
|
||||||
|
|
||||||
r = uv_pipe_chmod(&pipe_handle, UV_WRITABLE | UV_READABLE);
|
r = uv_pipe_chmod(&pipe_handle, UV_WRITABLE | UV_READABLE);
|
||||||
ASSERT(r == 0);
|
ASSERT(r == 0);
|
||||||
|
#ifndef _WIN32
|
||||||
|
stat(TEST_PIPENAME, &stat_buf);
|
||||||
|
ASSERT(stat_buf.st_mode & S_IRUSR);
|
||||||
|
ASSERT(stat_buf.st_mode & S_IRGRP);
|
||||||
|
ASSERT(stat_buf.st_mode & S_IROTH);
|
||||||
|
ASSERT(stat_buf.st_mode & S_IWUSR);
|
||||||
|
ASSERT(stat_buf.st_mode & S_IWGRP);
|
||||||
|
ASSERT(stat_buf.st_mode & S_IWOTH);
|
||||||
|
#endif
|
||||||
|
|
||||||
r = uv_pipe_chmod(NULL, UV_WRITABLE | UV_READABLE);
|
r = uv_pipe_chmod(NULL, UV_WRITABLE | UV_READABLE);
|
||||||
ASSERT(r == UV_EBADF);
|
ASSERT(r == UV_EBADF);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user