Changeset View
Changeset View
Standalone View
Standalone View
src/posix-io.c
Context not available. | |||||
/* Select on the list of fds. Returns: -1 = error, 0 = timeout or | /* Select on the list of fds. Returns: -1 = error, 0 = timeout or | ||||
nothing to select, > 0 = number of signaled fds. */ | nothing to select, > 0 = number of signaled fds. */ | ||||
int | #ifdef HAVE_POLL_H | ||||
_gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock) | static int | ||||
_gpgme_io_select_poll (struct io_select_fd_s *fds, size_t nfds, int nonblock) | |||||
{ | |||||
struct pollfd *poll_fds = NULL; | |||||
nfds_t poll_nfds; | |||||
/* Use a 1s timeout. */ | |||||
int timeout = 1000; | |||||
unsigned int i; | |||||
int any; | |||||
int count; | |||||
void *dbg_help = NULL; | |||||
TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_select", NULL, | |||||
"nfds=%zu, nonblock=%u", nfds, nonblock); | |||||
if (nonblock) | |||||
timeout = 0; | |||||
poll_fds = malloc (sizeof (*poll_fds)*nfds); | |||||
if (!poll_fds) | |||||
return -1; | |||||
poll_nfds = 0; | |||||
TRACE_SEQ (dbg_help, "poll on [ "); | |||||
any = 0; | |||||
for (i = 0; i < nfds; i++) | |||||
{ | |||||
if (fds[i].fd == -1) | |||||
continue; | |||||
if (fds[i].for_read || fds[i].for_write) | |||||
{ | |||||
poll_fds[poll_nfds].fd = fds[i].fd; | |||||
poll_fds[poll_nfds].events = 0; | |||||
poll_fds[poll_nfds].revents = 0; | |||||
if (fds[i].for_read) | |||||
{ | |||||
poll_fds[poll_nfds].events |= POLLIN; | |||||
TRACE_ADD1 (dbg_help, "r=%d ", fds[i].fd); | |||||
} | |||||
if (fds[i].for_write) | |||||
{ | |||||
poll_fds[poll_nfds].events |= POLLOUT; | |||||
TRACE_ADD1 (dbg_help, "w=%d ", fds[i].fd); | |||||
} | |||||
poll_nfds++; | |||||
any = 1; | |||||
} | |||||
fds[i].signaled = 0; | |||||
} | |||||
TRACE_END (dbg_help, "]"); | |||||
if (!any) | |||||
{ | |||||
free (poll_fds); | |||||
return TRACE_SYSRES (0); | |||||
} | |||||
do | |||||
count = poll (poll_fds, poll_nfds, timeout); | |||||
while (count < 0 && (errno == EINTR || errno == EAGAIN)); | |||||
if (count < 0) | |||||
{ | |||||
int save_errno = errno; | |||||
free (poll_fds); | |||||
errno = save_errno; | |||||
return TRACE_SYSRES (-1); | |||||
} | |||||
TRACE_SEQ (dbg_help, "poll OK [ "); | |||||
if (TRACE_ENABLED (dbg_help)) | |||||
{ | |||||
poll_nfds = 0; | |||||
for (i = 0; i < nfds; i++) | |||||
{ | |||||
if (fds[i].fd == -1) | |||||
continue; | |||||
if ((poll_fds[poll_nfds].revents & (POLLIN|POLLHUP))) | |||||
TRACE_ADD1 (dbg_help, "r=%d ", i); | |||||
if ((poll_fds[poll_nfds].revents & POLLOUT)) | |||||
TRACE_ADD1 (dbg_help, "w=%d ", i); | |||||
poll_nfds++; | |||||
} | |||||
TRACE_END (dbg_help, "]"); | |||||
} | |||||
poll_nfds = 0; | |||||
for (i = 0; i < nfds; i++) | |||||
{ | |||||
if (fds[i].fd == -1) | |||||
continue; | |||||
if (fds[i].for_read || fds[i].for_write) | |||||
{ | |||||
short events_to_be_checked = 0; | |||||
if (fds[i].for_read) | |||||
events_to_be_checked |= (POLLIN|POLLHUP); | |||||
if (fds[i].for_write) | |||||
events_to_be_checked |= POLLOUT; | |||||
if ((poll_fds[poll_nfds].revents & events_to_be_checked)) | |||||
fds[i].signaled = 1; | |||||
poll_nfds++; | |||||
} | |||||
} | |||||
free (poll_fds); | |||||
return TRACE_SYSRES (count); | |||||
} | |||||
#else | |||||
static int | |||||
_gpgme_io_select_select (struct io_select_fd_s *fds, size_t nfds, int nonblock) | |||||
{ | { | ||||
fd_set readfds; | fd_set readfds; | ||||
fd_set writefds; | fd_set writefds; | ||||
Context not available. | |||||
} | } | ||||
return TRACE_SYSRES (count); | return TRACE_SYSRES (count); | ||||
} | } | ||||
#endif | |||||
int | |||||
_gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock) | |||||
{ | |||||
#ifdef HAVE_POLL_H | |||||
return _gpgme_io_select_poll (fds, nfds, nonblock); | |||||
#else | |||||
return _gpgme_io_select_select (fds, nfds, nonblock); | |||||
#endif | |||||
} | |||||
␌ | ␌ | ||||
int | int | ||||
_gpgme_io_recvmsg (int fd, struct msghdr *msg, int flags) | _gpgme_io_recvmsg (int fd, struct msghdr *msg, int flags) | ||||
Context not available. |