1 | /* Copyright (C) 1993-2023 Free Software Foundation, Inc. |
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 Lesser General Public |
6 | License as published by the Free Software Foundation; either |
7 | version 2.1 of the 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 | Lesser General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU Lesser General Public |
15 | License along with the GNU C Library; if not, see |
16 | <https://www.gnu.org/licenses/>. |
17 | |
18 | As a special exception, if you link the code in this file with |
19 | files compiled with a GNU compiler to produce an executable, |
20 | that does not cause the resulting executable to be covered by |
21 | the GNU Lesser General Public License. This exception does not |
22 | however invalidate any other reasons why the executable file |
23 | might be covered by the GNU Lesser General Public License. |
24 | This exception applies to code released by its copyright holders |
25 | in files containing the exception. */ |
26 | |
27 | #include "libioP.h" |
28 | |
29 | #define _IOFBF 0 /* Fully buffered. */ |
30 | #define _IOLBF 1 /* Line buffered. */ |
31 | #define _IONBF 2 /* No buffering. */ |
32 | |
33 | int |
34 | _IO_setvbuf (FILE *fp, char *buf, int mode, size_t size) |
35 | { |
36 | int result; |
37 | CHECK_FILE (fp, EOF); |
38 | _IO_acquire_lock (fp); |
39 | switch (mode) |
40 | { |
41 | case _IOFBF: |
42 | fp->_flags &= ~(_IO_LINE_BUF|_IO_UNBUFFERED); |
43 | if (buf == NULL) |
44 | { |
45 | if (fp->_IO_buf_base == NULL) |
46 | { |
47 | /* There is no flag to distinguish between "fully buffered |
48 | mode has been explicitly set" as opposed to "line |
49 | buffering has not been explicitly set". In both |
50 | cases, _IO_LINE_BUF is off. If this is a tty, and |
51 | _IO_filedoalloc later gets called, it cannot know if |
52 | it should set the _IO_LINE_BUF flag (because that is |
53 | the default), or not (because we have explicitly asked |
54 | for fully buffered mode). So we make sure a buffer |
55 | gets allocated now, and explicitly turn off line |
56 | buffering. |
57 | |
58 | A possibly cleaner alternative would be to add an |
59 | extra flag, but then flags are a finite resource. */ |
60 | if (_IO_DOALLOCATE (fp) < 0) |
61 | { |
62 | result = EOF; |
63 | goto unlock_return; |
64 | } |
65 | fp->_flags &= ~_IO_LINE_BUF; |
66 | } |
67 | result = 0; |
68 | goto unlock_return; |
69 | } |
70 | break; |
71 | case _IOLBF: |
72 | fp->_flags &= ~_IO_UNBUFFERED; |
73 | fp->_flags |= _IO_LINE_BUF; |
74 | if (buf == NULL) |
75 | { |
76 | result = 0; |
77 | goto unlock_return; |
78 | } |
79 | break; |
80 | case _IONBF: |
81 | fp->_flags &= ~_IO_LINE_BUF; |
82 | fp->_flags |= _IO_UNBUFFERED; |
83 | buf = NULL; |
84 | size = 0; |
85 | break; |
86 | default: |
87 | result = EOF; |
88 | goto unlock_return; |
89 | } |
90 | result = _IO_SETBUF (fp, buf, size) == NULL ? EOF : 0; |
91 | |
92 | unlock_return: |
93 | _IO_release_lock (fp); |
94 | return result; |
95 | } |
96 | libc_hidden_def (_IO_setvbuf) |
97 | |
98 | weak_alias (_IO_setvbuf, setvbuf) |
99 | |