thr_fcntl.c revision 13546
113546Sjulian/*
213546Sjulian * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
313546Sjulian * All rights reserved.
413546Sjulian *
513546Sjulian * Redistribution and use in source and binary forms, with or without
613546Sjulian * modification, are permitted provided that the following conditions
713546Sjulian * are met:
813546Sjulian * 1. Redistributions of source code must retain the above copyright
913546Sjulian *    notice, this list of conditions and the following disclaimer.
1013546Sjulian * 2. Redistributions in binary form must reproduce the above copyright
1113546Sjulian *    notice, this list of conditions and the following disclaimer in the
1213546Sjulian *    documentation and/or other materials provided with the distribution.
1313546Sjulian * 3. All advertising materials mentioning features or use of this software
1413546Sjulian *    must display the following acknowledgement:
1513546Sjulian *	This product includes software developed by John Birrell.
1613546Sjulian * 4. Neither the name of the author nor the names of any co-contributors
1713546Sjulian *    may be used to endorse or promote products derived from this software
1813546Sjulian *    without specific prior written permission.
1913546Sjulian *
2013546Sjulian * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
2113546Sjulian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2213546Sjulian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2313546Sjulian * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2413546Sjulian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2513546Sjulian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2613546Sjulian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2713546Sjulian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2813546Sjulian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2913546Sjulian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3013546Sjulian * SUCH DAMAGE.
3113546Sjulian *
3213546Sjulian */
3313546Sjulian#include <stdarg.h>
3413546Sjulian#include <fcntl.h>
3513546Sjulian#ifdef _THREAD_SAFE
3613546Sjulian#include <pthread.h>
3713546Sjulian#include "pthread_private.h"
3813546Sjulian
3913546Sjulianint
4013546Sjulianfcntl(int fd, int cmd,...)
4113546Sjulian{
4213546Sjulian	int             flags = 0;
4313546Sjulian	int             oldfd;
4413546Sjulian	int             ret;
4513546Sjulian	int             status;
4613546Sjulian	va_list         ap;
4713546Sjulian
4813546Sjulian	/* Block signals: */
4913546Sjulian	_thread_kern_sig_block(&status);
5013546Sjulian
5113546Sjulian	/* Lock the file descriptor: */
5213546Sjulian	if ((ret = _thread_fd_lock(fd, FD_RDWR, NULL, __FILE__, __LINE__)) == 0) {
5313546Sjulian		/* Initialise the variable argument list: */
5413546Sjulian		va_start(ap, cmd);
5513546Sjulian
5613546Sjulian		/* Process according to file control command type: */
5713546Sjulian		switch (cmd) {
5813546Sjulian			/* Duplicate a file descriptor: */
5913546Sjulian		case F_DUPFD:
6013546Sjulian			/*
6113546Sjulian			 * Get the file descriptor that the caller wants to
6213546Sjulian			 * use:
6313546Sjulian			 */
6413546Sjulian			oldfd = va_arg(ap, int);
6513546Sjulian
6613546Sjulian			/* Initialise the file descriptor table entry: */
6713546Sjulian			if ((ret = _thread_sys_fcntl(fd, cmd, oldfd)) < 0) {
6813546Sjulian			}
6913546Sjulian			/* Initialise the file descriptor table entry: */
7013546Sjulian			else if (_thread_fd_table_init(ret) != 0) {
7113546Sjulian				/* Quietly close the file: */
7213546Sjulian				_thread_sys_close(ret);
7313546Sjulian
7413546Sjulian				/* Reset the file descriptor: */
7513546Sjulian				ret = -1;
7613546Sjulian			} else {
7713546Sjulian				/*
7813546Sjulian				 * Save the file open flags so that they can
7913546Sjulian				 * be         checked later:
8013546Sjulian				 */
8113546Sjulian				_thread_fd_table[ret]->flags = _thread_fd_table[fd]->flags;
8213546Sjulian			}
8313546Sjulian			break;
8413546Sjulian		case F_SETFD:
8513546Sjulian			break;
8613546Sjulian		case F_GETFD:
8713546Sjulian			break;
8813546Sjulian		case F_GETFL:
8913546Sjulian			ret = _thread_fd_table[fd]->flags;
9013546Sjulian			break;
9113546Sjulian		case F_SETFL:
9213546Sjulian			flags = va_arg(ap, int);
9313546Sjulian			if ((ret = _thread_sys_fcntl(fd, cmd, flags | O_NONBLOCK)) == 0) {
9413546Sjulian				_thread_fd_table[fd]->flags = flags;
9513546Sjulian			}
9613546Sjulian			break;
9713546Sjulian		default:
9813546Sjulian			/* Might want to make va_arg use a union */
9913546Sjulian			ret = _thread_sys_fcntl(fd, cmd, va_arg(ap, void *));
10013546Sjulian			break;
10113546Sjulian		}
10213546Sjulian
10313546Sjulian		/* Free variable arguments: */
10413546Sjulian		va_end(ap);
10513546Sjulian
10613546Sjulian		/* Unlock the file descriptor: */
10713546Sjulian		_thread_fd_unlock(fd, FD_RDWR);
10813546Sjulian	}
10913546Sjulian	/* Unblock signals: */
11013546Sjulian	_thread_kern_sig_unblock(status);
11113546Sjulian
11213546Sjulian	/* Return the completion status: */
11313546Sjulian	return (ret);
11413546Sjulian}
11513546Sjulian#endif
116