1 /*- 2 * Copyright (c) 1990 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Chris Torek. 7 * 8 * %sccs.include.redist.c% 9 */ 10 11 #if defined(LIBC_SCCS) && !defined(lint) 12 static char sccsid[] = "@(#)fdopen.c 5.6 (Berkeley) 02/24/91"; 13 #endif /* LIBC_SCCS and not lint */ 14 15 #include <sys/types.h> 16 #include <fcntl.h> 17 #include <unistd.h> 18 #include <stdio.h> 19 #include <errno.h> 20 #include "local.h" 21 22 FILE * 23 fdopen(fd, mode) 24 int fd; 25 const char *mode; 26 { 27 register FILE *fp; 28 static int nofile; 29 int flags, oflags, fdflags, tmp; 30 31 if (nofile == 0) 32 nofile = getdtablesize(); 33 34 if ((flags = __sflags(mode, &oflags)) == 0) 35 return (NULL); 36 37 /* Make sure the mode the user wants is a subset of the actual mode. */ 38 if ((fdflags = fcntl(fd, F_GETFL, 0)) < 0) 39 return (NULL); 40 tmp = fdflags & O_ACCMODE; 41 if (tmp != O_RDWR && (tmp != (oflags & O_ACCMODE))) { 42 errno = EINVAL; 43 return (NULL); 44 } 45 46 if ((fp = __sfp()) == NULL) 47 return (NULL); 48 fp->_flags = flags; 49 /* 50 * If opened for appending, but underlying descriptor does not have 51 * O_APPEND bit set, assert __SAPP so that __swrite() will lseek to 52 * end before each write. 53 */ 54 if ((oflags & O_APPEND) && !(fdflags & O_APPEND)) 55 fp->_flags |= __SAPP; 56 fp->_file = fd; 57 fp->_cookie = fp; 58 fp->_read = __sread; 59 fp->_write = __swrite; 60 fp->_seek = __sseek; 61 fp->_close = __sclose; 62 return (fp); 63 } 64