Commit | Line | Data |
---|---|---|
639aed4c KB |
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% | |
586c39b1 DF |
9 | */ |
10 | ||
2ce81398 | 11 | #if defined(LIBC_SCCS) && !defined(lint) |
d25ccb19 | 12 | static char sccsid[] = "@(#)fdopen.c 5.5 (Berkeley) %G%"; |
639aed4c | 13 | #endif /* LIBC_SCCS and not lint */ |
39195eb1 | 14 | |
41e01b3e S |
15 | #include <sys/types.h> |
16 | #include <sys/file.h> | |
17 | #include <stdio.h> | |
dacc684e | 18 | #include <errno.h> |
639aed4c | 19 | #include "local.h" |
39195eb1 BJ |
20 | |
21 | FILE * | |
22 | fdopen(fd, mode) | |
639aed4c | 23 | int fd; |
d25ccb19 | 24 | const char *mode; |
39195eb1 | 25 | { |
639aed4c | 26 | register FILE *fp; |
dacc684e KB |
27 | static int nofile; |
28 | int flags, oflags, fdflags, tmp; | |
39195eb1 | 29 | |
639aed4c | 30 | if (nofile == 0) |
41e01b3e S |
31 | nofile = getdtablesize(); |
32 | ||
dacc684e | 33 | if ((flags = __sflags(mode, &oflags)) == 0) |
639aed4c KB |
34 | return (NULL); |
35 | ||
36 | /* Make sure the mode the user wants is a subset of the actual mode. */ | |
dacc684e KB |
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))) { | |
639aed4c | 41 | errno = EINVAL; |
41e01b3e | 42 | return (NULL); |
639aed4c | 43 | } |
41e01b3e | 44 | |
639aed4c | 45 | if ((fp = __sfp()) == NULL) |
c72d2806 | 46 | return (NULL); |
dacc684e | 47 | fp->_flags = flags; |
639aed4c KB |
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; | |
639aed4c KB |
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); | |
39195eb1 | 62 | } |