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