146069Sbostic /*- 246069Sbostic * Copyright (c) 1990 The Regents of the University of California. 346069Sbostic * All rights reserved. 446069Sbostic * 546069Sbostic * This code is derived from software contributed to Berkeley by 646069Sbostic * Chris Torek. 746069Sbostic * 846069Sbostic * %sccs.include.redist.c% 921400Sdist */ 1021400Sdist 1126642Sdonn #if defined(LIBC_SCCS) && !defined(lint) 12*46209Sbostic static char sccsid[] = "@(#)fdopen.c 5.4 (Berkeley) 02/01/91"; 1346069Sbostic #endif /* LIBC_SCCS and not lint */ 1421400Sdist 1517952Sserge #include <sys/types.h> 1617952Sserge #include <sys/file.h> 1717952Sserge #include <stdio.h> 18*46209Sbostic #include <errno.h> 1946069Sbostic #include "local.h" 201999Swnj 211999Swnj FILE * 221999Swnj fdopen(fd, mode) 2346069Sbostic int fd; 2446069Sbostic char *mode; 251999Swnj { 26*46209Sbostic register FILE *fp; 2746069Sbostic static int nofile; 28*46209Sbostic int flags, oflags, fdflags, tmp; 291999Swnj 3046069Sbostic if (nofile == 0) 3117952Sserge nofile = getdtablesize(); 3217952Sserge 33*46209Sbostic if ((flags = __sflags(mode, &oflags)) == 0) 3413495Ssam return (NULL); 3517952Sserge 3646069Sbostic /* Make sure the mode the user wants is a subset of the actual mode. */ 37*46209Sbostic if ((fdflags = fcntl(fd, F_GETFL, 0)) < 0) 38*46209Sbostic return (NULL); 39*46209Sbostic tmp = fdflags & O_ACCMODE; 40*46209Sbostic if (tmp != O_RDWR && (tmp != (oflags & O_ACCMODE))) { 4146069Sbostic errno = EINVAL; 4217952Sserge return (NULL); 4346069Sbostic } 4417952Sserge 4546069Sbostic if ((fp = __sfp()) == NULL) 4646069Sbostic return (NULL); 47*46209Sbostic fp->_flags = flags; 4846069Sbostic /* 4946069Sbostic * If opened for appending, but underlying descriptor does not have 5046069Sbostic * O_APPEND bit set, assert __SAPP so that __swrite() will lseek to 5146069Sbostic * end before each write. 5246069Sbostic */ 5346069Sbostic if ((oflags & O_APPEND) && !(fdflags & O_APPEND)) 5446069Sbostic fp->_flags |= __SAPP; 5546069Sbostic fp->_file = fd; 5646069Sbostic fp->_cookie = fp; 5746069Sbostic fp->_read = __sread; 5846069Sbostic fp->_write = __swrite; 5946069Sbostic fp->_seek = __sseek; 6046069Sbostic fp->_close = __sclose; 6146069Sbostic return (fp); 621999Swnj } 63