aboutsummaryrefslogtreecommitdiff
path: root/lib/libc_r
diff options
context:
space:
mode:
authorJohn Birrell <jb@FreeBSD.org>1998-06-10 22:24:12 +0000
committerJohn Birrell <jb@FreeBSD.org>1998-06-10 22:24:12 +0000
commit3c165ef7b73f0e1f94c9e6b9517072aa0101d14b (patch)
treec0437da7f6b623df24700c2ac21df7ae5f02772c /lib/libc_r
parent32f5d4d843497a8072f2b107d5c9b0e9e82051f2 (diff)
downloadsrc-3c165ef7b73f0e1f94c9e6b9517072aa0101d14b.tar.gz
src-3c165ef7b73f0e1f94c9e6b9517072aa0101d14b.zip
When doing a F_SETFL, read the flags back so that the ones stored
in the file descriptor table are exactly what the kernel knows subject to the O_NONBLOCK flag being requested by the user.
Notes
Notes: svn path=/head/; revision=36875
Diffstat (limited to 'lib/libc_r')
-rw-r--r--lib/libc_r/uthread/uthread_fcntl.c34
1 files changed, 31 insertions, 3 deletions
diff --git a/lib/libc_r/uthread/uthread_fcntl.c b/lib/libc_r/uthread/uthread_fcntl.c
index 556bd1fa51af..eecda60d8ae6 100644
--- a/lib/libc_r/uthread/uthread_fcntl.c
+++ b/lib/libc_r/uthread/uthread_fcntl.c
@@ -41,6 +41,7 @@ int
fcntl(int fd, int cmd,...)
{
int flags = 0;
+ int nonblock;
int oldfd;
int ret;
int status;
@@ -90,10 +91,37 @@ fcntl(int fd, int cmd,...)
ret = _thread_fd_table[fd]->flags;
break;
case F_SETFL:
+ /*
+ * Get the file descriptor flags passed by the
+ * caller:
+ */
flags = va_arg(ap, int);
- if ((ret = _thread_sys_fcntl(fd, cmd, flags | O_NONBLOCK)) == 0) {
- _thread_fd_table[fd]->flags = flags;
- }
+
+ /*
+ * Check if the user wants a non-blocking file
+ * descriptor:
+ */
+ nonblock = flags & O_NONBLOCK;
+
+ /* Set the file descriptor flags: */
+ if ((ret = _thread_sys_fcntl(fd, cmd, flags | O_NONBLOCK)) != 0) {
+
+ /* Get the flags so that we behave like the kernel: */
+ } else if ((flags = _thread_sys_fcntl(fd,
+ F_GETFL, 0)) == -1) {
+ /* Error getting flags: */
+ ret = -1;
+
+ /*
+ * Check if the file descriptor is non-blocking
+ * with respect to the user:
+ */
+ } else if (nonblock)
+ /* A non-blocking descriptor: */
+ _thread_fd_table[fd]->flags = flags | O_NONBLOCK;
+ else
+ /* Save the flags: */
+ _thread_fd_table[fd]->flags = flags & ~O_NONBLOCK;
break;
default:
/* Might want to make va_arg use a union */