diff options
author | Marco S Hyman <marc@cvs.openbsd.org> | 2003-02-05 05:51:52 +0000 |
---|---|---|
committer | Marco S Hyman <marc@cvs.openbsd.org> | 2003-02-05 05:51:52 +0000 |
commit | 412c41306c7c8f82b015d9607b44b9b90b64ab75 (patch) | |
tree | 381ec1e053f1a19922cef9b09cf32c6d05577ab2 /lib | |
parent | 5b5778d2d69324d5b2a0e6bac69cc839d27f707d (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.c | 7 | ||||
-rw-r--r-- | lib/libpthread/uthread/uthread_dup2.c | 7 | ||||
-rw-r--r-- | lib/libpthread/uthread/uthread_fd.c | 26 |
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); |