13391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes/* 23391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes * Copyright (C) 2015 The Android Open Source Project 33391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes * All rights reserved. 43391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes * 53391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes * Redistribution and use in source and binary forms, with or without 63391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes * modification, are permitted provided that the following conditions 73391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes * are met: 83391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes * * Redistributions of source code must retain the above copyright 93391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes * notice, this list of conditions and the following disclaimer. 103391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes * * Redistributions in binary form must reproduce the above copyright 113391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes * notice, this list of conditions and the following disclaimer in 123391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes * the documentation and/or other materials provided with the 133391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes * distribution. 143391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes * 153391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 163391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 173391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 183391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 193391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 203391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 213391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 223391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 233391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 243391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 253391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 263391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes * SUCH DAMAGE. 273391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes */ 283391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes 293391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes#include <errno.h> 303391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes#include <unistd.h> 313391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes 323391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughesextern "C" int ___close(int); 333391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes 343391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughesint close(int fd) { 353391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes int rc = ___close(fd); 363391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes if (rc == -1 && errno == EINTR) { 373391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes // POSIX says that if close returns with EINTR, the fd must not be closed. 383391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes // Linus disagrees: http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html 393391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes // The future POSIX solution is posix_close (http://austingroupbugs.net/view.php?id=529), 403391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes // with the state after EINTR being undefined, and EINPROGRESS for the case where close 413391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes // was interrupted by a signal but the file descriptor was actually closed. 423391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes // My concern with that future behavior is that it breaks existing code that assumes 433391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes // that close only returns -1 if it failed. Unlike other system calls, I have real 443391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes // difficulty even imagining a caller that would need to know that close was interrupted 453391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes // but succeeded. So returning EINTR is wrong (because Linux always closes) and EINPROGRESS 463391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes // is harmful because callers need to be rewritten to understand that EINPROGRESS isn't 473391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes // actually a failure, but will be reported as one. 483391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes 493391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes // We don't restore errno because that would incur a cost (the TLS read) for every caller. 503391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes // Since callers don't know ahead of time whether close will legitimately fail, they need 513391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes // to have stashed the old errno value anyway if they plan on using it afterwards, so 523391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes // us clobbering errno here doesn't change anything in that respect. 533391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes return 0; 543391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes } 553391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes return rc; 563391a9ff139d57fe4f8a2ff2d81a5ddc230a6208Elliott Hughes} 57