diff options
author | Marco S Hyman <marc@cvs.openbsd.org> | 2004-01-15 22:22:13 +0000 |
---|---|---|
committer | Marco S Hyman <marc@cvs.openbsd.org> | 2004-01-15 22:22:13 +0000 |
commit | 053c1bae4e7785db7f205860de316381899fada2 (patch) | |
tree | 297b9019cb6df35f5ebc6d34e4b10aaabe47bde6 /lib/libpthread/uthread | |
parent | 913491a406dd07fee22f53938d13b879dda90dbc (diff) |
threaded version of closefrom
pthread_stackseg_np added. Minor bump for these changes occurred
a day or so ago and will not be bumped again
Diffstat (limited to 'lib/libpthread/uthread')
-rw-r--r-- | lib/libpthread/uthread/Makefile.inc | 4 | ||||
-rw-r--r-- | lib/libpthread/uthread/pthread_private.h | 3 | ||||
-rw-r--r-- | lib/libpthread/uthread/uthread_closefrom.c | 73 | ||||
-rw-r--r-- | lib/libpthread/uthread/uthread_init.c | 3 | ||||
-rw-r--r-- | lib/libpthread/uthread/uthread_stackseg_np.c | 63 |
5 files changed, 143 insertions, 3 deletions
diff --git a/lib/libpthread/uthread/Makefile.inc b/lib/libpthread/uthread/Makefile.inc index 81553971e20..b502529afd9 100644 --- a/lib/libpthread/uthread/Makefile.inc +++ b/lib/libpthread/uthread/Makefile.inc @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile.inc,v 1.16 2003/12/23 22:37:03 brad Exp $ +# $OpenBSD: Makefile.inc,v 1.17 2004/01/15 22:22:11 marc Exp $ # $FreeBSD: Makefile.inc,v 1.19 1999/08/28 00:03:19 peter Exp $ # uthread sources @@ -30,6 +30,7 @@ SRCS+= \ uthread_cancel.c \ uthread_clean.c \ uthread_close.c \ + uthread_closefrom.c \ uthread_concurrency.c \ uthread_cond.c \ uthread_condattr_destroy.c \ @@ -119,6 +120,7 @@ SRCS+= \ uthread_spec.c \ uthread_spinlock.c \ uthread_stack.c \ + uthread_stackseg_np.c \ uthread_suspend_np.c \ uthread_switch_np.c \ uthread_vfork.c \ diff --git a/lib/libpthread/uthread/pthread_private.h b/lib/libpthread/uthread/pthread_private.h index 00001a67fed..42ad837b4ee 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.50 2003/12/31 22:15:28 brad Exp $ */ +/* $OpenBSD: pthread_private.h,v 1.51 2004/01/15 22:22:11 marc Exp $ */ /* * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>. * All rights reserved. @@ -1243,6 +1243,7 @@ void _thread_sys_setbuffer(FILE *, char *, int); #ifdef _UNISTD_H_ char *_thread_sys_ttyname(int); int _thread_sys_close(int); +int _thread_sys_closefrom(int); int _thread_sys_dup(int); int _thread_sys_dup2(int, int); int _thread_sys_exect(const char *, char * const *, char * const *); diff --git a/lib/libpthread/uthread/uthread_closefrom.c b/lib/libpthread/uthread/uthread_closefrom.c new file mode 100644 index 00000000000..20d332f92a7 --- /dev/null +++ b/lib/libpthread/uthread/uthread_closefrom.c @@ -0,0 +1,73 @@ +/* $OpenBSD: uthread_closefrom.c,v 1.1 2004/01/15 22:22:11 marc 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) +{ + int ret; + int safe_fd; + int lock_fd; + + _thread_enter_cancellation_point(); + + if (fd < 0 || fd >= _thread_dtablesize) { + errno = EBADF; + ret = -1; + } else { + safe_fd = _thread_kern_pipe[0] > _thread_kern_pipe[1] ? + _thread_kern_pipe[0] : _thread_kern_pipe[1]; + + /* + * close individual files until we get past the pipe + * fds. Attempting to close a pipe fd is a no-op. + */ + for (safe_fd++; fd < safe_fd; fd++) + close(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); + + /* Now let the system do its thing */ + ret = _thread_sys_closefrom(fd); + } + + _thread_leave_cancellation_point(); + + return ret; + +} diff --git a/lib/libpthread/uthread/uthread_init.c b/lib/libpthread/uthread/uthread_init.c index bb5bc1f34a4..6a1833039e2 100644 --- a/lib/libpthread/uthread/uthread_init.c +++ b/lib/libpthread/uthread/uthread_init.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uthread_init.c,v 1.30 2003/10/22 00:25:42 brad Exp $ */ +/* $OpenBSD: uthread_init.c,v 1.31 2004/01/15 22:22:12 marc Exp $ */ /* * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> * All rights reserved. @@ -80,6 +80,7 @@ static void *references[] = { &accept, &bind, &close, + &closefrom, &connect, &dup, &dup2, diff --git a/lib/libpthread/uthread/uthread_stackseg_np.c b/lib/libpthread/uthread/uthread_stackseg_np.c new file mode 100644 index 00000000000..8ad09f971d7 --- /dev/null +++ b/lib/libpthread/uthread/uthread_stackseg_np.c @@ -0,0 +1,63 @@ +/* $OpenBSD: uthread_stackseg_np.c,v 1.1 2004/01/15 22:22:12 marc Exp $ */ + +/* PUBLIC DOMAIN: No Rights Reserved. Marco S Hyman <marc@snafu.org> */ + +#include <sys/types.h> +#include <sys/lock.h> +#include <sys/queue.h> +#include <uvm/uvm_pmap.h> +#include <machine/pmap.h> +#include <machine/param.h> +#include <machine/vmparam.h> + +#include <errno.h> +#include <pthread.h> +#include <pthread_np.h> +#include <unistd.h> + +#include "pthread_private.h" + +/* + * Return stack info from the current thread. Based upon the solaris + * thr_stksegment function. + */ + +int +pthread_stackseg_np(stack_t *sinfo) +{ + struct pthread *thread = pthread_self(); + char *base; + size_t pgsz; + int ret; + + if (thread->stack) { + base = thread->stack->base; +#if !defined(MACHINE_STACK_GROWS_UP) + base += thread->stack->size; +#endif + sinfo->ss_sp = base; + sinfo->ss_size = thread->stack->size; + sinfo->ss_flags = 0; + ret = 0; + } else if (thread == _thread_initial) { + pgsz = sysconf(_SC_PAGESIZE); + if (pgsz == (size_t)-1) + ret = EAGAIN; + else { +#if defined(MACHINE_STACK_GROWS_UP) + base = (caddr_t) USRSTACK; +#else + base = (caddr_t) ((USRSTACK - DFLSSIZ) & ~(pgsz - 1)); + base += DFLSSIZ; +#endif + sinfo->ss_sp = base; + sinfo->ss_size = DFLSSIZ; + sinfo->ss_flags = 0; + ret = 0; + } + + } else + ret = EAGAIN; + + return ret; +} |