fopen.c revision 176629
1238730Sdelphij/*- 2238730Sdelphij * Copyright (c) 1990, 1993 3238730Sdelphij * The Regents of the University of California. All rights reserved. 4238730Sdelphij * 5238730Sdelphij * This code is derived from software contributed to Berkeley by 6238730Sdelphij * Chris Torek. 7238730Sdelphij * 8238730Sdelphij * Redistribution and use in source and binary forms, with or without 960786Sps * modification, are permitted provided that the following conditions 1060786Sps * are met: 1160786Sps * 1. Redistributions of source code must retain the above copyright 1260786Sps * notice, this list of conditions and the following disclaimer. 1360786Sps * 2. Redistributions in binary form must reproduce the above copyright 1460786Sps * notice, this list of conditions and the following disclaimer in the 1560786Sps * documentation and/or other materials provided with the distribution. 1660786Sps * 4. Neither the name of the University nor the names of its contributors 1760786Sps * may be used to endorse or promote products derived from this software 1860786Sps * without specific prior written permission. 1960786Sps * 2060786Sps * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2160786Sps * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2260786Sps * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2360786Sps * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2460786Sps * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25128345Stjr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2660786Sps * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2760786Sps * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2860786Sps * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29221715Sdelphij * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30221715Sdelphij * SUCH DAMAGE. 3160786Sps */ 3260786Sps 3360786Sps#if defined(LIBC_SCCS) && !defined(lint) 3460786Spsstatic char sccsid[] = "@(#)fopen.c 8.1 (Berkeley) 6/4/93"; 3560786Sps#endif /* LIBC_SCCS and not lint */ 3660786Sps#include <sys/cdefs.h> 3760786Sps__FBSDID("$FreeBSD: head/lib/libc/stdio/fopen.c 176629 2008-02-27 21:25:19Z jhb $"); 3860786Sps 3960786Sps#include "namespace.h" 4060786Sps#include <sys/types.h> 4160786Sps#include <sys/stat.h> 4260786Sps#include <fcntl.h> 4360786Sps#include <unistd.h> 4460786Sps#include <stdio.h> 4560786Sps#include <errno.h> 4660786Sps#include <limits.h> 4760786Sps#include "un-namespace.h" 4860786Sps 4960786Sps#include "local.h" 5060786Sps 5160786SpsFILE * 5260786Spsfopen(file, mode) 5360786Sps const char * __restrict file; 54221715Sdelphij const char * __restrict mode; 55221715Sdelphij{ 56128345Stjr FILE *fp; 5760786Sps int f; 5860786Sps int flags, oflags; 5960786Sps 6060786Sps if ((flags = __sflags(mode, &oflags)) == 0) 6160786Sps return (NULL); 6260786Sps if ((fp = __sfp()) == NULL) 6360786Sps return (NULL); 6460786Sps if ((f = _open(file, oflags, DEFFILEMODE)) < 0) { 6560786Sps fp->_flags = 0; /* release */ 6660786Sps return (NULL); 67 } 68 /* 69 * File descriptors are a full int, but _file is only a short. 70 * If we get a valid file descriptor that is greater than 71 * SHRT_MAX, then the fd will get sign-extended into an 72 * invalid file descriptor. Handle this case by failing the 73 * open. 74 */ 75 if (f > SHRT_MAX) { 76 _close(f); 77 errno = EMFILE; 78 return (NULL); 79 } 80 fp->_file = f; 81 fp->_flags = flags; 82 fp->_cookie = fp; 83 fp->_read = __sread; 84 fp->_write = __swrite; 85 fp->_seek = __sseek; 86 fp->_close = __sclose; 87 /* 88 * When opening in append mode, even though we use O_APPEND, 89 * we need to seek to the end so that ftell() gets the right 90 * answer. If the user then alters the seek pointer, or 91 * the file extends, this will fail, but there is not much 92 * we can do about this. (We could set __SAPP and check in 93 * fseek and ftell.) 94 */ 95 if (oflags & O_APPEND) 96 (void)_sseek(fp, (fpos_t)0, SEEK_END); 97 return (fp); 98} 99