diff --git a/Pal/src/host/Linux-SGX/db_eventfd.c b/Pal/src/host/Linux-SGX/db_eventfd.c index e67c70e2..056e96a7 100644 --- a/Pal/src/host/Linux-SGX/db_eventfd.c +++ b/Pal/src/host/Linux-SGX/db_eventfd.c @@ -135,29 +135,36 @@ static int64_t eventfd_pal_write(PAL_HANDLE handle, uint64_t offset, uint64_t le /* invoked during poll operation on eventfd from LibOS. */ static int eventfd_pal_attrquerybyhdl(PAL_HANDLE handle, PAL_STREAM_ATTR* attr) { - if (handle->generic.fds[0] == PAL_IDX_POISON) + int ret; + + if (handle->eventfd.fd == PAL_IDX_POISON) return -PAL_ERROR_BADHANDLE; - attr->handle_type = PAL_GET_TYPE(handle); - - int efd = handle->eventfd.fd; - int flags = HANDLE_HDR(handle)->flags; - - struct pollfd pfd = {.fd = efd, .events = POLLIN, .revents = 0}; - int ret = ocall_poll(&pfd, 1, 0); + attr->handle_type = HANDLE_HDR(handle)->type; + attr->nonblocking = handle->eventfd.nonblocking; + attr->disconnected = HANDLE_HDR(handle)->flags & ERROR(0); + attr->writable = HANDLE_HDR(handle)->flags & WRITABLE(0); + /* get number of bytes available for reading */ + ret = ocall_fionread(handle->eventfd.fd); if (IS_ERR(ret)) return unix_to_pal_error(ERRNO(ret)); - attr->readable = (ret == 1 && pfd.revents == POLLIN); - attr->disconnected = flags & ERROR(0); - attr->nonblocking = handle->eventfd.nonblocking; + attr->pending_size = ret; + + /* query if there is data available for reading */ + struct pollfd pfd = {.fd = handle->eventfd.fd, .events = POLLIN, .revents = 0}; + ret = ocall_poll(&pfd, 1, 0); + if (IS_ERR(ret)) + return unix_to_pal_error(ERRNO(ret)); + + attr->readable = (ret == 1 && pfd.revents == POLLIN); /* For future use, so that Linux host kernel can send notifications to user-space apps. App * receives virtual FD from LibOS, but the Linux-host eventfd is memorized here, such that this * Linux-host eventfd can be retrieved (by LibOS) during app's ioctl(). */ attr->no_of_fds = 1; - attr->fds[0] = efd; + attr->fds[0] = handle->eventfd.fd; return 0; } diff --git a/Pal/src/host/Linux-SGX/db_pipes.c b/Pal/src/host/Linux-SGX/db_pipes.c index e83bbd5b..91cb66e0 100644 --- a/Pal/src/host/Linux-SGX/db_pipes.c +++ b/Pal/src/host/Linux-SGX/db_pipes.c @@ -307,37 +307,37 @@ static int pipe_delete(PAL_HANDLE handle, int access) { } static int pipe_attrquerybyhdl(PAL_HANDLE handle, PAL_STREAM_ATTR* attr) { + int ret; + if (handle->generic.fds[0] == PAL_IDX_POISON) return -PAL_ERROR_BADHANDLE; - attr->handle_type = PAL_GET_TYPE(handle); - - int read_fd = handle->generic.fds[0]; - int flags = HANDLE_HDR(handle)->flags; + attr->handle_type = HANDLE_HDR(handle)->type; + attr->nonblocking = IS_HANDLE_TYPE(handle, pipeprv) ? handle->pipeprv.nonblocking + : handle->pipe.nonblocking; + attr->disconnected = HANDLE_HDR(handle)->flags & ERROR(0); + attr->writable = PAL_FALSE; + /* get number of bytes available for reading (doesn't make sense for "listening" pipes) */ + attr->pending_size = 0; if (!IS_HANDLE_TYPE(handle, pipesrv)) { - int ret = ocall_fionread(read_fd); + ret = ocall_fionread(handle->generic.fds[0]); if (IS_ERR(ret)) return unix_to_pal_error(ERRNO(ret)); attr->pending_size = ret; - attr->writable = flags & (IS_HANDLE_TYPE(handle, pipeprv) ? WRITABLE(1) : WRITABLE(0)); - } else { - attr->pending_size = 0; - attr->writable = PAL_FALSE; + attr->writable = HANDLE_HDR(handle)->flags & (IS_HANDLE_TYPE(handle, pipeprv) + ? WRITABLE(1) : WRITABLE(0)); } - struct pollfd pfd = {.fd = read_fd, .events = POLLIN, .revents = 0}; - int ret = ocall_poll(&pfd, 1, 0); + /* query if there is data available for reading */ + struct pollfd pfd = {.fd = handle->generic.fds[0], .events = POLLIN, .revents = 0}; + ret = ocall_poll(&pfd, 1, 0); if (IS_ERR(ret)) return unix_to_pal_error(ERRNO(ret)); attr->readable = (ret == 1 && pfd.revents == POLLIN); - attr->disconnected = flags & ERROR(0); - attr->nonblocking = - IS_HANDLE_TYPE(handle, pipeprv) ? handle->pipeprv.nonblocking : handle->pipe.nonblocking; - return 0; } diff --git a/Pal/src/host/Linux-SGX/db_process.c b/Pal/src/host/Linux-SGX/db_process.c index b55f42be..5e97dc74 100644 --- a/Pal/src/host/Linux-SGX/db_process.c +++ b/Pal/src/host/Linux-SGX/db_process.c @@ -435,21 +435,32 @@ static int proc_delete (PAL_HANDLE handle, int access) return 0; } -static int proc_attrquerybyhdl (PAL_HANDLE handle, PAL_STREAM_ATTR * attr) -{ +static int proc_attrquerybyhdl(PAL_HANDLE handle, PAL_STREAM_ATTR* attr) { + int ret; + if (handle->process.stream == PAL_IDX_POISON) return -PAL_ERROR_BADHANDLE; - int ret = ocall_fionread(handle->process.stream); + attr->handle_type = HANDLE_HDR(handle)->type; + attr->nonblocking = handle->process.nonblocking; + attr->disconnected = HANDLE_HDR(handle)->flags & ERROR(0); + attr->writable = HANDLE_HDR(handle)->flags & WRITABLE(0); + + /* get number of bytes available for reading */ + ret = ocall_fionread(handle->process.stream); if (IS_ERR(ret)) return unix_to_pal_error(ERRNO(ret)); - memset(attr, 0, sizeof(PAL_STREAM_ATTR)); attr->pending_size = ret; - attr->disconnected = HANDLE_HDR(handle)->flags & ERROR(0); - attr->readable = (attr->pending_size > 0); - attr->writable = HANDLE_HDR(handle)->flags & WRITABLE(0); - attr->nonblocking = handle->process.nonblocking; + + /* query if there is data available for reading */ + struct pollfd pfd = {.fd = handle->process.stream, .events = POLLIN, .revents = 0}; + ret = ocall_poll(&pfd, 1, 0); + if (IS_ERR(ret)) + return unix_to_pal_error(ERRNO(ret)); + + attr->readable = (ret == 1 && pfd.revents == POLLIN); + return 0; } diff --git a/Pal/src/host/Linux-SGX/db_sockets.c b/Pal/src/host/Linux-SGX/db_sockets.c index 884ff9a5..38997670 100644 --- a/Pal/src/host/Linux-SGX/db_sockets.c +++ b/Pal/src/host/Linux-SGX/db_sockets.c @@ -789,14 +789,16 @@ static int socket_close(PAL_HANDLE handle) { } static int socket_attrquerybyhdl(PAL_HANDLE handle, PAL_STREAM_ATTR* attr) { + int ret; + if (handle->sock.fd == PAL_IDX_POISON) return -PAL_ERROR_BADHANDLE; attr->handle_type = HANDLE_HDR(handle)->type; - attr->disconnected = HANDLE_HDR(handle)->flags & ERROR(0); attr->nonblocking = handle->sock.nonblocking; + attr->disconnected = HANDLE_HDR(handle)->flags & ERROR(0); attr->writable = HANDLE_HDR(handle)->flags & WRITABLE(0); - attr->pending_size = 0; /* fill in later */ + attr->socket.linger = handle->sock.linger; attr->socket.receivebuf = handle->sock.receivebuf; attr->socket.sendbuf = handle->sock.sendbuf; @@ -806,20 +808,22 @@ static int socket_attrquerybyhdl(PAL_HANDLE handle, PAL_STREAM_ATTR* attr) { attr->socket.tcp_keepalive = handle->sock.tcp_keepalive; attr->socket.tcp_nodelay = handle->sock.tcp_nodelay; - int fd = handle->sock.fd, ret; - + /* get number of bytes available for reading (doesn't make sense for listening sockets) */ + attr->pending_size = 0; if (!IS_HANDLE_TYPE(handle, tcpsrv)) { - /* try use ioctl FIONEAD to get the size of socket */ - ret = ocall_fionread(fd); + ret = ocall_fionread(handle->sock.fd); if (IS_ERR(ret)) return unix_to_pal_error(ERRNO(ret)); + attr->pending_size = ret; } - struct pollfd pfd = {.fd = fd, .events = POLLIN, .revents = 0}; - ret = ocall_poll(&pfd, 1, 0); + /* query if there is data available for reading */ + struct pollfd pfd = {.fd = handle->sock.fd, .events = POLLIN, .revents = 0}; + ret = ocall_poll(&pfd, 1, 0); if (IS_ERR(ret)) return unix_to_pal_error(ERRNO(ret)); + attr->readable = (ret == 1 && pfd.revents == POLLIN); return 0; diff --git a/Pal/src/host/Linux/db_eventfd.c b/Pal/src/host/Linux/db_eventfd.c index ff5f6524..2006ce55 100644 --- a/Pal/src/host/Linux/db_eventfd.c +++ b/Pal/src/host/Linux/db_eventfd.c @@ -38,6 +38,10 @@ #include "pal_linux_error.h" #include "pal_security.h" +#ifndef FIONREAD +#define FIONREAD 0x541B +#endif + static inline int eventfd_type(int options) { int type = 0; if (options & PAL_OPTION_NONBLOCK) @@ -133,31 +137,39 @@ static int64_t eventfd_pal_write(PAL_HANDLE handle, uint64_t offset, uint64_t le return bytes; } -/* invoked during poll operation on eventfd from LibOS. */ static int eventfd_pal_attrquerybyhdl(PAL_HANDLE handle, PAL_STREAM_ATTR* attr) { - if (handle->generic.fds[0] == PAL_IDX_POISON) + int ret; + int val; + + if (handle->eventfd.fd == PAL_IDX_POISON) return -PAL_ERROR_BADHANDLE; - attr->handle_type = PAL_GET_TYPE(handle); - int efd = handle->eventfd.fd; - int flags = HANDLE_HDR(handle)->flags; - - struct pollfd pfd = {.fd = efd, .events = POLLIN, .revents = 0}; - struct timespec tp = {0, 0}; - int ret = INLINE_SYSCALL(ppoll, 5, &pfd, 1, &tp, NULL, 0); + attr->handle_type = HANDLE_HDR(handle)->type; + attr->nonblocking = handle->eventfd.nonblocking; + attr->disconnected = HANDLE_HDR(handle)->flags & ERROR(0); + attr->writable = HANDLE_HDR(handle)->flags & WRITABLE(0); + /* get number of bytes available for reading */ + ret = INLINE_SYSCALL(ioctl, 3, handle->eventfd.fd, FIONREAD, &val); if (IS_ERR(ret)) return unix_to_pal_error(ERRNO(ret)); - attr->readable = (ret == 1 && pfd.revents == POLLIN); - attr->disconnected = flags & ERROR(0); - attr->nonblocking = handle->eventfd.nonblocking; + attr->pending_size = val; + + /* query if there is data available for reading */ + struct pollfd pfd = {.fd = handle->eventfd.fd, .events = POLLIN, .revents = 0}; + struct timespec tp = {0, 0}; + ret = INLINE_SYSCALL(ppoll, 5, &pfd, 1, &tp, NULL, 0); + if (IS_ERR(ret)) + return unix_to_pal_error(ERRNO(ret)); + + attr->readable = (ret == 1 && pfd.revents == POLLIN); /* For future use, so that Linux host kernel can send notifications to user-space apps. App * receives virtual FD from LibOS, but the Linux-host eventfd is memorized here, such that this * Linux-host eventfd can be retrieved (by LibOS) during app's ioctl(). */ attr->no_of_fds = 1; - attr->fds[0] = efd; + attr->fds[0] = handle->eventfd.fd; return 0; } diff --git a/Pal/src/host/Linux/db_pipes.c b/Pal/src/host/Linux/db_pipes.c index 0542f08a..65ae2398 100644 --- a/Pal/src/host/Linux/db_pipes.c +++ b/Pal/src/host/Linux/db_pipes.c @@ -40,6 +40,10 @@ typedef __kernel_pid_t pid_t; #include #include +#ifndef FIONREAD +#define FIONREAD 0x541B +#endif + static int pipe_path(int pipeid, char* path, int len) { /* use abstract UNIX sockets for pipes */ memset(path, 0, len); @@ -336,39 +340,40 @@ static int pipe_delete(PAL_HANDLE handle, int access) { return 0; } -#ifndef FIONREAD -#define FIONREAD 0x541B -#endif - static int pipe_attrquerybyhdl(PAL_HANDLE handle, PAL_STREAM_ATTR* attr) { - int ret, val; + int ret; + int val; if (handle->generic.fds[0] == PAL_IDX_POISON) return -PAL_ERROR_BADHANDLE; - attr->handle_type = PAL_GET_TYPE(handle); + attr->handle_type = HANDLE_HDR(handle)->type; + attr->nonblocking = IS_HANDLE_TYPE(handle, pipeprv) ? handle->pipeprv.nonblocking + : handle->pipe.nonblocking; + attr->disconnected = HANDLE_HDR(handle)->flags & ERROR(0); + attr->writable = PAL_FALSE; - if (attr->handle_type != pal_type_pipesrv) { + /* get number of bytes available for reading (doesn't make sense for "listening" pipes) */ + attr->pending_size = 0; + if (!IS_HANDLE_TYPE(handle, pipesrv)) { ret = INLINE_SYSCALL(ioctl, 3, handle->generic.fds[0], FIONREAD, &val); - if (IS_ERR(ret)) { + if (IS_ERR(ret)) return unix_to_pal_error(ERRNO(ret)); - } + attr->pending_size = val; - attr->writable = HANDLE_HDR(handle)->flags & - (IS_HANDLE_TYPE(handle, pipeprv) ? WRITABLE(1) : WRITABLE(0)); - } else { - attr->pending_size = 0; - attr->writable = PAL_FALSE; + attr->writable = HANDLE_HDR(handle)->flags & (IS_HANDLE_TYPE(handle, pipeprv) + ? WRITABLE(1) : WRITABLE(0)); } + /* query if there is data available for reading */ struct pollfd pfd = {.fd = handle->generic.fds[0], .events = POLLIN, .revents = 0}; struct timespec tp = {0, 0}; - ret = INLINE_SYSCALL(ppoll, 5, &pfd, 1, &tp, NULL, 0); - attr->readable = (ret == 1 && pfd.revents == POLLIN); + ret = INLINE_SYSCALL(ppoll, 5, &pfd, 1, &tp, NULL, 0); + if (IS_ERR(ret)) + return unix_to_pal_error(ERRNO(ret)); + + attr->readable = (ret == 1 && pfd.revents == POLLIN); - attr->disconnected = HANDLE_HDR(handle)->flags & ERROR(0); - attr->nonblocking = - IS_HANDLE_TYPE(handle, pipeprv) ? handle->pipeprv.nonblocking : handle->pipe.nonblocking; return 0; } diff --git a/Pal/src/host/Linux/db_process.c b/Pal/src/host/Linux/db_process.c index 84511f91..42406e13 100644 --- a/Pal/src/host/Linux/db_process.c +++ b/Pal/src/host/Linux/db_process.c @@ -25,28 +25,33 @@ * at creation. */ -#include "pal_defs.h" -#include "pal_linux_defs.h" +#include "api.h" #include "pal.h" +#include "pal_debug.h" +#include "pal_defs.h" +#include "pal_error.h" #include "pal_internal.h" #include "pal_linux.h" -#include "pal_debug.h" -#include "pal_error.h" -#include "pal_security.h" +#include "pal_linux_defs.h" #include "pal_rtld.h" -#include "api.h" - -#include -#include +#include "pal_security.h" typedef __kernel_pid_t pid_t; -#include -#include #include +#include +#include +#include +#include +#include +#include #ifndef SEEK_SET # define SEEK_SET 0 #endif +#ifndef FIONREAD +# define FIONREAD 0x541B +#endif + static inline int create_process_handle (PAL_HANDLE * parent, PAL_HANDLE * child) { @@ -521,29 +526,34 @@ static int proc_delete (PAL_HANDLE handle, int access) return 0; } -#ifndef FIONREAD -# define FIONREAD 0x541B -#endif - -static int proc_attrquerybyhdl (PAL_HANDLE handle, PAL_STREAM_ATTR * attr) -{ - int ret, val; +static int proc_attrquerybyhdl(PAL_HANDLE handle, PAL_STREAM_ATTR* attr) { + int ret; + int val; if (handle->process.stream == PAL_IDX_POISON) return -PAL_ERROR_BADHANDLE; + attr->handle_type = HANDLE_HDR(handle)->type; + attr->nonblocking = handle->process.nonblocking; + attr->disconnected = HANDLE_HDR(handle)->flags & ERROR(0); + attr->writable = HANDLE_HDR(handle)->flags & WRITABLE(0); + + /* get number of bytes available for reading */ ret = INLINE_SYSCALL(ioctl, 3, handle->process.stream, FIONREAD, &val); if (IS_ERR(ret)) return unix_to_pal_error(ERRNO(ret)); - attr->handle_type = pal_type_process; - attr->nonblocking = handle->process.nonblocking; - attr->disconnected = HANDLE_HDR(handle)->flags & ERROR(0); - attr->readable = !!val; - attr->writable = HANDLE_HDR(handle)->flags & WRITABLE(0); - attr->runnable = PAL_FALSE; attr->pending_size = val; + /* query if there is data available for reading */ + struct pollfd pfd = {.fd = handle->process.stream, .events = POLLIN, .revents = 0}; + struct timespec tp = {0, 0}; + ret = INLINE_SYSCALL(ppoll, 5, &pfd, 1, &tp, NULL, 0); + if (IS_ERR(ret)) + return unix_to_pal_error(ERRNO(ret)); + + attr->readable = (ret == 1 && pfd.revents == POLLIN); + return 0; } diff --git a/Pal/src/host/Linux/db_sockets.c b/Pal/src/host/Linux/db_sockets.c index b3b9323c..4a9ab78f 100644 --- a/Pal/src/host/Linux/db_sockets.c +++ b/Pal/src/host/Linux/db_sockets.c @@ -58,6 +58,10 @@ typedef __kernel_pid_t pid_t; #define SOL_IPV6 41 #endif +#ifndef FIONREAD +#define FIONREAD 0x541B +#endif + /* 96 bytes is the minimal size of buffer to store a IPv4/IPv6 address */ #define PAL_SOCKADDR_SIZE 96 @@ -969,19 +973,17 @@ static int socket_close(PAL_HANDLE handle) { return 0; } -#ifndef FIONREAD -#define FIONREAD 0x541B -#endif - static int socket_attrquerybyhdl(PAL_HANDLE handle, PAL_STREAM_ATTR* attr) { + int ret; + if (handle->sock.fd == PAL_IDX_POISON) return -PAL_ERROR_BADHANDLE; attr->handle_type = HANDLE_HDR(handle)->type; - attr->disconnected = HANDLE_HDR(handle)->flags & ERROR(0); attr->nonblocking = handle->sock.nonblocking; + attr->disconnected = HANDLE_HDR(handle)->flags & ERROR(0); attr->writable = HANDLE_HDR(handle)->flags & WRITABLE(0); - attr->pending_size = 0; /* fill in later */ + attr->socket.linger = handle->sock.linger; attr->socket.receivebuf = handle->sock.receivebuf; attr->socket.sendbuf = handle->sock.sendbuf; @@ -991,20 +993,25 @@ static int socket_attrquerybyhdl(PAL_HANDLE handle, PAL_STREAM_ATTR* attr) { attr->socket.tcp_keepalive = handle->sock.tcp_keepalive; attr->socket.tcp_nodelay = handle->sock.tcp_nodelay; - int fd = handle->sock.fd, ret, val; - + /* get number of bytes available for reading (doesn't make sense for listening sockets) */ + attr->pending_size = 0; if (!IS_HANDLE_TYPE(handle, tcpsrv)) { - /* try use ioctl FIONEAD to get the size of socket */ - ret = INLINE_SYSCALL(ioctl, 3, fd, FIONREAD, &val); + int val; + ret = INLINE_SYSCALL(ioctl, 3, handle->sock.fd, FIONREAD, &val); if (IS_ERR(ret)) return unix_to_pal_error(ERRNO(ret)); + attr->pending_size = val; } - struct pollfd pfd = {.fd = fd, .events = POLLIN, .revents = 0}; + /* query if there is data available for reading */ + struct pollfd pfd = {.fd = handle->sock.fd, .events = POLLIN, .revents = 0}; struct timespec tp = {0, 0}; - ret = INLINE_SYSCALL(ppoll, 5, &pfd, 1, &tp, NULL, 0); - attr->readable = (ret == 1 && pfd.revents == POLLIN); + ret = INLINE_SYSCALL(ppoll, 5, &pfd, 1, &tp, NULL, 0); + if (IS_ERR(ret)) + return unix_to_pal_error(ERRNO(ret)); + + attr->readable = (ret == 1 && pfd.revents == POLLIN); return 0; }