1d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// found in the LICENSE file. 4d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 5d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// http://crbug.com/269623 6d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// http://openradar.appspot.com/14999594 7d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// 8d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// When the default version of close used on Mac OS X fails with EINTR, the 9d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// file descriptor is not in a deterministic state. It may have been closed, 10d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// or it may not have been. This makes it impossible to gracefully recover 11d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// from the error. If the close is retried after the FD has been closed, the 12d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// subsequent close can report EBADF, or worse, it can close an unrelated FD 13d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// opened by another thread. If the close is not retried after the FD has been 14d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// left open, the FD is leaked. Neither of these are good options. 15d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// 16d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Mac OS X provides an alternate version of close, close$NOCANCEL. This 17d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// version will never fail with EINTR before the FD is actually closed. With 18d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// this version, it is thus safe to call close without checking for EINTR (as 19d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// the HANDLE_EINTR macro does) and not risk leaking the FD. In fact, mixing 20d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// this verison of close with HANDLE_EINTR is hazardous. 21d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// 22d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// The $NOCANCEL variants of various system calls are activated by compiling 23d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// with __DARWIN_NON_CANCELABLE, which prevents them from being pthread 24d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// cancellation points. Rather than taking such a heavy-handed approach, this 25d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// file implements an alternative: to use the $NOCANCEL variant of close (thus 26d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// preventing it from being a pthread cancellation point) without affecting 27d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// any other system calls. 28d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// 29d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// This file operates by providing a close function with the non-$NOCANCEL 30d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// symbol name expected for the compilation environment as set by <unistd.h> 31d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// and <sys/cdefs.h> (the DARWIN_ALIAS_C macro). That function calls the 32d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// $NOCANCEL variant, which is resolved from libsyscall. By linking with this 33d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// version of close prior to the libsyscall version, close's implementation is 34d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// overridden. 35d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 36d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include <sys/cdefs.h> 37d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 38d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// If the non-cancelable variants of all system calls have already been 39d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// chosen, do nothing. 40d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#if !__DARWIN_NON_CANCELABLE 41d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 42d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)extern "C" { 43d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 44d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#if __DARWIN_UNIX03 && !__DARWIN_ONLY_UNIX_CONFORMANCE 45d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 46d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// When there's a choice between UNIX2003 and pre-UNIX2003 and UNIX2003 has 47d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// been chosen: 48d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#define close_interface close$UNIX2003 49d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#define close_implementation close$NOCANCEL$UNIX2003 50d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 51d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#elif !__DARWIN_UNIX03 && !__DARWIN_ONLY_UNIX_CONFORMANCE 52d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 53d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// When there's a choice between UNIX2003 and pre-UNIX2003 and pre-UNIX2003 54d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// has been chosen. There's no close$NOCANCEL symbol in this case, so use 55d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// close$NOCANCEL$UNIX2003 as the implementation. It does the same thing 56d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// that close$NOCANCEL would do. 57d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#define close_interface close 58d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#define close_implementation close$NOCANCEL$UNIX2003 59d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 60d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#else // __DARWIN_ONLY_UNIX_CONFORMANCE 61d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 62d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// When only UNIX2003 is supported: 63d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#define close_interface close 64d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#define close_implementation close$NOCANCEL 65d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 66d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#endif 67d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 68d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)int close_implementation(int fd); 69d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 70d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)int close_interface(int fd) { 71d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return close_implementation(fd); 72d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 73d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 74d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#undef close_interface 75d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#undef close_implementation 76d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 77d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} // extern "C" 78d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 79d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#endif // !__DARWIN_NON_CANCELABLE 80