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))
|
||||
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. */
|
||||
name_len = 0;
|
||||
r = uv_pipe_getsockname(handle, NULL, &name_len);
|
||||
@ -350,6 +335,26 @@ int uv_pipe_chmod(uv_pipe_t* handle, int mode) {
|
||||
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);
|
||||
uv__free(name_buffer);
|
||||
|
||||
|
||||
@ -27,6 +27,9 @@ TEST_IMPL(pipe_set_chmod) {
|
||||
uv_pipe_t pipe_handle;
|
||||
uv_loop_t* loop;
|
||||
int r;
|
||||
#ifndef _WIN32
|
||||
struct stat stat_buf;
|
||||
#endif
|
||||
|
||||
loop = uv_default_loop();
|
||||
|
||||
@ -44,12 +47,33 @@ TEST_IMPL(pipe_set_chmod) {
|
||||
RETURN_SKIP("Insufficient privileges to alter pipe fmode");
|
||||
}
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
ASSERT(r == UV_EBADF);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user