summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMarco S Hyman <marc@cvs.openbsd.org>2003-02-05 05:51:52 +0000
committerMarco S Hyman <marc@cvs.openbsd.org>2003-02-05 05:51:52 +0000
commit412c41306c7c8f82b015d9607b44b9b90b64ab75 (patch)
tree381ec1e053f1a19922cef9b09cf32c6d05577ab2 /lib
parent5b5778d2d69324d5b2a0e6bac69cc839d27f707d (diff)
thread fd handling, part 2. Don't mung file flags until forced
to notice that the file exists. This fixes a problem where an application may think a file was in non-block mode because the threads kernel played with the flags. Also fix a stupid error introduced in the last commit -- the threaded version of dup and dup2 were foobared. Bad marc.
Diffstat (limited to 'lib')
-rw-r--r--lib/libpthread/uthread/uthread_dup.c7
-rw-r--r--lib/libpthread/uthread/uthread_dup2.c7
-rw-r--r--lib/libpthread/uthread/uthread_fd.c26
3 files changed, 25 insertions, 15 deletions
diff --git a/lib/libpthread/uthread/uthread_dup.c b/lib/libpthread/uthread/uthread_dup.c
index ad1adc3081d..9ca6343043a 100644
--- a/lib/libpthread/uthread/uthread_dup.c
+++ b/lib/libpthread/uthread/uthread_dup.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_dup.c,v 1.4 2003/02/04 22:14:27 marc Exp $ */
+/* $OpenBSD: uthread_dup.c,v 1.5 2003/02/05 05:51:51 marc Exp $ */
/* PUBLIC DOMAIN <marc@snafu.org> */
#include <unistd.h>
@@ -15,7 +15,10 @@ dup(int fd)
if (ret == 0) {
ret = _thread_sys_dup(fd);
if (ret != -1)
- ret = _thread_fd_table_dup(fd, ret);
+ if (_thread_fd_table_dup(fd, ret) == -1) {
+ close(ret);
+ ret = -1;
+ }
_FD_UNLOCK(fd, FD_RDWR);
}
return (ret);
diff --git a/lib/libpthread/uthread/uthread_dup2.c b/lib/libpthread/uthread/uthread_dup2.c
index 61b172b3fc3..e0a1dc5d972 100644
--- a/lib/libpthread/uthread/uthread_dup2.c
+++ b/lib/libpthread/uthread/uthread_dup2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_dup2.c,v 1.6 2003/02/04 22:14:27 marc Exp $ */
+/* $OpenBSD: uthread_dup2.c,v 1.7 2003/02/05 05:51:51 marc Exp $ */
/* PUBLIC DOMAIN <marc@snafu.org> */
#include <errno.h>
@@ -18,7 +18,10 @@ dup2(int fd, int newfd)
if (ret == 0) {
ret = _thread_sys_dup2(fd, newfd);
if (ret != -1)
- ret = _thread_fd_table_dup(fd, newfd);
+ if (_thread_fd_table_dup(fd, newfd) == -1) {
+ close(newfd);
+ ret = -1;
+ }
_FD_UNLOCK(fd, FD_RDWR);
}
} else {
diff --git a/lib/libpthread/uthread/uthread_fd.c b/lib/libpthread/uthread/uthread_fd.c
index f583fe04067..4517112459f 100644
--- a/lib/libpthread/uthread/uthread_fd.c
+++ b/lib/libpthread/uthread/uthread_fd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_fd.c,v 1.17 2003/02/04 22:14:27 marc Exp $ */
+/* $OpenBSD: uthread_fd.c,v 1.18 2003/02/05 05:51:51 marc Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -88,11 +88,11 @@ _thread_fd_init(void)
flags[fd] = _thread_sys_fcntl(fd, F_GETFL, 0);
/*
- * Now toggle the non-block flags and see what other fd's
+ * Now toggle the sync flags and see what other fd's
* change. Those are the dup-ed fd's. Dup-ed fd's are
* added to the table, all others are NOT added to the
* table. They MUST NOT be added as the fds may belong
- * to dlopen and dlclose doesn't go through the thread code
+ * to dlopen. As dlclose doesn't go through the thread code
* so the entries would never be cleaned.
*/
@@ -104,7 +104,7 @@ _thread_fd_init(void)
if (entry != NULL) {
entry->flags = flags[fd];
_thread_sys_fcntl(fd, F_SETFL,
- entry->flags ^ O_NONBLOCK);
+ entry->flags ^ O_SYNC);
for (fd2 = fd + 1; fd2 < _thread_dtablesize; fd2 += 1) {
if (flags[fd2] == -1)
continue;
@@ -118,18 +118,20 @@ _thread_fd_init(void)
if (entry->refcnt) {
entry->refcnt += 1;
_thread_fd_table[fd] = entry;
+ flags[fd] |= O_NONBLOCK;
} else
free(entry);
}
}
_SPINUNLOCK(&fd_table_lock);
- /* lastly, set all files to non-blocking, ignoring errors for
- those files/devices that don't support such a mode. */
+ /* lastly, restore the file flags. Flags for files that we
+ know to be duped have been modified so set the non-blocking'
+ flag. Other files will be set to non-blocking when the
+ thread code is forced to take notice of the file. */
for (fd = 0; fd < _thread_dtablesize; fd += 1)
if (flags[fd] != -1)
- _thread_sys_fcntl(fd, F_SETFL,
- flags[fd] | O_NONBLOCK);
+ _thread_sys_fcntl(fd, F_SETFL, flags[fd]);
free(flags);
errno = saved_errno;
@@ -175,10 +177,12 @@ _thread_fd_table_init(int fd)
* not support non-blocking calls, or if the
* driver is naturally non-blocking.
*/
- saved_errno = errno;
- _thread_sys_fcntl(fd, F_SETFL,
+ if ((entry->flags & O_NONBLOCK) == 0) {
+ saved_errno = errno;
+ _thread_sys_fcntl(fd, F_SETFL,
entry->flags | O_NONBLOCK);
- errno = saved_errno;
+ errno = saved_errno;
+ }
/* Lock the file descriptor table: */
_SPINLOCK(&fd_table_lock);