build: add MemorySanitizer (MSAN) support (#3788)
- unpoison results from linux system call wrappers - unpoison results from stat/fstat/lstat to pacify clang 14 (fixed in later versions) - add MSAN build option - turn on MSAN CI build
This commit is contained in:
parent
73b0c1f947
commit
acfe668ecb
29
.github/workflows/sanitizer.yml
vendored
29
.github/workflows/sanitizer.yml
vendored
@ -14,7 +14,7 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
sanitizers:
|
sanitizers:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Setup
|
- name: Setup
|
||||||
@ -22,6 +22,25 @@ jobs:
|
|||||||
sudo apt-get install ninja-build
|
sudo apt-get install ninja-build
|
||||||
- name: Envinfo
|
- name: Envinfo
|
||||||
run: npx envinfo
|
run: npx envinfo
|
||||||
|
|
||||||
|
- name: ASAN Build
|
||||||
|
run: |
|
||||||
|
mkdir build-asan
|
||||||
|
(cd build-asan && cmake .. -G Ninja -DBUILD_TESTING=ON -DASAN=ON -DCMAKE_BUILD_TYPE=Debug)
|
||||||
|
cmake --build build-asan
|
||||||
|
- name: ASAN Test
|
||||||
|
run: |
|
||||||
|
./build-asan/uv_run_tests_a
|
||||||
|
|
||||||
|
- name: MSAN Build
|
||||||
|
run: |
|
||||||
|
mkdir build-msan
|
||||||
|
(cd build-msan && cmake .. -G Ninja -DBUILD_TESTING=ON -DMSAN=ON -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=clang)
|
||||||
|
cmake --build build-msan
|
||||||
|
- name: MSAN Test
|
||||||
|
run: |
|
||||||
|
./build-msan/uv_run_tests_a
|
||||||
|
|
||||||
- name: TSAN Build
|
- name: TSAN Build
|
||||||
run: |
|
run: |
|
||||||
mkdir build-tsan
|
mkdir build-tsan
|
||||||
@ -31,11 +50,3 @@ jobs:
|
|||||||
continue-on-error: true # currently permit failures
|
continue-on-error: true # currently permit failures
|
||||||
run: |
|
run: |
|
||||||
./build-tsan/uv_run_tests_a
|
./build-tsan/uv_run_tests_a
|
||||||
- name: ASAN Build
|
|
||||||
run: |
|
|
||||||
mkdir build-asan
|
|
||||||
(cd build-asan && cmake .. -G Ninja -DBUILD_TESTING=ON -DASAN=ON -DCMAKE_BUILD_TYPE=Debug)
|
|
||||||
cmake --build build-asan
|
|
||||||
- name: ASAN Test
|
|
||||||
run: |
|
|
||||||
./build-asan/uv_run_tests_a
|
|
||||||
|
|||||||
@ -36,13 +36,19 @@ if(QEMU)
|
|||||||
add_definitions(-D__QEMU__=1)
|
add_definitions(-D__QEMU__=1)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Note: these are mutually exclusive.
|
||||||
option(ASAN "Enable AddressSanitizer (ASan)" OFF)
|
option(ASAN "Enable AddressSanitizer (ASan)" OFF)
|
||||||
|
option(MSAN "Enable MemorySanitizer (MSan)" OFF)
|
||||||
option(TSAN "Enable ThreadSanitizer (TSan)" OFF)
|
option(TSAN "Enable ThreadSanitizer (TSan)" OFF)
|
||||||
|
|
||||||
if((ASAN OR TSAN) AND NOT (CMAKE_C_COMPILER_ID MATCHES "AppleClang|GNU|Clang"))
|
if((ASAN OR TSAN) AND NOT (CMAKE_C_COMPILER_ID MATCHES "AppleClang|GNU|Clang"))
|
||||||
message(SEND_ERROR "Sanitizer support requires clang or gcc. Try again with -DCMAKE_C_COMPILER.")
|
message(SEND_ERROR "Sanitizer support requires clang or gcc. Try again with -DCMAKE_C_COMPILER.")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(MSAN AND NOT CMAKE_C_COMPILER_ID MATCHES "AppleClang|Clang")
|
||||||
|
message(SEND_ERROR "MemorySanitizer requires clang. Try again with -DCMAKE_C_COMPILER=clang")
|
||||||
|
endif()
|
||||||
|
|
||||||
if(ASAN)
|
if(ASAN)
|
||||||
add_definitions(-D__ASAN__=1)
|
add_definitions(-D__ASAN__=1)
|
||||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-omit-frame-pointer -fsanitize=address")
|
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-omit-frame-pointer -fsanitize=address")
|
||||||
@ -50,6 +56,13 @@ if(ASAN)
|
|||||||
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fno-omit-frame-pointer -fsanitize=address")
|
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fno-omit-frame-pointer -fsanitize=address")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(MSAN)
|
||||||
|
add_definitions(-D__MSAN__=1)
|
||||||
|
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-omit-frame-pointer -fsanitize=memory")
|
||||||
|
set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fno-omit-frame-pointer -fsanitize=memory")
|
||||||
|
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fno-omit-frame-pointer -fsanitize=memory")
|
||||||
|
endif()
|
||||||
|
|
||||||
if(TSAN)
|
if(TSAN)
|
||||||
add_definitions(-D__TSAN__=1)
|
add_definitions(-D__TSAN__=1)
|
||||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-omit-frame-pointer -fsanitize=thread")
|
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-omit-frame-pointer -fsanitize=thread")
|
||||||
|
|||||||
@ -425,7 +425,7 @@ static char* uv__rawname(const char* cp, char (*dst)[FILENAME_MAX+1]) {
|
|||||||
static int uv__path_is_a_directory(char* filename) {
|
static int uv__path_is_a_directory(char* filename) {
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
|
|
||||||
if (stat(filename, &statbuf) < 0)
|
if (uv__stat(filename, &statbuf) < 0)
|
||||||
return -1; /* failed: not a directory, assume it is a file */
|
return -1; /* failed: not a directory, assume it is a file */
|
||||||
|
|
||||||
if (statbuf.st_type == VDIR)
|
if (statbuf.st_type == VDIR)
|
||||||
|
|||||||
@ -516,7 +516,7 @@ done:
|
|||||||
if (result == -1 && errno == EOPNOTSUPP) {
|
if (result == -1 && errno == EOPNOTSUPP) {
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
ssize_t rc;
|
ssize_t rc;
|
||||||
rc = fstat(req->file, &buf);
|
rc = uv__fstat(req->file, &buf);
|
||||||
if (rc == 0 && S_ISDIR(buf.st_mode)) {
|
if (rc == 0 && S_ISDIR(buf.st_mode)) {
|
||||||
errno = EISDIR;
|
errno = EISDIR;
|
||||||
}
|
}
|
||||||
@ -708,7 +708,7 @@ static ssize_t uv__fs_readlink(uv_fs_t* req) {
|
|||||||
/* We may not have a real PATH_MAX. Read size of link. */
|
/* We may not have a real PATH_MAX. Read size of link. */
|
||||||
struct stat st;
|
struct stat st;
|
||||||
int ret;
|
int ret;
|
||||||
ret = lstat(req->path, &st);
|
ret = uv__lstat(req->path, &st);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (!S_ISLNK(st.st_mode)) {
|
if (!S_ISLNK(st.st_mode)) {
|
||||||
@ -1281,7 +1281,7 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) {
|
|||||||
return srcfd;
|
return srcfd;
|
||||||
|
|
||||||
/* Get the source file's mode. */
|
/* Get the source file's mode. */
|
||||||
if (fstat(srcfd, &src_statsbuf)) {
|
if (uv__fstat(srcfd, &src_statsbuf)) {
|
||||||
err = UV__ERR(errno);
|
err = UV__ERR(errno);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -1309,7 +1309,7 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) {
|
|||||||
destination are not the same file. If they are the same, bail out early. */
|
destination are not the same file. If they are the same, bail out early. */
|
||||||
if ((req->flags & UV_FS_COPYFILE_EXCL) == 0) {
|
if ((req->flags & UV_FS_COPYFILE_EXCL) == 0) {
|
||||||
/* Get the destination file's mode. */
|
/* Get the destination file's mode. */
|
||||||
if (fstat(dstfd, &dst_statsbuf)) {
|
if (uv__fstat(dstfd, &dst_statsbuf)) {
|
||||||
err = UV__ERR(errno);
|
err = UV__ERR(errno);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -1588,7 +1588,7 @@ static int uv__fs_stat(const char *path, uv_stat_t *buf) {
|
|||||||
if (ret != UV_ENOSYS)
|
if (ret != UV_ENOSYS)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = stat(path, &pbuf);
|
ret = uv__stat(path, &pbuf);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
uv__to_stat(&pbuf, buf);
|
uv__to_stat(&pbuf, buf);
|
||||||
|
|
||||||
@ -1604,7 +1604,7 @@ static int uv__fs_lstat(const char *path, uv_stat_t *buf) {
|
|||||||
if (ret != UV_ENOSYS)
|
if (ret != UV_ENOSYS)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = lstat(path, &pbuf);
|
ret = uv__lstat(path, &pbuf);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
uv__to_stat(&pbuf, buf);
|
uv__to_stat(&pbuf, buf);
|
||||||
|
|
||||||
@ -1620,7 +1620,7 @@ static int uv__fs_fstat(int fd, uv_stat_t *buf) {
|
|||||||
if (ret != UV_ENOSYS)
|
if (ret != UV_ENOSYS)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = fstat(fd, &pbuf);
|
ret = uv__fstat(fd, &pbuf);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
uv__to_stat(&pbuf, buf);
|
uv__to_stat(&pbuf, buf);
|
||||||
|
|
||||||
|
|||||||
@ -33,6 +33,22 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#define uv__msan_unpoison(p, n) \
|
||||||
|
do { \
|
||||||
|
(void) (p); \
|
||||||
|
(void) (n); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#if defined(__has_feature)
|
||||||
|
# if __has_feature(memory_sanitizer)
|
||||||
|
# include <sanitizer/msan_interface.h>
|
||||||
|
# undef uv__msan_unpoison
|
||||||
|
# define uv__msan_unpoison __msan_unpoison
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__STRICT_ANSI__)
|
#if defined(__STRICT_ANSI__)
|
||||||
# define inline __inline
|
# define inline __inline
|
||||||
@ -341,6 +357,36 @@ UV_UNUSED(static char* uv__basename_r(const char* path)) {
|
|||||||
return s + 1;
|
return s + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UV_UNUSED(static int uv__fstat(int fd, struct stat* s)) {
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = fstat(fd, s);
|
||||||
|
if (rc >= 0)
|
||||||
|
uv__msan_unpoison(s, sizeof(*s));
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
UV_UNUSED(static int uv__lstat(const char* path, struct stat* s)) {
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = lstat(path, s);
|
||||||
|
if (rc >= 0)
|
||||||
|
uv__msan_unpoison(s, sizeof(*s));
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
UV_UNUSED(static int uv__stat(const char* path, struct stat* s)) {
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = stat(path, s);
|
||||||
|
if (rc >= 0)
|
||||||
|
uv__msan_unpoison(s, sizeof(*s));
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
int uv__inotify_fork(uv_loop_t* loop, void* old_watchers);
|
int uv__inotify_fork(uv_loop_t* loop, void* old_watchers);
|
||||||
ssize_t
|
ssize_t
|
||||||
|
|||||||
@ -529,7 +529,7 @@ int uv_fs_event_start(uv_fs_event_t* handle,
|
|||||||
handle->realpath_len = 0;
|
handle->realpath_len = 0;
|
||||||
handle->cf_flags = flags;
|
handle->cf_flags = flags;
|
||||||
|
|
||||||
if (fstat(fd, &statbuf))
|
if (uv__fstat(fd, &statbuf))
|
||||||
goto fallback;
|
goto fallback;
|
||||||
/* FSEvents works only with directories */
|
/* FSEvents works only with directories */
|
||||||
if (!(statbuf.st_mode & S_IFDIR))
|
if (!(statbuf.st_mode & S_IFDIR))
|
||||||
|
|||||||
@ -34,16 +34,18 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <sys/epoll.h>
|
#include <sys/epoll.h>
|
||||||
#include <sys/inotify.h>
|
#include <sys/inotify.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/prctl.h>
|
#include <sys/prctl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
#include <sys/sysinfo.h>
|
#include <sys/sysinfo.h>
|
||||||
#include <unistd.h>
|
#include <sys/types.h>
|
||||||
#include <fcntl.h>
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#if defined(__arm__)
|
#if defined(__arm__)
|
||||||
# if defined(__thumb__) || defined(__ARM_EABI__)
|
# if defined(__thumb__) || defined(__ARM_EABI__)
|
||||||
@ -212,7 +214,13 @@ int uv__statx(int dirfd,
|
|||||||
#if !defined(__NR_statx) || defined(__ANDROID_API__) && __ANDROID_API__ < 30
|
#if !defined(__NR_statx) || defined(__ANDROID_API__) && __ANDROID_API__ < 30
|
||||||
return errno = ENOSYS, -1;
|
return errno = ENOSYS, -1;
|
||||||
#else
|
#else
|
||||||
return syscall(__NR_statx, dirfd, path, flags, mask, statxbuf);
|
int rc;
|
||||||
|
|
||||||
|
rc = syscall(__NR_statx, dirfd, path, flags, mask, statxbuf);
|
||||||
|
if (rc >= 0)
|
||||||
|
uv__msan_unpoison(statxbuf, sizeof(*statxbuf));
|
||||||
|
|
||||||
|
return rc;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,7 +229,13 @@ ssize_t uv__getrandom(void* buf, size_t buflen, unsigned flags) {
|
|||||||
#if !defined(__NR_getrandom) || defined(__ANDROID_API__) && __ANDROID_API__ < 28
|
#if !defined(__NR_getrandom) || defined(__ANDROID_API__) && __ANDROID_API__ < 28
|
||||||
return errno = ENOSYS, -1;
|
return errno = ENOSYS, -1;
|
||||||
#else
|
#else
|
||||||
return syscall(__NR_getrandom, buf, buflen, flags);
|
ssize_t rc;
|
||||||
|
|
||||||
|
rc = syscall(__NR_getrandom, buf, buflen, flags);
|
||||||
|
if (rc >= 0)
|
||||||
|
uv__msan_unpoison(buf, buflen);
|
||||||
|
|
||||||
|
return rc;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1685,6 +1699,35 @@ int uv__sendmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void uv__recvmmsg_unpoison(struct uv__mmsghdr* mmsg, int rc) {
|
||||||
|
struct uv__mmsghdr* m;
|
||||||
|
struct msghdr* h;
|
||||||
|
struct iovec* v;
|
||||||
|
size_t j;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < rc; i++) {
|
||||||
|
m = mmsg + i;
|
||||||
|
uv__msan_unpoison(m, sizeof(*m));
|
||||||
|
|
||||||
|
h = &m->msg_hdr;
|
||||||
|
if (h->msg_name != NULL)
|
||||||
|
uv__msan_unpoison(h->msg_name, h->msg_namelen);
|
||||||
|
|
||||||
|
if (h->msg_iov != NULL)
|
||||||
|
uv__msan_unpoison(h->msg_iov, h->msg_iovlen * sizeof(*h->msg_iov));
|
||||||
|
|
||||||
|
for (j = 0; j < h->msg_iovlen; j++) {
|
||||||
|
v = h->msg_iov + j;
|
||||||
|
uv__msan_unpoison(v->iov_base, v->iov_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (h->msg_control != NULL)
|
||||||
|
uv__msan_unpoison(h->msg_control, h->msg_controllen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int uv__recvmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen) {
|
int uv__recvmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen) {
|
||||||
#if defined(__i386__)
|
#if defined(__i386__)
|
||||||
unsigned long args[5];
|
unsigned long args[5];
|
||||||
@ -1698,13 +1741,19 @@ int uv__recvmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen) {
|
|||||||
|
|
||||||
/* socketcall() raises EINVAL when SYS_RECVMMSG is not supported. */
|
/* socketcall() raises EINVAL when SYS_RECVMMSG is not supported. */
|
||||||
rc = syscall(/* __NR_socketcall */ 102, 19 /* SYS_RECVMMSG */, args);
|
rc = syscall(/* __NR_socketcall */ 102, 19 /* SYS_RECVMMSG */, args);
|
||||||
|
uv__recvmmsg_unpoison(mmsg, rc);
|
||||||
if (rc == -1)
|
if (rc == -1)
|
||||||
if (errno == EINVAL)
|
if (errno == EINVAL)
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
#elif defined(__NR_recvmmsg)
|
#elif defined(__NR_recvmmsg)
|
||||||
return syscall(__NR_recvmmsg, fd, mmsg, vlen, /* flags */ 0, /* timeout */ 0);
|
int rc;
|
||||||
|
|
||||||
|
rc = syscall(__NR_recvmmsg, fd, mmsg, vlen, /* flags */ 0, /* timeout */ 0);
|
||||||
|
uv__recvmmsg_unpoison(mmsg, rc);
|
||||||
|
|
||||||
|
return rc;
|
||||||
#else
|
#else
|
||||||
return errno = ENOSYS, -1;
|
return errno = ENOSYS, -1;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -357,7 +357,7 @@ int uv_pipe_chmod(uv_pipe_t* handle, int mode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* stat must be used as fstat has a bug on Darwin */
|
/* stat must be used as fstat has a bug on Darwin */
|
||||||
if (stat(name_buffer, &pipe_stat) == -1) {
|
if (uv__stat(name_buffer, &pipe_stat) == -1) {
|
||||||
uv__free(name_buffer);
|
uv__free(name_buffer);
|
||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -40,7 +40,7 @@ int uv__random_readpath(const char* path, void* buf, size_t buflen) {
|
|||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return fd;
|
return fd;
|
||||||
|
|
||||||
if (fstat(fd, &s)) {
|
if (uv__fstat(fd, &s)) {
|
||||||
uv__close(fd);
|
uv__close(fd);
|
||||||
return UV__ERR(errno);
|
return UV__ERR(errno);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -113,7 +113,7 @@ static int uv__tty_is_slave(const int fd) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Lookup stat structure behind the file descriptor. */
|
/* Lookup stat structure behind the file descriptor. */
|
||||||
if (fstat(fd, &sb) != 0)
|
if (uv__fstat(fd, &sb) != 0)
|
||||||
abort();
|
abort();
|
||||||
|
|
||||||
/* Assert character device. */
|
/* Assert character device. */
|
||||||
@ -365,7 +365,7 @@ uv_handle_type uv_guess_handle(uv_file file) {
|
|||||||
if (isatty(file))
|
if (isatty(file))
|
||||||
return UV_TTY;
|
return UV_TTY;
|
||||||
|
|
||||||
if (fstat(file, &s)) {
|
if (uv__fstat(file, &s)) {
|
||||||
#if defined(__PASE__)
|
#if defined(__PASE__)
|
||||||
/* On ibmi receiving RST from TCP instead of FIN immediately puts fd into
|
/* On ibmi receiving RST from TCP instead of FIN immediately puts fd into
|
||||||
* an error state. fstat will return EINVAL, getsockname will also return
|
* an error state. fstat will return EINVAL, getsockname will also return
|
||||||
|
|||||||
@ -344,6 +344,7 @@ long int process_output_size(process_info_t *p) {
|
|||||||
/* Size of the p->stdout_file */
|
/* Size of the p->stdout_file */
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
|
|
||||||
|
memset(&buf, 0, sizeof(buf));
|
||||||
int r = fstat(fileno(p->stdout_file), &buf);
|
int r = fstat(fileno(p->stdout_file), &buf);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
@ -1239,6 +1239,8 @@ static int test_sendfile(void (*setup)(int), uv_fs_cb cb, off_t expected_size) {
|
|||||||
ASSERT(r == 0);
|
ASSERT(r == 0);
|
||||||
uv_fs_req_cleanup(&close_req);
|
uv_fs_req_cleanup(&close_req);
|
||||||
|
|
||||||
|
memset(&s1, 0, sizeof(s1));
|
||||||
|
memset(&s2, 0, sizeof(s2));
|
||||||
ASSERT(0 == stat("test_file", &s1));
|
ASSERT(0 == stat("test_file", &s1));
|
||||||
ASSERT(0 == stat("test_file2", &s2));
|
ASSERT(0 == stat("test_file2", &s2));
|
||||||
ASSERT(s2.st_size == expected_size);
|
ASSERT(s2.st_size == expected_size);
|
||||||
@ -1413,6 +1415,7 @@ TEST_IMPL(fs_fstat) {
|
|||||||
uv_fs_req_cleanup(&req);
|
uv_fs_req_cleanup(&req);
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
|
memset(&t, 0, sizeof(t));
|
||||||
ASSERT(0 == fstat(file, &t));
|
ASSERT(0 == fstat(file, &t));
|
||||||
ASSERT(0 == uv_fs_fstat(NULL, &req, file, NULL));
|
ASSERT(0 == uv_fs_fstat(NULL, &req, file, NULL));
|
||||||
ASSERT(req.result == 0);
|
ASSERT(req.result == 0);
|
||||||
@ -3707,9 +3710,9 @@ static void test_fs_partial(int doread) {
|
|||||||
ctx.doread = doread;
|
ctx.doread = doread;
|
||||||
ctx.interval = 1000;
|
ctx.interval = 1000;
|
||||||
ctx.size = sizeof(test_buf) * iovcount;
|
ctx.size = sizeof(test_buf) * iovcount;
|
||||||
ctx.data = malloc(ctx.size);
|
ctx.data = calloc(ctx.size, 1);
|
||||||
ASSERT_NOT_NULL(ctx.data);
|
ASSERT_NOT_NULL(ctx.data);
|
||||||
buffer = malloc(ctx.size);
|
buffer = calloc(ctx.size, 1);
|
||||||
ASSERT_NOT_NULL(buffer);
|
ASSERT_NOT_NULL(buffer);
|
||||||
|
|
||||||
for (index = 0; index < iovcount; ++index)
|
for (index = 0; index < iovcount; ++index)
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#include "uv.h"
|
#include "uv.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
TEST_IMPL(pipe_set_chmod) {
|
TEST_IMPL(pipe_set_chmod) {
|
||||||
uv_pipe_t pipe_handle;
|
uv_pipe_t pipe_handle;
|
||||||
@ -48,7 +49,8 @@ TEST_IMPL(pipe_set_chmod) {
|
|||||||
}
|
}
|
||||||
ASSERT(r == 0);
|
ASSERT(r == 0);
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
stat(TEST_PIPENAME, &stat_buf);
|
memset(&stat_buf, 0, sizeof(stat_buf));
|
||||||
|
ASSERT_EQ(0, stat(TEST_PIPENAME, &stat_buf));
|
||||||
ASSERT(stat_buf.st_mode & S_IRUSR);
|
ASSERT(stat_buf.st_mode & S_IRUSR);
|
||||||
ASSERT(stat_buf.st_mode & S_IRGRP);
|
ASSERT(stat_buf.st_mode & S_IRGRP);
|
||||||
ASSERT(stat_buf.st_mode & S_IROTH);
|
ASSERT(stat_buf.st_mode & S_IROTH);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user