summaryrefslogtreecommitdiffstats
path: root/lib/libpthread/thread/thr_writev.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libpthread/thread/thr_writev.c')
-rw-r--r--lib/libpthread/thread/thr_writev.c37
1 files changed, 22 insertions, 15 deletions
diff --git a/lib/libpthread/thread/thr_writev.c b/lib/libpthread/thread/thr_writev.c
index f40e611..2a3c0c8 100644
--- a/lib/libpthread/thread/thr_writev.c
+++ b/lib/libpthread/thread/thr_writev.c
@@ -42,22 +42,31 @@
ssize_t
writev(int fd, const struct iovec * iov, int iovcnt)
{
- int nonblock;
- int ret;
- int status;
- if (fd < 0 || fd > _thread_dtablesize || _thread_fd_table[fd] == NULL) {
- _thread_seterrno(_thread_run, EBADF);
- ret = -1;
- } else if ((nonblock = _thread_fd_table[fd]->flags & O_NONBLOCK) == 0 && (ret = _thread_fd_lock(fd, FD_RDWR, NULL, __FILE__, __LINE__)) != 0) {
- /* Cannot lock file descriptor. */
- } else {
+ int ret;
+ int status;
+
+ /* Lock the file descriptor for read and write: */
+ if ((ret = _thread_fd_lock(fd, FD_RDWR, NULL,
+ __FILE__, __LINE__)) == 0) {
+ /* Perform a non-blocking writev syscall: */
while ((ret = _thread_sys_writev(fd, iov, iovcnt)) < 0) {
- if (nonblock == 0 && (errno == EWOULDBLOCK || errno == EAGAIN)) {
+ if (_thread_fd_table[fd]->flags & O_NONBLOCK == 0 &&
+ (errno == EWOULDBLOCK || errno == EAGAIN)) {
_thread_kern_sig_block(&status);
_thread_run->data.fd.fd = fd;
_thread_kern_set_timeout(NULL);
- _thread_kern_sched_state(PS_FDW_WAIT, __FILE__, __LINE__);
- if (errno == EINTR) {
+
+ /* Reset the interrupted operation flag: */
+ _thread_run->interrupted = 0;
+
+ _thread_kern_sched_state(PS_FDW_WAIT,
+ __FILE__, __LINE__);
+
+ /*
+ * Check if the operation was
+ * interrupted by a signal
+ */
+ if (_thread_run->interrupted) {
ret = -1;
break;
}
@@ -65,9 +74,7 @@ writev(int fd, const struct iovec * iov, int iovcnt)
break;
}
}
- if (nonblock == 0) {
- _thread_fd_unlock(fd, FD_RDWR);
- }
+ _thread_fd_unlock(fd, FD_RDWR);
}
return (ret);
}
OpenPOWER on IntegriCloud