summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2008-10-02 23:27:25 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2008-10-02 23:27:25 +0000
commit573e1e861839c2b2ab25694a1e370ff3c4218b51 (patch)
treef6989c854afb9661d01ba79d358c6ec2652f953d
parentd645b11e9566a2476e5cf26691df729f1d298a79 (diff)
Fix PR #5942: preserve errno across fd flag updates, so that successful
calls to close(), closefrom(), and dup2() don't change it. ok tedu@, deraadt@, kurt@, millert@, art@, marco@ (miscommit: originally by guenther@)
-rw-r--r--lib/libpthread/uthread/uthread_fd.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/lib/libpthread/uthread/uthread_fd.c b/lib/libpthread/uthread/uthread_fd.c
index c214e20ab9d..4de7371b4b5 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.30 2007/05/18 19:28:50 kurt Exp $ */
+/* $OpenBSD: uthread_fd.c,v 1.31 2008/10/02 23:27:24 deraadt Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -106,6 +106,7 @@ _thread_fs_flags_replace(int fd, struct fs_flags *new_status_flags)
struct fs_flags *old_status_flags;
struct stat sb;
int flags;
+ int saved_errno;
if (entry->status_flags != new_status_flags) {
if (entry->status_flags != NULL) {
@@ -140,6 +141,7 @@ _thread_fs_flags_replace(int fd, struct fs_flags *new_status_flags)
* Also don't reset fd to blocking if we are replacing
* the status flags with a shared version.
*/
+ saved_errno = errno;
if (new_status_flags == NULL &&
(old_status_flags->flags & O_NONBLOCK) == 0 &&
(fd < 3 || (_thread_sys_fstat(fd, &sb) == 0 &&
@@ -151,6 +153,7 @@ _thread_fs_flags_replace(int fd, struct fs_flags *new_status_flags)
_thread_sys_fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
}
free(old_status_flags);
+ errno = saved_errno;
} else
_SPINUNLOCK(&old_status_flags->lock);
}