]>
Commit | Line | Data |
---|---|---|
c4029823 | 1 | /* Copyright (C) 1991, 1992, 1993, 1996 Free Software Foundation, Inc. |
28f540f4 RM |
2 | This file is part of the GNU C Library. |
3 | ||
4 | The GNU C Library is free software; you can redistribute it and/or | |
5 | modify it under the terms of the GNU Library General Public License as | |
6 | published by the Free Software Foundation; either version 2 of the | |
7 | License, or (at your option) any later version. | |
8 | ||
9 | The GNU C Library is distributed in the hope that it will be useful, | |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
12 | Library General Public License for more details. | |
13 | ||
14 | You should have received a copy of the GNU Library General Public | |
15 | License along with the GNU C Library; see the file COPYING.LIB. If | |
16 | not, write to the Free Software Foundation, Inc., 675 Mass Ave, | |
17 | Cambridge, MA 02139, USA. */ | |
18 | ||
28f540f4 RM |
19 | #include <errno.h> |
20 | #include <stddef.h> | |
21 | #include <stdio.h> | |
22 | #include <stdlib.h> | |
23 | #include <string.h> | |
24 | ||
25 | ||
26 | /* Defined in fopen.c. */ | |
c4029823 | 27 | extern int __getmode __P ((const char *mode, __io_mode *mptr)); |
28f540f4 RM |
28 | |
29 | /* Open a new stream that will read and/or write from the buffer in | |
30 | S, which is of LEN bytes. If the mode indicates appending, the | |
31 | buffer pointer is set to point to the first '\0' in the buffer. | |
32 | If S is NULL, the buffer is allocated by malloc and will be freed | |
33 | when the stream is closed. The only purpose of this is to write | |
34 | things and then read what's been written. If LEN is zero, writes will | |
35 | always return errors and reads will always return end-of-file. | |
36 | ||
37 | The stream is set up such that seeks and tells will always fail and | |
38 | once the buffer is full of written characters or empty of characters | |
39 | to read, attempted writes always return an output error and attempted | |
40 | reads always return end-of-file. */ | |
41 | FILE * | |
c4029823 UD |
42 | fmemopen (s, len, mode) |
43 | void *s; | |
44 | size_t len; | |
45 | const char *mode; | |
28f540f4 RM |
46 | { |
47 | __io_mode m; | |
48 | register FILE *stream; | |
49 | ||
50 | if (!__getmode (mode, &m)) | |
51 | return NULL; | |
52 | ||
53 | stream = __newstream (); | |
54 | if (stream == NULL) | |
55 | return NULL; | |
56 | ||
57 | stream->__mode = m; | |
58 | ||
59 | /* Input gets EOF. */ | |
60 | stream->__room_funcs.__input = NULL; | |
61 | /* Output gets error. */ | |
62 | stream->__room_funcs.__output = NULL; | |
63 | ||
64 | /* Do nothing for close. */ | |
65 | stream->__io_funcs.__close = NULL; | |
66 | /* Can't seek outside the buffer. */ | |
67 | stream->__io_funcs.__seek = NULL; | |
68 | /* There is no associated file descriptor to fetch. */ | |
69 | stream->__io_funcs.__fileno = NULL; | |
70 | ||
71 | stream->__seen = 1; | |
72 | ||
73 | stream->__userbuf = s != NULL && len > 0; | |
74 | if (s == NULL) | |
75 | { | |
76 | s = malloc (len); | |
77 | if (s == NULL) | |
78 | { | |
79 | int save = errno; | |
80 | (void) fclose (stream); | |
c4029823 | 81 | __set_errno (save); |
28f540f4 RM |
82 | return NULL; |
83 | } | |
84 | } | |
85 | ||
86 | stream->__buffer = (char *) s; | |
87 | stream->__bufsize = len; | |
88 | ||
89 | stream->__bufp = stream->__buffer; | |
90 | stream->__get_limit = (stream->__buffer + | |
91 | (stream->__mode.__read ? stream->__bufsize : 0)); | |
92 | stream->__put_limit = (stream->__buffer + | |
93 | (stream->__mode.__write ? stream->__bufsize : 0)); | |
94 | stream->__cookie = NULL; | |
95 | ||
96 | if (stream->__mode.__append) | |
97 | { | |
98 | char *p = memchr (stream->__bufp, '\0', | |
99 | stream->__get_limit - stream->__bufp); | |
100 | if (p == NULL) | |
101 | stream->__bufp = stream->__get_limit; | |
102 | else | |
103 | stream->__bufp = p; | |
104 | } | |
105 | else if (stream->__mode.__truncate) | |
c4029823 | 106 | memset ((void *) stream->__buffer, 0, len); |
28f540f4 RM |
107 | |
108 | return stream; | |
109 | } |