fdopen.c revision 290110
19781SMoriah.Waterland@Sun.COM/*- 29781SMoriah.Waterland@Sun.COM * Copyright (c) 1990, 1993 39781SMoriah.Waterland@Sun.COM * The Regents of the University of California. All rights reserved. 49781SMoriah.Waterland@Sun.COM * 59781SMoriah.Waterland@Sun.COM * This code is derived from software contributed to Berkeley by 69781SMoriah.Waterland@Sun.COM * Chris Torek. 79781SMoriah.Waterland@Sun.COM * 89781SMoriah.Waterland@Sun.COM * Redistribution and use in source and binary forms, with or without 99781SMoriah.Waterland@Sun.COM * modification, are permitted provided that the following conditions 109781SMoriah.Waterland@Sun.COM * are met: 119781SMoriah.Waterland@Sun.COM * 1. Redistributions of source code must retain the above copyright 129781SMoriah.Waterland@Sun.COM * notice, this list of conditions and the following disclaimer. 139781SMoriah.Waterland@Sun.COM * 2. Redistributions in binary form must reproduce the above copyright 149781SMoriah.Waterland@Sun.COM * notice, this list of conditions and the following disclaimer in the 159781SMoriah.Waterland@Sun.COM * documentation and/or other materials provided with the distribution. 169781SMoriah.Waterland@Sun.COM * 3. Neither the name of the University nor the names of its contributors 179781SMoriah.Waterland@Sun.COM * may be used to endorse or promote products derived from this software 189781SMoriah.Waterland@Sun.COM * without specific prior written permission. 199781SMoriah.Waterland@Sun.COM * 209781SMoriah.Waterland@Sun.COM * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 219781SMoriah.Waterland@Sun.COM * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 229781SMoriah.Waterland@Sun.COM * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 239781SMoriah.Waterland@Sun.COM * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 249781SMoriah.Waterland@Sun.COM * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 259781SMoriah.Waterland@Sun.COM * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 269781SMoriah.Waterland@Sun.COM * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 279781SMoriah.Waterland@Sun.COM * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 289781SMoriah.Waterland@Sun.COM * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 299781SMoriah.Waterland@Sun.COM * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 309781SMoriah.Waterland@Sun.COM * SUCH DAMAGE. 319781SMoriah.Waterland@Sun.COM */ 329781SMoriah.Waterland@Sun.COM 339781SMoriah.Waterland@Sun.COM#if defined(LIBC_SCCS) && !defined(lint) 349781SMoriah.Waterland@Sun.COMstatic char sccsid[] = "@(#)fdopen.c 8.1 (Berkeley) 6/4/93"; 359781SMoriah.Waterland@Sun.COM#endif /* LIBC_SCCS and not lint */ 369781SMoriah.Waterland@Sun.COM#include <sys/cdefs.h> 379781SMoriah.Waterland@Sun.COM__FBSDID("$FreeBSD: head/lib/libc/stdio/fdopen.c 290110 2015-10-28 14:40:02Z ache $"); 389781SMoriah.Waterland@Sun.COM 399781SMoriah.Waterland@Sun.COM#include "namespace.h" 409781SMoriah.Waterland@Sun.COM#include <sys/types.h> 419781SMoriah.Waterland@Sun.COM#include <fcntl.h> 429781SMoriah.Waterland@Sun.COM#include <unistd.h> 439781SMoriah.Waterland@Sun.COM#include <stdio.h> 449781SMoriah.Waterland@Sun.COM#include <errno.h> 459781SMoriah.Waterland@Sun.COM#include <limits.h> 469781SMoriah.Waterland@Sun.COM#include "un-namespace.h" 479781SMoriah.Waterland@Sun.COM#include "local.h" 489781SMoriah.Waterland@Sun.COM 499781SMoriah.Waterland@Sun.COMFILE * 509781SMoriah.Waterland@Sun.COMfdopen(int fd, const char *mode) 519781SMoriah.Waterland@Sun.COM{ 529781SMoriah.Waterland@Sun.COM FILE *fp; 539781SMoriah.Waterland@Sun.COM int flags, oflags, fdflags, tmp; 549781SMoriah.Waterland@Sun.COM 559781SMoriah.Waterland@Sun.COM /* 569781SMoriah.Waterland@Sun.COM * File descriptors are a full int, but _file is only a short. 579781SMoriah.Waterland@Sun.COM * If we get a valid file descriptor that is greater than 589781SMoriah.Waterland@Sun.COM * SHRT_MAX, then the fd will get sign-extended into an 599781SMoriah.Waterland@Sun.COM * invalid file descriptor. Handle this case by failing the 609781SMoriah.Waterland@Sun.COM * open. 619781SMoriah.Waterland@Sun.COM */ 629781SMoriah.Waterland@Sun.COM if (fd > SHRT_MAX) { 639781SMoriah.Waterland@Sun.COM errno = EMFILE; 649781SMoriah.Waterland@Sun.COM return (NULL); 659781SMoriah.Waterland@Sun.COM } 669781SMoriah.Waterland@Sun.COM 679781SMoriah.Waterland@Sun.COM if ((flags = __sflags(mode, &oflags)) == 0) 689781SMoriah.Waterland@Sun.COM return (NULL); 699781SMoriah.Waterland@Sun.COM 709781SMoriah.Waterland@Sun.COM /* Make sure the mode the user wants is a subset of the actual mode. */ 719781SMoriah.Waterland@Sun.COM if ((fdflags = _fcntl(fd, F_GETFL, 0)) < 0) 729781SMoriah.Waterland@Sun.COM return (NULL); 739781SMoriah.Waterland@Sun.COM /* Work around incorrect O_ACCMODE. */ 749781SMoriah.Waterland@Sun.COM tmp = fdflags & (O_ACCMODE | O_EXEC); 759781SMoriah.Waterland@Sun.COM if (tmp != O_RDWR && (tmp != (oflags & O_ACCMODE))) { 769781SMoriah.Waterland@Sun.COM errno = EINVAL; 779781SMoriah.Waterland@Sun.COM return (NULL); 789781SMoriah.Waterland@Sun.COM } 799781SMoriah.Waterland@Sun.COM 809781SMoriah.Waterland@Sun.COM if ((fp = __sfp()) == NULL) 819781SMoriah.Waterland@Sun.COM return (NULL); 829781SMoriah.Waterland@Sun.COM 839781SMoriah.Waterland@Sun.COM if ((oflags & O_CLOEXEC) && _fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) { 849781SMoriah.Waterland@Sun.COM fp->_flags = 0; 859781SMoriah.Waterland@Sun.COM return (NULL); 869781SMoriah.Waterland@Sun.COM } 879781SMoriah.Waterland@Sun.COM 889781SMoriah.Waterland@Sun.COM fp->_flags = flags; 899781SMoriah.Waterland@Sun.COM /* 909781SMoriah.Waterland@Sun.COM * If opened for appending, but underlying descriptor does not have 919781SMoriah.Waterland@Sun.COM * O_APPEND bit set, assert __SAPP so that __swrite() caller 929781SMoriah.Waterland@Sun.COM * will _sseek() to the end before write. 939781SMoriah.Waterland@Sun.COM */ 949781SMoriah.Waterland@Sun.COM if (fdflags & O_APPEND) 959781SMoriah.Waterland@Sun.COM fp->_flags2 |= __S2OAP; 969781SMoriah.Waterland@Sun.COM else if (oflags & O_APPEND) 979781SMoriah.Waterland@Sun.COM fp->_flags |= __SAPP; 989781SMoriah.Waterland@Sun.COM fp->_file = fd; 999781SMoriah.Waterland@Sun.COM fp->_cookie = fp; 1009781SMoriah.Waterland@Sun.COM fp->_read = __sread; 1019781SMoriah.Waterland@Sun.COM fp->_write = __swrite; 1029781SMoriah.Waterland@Sun.COM fp->_seek = __sseek; 1039781SMoriah.Waterland@Sun.COM fp->_close = __sclose; 1049781SMoriah.Waterland@Sun.COM return (fp); 1059781SMoriah.Waterland@Sun.COM} 1069781SMoriah.Waterland@Sun.COM