thr_close.c revision 17706
1122394Sharti/* 2122394Sharti * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>. 3122394Sharti * All rights reserved. 4122394Sharti * 5122394Sharti * Redistribution and use in source and binary forms, with or without 6122394Sharti * modification, are permitted provided that the following conditions 7310903Sngie * are met: 8133211Sharti * 1. Redistributions of source code must retain the above copyright 9133211Sharti * notice, this list of conditions and the following disclaimer. 10133211Sharti * 2. Redistributions in binary form must reproduce the above copyright 11133211Sharti * notice, this list of conditions and the following disclaimer in the 12133211Sharti * documentation and/or other materials provided with the distribution. 13122394Sharti * 3. All advertising materials mentioning features or use of this software 14122394Sharti * must display the following acknowledgement: 15122394Sharti * This product includes software developed by John Birrell. 16310903Sngie * 4. Neither the name of the author nor the names of any co-contributors 17133211Sharti * may be used to endorse or promote products derived from this software 18133211Sharti * without specific prior written permission. 19133211Sharti * 20133211Sharti * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND 21133211Sharti * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22133211Sharti * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23133211Sharti * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24133211Sharti * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25133211Sharti * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26133211Sharti * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27133211Sharti * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28122394Sharti * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29156066Sharti * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30122394Sharti * SUCH DAMAGE. 31122394Sharti * 32122394Sharti */ 33122394Sharti#include <stdlib.h> 34122394Sharti#include <unistd.h> 35122394Sharti#include <fcntl.h> 36122394Sharti#include <sys/stat.h> 37122394Sharti#ifdef _THREAD_SAFE 38122394Sharti#include <pthread.h> 39122394Sharti#include "pthread_private.h" 40122394Sharti 41122394Shartiint 42122394Sharticlose(int fd) 43122394Sharti{ 44122394Sharti int flags; 45122394Sharti int ret; 46122394Sharti int status; 47122394Sharti struct stat sb; 48122394Sharti 49122394Sharti /* Lock the file descriptor while the file is closed: */ 50122394Sharti if ((ret = _thread_fd_lock(fd, FD_RDWR, NULL, __FILE__, __LINE__)) == 0) { 51122394Sharti /* Block signals: */ 52122394Sharti _thread_kern_sig_block(&status); 53122394Sharti 54122394Sharti /* Get file descriptor status. */ 55122394Sharti fstat(fd, &sb); 56122394Sharti 57122394Sharti /* 58122394Sharti * Check if the file should be left as blocking. 59122394Sharti * 60122394Sharti * This is so that the file descriptors shared with a parent 61146525Sharti * process aren't left set to non-blocking if the child 62122394Sharti * closes them prior to exit. An example where this causes 63122394Sharti * problems with /bin/sh is when a child closes stdin. 64122394Sharti * 65122394Sharti * Setting a file as blocking causes problems if a threaded 66122394Sharti * parent accesses the file descriptor before the child exits. 67122394Sharti * Once the threaded parent receives a SIGCHLD then it resets 68146525Sharti * all of its files to non-blocking, and so it is then safe 69122394Sharti * to access them. 70122394Sharti * 71122394Sharti * Pipes are not set to blocking when they are closed, as 72122394Sharti * the parent and child will normally close the file 73122394Sharti * descriptor of the end of the pipe that they are not 74122394Sharti * using, which would then cause any reads to block 75122394Sharti * indefinitely. 76122394Sharti */ 77122394Sharti if ((S_ISREG(sb.st_mode) || S_ISCHR(sb.st_mode)) && (_thread_fd_table[fd]->flags & O_NONBLOCK) == 0) { 78122394Sharti /* Get the current flags: */ 79142810Sharti flags = _thread_sys_fcntl(fd, F_GETFL, NULL); 80142810Sharti /* Clear the nonblocking file descriptor flag: */ 81142810Sharti _thread_sys_fcntl(fd, F_SETFL, flags & ~O_NONBLOCK); 82155602Sharti } 83338311Seugen 84338311Seugen /* Close the file descriptor: */ 85338311Seugen ret = _thread_sys_close(fd); 86155602Sharti 87155602Sharti /* Free the file descriptor table entry: */ 88122394Sharti free(_thread_fd_table[fd]); 89122394Sharti _thread_fd_table[fd] = NULL; 90122394Sharti 91122394Sharti /* Unblock signals again: */ 92122394Sharti _thread_kern_sig_unblock(status); 93122394Sharti } 94122394Sharti return (ret); 95122394Sharti} 96122394Sharti#endif 97122394Sharti