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.3 (Berkeley) 01/20/91"; 13 #endif /* LIBC_SCCS and not lint */ 14 15 #include <sys/types.h> 16 #include <sys/file.h> 17 #include <sys/errno.h> 18 #include <stdio.h> 19 #include "local.h" 20 21 FILE * 22 fdopen(fd, mode) 23 int fd; 24 char *mode; 25 { 26 static int nofile; 27 register FILE *fp; 28 int flags, oflags, fdflags, fdmode; 29 30 if (nofile == 0) 31 nofile = getdtablesize(); 32 33 if ((fdflags = fcntl(fd, F_GETFL, 0)) < 0) 34 return (NULL); 35 36 /* Make sure the mode the user wants is a subset of the actual mode. */ 37 fdmode = fdflags & O_ACCMODE; 38 if (fdmode != O_RDWR && fdmode != (oflags & O_ACCMODE)) { 39 errno = EINVAL; 40 return (NULL); 41 } 42 43 if ((fp = __sfp()) == NULL) 44 return (NULL); 45 46 if ((fp->_flags = __sflags(mode, &oflags)) == 0) 47 return (NULL); 48 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 57 fp->_file = fd; 58 fp->_cookie = fp; 59 fp->_read = __sread; 60 fp->_write = __swrite; 61 fp->_seek = __sseek; 62 fp->_close = __sclose; 63 return (fp); 64 } 65