diff options
Diffstat (limited to 'lib/libkse/thread/thr_read.c')
-rw-r--r-- | lib/libkse/thread/thr_read.c | 37 |
1 files changed, 22 insertions, 15 deletions
diff --git a/lib/libkse/thread/thr_read.c b/lib/libkse/thread/thr_read.c index 9158844..504143d 100644 --- a/lib/libkse/thread/thr_read.c +++ b/lib/libkse/thread/thr_read.c @@ -42,22 +42,31 @@ ssize_t read(int fd, void *buf, size_t nbytes) { - 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_READ, NULL, __FILE__, __LINE__)) != 0) { - /* Cannot lock file descriptor. */ - } else { + int ret; + int status; + + /* Lock the file descriptor for read: */ + if ((ret = _thread_fd_lock(fd, FD_READ, NULL, + __FILE__, __LINE__)) == 0) { + /* Perform a non-blocking read syscall: */ while ((ret = _thread_sys_read(fd, buf, nbytes)) < 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_FDR_WAIT, __FILE__, __LINE__); - if (errno == EINTR) { + + /* Reset the interrupted operation flag: */ + _thread_run->interrupted = 0; + + _thread_kern_sched_state(PS_FDR_WAIT, + __FILE__, __LINE__); + + /* + * Check if the operation was + * interrupted by a signal + */ + if (_thread_run->interrupted) { ret = -1; break; } @@ -65,9 +74,7 @@ read(int fd, void *buf, size_t nbytes) break; } } - if (nonblock == 0) { - _thread_fd_unlock(fd, FD_READ); - } + _thread_fd_unlock(fd, FD_READ); } return (ret); } |