mirror of
https://github.com/clearlinux/graphene.git
synced 2026-09-06 22:01:29 +00:00
[Pal] Clean up attrquerybyhdl() for process, socket, pipe, eventfd
Clean up and make uniform the attrquerybyhdl() callback for stream PAL handles: process, socket, pipe, and eventfd. This includes using ioctl(FIONREAD) to query the number of bytes available for reading and using ppoll() to query whether data is available.
This commit is contained in:
committed by
Michał Kowalczyk
parent
c99497e51b
commit
eb77265096
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -40,6 +40,10 @@ typedef __kernel_pid_t pid_t;
|
||||
#include <linux/un.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 <linux/sched.h>
|
||||
#include <linux/types.h>
|
||||
#include "pal_security.h"
|
||||
typedef __kernel_pid_t pid_t;
|
||||
#include <asm/fcntl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <asm/errno.h>
|
||||
#include <asm/fcntl.h>
|
||||
#include <asm/poll.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user