1 /*-
2 * Copyright (c) 1990, 1993
3 * The Regents of the University of California. 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 8.1 (Berkeley) 06/04/93";
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 *
fdopen(fd,mode)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