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.4 (Berkeley) 02/01/91"; 13 #endif /* LIBC_SCCS and not lint */ 14 15 #include <sys/types.h> 16 #include <sys/file.h> 17 #include <stdio.h> 18 #include <errno.h> 19 #include "local.h" 20 21 FILE * 22 fdopen(fd, mode) 23 int fd; 24 char *mode; 25 { 26 register FILE *fp; 27 static int nofile; 28 int flags, oflags, fdflags, tmp; 29 30 if (nofile == 0) 31 nofile = getdtablesize(); 32 33 if ((flags = __sflags(mode, &oflags)) == 0) 34 return (NULL); 35 36 /* Make sure the mode the user wants is a subset of the actual mode. */ 37 if ((fdflags = fcntl(fd, F_GETFL, 0)) < 0) 38 return (NULL); 39 tmp = fdflags & O_ACCMODE; 40 if (tmp != O_RDWR && (tmp != (oflags & O_ACCMODE))) { 41 errno = EINVAL; 42 return (NULL); 43 } 44 45 if ((fp = __sfp()) == NULL) 46 return (NULL); 47 fp->_flags = flags; 48 /* 49 * If opened for appending, but underlying descriptor does not have 50 * O_APPEND bit set, assert __SAPP so that __swrite() will lseek to 51 * end before each write. 52 */ 53 if ((oflags & O_APPEND) && !(fdflags & O_APPEND)) 54 fp->_flags |= __SAPP; 55 fp->_file = fd; 56 fp->_cookie = fp; 57 fp->_read = __sread; 58 fp->_write = __swrite; 59 fp->_seek = __sseek; 60 fp->_close = __sclose; 61 return (fp); 62 } 63