diff options
author | Kurt Miller <kurt@cvs.openbsd.org> | 2006-09-22 19:04:34 +0000 |
---|---|---|
committer | Kurt Miller <kurt@cvs.openbsd.org> | 2006-09-22 19:04:34 +0000 |
commit | 7b0347847c0d6eea5eea4d695761d24f1b151d53 (patch) | |
tree | 1f3f8ccccc135dfe4bbb20426cc5557f14403d53 /lib | |
parent | d18267fdcf69320a8929dd06de2610e29bbb2b75 (diff) |
Part 1 of file descriptor race and deadlock corrections.
File status flags should be shared for dup'ed file descriptors.
However fd_table_entry's should not be shared for dup'ed file
descriptors so they can be independently be closed without
interfering with dup'ed fd's.
- split out file status flags into its own structure
fs_flags to manage sharing of status flags between
dup'ed file descriptors.
- when duplicating a fd, initialize a new fd_table_entry
for the new fd, but share the status flags via status_flags.
- consolidate the code that sets the underlying system fd
to be non-blocking to a new function _thread_fs_flags_init()
- consolidate the code that sets the underlying system
fd back to blocking into a new function _thread_fs_flags_replace()
This change is needed as a prerequisite to the coming race
and deadlock corrections. okay marc@
Diffstat (limited to 'lib')
27 files changed, 305 insertions, 218 deletions
diff --git a/lib/libpthread/uthread/pthread_private.h b/lib/libpthread/uthread/pthread_private.h index 83d87db2292..35c927e31fa 100644 --- a/lib/libpthread/uthread/pthread_private.h +++ b/lib/libpthread/uthread/pthread_private.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pthread_private.h,v 1.55 2006/01/06 18:53:04 millert Exp $ */ +/* $OpenBSD: pthread_private.h,v 1.56 2006/09/22 19:04:33 kurt Exp $ */ /* * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>. * All rights reserved. @@ -497,6 +497,15 @@ enum pthread_state { */ /* + * File status flags struture - shared for dup'ed fd's + */ +struct fs_flags { + spinlock_t lock; + int flags; + int refcnt; +}; + +/* * File descriptor table structure. */ struct fd_table_entry { @@ -517,8 +526,7 @@ struct fd_table_entry { int w_lineno; /* Write lock src line no. */ int r_lockcount; /* Count for FILE read locks. */ int w_lockcount; /* Count for FILE write locks.*/ - int flags; /* Flags used in open. */ - int refcnt; /* how many fds use this entry*/ + struct fs_flags *status_flags; /* Shared file status flags. */ }; struct pthread_poll_data { @@ -1122,8 +1130,9 @@ void _thread_sig_init(void); void _thread_start(void); void _thread_start_sig_handler(void); void _thread_seterrno(pthread_t,int); +void _thread_fs_flags_replace(int, struct fs_flags *); void _thread_fd_init(void); -int _thread_fd_table_init(int); +int _thread_fd_table_init(int, struct fs_flags *); int _thread_fd_table_dup(int, int); void _thread_fd_table_remove(int); void _thread_fd_unlock_owned(pthread_t); diff --git a/lib/libpthread/uthread/uthread_accept.c b/lib/libpthread/uthread/uthread_accept.c index eb88a166753..a84312ba56f 100644 --- a/lib/libpthread/uthread/uthread_accept.c +++ b/lib/libpthread/uthread/uthread_accept.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uthread_accept.c,v 1.8 2003/12/23 19:31:05 brad Exp $ */ +/* $OpenBSD: uthread_accept.c,v 1.9 2006/09/22 19:04:33 kurt Exp $ */ /* * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> * All rights reserved. @@ -55,7 +55,7 @@ accept(int fd, struct sockaddr * name, socklen_t *namelen) /* Enter a loop to wait for a connection request: */ while ((ret = _thread_sys_accept(fd, name, namelen)) < 0) { /* Check if the socket is to block: */ - if ((_thread_fd_table[fd]->flags & O_NONBLOCK) == 0 && + if ((_thread_fd_table[fd]->status_flags->flags & O_NONBLOCK) == 0 && (errno == EWOULDBLOCK || errno == EAGAIN)) { /* Save the socket file descriptor: */ curthread->data.fd.fd = fd; @@ -93,12 +93,12 @@ accept(int fd, struct sockaddr * name, socklen_t *namelen) * as _thread_fd_table_init *may* have turned the flag on. */ if (ret != -1) { - if (_thread_fd_table_init(ret) != 0) { + if (_thread_fd_table_init(ret, NULL) != 0) { /* Quietly close the socket: */ _thread_sys_close(ret); ret = -1; - } else if ((_thread_fd_table[fd]->flags & O_NONBLOCK) == 0) - _thread_fd_table[ret]->flags &= ~O_NONBLOCK; + } else if ((_thread_fd_table[fd]->status_flags->flags & O_NONBLOCK) == 0) + _thread_fd_table[ret]->status_flags->flags &= ~O_NONBLOCK; } /* Unlock the file descriptor: */ diff --git a/lib/libpthread/uthread/uthread_close.c b/lib/libpthread/uthread/uthread_close.c index c850d50a464..fa45be87e68 100644 --- a/lib/libpthread/uthread/uthread_close.c +++ b/lib/libpthread/uthread/uthread_close.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uthread_close.c,v 1.11 2003/12/23 20:03:54 marc Exp $ */ +/* $OpenBSD: uthread_close.c,v 1.12 2006/09/22 19:04:33 kurt Exp $ */ /* * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> * All rights reserved. @@ -35,8 +35,6 @@ #include <errno.h> #include <stdlib.h> #include <unistd.h> -#include <fcntl.h> -#include <sys/stat.h> #ifdef _THREAD_SAFE #include <pthread.h> #include "pthread_private.h" @@ -44,9 +42,7 @@ int close(int fd) { - int flags; int ret; - struct stat sb; /* This is a cancelation point: */ _thread_enter_cancellation_point(); @@ -59,40 +55,6 @@ close(int fd) /* unknown to thread kernel, let system handle the close */ ret = _thread_sys_close(fd); else if ((ret = _FD_LOCK(fd, FD_RDWR, NULL)) == 0) { - /* - * Check if the file should be left as blocking. - * - * This is so that the file descriptors shared with a parent - * process aren't left set to non-blocking if the child - * closes them prior to exit. An example where this causes - * problems with /bin/sh is when a child closes stdin. - * - * Setting a file as blocking causes problems if a threaded - * parent accesses the file descriptor before the child exits. - * Once the threaded parent receives a SIGCHLD then it resets - * all of its files to non-blocking, and so it is then safe - * to access them. - * - * Pipes are not set to blocking when they are closed, as - * the parent and child will normally close the file - * descriptor of the end of the pipe that they are not - * using, which would then cause any reads to block - * indefinitely. - * - * Files that we cannot fstat are probably not regular - * so we don't bother with them. - */ - - if ((_thread_sys_fstat(fd, &sb) == 0) && - ((S_ISREG(sb.st_mode) || S_ISCHR(sb.st_mode)) && - (_thread_fd_table[fd]->flags & O_NONBLOCK) == 0)) - { - /* Get the current flags: */ - flags = _thread_sys_fcntl(fd, F_GETFL, NULL); - /* Clear the nonblocking file descriptor flag: */ - _thread_sys_fcntl(fd, F_SETFL, flags & ~O_NONBLOCK); - } - /* XXX: Assumes well behaved threads. */ /* XXX: Defer real close to avoid race condition */ _thread_fd_table_remove(fd); diff --git a/lib/libpthread/uthread/uthread_closefrom.c b/lib/libpthread/uthread/uthread_closefrom.c index 20d332f92a7..d80c0cff21d 100644 --- a/lib/libpthread/uthread/uthread_closefrom.c +++ b/lib/libpthread/uthread/uthread_closefrom.c @@ -1,39 +1,15 @@ -/* $OpenBSD: uthread_closefrom.c,v 1.1 2004/01/15 22:22:11 marc Exp $ */ +/* $OpenBSD: uthread_closefrom.c,v 1.2 2006/09/22 19:04:33 kurt Exp $ */ /* PUBLIC DOMAIN: No Rights Reserved. Marco S Hyman <marc@snafu.org> */ #include <sys/stat.h> #include <errno.h> -#include <fcntl.h> #include <pthread.h> #include <unistd.h> #include "pthread_private.h" -/* - * Reset the non-blocking flag if necessary. Remove the fd table entry - * for the given fd. - */ -static void -_close_flags(int fd) -{ - struct stat sb; - int flags; - - if (_FD_LOCK(fd, FD_RDWR, NULL) == 0) { - if ((_thread_sys_fstat(fd, &sb) == 0) && - ((S_ISREG(sb.st_mode) || S_ISCHR(sb.st_mode)) && - (_thread_fd_table[fd]->flags & O_NONBLOCK) == 0)) { - /* Get the current flags: */ - flags = _thread_sys_fcntl(fd, F_GETFL, NULL); - /* Clear the nonblocking file descriptor flag: */ - _thread_sys_fcntl(fd, F_SETFL, flags & ~O_NONBLOCK); - } - _thread_fd_table_remove(fd); - } -} - int closefrom(int fd) { @@ -60,7 +36,7 @@ closefrom(int fd) /* Reset flags and clean up the fd table for fds to close */ for (lock_fd = fd; lock_fd < _thread_dtablesize; lock_fd++) if (_thread_fd_table[lock_fd] != NULL) - _close_flags(lock_fd); + _thread_fd_table_remove(lock_fd); /* Now let the system do its thing */ ret = _thread_sys_closefrom(fd); @@ -68,6 +44,6 @@ closefrom(int fd) _thread_leave_cancellation_point(); - return ret; + return (ret); } diff --git a/lib/libpthread/uthread/uthread_connect.c b/lib/libpthread/uthread/uthread_connect.c index 85e344f2975..8987e1b56df 100644 --- a/lib/libpthread/uthread/uthread_connect.c +++ b/lib/libpthread/uthread/uthread_connect.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uthread_connect.c,v 1.5 2003/12/23 19:31:05 brad Exp $ */ +/* $OpenBSD: uthread_connect.c,v 1.6 2006/09/22 19:04:33 kurt Exp $ */ /* * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> * All rights reserved. @@ -52,7 +52,7 @@ connect(int fd, const struct sockaddr * name, socklen_t namelen) if ((ret = _FD_LOCK(fd, FD_RDWR, NULL)) == 0) { if ((ret = _thread_sys_connect(fd, name, namelen)) < 0) { - if (!(_thread_fd_table[fd]->flags & O_NONBLOCK) && + if (!(_thread_fd_table[fd]->status_flags->flags & O_NONBLOCK) && ((errno == EWOULDBLOCK) || (errno == EINPROGRESS) || (errno == EALREADY) || (errno == EAGAIN))) { curthread->data.fd.fd = fd; diff --git a/lib/libpthread/uthread/uthread_dup.c b/lib/libpthread/uthread/uthread_dup.c index 9ca6343043a..7b7d01c3069 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.5 2003/02/05 05:51:51 marc Exp $ */ +/* $OpenBSD: uthread_dup.c,v 1.6 2006/09/22 19:04:33 kurt Exp $ */ /* PUBLIC DOMAIN <marc@snafu.org> */ #include <unistd.h> @@ -14,11 +14,13 @@ dup(int fd) ret = _FD_LOCK(fd, FD_RDWR, NULL); if (ret == 0) { ret = _thread_sys_dup(fd); - if (ret != -1) - if (_thread_fd_table_dup(fd, ret) == -1) { - close(ret); + if (ret != -1) { + if (_thread_fd_table_init(ret, + _thread_fd_table[fd]->status_flags) == -1) { + _thread_sys_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 e0a1dc5d972..d8ef28d729d 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.7 2003/02/05 05:51:51 marc Exp $ */ +/* $OpenBSD: uthread_dup2.c,v 1.8 2006/09/22 19:04:33 kurt Exp $ */ /* PUBLIC DOMAIN <marc@snafu.org> */ #include <errno.h> @@ -11,17 +11,45 @@ int dup2(int fd, int newfd) { int ret; + int saved_errno; + int newfd_opened; if (newfd >= 0 && newfd < _thread_dtablesize && newfd != _thread_kern_pipe[0] && newfd != _thread_kern_pipe[1]) { ret = _FD_LOCK(fd, FD_RDWR, NULL); if (ret == 0) { - ret = _thread_sys_dup2(fd, newfd); - if (ret != -1) - if (_thread_fd_table_dup(fd, newfd) == -1) { - close(newfd); - ret = -1; + newfd_opened = _thread_fd_table[newfd] != NULL; + if (!newfd_opened || + (ret = _FD_LOCK(newfd, FD_RDWR, NULL)) == 0) { + /* + * If newfd was open then drop reference + * and reset flags if needed. + */ + if (newfd_opened) + _thread_fs_flags_replace(newfd, NULL); + ret = _thread_sys_dup2(fd, newfd); + if (ret != -1) + ret = _thread_fd_table_init(newfd, + _thread_fd_table[fd]->status_flags); + /* + * If the dup2 or the _thread_fd_table_init + * failed we've already removed the status + * flags, so finish closing newfd. Return + * the current errno in case the sys_close + * fails too. + */ + if (ret == -1) { + saved_errno = errno; + + if (newfd_opened) + _thread_fd_table_remove(newfd); + _thread_sys_close(newfd); + + errno = saved_errno ; + } else if (newfd_opened) { + _FD_UNLOCK(newfd, FD_RDWR); } + } _FD_UNLOCK(fd, FD_RDWR); } } else { diff --git a/lib/libpthread/uthread/uthread_execve.c b/lib/libpthread/uthread/uthread_execve.c index e5df58d97f3..7769d3e6685 100644 --- a/lib/libpthread/uthread/uthread_execve.c +++ b/lib/libpthread/uthread/uthread_execve.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uthread_execve.c,v 1.7 2003/10/22 00:24:14 brad Exp $ */ +/* $OpenBSD: uthread_execve.c,v 1.8 2006/09/22 19:04:33 kurt Exp $ */ /* * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> * All rights reserved. @@ -68,7 +68,7 @@ execve(const char *name, char *const * argv, char *const * envp) for (i = 0; i < _thread_dtablesize; i++) { /* Check if this file descriptor is in use: */ if (_thread_fd_table[i] != NULL && - !(_thread_fd_table[i]->flags & O_NONBLOCK)) { + !(_thread_fd_table[i]->status_flags->flags & O_NONBLOCK)) { /* Skip if the close-on-exec flag is set */ flags = _thread_sys_fcntl(i, F_GETFD, NULL); if ((flags & FD_CLOEXEC) != 0) diff --git a/lib/libpthread/uthread/uthread_exit.c b/lib/libpthread/uthread/uthread_exit.c index 91f41343583..94fc1699c37 100644 --- a/lib/libpthread/uthread/uthread_exit.c +++ b/lib/libpthread/uthread/uthread_exit.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uthread_exit.c,v 1.17 2002/11/07 02:56:20 marc Exp $ */ +/* $OpenBSD: uthread_exit.c,v 1.18 2006/09/22 19:04:33 kurt Exp $ */ /* * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> * All rights reserved. @@ -67,7 +67,7 @@ _exit(int status) for (i = 0; i < _thread_dtablesize; i++) { /* Check if this file descriptor is in use: */ if (_thread_fd_table[i] != NULL && - !(_thread_fd_table[i]->flags & O_NONBLOCK)) { + !(_thread_fd_table[i]->status_flags->flags & O_NONBLOCK)) { /* Get the current flags: */ flags = _thread_sys_fcntl(i, F_GETFL, NULL); /* Clear the nonblocking file descriptor flag: */ diff --git a/lib/libpthread/uthread/uthread_fcntl.c b/lib/libpthread/uthread/uthread_fcntl.c index 8955618efcd..0b772778ece 100644 --- a/lib/libpthread/uthread/uthread_fcntl.c +++ b/lib/libpthread/uthread/uthread_fcntl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uthread_fcntl.c,v 1.7 2003/02/04 22:14:27 marc Exp $ */ +/* $OpenBSD: uthread_fcntl.c,v 1.8 2006/09/22 19:04:33 kurt Exp $ */ /* * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> * All rights reserved. @@ -70,7 +70,8 @@ fcntl(int fd, int cmd,...) if ((ret = _thread_sys_fcntl(fd, cmd, oldfd)) < 0) { } /* Initialise the file descriptor table entry: */ - else if (_thread_fd_table_dup(fd, ret) != 0) { + else if (_thread_fd_table_init(ret, + _thread_fd_table[fd]->status_flags) == -1) { /* Quietly close the file: */ _thread_sys_close(ret); @@ -86,7 +87,7 @@ fcntl(int fd, int cmd,...) ret = _thread_sys_fcntl(fd, cmd, 0); break; case F_GETFL: - ret = _thread_fd_table[fd]->flags; + ret = _thread_fd_table[fd]->status_flags->flags; break; case F_SETFL: /* @@ -116,10 +117,10 @@ fcntl(int fd, int cmd,...) */ } else if (nonblock) /* A non-blocking descriptor: */ - _thread_fd_table[fd]->flags = flags | O_NONBLOCK; + _thread_fd_table[fd]->status_flags->flags = flags | O_NONBLOCK; else /* Save the flags: */ - _thread_fd_table[fd]->flags = flags & ~O_NONBLOCK; + _thread_fd_table[fd]->status_flags->flags = flags & ~O_NONBLOCK; break; default: /* Might want to make va_arg use a union */ diff --git a/lib/libpthread/uthread/uthread_fd.c b/lib/libpthread/uthread/uthread_fd.c index a32a09c07e9..9cfae2af508 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.22 2004/06/07 21:11:23 marc Exp $ */ +/* $OpenBSD: uthread_fd.c,v 1.23 2006/09/22 19:04:33 kurt Exp $ */ /* * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> * All rights reserved. @@ -37,6 +37,7 @@ #include <fcntl.h> #include <stdlib.h> #include <string.h> +#include <sys/stat.h> #ifdef _THREAD_SAFE #include <pthread.h> #include "pthread_private.h" @@ -47,6 +48,124 @@ static spinlock_t fd_table_lock = _SPINLOCK_INITIALIZER; /* * Build a new fd entry and return it. */ +static struct fs_flags * +_thread_fs_flags_entry(void) +{ + struct fs_flags *entry; + + entry = (struct fs_flags *) malloc(sizeof(struct fs_flags)); + if (entry != NULL) { + memset(entry, 0, sizeof *entry); + _SPINLOCK_INIT(&entry->lock); + } + return entry; +} + +/* + * Initialize a new status_flags entry and set system + * file descriptor non-blocking. + */ +static int +_thread_fs_flags_init(struct fs_flags *status_flags, int fd) +{ + int ret = 0; + int saved_errno; + + status_flags->flags = _thread_sys_fcntl(fd, F_GETFL, 0); + if (status_flags->flags == -1) + /* use the errno fcntl returned */ + ret = -1; + else { + /* + * Make the file descriptor non-blocking. + * This might fail if the device driver does + * not support non-blocking calls, or if the + * driver is naturally non-blocking. + */ + if ((status_flags->flags & O_NONBLOCK) == 0) { + saved_errno = errno; + _thread_sys_fcntl(fd, F_SETFL, + status_flags->flags | O_NONBLOCK); + errno = saved_errno; + } + } + + return (ret); +} + +/* + * If existing entry's status_flags don't match new one, + * then replace the current status flags with the new one. + * It is assumed the entry is locked with a FD_RDWR + * lock when this function is called. + */ +void +_thread_fs_flags_replace(int fd, struct fs_flags *new_status_flags) +{ + struct fd_table_entry *entry = _thread_fd_table[fd]; + struct fs_flags *old_status_flags; + struct stat sb; + int flags; + + if (entry->status_flags != new_status_flags) { + if (entry->status_flags != NULL) { + old_status_flags = entry->status_flags; + _SPINLOCK(&old_status_flags->lock); + old_status_flags->refcnt -= 1; + if (old_status_flags->refcnt <= 0) { + /* + * Check if the file should be left as blocking. + * + * This is so that the file descriptors shared with a parent + * process aren't left set to non-blocking if the child + * closes them prior to exit. An example where this causes + * problems with /bin/sh is when a child closes stdin. + * + * Setting a file as blocking causes problems if a threaded + * parent accesses the file descriptor before the child exits. + * Once the threaded parent receives a SIGCHLD then it resets + * all of its files to non-blocking, and so it is then safe + * to access them. + * + * Pipes are not set to blocking when they are closed, as + * the parent and child will normally close the file + * descriptor of the end of the pipe that they are not + * using, which would then cause any reads to block + * indefinitely. + * + * Files that we cannot fstat are probably not regular + * so we don't bother with them. + * + * Also don't reset fd to blocking if we are replacing + * the status flags with a shared version. + */ + if (new_status_flags != NULL && + (_thread_sys_fstat(fd, &sb) == 0) && + ((S_ISREG(sb.st_mode) || S_ISCHR(sb.st_mode)) && + (old_status_flags->flags & O_NONBLOCK) == 0)) + { + /* Get the current flags: */ + flags = _thread_sys_fcntl(fd, F_GETFL, NULL); + /* Clear the nonblocking file descriptor flag: */ + _thread_sys_fcntl(fd, F_SETFL, flags & ~O_NONBLOCK); + } + free(old_status_flags); + } else + _SPINUNLOCK(&old_status_flags->lock); + } + /* replace with new status flags */ + if (new_status_flags != NULL) { + _SPINLOCK(&new_status_flags->lock); + new_status_flags->refcnt += 1; + _SPINUNLOCK(&new_status_flags->lock); + } + entry->status_flags = new_status_flags; + } +} + +/* + * Build a new fd entry and return it. + */ static struct fd_table_entry * _thread_fd_entry(void) { @@ -75,14 +194,14 @@ _thread_fd_init(void) int fd2; int flag; int *flags; - struct fd_table_entry *entry; + struct fd_table_entry *entry1, *entry2; + struct fs_flags *status_flags; saved_errno = errno; flags = calloc(_thread_dtablesize, sizeof *flags); if (flags == NULL) PANIC("Cannot allocate memory for flags table"); - /* read the current file flags */ for (fd = 0; fd < _thread_dtablesize; fd += 1) flags[fd] = _thread_sys_fcntl(fd, F_GETFL, 0); @@ -100,27 +219,38 @@ _thread_fd_init(void) for (fd = 0; fd < _thread_dtablesize; fd += 1) { if (flags[fd] == -1) continue; - entry = _thread_fd_entry(); - if (entry != NULL) { - entry->flags = flags[fd]; + entry1 = _thread_fd_entry(); + status_flags = _thread_fs_flags_entry(); + if (entry1 != NULL && status_flags != NULL) { _thread_sys_fcntl(fd, F_SETFL, - entry->flags ^ O_SYNC); + flags[fd] ^ O_SYNC); for (fd2 = fd + 1; fd2 < _thread_dtablesize; fd2 += 1) { if (flags[fd2] == -1) continue; flag = _thread_sys_fcntl(fd2, F_GETFL, 0); if (flag != flags[fd2]) { - entry->refcnt += 1; - _thread_fd_table[fd2] = entry; + entry2 = _thread_fd_entry(); + if (entry2 != NULL) { + status_flags->refcnt += 1; + entry2->status_flags = status_flags; + _thread_fd_table[fd2] = entry2; + } else + PANIC("Cannot allocate memory for flags table"); flags[fd2] = -1; } } - if (entry->refcnt) { - entry->refcnt += 1; - _thread_fd_table[fd] = entry; + if (status_flags->refcnt) { + status_flags->refcnt += 1; + status_flags->flags = flags[fd]; + entry1->status_flags = status_flags; + _thread_fd_table[fd] = entry1; flags[fd] |= O_NONBLOCK; - } else - free(entry); + } else { + free(entry1); + free(status_flags); + } + } else { + PANIC("Cannot allocate memory for flags table"); } } _SPINUNLOCK(&fd_table_lock); @@ -146,11 +276,11 @@ _thread_fd_init(void) * calls. */ int -_thread_fd_table_init(int fd) +_thread_fd_table_init(int fd, struct fs_flags *status_flags) { int ret = 0; struct fd_table_entry *entry; - int saved_errno; + struct fs_flags *new_status_flags = NULL; if (fd < 0 || fd >= _thread_dtablesize) { /* @@ -158,32 +288,24 @@ _thread_fd_table_init(int fd) * descriptor error: */ errno = EBADF; - ret = -1; - } else if (_thread_fd_table[fd] == NULL) { + return (-1); + } + + if (_thread_fd_table[fd] == NULL) { /* First time for this fd, build an entry */ entry = _thread_fd_entry(); if (entry == NULL) { errno = ENOMEM; ret = -1; } else { - entry->flags = _thread_sys_fcntl(fd, F_GETFL, 0); - if (entry->flags == -1) - /* use the errno fcntl returned */ - ret = -1; - else { - /* - * Make the file descriptor non-blocking. - * This might fail if the device driver does - * not support non-blocking calls, or if the - * driver is naturally non-blocking. - */ - if ((entry->flags & O_NONBLOCK) == 0) { - saved_errno = errno; - _thread_sys_fcntl(fd, F_SETFL, - entry->flags | O_NONBLOCK); - errno = saved_errno; - } - + if (status_flags == NULL) { + new_status_flags = _thread_fs_flags_entry(); + if (new_status_flags == NULL) + ret = -1; + else + ret = _thread_fs_flags_init(new_status_flags, fd); + } + if (ret == 0) { /* Lock the file descriptor table: */ _SPINLOCK(&fd_table_lock); @@ -195,9 +317,19 @@ _thread_fd_table_init(int fd) * it has the potential to recurse. */ if (_thread_fd_table[fd] == NULL) { + if (status_flags != NULL) { + _SPINLOCK(&status_flags->lock); + status_flags->refcnt += 1; + _SPINUNLOCK(&status_flags->lock); + entry->status_flags = status_flags; + } else { + new_status_flags->refcnt = 1; + entry->status_flags = new_status_flags; + } /* This thread wins: */ - entry->refcnt += 1; _thread_fd_table[fd] = entry; + entry = NULL; + new_status_flags = NULL; } /* Unlock the file descriptor table: */ @@ -207,11 +339,18 @@ _thread_fd_table_init(int fd) /* * If there was an error in getting the flags for * the file or if another thread initialized the - * table entry throw this entry away. + * table entry throw this entry and new_status_flags + * away. */ - if (entry->refcnt == 0) + if (entry != NULL) free(entry); + + if (new_status_flags != NULL) + free(new_status_flags); } + } else { + if (status_flags != NULL) + _thread_fs_flags_replace(fd, status_flags); } /* Return the completion status: */ @@ -219,55 +358,18 @@ _thread_fd_table_init(int fd) } /* - * Dup from_fd -> to_fd. from_fd is assumed to be locked (which - * guarantees that _thread_fd_table[from_fd] exists). - */ -int -_thread_fd_table_dup(int from_fd, int to_fd) -{ - struct fd_table_entry *entry; - int ret; - - if (from_fd != to_fd) { - /* release any existing to_fd table entry */ - entry = _thread_fd_table[to_fd]; - if (entry != NULL) { - ret = _FD_LOCK(to_fd, FD_RDWR, NULL); - if (ret != -1) - _thread_fd_table_remove(to_fd); - } else - ret = 0; - - /* to_fd is a copy of from_fd */ - if (ret != -1) { - _SPINLOCK(&fd_table_lock); - _thread_fd_table[to_fd] = _thread_fd_table[from_fd]; - _thread_fd_table[to_fd]->refcnt += 1; - _SPINUNLOCK(&fd_table_lock); - } - } else - ret = 0; - - return (ret); -} - -/* - * Remove an fd entry from the table and free it if it's reference count - * goes to zero. The entry is assumed to be locked with a RDWR lock! It - * will be unlocked if it is not freed. + * Remove an fd entry from the table and replace its status flags + * with NULL. The entry is assummed to be locked with a RDWR lock. */ void _thread_fd_table_remove(int fd) { - struct fd_table_entry *entry; - _SPINLOCK(&fd_table_lock); - entry = _thread_fd_table[fd]; - if (--entry->refcnt == 0) - free(entry); - else - _FD_UNLOCK(fd, FD_RDWR); + + _thread_fs_flags_replace(fd, NULL); + free(_thread_fd_table[fd]); _thread_fd_table[fd] = NULL; + _SPINUNLOCK(&fd_table_lock); } @@ -284,7 +386,7 @@ _thread_fd_unlock_thread(struct pthread *thread, int fd, int lock_type) * Check that the file descriptor table is initialised for this * entry: */ - ret = _thread_fd_table_init(fd); + ret = _thread_fd_table_init(fd, NULL); if (ret == 0) { entry = _thread_fd_table[fd]; @@ -443,7 +545,7 @@ _thread_fd_lock(int fd, int lock_type, struct timespec * timeout) * Check that the file descriptor table is initialised for this * entry: */ - ret = _thread_fd_table_init(fd); + ret = _thread_fd_table_init(fd, NULL); if (ret == 0) { entry = _thread_fd_table[fd]; @@ -453,6 +555,7 @@ _thread_fd_lock(int fd, int lock_type, struct timespec * timeout) * thread's accesses: */ _SPINLOCK(&entry->lock); + /* Handle read locks */ if (lock_type == FD_READ || lock_type == FD_RDWR) { /* diff --git a/lib/libpthread/uthread/uthread_fork.c b/lib/libpthread/uthread/uthread_fork.c index 09a3279392a..3c51d6cf305 100644 --- a/lib/libpthread/uthread/uthread_fork.c +++ b/lib/libpthread/uthread/uthread_fork.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uthread_fork.c,v 1.12 2005/10/30 03:37:34 brad Exp $ */ +/* $OpenBSD: uthread_fork.c,v 1.13 2006/09/22 19:04:33 kurt Exp $ */ /* * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> * All rights reserved. @@ -185,6 +185,8 @@ fork(void) _thread_fd_table[i]->w_lineno = 0; _thread_fd_table[i]->r_lockcount = 0; _thread_fd_table[i]->w_lockcount = 0; + if (_thread_fd_table[i]->status_flags != NULL) + _SPINLOCK_INIT(&_thread_fd_table[i]->status_flags->lock); /* Initialise the read/write queues: */ TAILQ_INIT(&_thread_fd_table[i]->r_queue); diff --git a/lib/libpthread/uthread/uthread_ioctl.c b/lib/libpthread/uthread/uthread_ioctl.c index d7daa17196b..a8347dfb94e 100644 --- a/lib/libpthread/uthread/uthread_ioctl.c +++ b/lib/libpthread/uthread/uthread_ioctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uthread_ioctl.c,v 1.3 1999/11/25 07:01:37 d Exp $ */ +/* $OpenBSD: uthread_ioctl.c,v 1.4 2006/09/22 19:04:33 kurt Exp $ */ /* * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> * All rights reserved. @@ -58,8 +58,8 @@ ioctl(int fd, unsigned long request,...) * twiddling the flag based on the request */ op = va_arg(ap, int *); - _thread_fd_table[fd]->flags &= ~O_NONBLOCK; - _thread_fd_table[fd]->flags |= ((*op) ? O_NONBLOCK : 0); + _thread_fd_table[fd]->status_flags->flags &= ~O_NONBLOCK; + _thread_fd_table[fd]->status_flags->flags |= ((*op) ? O_NONBLOCK : 0); ret = 0; break; default: diff --git a/lib/libpthread/uthread/uthread_kqueue.c b/lib/libpthread/uthread/uthread_kqueue.c index 7ba41db1f48..638d9fe445a 100644 --- a/lib/libpthread/uthread/uthread_kqueue.c +++ b/lib/libpthread/uthread/uthread_kqueue.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uthread_kqueue.c,v 1.1 2003/10/22 00:25:42 brad Exp $ */ +/* $OpenBSD: uthread_kqueue.c,v 1.2 2006/09/22 19:04:33 kurt Exp $ */ /* * Copyright (c) 2003 Mark Peek <mp@freebsd.org> @@ -46,7 +46,7 @@ kqueue(void) /* Error creating socket. */ /* Initialise the entry in the file descriptor table: */ - } else if (_thread_fd_table_init(fd) != 0) { + } else if (_thread_fd_table_init(fd, NULL) != 0) { _thread_sys_close(fd); fd = -1; } diff --git a/lib/libpthread/uthread/uthread_open.c b/lib/libpthread/uthread/uthread_open.c index bf55d7d8bb9..aa2d3dd9b56 100644 --- a/lib/libpthread/uthread/uthread_open.c +++ b/lib/libpthread/uthread/uthread_open.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uthread_open.c,v 1.6 2000/01/06 07:20:10 d Exp $ */ +/* $OpenBSD: uthread_open.c,v 1.7 2006/09/22 19:04:33 kurt Exp $ */ /* * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> * All rights reserved. @@ -63,7 +63,7 @@ open(const char *path, int flags,...) if ((fd = _thread_sys_open(path, flags, mode)) < 0) { } /* Initialise the file descriptor table entry: */ - else if (_thread_fd_table_init(fd) != 0) { + else if (_thread_fd_table_init(fd, NULL) != 0) { /* Quietly close the file: */ _thread_sys_close(fd); diff --git a/lib/libpthread/uthread/uthread_pipe.c b/lib/libpthread/uthread/uthread_pipe.c index 6288ab82cbc..ca798183769 100644 --- a/lib/libpthread/uthread/uthread_pipe.c +++ b/lib/libpthread/uthread/uthread_pipe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uthread_pipe.c,v 1.3 1999/11/25 07:01:41 d Exp $ */ +/* $OpenBSD: uthread_pipe.c,v 1.4 2006/09/22 19:04:33 kurt Exp $ */ /* * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> * All rights reserved. @@ -43,8 +43,8 @@ pipe(int fds[2]) { int ret; if ((ret = _thread_sys_pipe(fds)) >= 0) { - if (_thread_fd_table_init(fds[0]) != 0 || - _thread_fd_table_init(fds[1]) != 0) { + if (_thread_fd_table_init(fds[0], NULL) != 0 || + _thread_fd_table_init(fds[1], NULL) != 0) { _thread_sys_close(fds[0]); _thread_sys_close(fds[1]); ret = -1; diff --git a/lib/libpthread/uthread/uthread_read.c b/lib/libpthread/uthread/uthread_read.c index b491ea99116..8455c97d2f5 100644 --- a/lib/libpthread/uthread/uthread_read.c +++ b/lib/libpthread/uthread/uthread_read.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uthread_read.c,v 1.7 2001/08/21 19:24:53 fgsch Exp $ */ +/* $OpenBSD: uthread_read.c,v 1.8 2006/09/22 19:04:33 kurt Exp $ */ /* * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> * All rights reserved. @@ -59,7 +59,7 @@ read(int fd, void *buf, size_t nbytes) /* Lock the file descriptor for read: */ else if ((ret = _FD_LOCK(fd, FD_READ, NULL)) == 0) { /* Get the read/write mode type: */ - type = _thread_fd_table[fd]->flags & O_ACCMODE; + type = _thread_fd_table[fd]->status_flags->flags & O_ACCMODE; /* Check if the file is not open for read: */ if (type != O_RDONLY && type != O_RDWR) { @@ -70,7 +70,7 @@ read(int fd, void *buf, size_t nbytes) /* Perform a non-blocking read syscall: */ else while ((ret = _thread_sys_read(fd, buf, nbytes)) < 0) { - if ((_thread_fd_table[fd]->flags & O_NONBLOCK) == 0 && + if ((_thread_fd_table[fd]->status_flags->flags & O_NONBLOCK) == 0 && (errno == EWOULDBLOCK || errno == EAGAIN)) { curthread->data.fd.fd = fd; _thread_kern_set_timeout(NULL); diff --git a/lib/libpthread/uthread/uthread_readv.c b/lib/libpthread/uthread/uthread_readv.c index f87fa652c38..a83002fb5c0 100644 --- a/lib/libpthread/uthread/uthread_readv.c +++ b/lib/libpthread/uthread/uthread_readv.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uthread_readv.c,v 1.7 2004/11/30 00:14:51 pat Exp $ */ +/* $OpenBSD: uthread_readv.c,v 1.8 2006/09/22 19:04:33 kurt Exp $ */ /* * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> * All rights reserved. @@ -55,7 +55,7 @@ readv(int fd, const struct iovec * iov, int iovcnt) /* Lock the file descriptor for read: */ if ((ret = _FD_LOCK(fd, FD_READ, NULL)) == 0) { /* Get the read/write mode type: */ - type = _thread_fd_table[fd]->flags & O_ACCMODE; + type = _thread_fd_table[fd]->status_flags->flags & O_ACCMODE; /* Check if the file is not open for read: */ if (type != O_RDONLY && type != O_RDWR) { @@ -68,7 +68,7 @@ readv(int fd, const struct iovec * iov, int iovcnt) /* Perform a non-blocking readv syscall: */ while ((ret = _thread_sys_readv(fd, iov, iovcnt)) < 0) { - if ((_thread_fd_table[fd]->flags & O_NONBLOCK) == 0 && + if ((_thread_fd_table[fd]->status_flags->flags & O_NONBLOCK) == 0 && (errno == EWOULDBLOCK || errno == EAGAIN)) { curthread->data.fd.fd = fd; _thread_kern_set_timeout(NULL); diff --git a/lib/libpthread/uthread/uthread_recvfrom.c b/lib/libpthread/uthread/uthread_recvfrom.c index 5817832a43c..0c693de57a1 100644 --- a/lib/libpthread/uthread/uthread_recvfrom.c +++ b/lib/libpthread/uthread/uthread_recvfrom.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uthread_recvfrom.c,v 1.6 2003/12/23 19:31:05 brad Exp $ */ +/* $OpenBSD: uthread_recvfrom.c,v 1.7 2006/09/22 19:04:33 kurt Exp $ */ /* * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> * All rights reserved. @@ -51,7 +51,8 @@ recvfrom(int fd, void *buf, size_t len, int flags, struct sockaddr * from, sockl if ((ret = _FD_LOCK(fd, FD_READ, NULL)) == 0) { while ((ret = _thread_sys_recvfrom(fd, buf, len, flags, from, from_len)) < 0) { - if (!(_thread_fd_table[fd]->flags & O_NONBLOCK) && ((errno == EWOULDBLOCK) || (errno == EAGAIN))) { + if (!(_thread_fd_table[fd]->status_flags->flags & O_NONBLOCK) && + ((errno == EWOULDBLOCK) || (errno == EAGAIN))) { curthread->data.fd.fd = fd; /* Set the timeout: */ diff --git a/lib/libpthread/uthread/uthread_recvmsg.c b/lib/libpthread/uthread/uthread_recvmsg.c index 6c1f9668c5e..5e8f13bd6dc 100644 --- a/lib/libpthread/uthread/uthread_recvmsg.c +++ b/lib/libpthread/uthread/uthread_recvmsg.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uthread_recvmsg.c,v 1.5 2003/12/23 19:31:05 brad Exp $ */ +/* $OpenBSD: uthread_recvmsg.c,v 1.6 2006/09/22 19:04:33 kurt Exp $ */ /* * Copyright (c) 1998 John Birrell <jb@cimlogic.com.au> * All rights reserved. @@ -51,7 +51,8 @@ recvmsg(int fd, struct msghdr *msg, int flags) if ((ret = _FD_LOCK(fd, FD_READ, NULL)) == 0) { while ((ret = _thread_sys_recvmsg(fd, msg, flags)) < 0) { - if (!(_thread_fd_table[fd]->flags & O_NONBLOCK) && ((errno == EWOULDBLOCK) || (errno == EAGAIN))) { + if (!(_thread_fd_table[fd]->status_flags->flags & O_NONBLOCK) && + ((errno == EWOULDBLOCK) || (errno == EAGAIN))) { curthread->data.fd.fd = fd; /* Set the timeout: */ diff --git a/lib/libpthread/uthread/uthread_sendmsg.c b/lib/libpthread/uthread/uthread_sendmsg.c index 5910e7b04cc..7cfb714606a 100644 --- a/lib/libpthread/uthread/uthread_sendmsg.c +++ b/lib/libpthread/uthread/uthread_sendmsg.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uthread_sendmsg.c,v 1.5 2003/12/23 19:31:05 brad Exp $ */ +/* $OpenBSD: uthread_sendmsg.c,v 1.6 2006/09/22 19:04:33 kurt Exp $ */ /* * Copyright (c) 1998 John Birrell <jb@cimlogic.com.au> * All rights reserved. @@ -51,7 +51,8 @@ sendmsg(int fd, const struct msghdr *msg, int flags) if ((ret = _FD_LOCK(fd, FD_WRITE, NULL)) == 0) { while ((ret = _thread_sys_sendmsg(fd, msg, flags)) < 0) { - if (!(_thread_fd_table[fd]->flags & O_NONBLOCK) && ((errno == EWOULDBLOCK) || (errno == EAGAIN))) { + if (!(_thread_fd_table[fd]->status_flags->flags & O_NONBLOCK) && + ((errno == EWOULDBLOCK) || (errno == EAGAIN))) { curthread->data.fd.fd = fd; /* Set the timeout: */ diff --git a/lib/libpthread/uthread/uthread_sendto.c b/lib/libpthread/uthread/uthread_sendto.c index c2ad04b0e2a..5b342315da3 100644 --- a/lib/libpthread/uthread/uthread_sendto.c +++ b/lib/libpthread/uthread/uthread_sendto.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uthread_sendto.c,v 1.6 2003/12/23 19:31:05 brad Exp $ */ +/* $OpenBSD: uthread_sendto.c,v 1.7 2006/09/22 19:04:33 kurt Exp $ */ /* * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> * All rights reserved. @@ -51,7 +51,8 @@ sendto(int fd, const void *msg, size_t len, int flags, const struct sockaddr * t if ((ret = _FD_LOCK(fd, FD_WRITE, NULL)) == 0) { while ((ret = _thread_sys_sendto(fd, msg, len, flags, to, to_len)) < 0) { - if (!(_thread_fd_table[fd]->flags & O_NONBLOCK) && ((errno == EWOULDBLOCK) || (errno == EAGAIN))) { + if (!(_thread_fd_table[fd]->status_flags->flags & O_NONBLOCK) && + ((errno == EWOULDBLOCK) || (errno == EAGAIN))) { curthread->data.fd.fd = fd; /* Set the timeout: */ diff --git a/lib/libpthread/uthread/uthread_sig.c b/lib/libpthread/uthread/uthread_sig.c index a7cf1eb9fc4..7f4d9dd082c 100644 --- a/lib/libpthread/uthread/uthread_sig.c +++ b/lib/libpthread/uthread/uthread_sig.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uthread_sig.c,v 1.20 2003/04/30 17:54:17 marc Exp $ */ +/* $OpenBSD: uthread_sig.c,v 1.21 2006/09/22 19:04:33 kurt Exp $ */ /* * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> * All rights reserved. @@ -187,7 +187,7 @@ _thread_sig_handle(int sig, struct sigcontext * scp) for (i = 0; i < _thread_dtablesize; i++) if (_thread_fd_table[i] != NULL) _thread_sys_fcntl(i, F_SETFL, - _thread_fd_table[i]->flags | + _thread_fd_table[i]->status_flags->flags | O_NONBLOCK); } diff --git a/lib/libpthread/uthread/uthread_socket.c b/lib/libpthread/uthread/uthread_socket.c index b4a96b8185a..3cecc3b57da 100644 --- a/lib/libpthread/uthread/uthread_socket.c +++ b/lib/libpthread/uthread/uthread_socket.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uthread_socket.c,v 1.3 1999/11/25 07:01:46 d Exp $ */ +/* $OpenBSD: uthread_socket.c,v 1.4 2006/09/22 19:04:33 kurt Exp $ */ /* * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> * All rights reserved. @@ -50,7 +50,7 @@ socket(int af, int type, int protocol) /* Error creating socket. */ /* Initialise the entry in the file descriptor table: */ - } else if (_thread_fd_table_init(fd) != 0) { + } else if (_thread_fd_table_init(fd, NULL) != 0) { _thread_sys_close(fd); fd = -1; } diff --git a/lib/libpthread/uthread/uthread_socketpair.c b/lib/libpthread/uthread/uthread_socketpair.c index 5ccdf6ee602..bd824bb867d 100644 --- a/lib/libpthread/uthread/uthread_socketpair.c +++ b/lib/libpthread/uthread/uthread_socketpair.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uthread_socketpair.c,v 1.4 2000/01/06 07:21:35 d Exp $ */ +/* $OpenBSD: uthread_socketpair.c,v 1.5 2006/09/22 19:04:33 kurt Exp $ */ /* * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> * All rights reserved. @@ -46,8 +46,8 @@ socketpair(int af, int type, int protocol, int pair[2]) { int ret; if (!((ret = _thread_sys_socketpair(af, type, protocol, pair)) < 0)) - if (_thread_fd_table_init(pair[0]) != 0 || - _thread_fd_table_init(pair[1]) != 0) { + if (_thread_fd_table_init(pair[0], NULL) != 0 || + _thread_fd_table_init(pair[1], NULL) != 0) { _thread_sys_close(pair[0]); _thread_sys_close(pair[1]); ret = -1; diff --git a/lib/libpthread/uthread/uthread_write.c b/lib/libpthread/uthread/uthread_write.c index 393b9da65c7..71581d05387 100644 --- a/lib/libpthread/uthread/uthread_write.c +++ b/lib/libpthread/uthread/uthread_write.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uthread_write.c,v 1.10 2003/12/22 00:33:42 brad Exp $ */ +/* $OpenBSD: uthread_write.c,v 1.11 2006/09/22 19:04:33 kurt Exp $ */ /* * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> * All rights reserved. @@ -62,7 +62,7 @@ write(int fd, const void *buf, size_t nbytes) /* Lock the file descriptor for write: */ else if ((ret = _FD_LOCK(fd, FD_WRITE, NULL)) == 0) { /* Get the read/write mode type: */ - type = _thread_fd_table[fd]->flags & O_ACCMODE; + type = _thread_fd_table[fd]->status_flags->flags & O_ACCMODE; /* Check if the file is not open for write: */ if (type != O_WRONLY && type != O_RDWR) { @@ -73,7 +73,7 @@ write(int fd, const void *buf, size_t nbytes) else { /* Check if file operations are to block */ - blocking = ((_thread_fd_table[fd]->flags & O_NONBLOCK) == 0); + blocking = ((_thread_fd_table[fd]->status_flags->flags & O_NONBLOCK) == 0); /* * Loop while no error occurs and until the expected number diff --git a/lib/libpthread/uthread/uthread_writev.c b/lib/libpthread/uthread/uthread_writev.c index 020868ab58f..cf7733f6290 100644 --- a/lib/libpthread/uthread/uthread_writev.c +++ b/lib/libpthread/uthread/uthread_writev.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uthread_writev.c,v 1.10 2004/12/12 21:56:07 brad Exp $ */ +/* $OpenBSD: uthread_writev.c,v 1.11 2006/09/22 19:04:33 kurt Exp $ */ /* * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> * All rights reserved. @@ -79,7 +79,7 @@ writev(int fd, const struct iovec * iov, int iovcnt) /* Lock the file descriptor for write: */ if ((ret = _FD_LOCK(fd, FD_WRITE, NULL)) == 0) { /* Get the read/write mode type: */ - type = _thread_fd_table[fd]->flags & O_ACCMODE; + type = _thread_fd_table[fd]->status_flags->flags & O_ACCMODE; /* Check if the file is not open for write: */ if (type != O_WRONLY && type != O_RDWR) { @@ -93,7 +93,7 @@ writev(int fd, const struct iovec * iov, int iovcnt) } /* Check if file operations are to block */ - blocking = ((_thread_fd_table[fd]->flags & O_NONBLOCK) == 0); + blocking = ((_thread_fd_table[fd]->status_flags->flags & O_NONBLOCK) == 0); /* * Loop while no error occurs and until the expected number |