1*5af32e75SAxel Dörfler /* Copyright (C) 1994,1997,1999,2000,2001,2002 Free Software Foundation, Inc.
2*5af32e75SAxel Dörfler This file is part of the GNU C Library.
3*5af32e75SAxel Dörfler
4*5af32e75SAxel Dörfler The GNU C Library is free software; you can redistribute it and/or
5*5af32e75SAxel Dörfler modify it under the terms of the GNU Lesser General Public
6*5af32e75SAxel Dörfler License as published by the Free Software Foundation; either
7*5af32e75SAxel Dörfler version 2.1 of the License, or (at your option) any later version.
8*5af32e75SAxel Dörfler
9*5af32e75SAxel Dörfler The GNU C Library is distributed in the hope that it will be useful,
10*5af32e75SAxel Dörfler but WITHOUT ANY WARRANTY; without even the implied warranty of
11*5af32e75SAxel Dörfler MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12*5af32e75SAxel Dörfler Lesser General Public License for more details.
13*5af32e75SAxel Dörfler
14*5af32e75SAxel Dörfler You should have received a copy of the GNU Lesser General Public
15*5af32e75SAxel Dörfler License along with the GNU C Library; if not, write to the Free
16*5af32e75SAxel Dörfler Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17*5af32e75SAxel Dörfler 02111-1307 USA.
18*5af32e75SAxel Dörfler
19*5af32e75SAxel Dörfler As a special exception, if you link the code in this file with
20*5af32e75SAxel Dörfler files compiled with a GNU compiler to produce an executable,
21*5af32e75SAxel Dörfler that does not cause the resulting executable to be covered by
22*5af32e75SAxel Dörfler the GNU Lesser General Public License. This exception does not
23*5af32e75SAxel Dörfler however invalidate any other reasons why the executable file
24*5af32e75SAxel Dörfler might be covered by the GNU Lesser General Public License.
25*5af32e75SAxel Dörfler This exception applies to code released by its copyright holders
26*5af32e75SAxel Dörfler in files containing the exception. */
27*5af32e75SAxel Dörfler
28*5af32e75SAxel Dörfler #include "libioP.h"
29*5af32e75SAxel Dörfler #include "strfile.h"
30*5af32e75SAxel Dörfler
31*5af32e75SAxel Dörfler
32*5af32e75SAxel Dörfler typedef struct
33*5af32e75SAxel Dörfler {
34*5af32e75SAxel Dörfler _IO_strfile f;
35*5af32e75SAxel Dörfler /* This is used for the characters which do not fit in the buffer
36*5af32e75SAxel Dörfler provided by the user. */
37*5af32e75SAxel Dörfler char overflow_buf[64];
38*5af32e75SAxel Dörfler } _IO_strnfile;
39*5af32e75SAxel Dörfler
40*5af32e75SAxel Dörfler
41*5af32e75SAxel Dörfler static int _IO_strn_overflow __P ((_IO_FILE *fp, int c));
42*5af32e75SAxel Dörfler
43*5af32e75SAxel Dörfler static int
_IO_strn_overflow(fp,c)44*5af32e75SAxel Dörfler _IO_strn_overflow (fp, c)
45*5af32e75SAxel Dörfler _IO_FILE *fp;
46*5af32e75SAxel Dörfler int c;
47*5af32e75SAxel Dörfler {
48*5af32e75SAxel Dörfler /* When we come to here this means the user supplied buffer is
49*5af32e75SAxel Dörfler filled. But since we must return the number of characters which
50*5af32e75SAxel Dörfler would have been written in total we must provide a buffer for
51*5af32e75SAxel Dörfler further use. We can do this by writing on and on in the overflow
52*5af32e75SAxel Dörfler buffer in the _IO_strnfile structure. */
53*5af32e75SAxel Dörfler _IO_strnfile *snf = (_IO_strnfile *) fp;
54*5af32e75SAxel Dörfler
55*5af32e75SAxel Dörfler if (fp->_IO_buf_base != snf->overflow_buf)
56*5af32e75SAxel Dörfler {
57*5af32e75SAxel Dörfler /* Terminate the string. We know that there is room for at
58*5af32e75SAxel Dörfler least one more character since we initialized the stream with
59*5af32e75SAxel Dörfler a size to make this possible. */
60*5af32e75SAxel Dörfler *fp->_IO_write_ptr = '\0';
61*5af32e75SAxel Dörfler
62*5af32e75SAxel Dörfler INTUSE(_IO_setb) (fp, snf->overflow_buf,
63*5af32e75SAxel Dörfler snf->overflow_buf + sizeof (snf->overflow_buf), 0);
64*5af32e75SAxel Dörfler
65*5af32e75SAxel Dörfler fp->_IO_write_base = snf->overflow_buf;
66*5af32e75SAxel Dörfler fp->_IO_read_base = snf->overflow_buf;
67*5af32e75SAxel Dörfler fp->_IO_read_ptr = snf->overflow_buf;
68*5af32e75SAxel Dörfler fp->_IO_read_end = snf->overflow_buf + sizeof (snf->overflow_buf);
69*5af32e75SAxel Dörfler }
70*5af32e75SAxel Dörfler
71*5af32e75SAxel Dörfler fp->_IO_write_ptr = snf->overflow_buf;
72*5af32e75SAxel Dörfler fp->_IO_write_end = snf->overflow_buf;
73*5af32e75SAxel Dörfler
74*5af32e75SAxel Dörfler /* Since we are not really interested in storing the characters
75*5af32e75SAxel Dörfler which do not fit in the buffer we simply ignore it. */
76*5af32e75SAxel Dörfler return c;
77*5af32e75SAxel Dörfler }
78*5af32e75SAxel Dörfler
79*5af32e75SAxel Dörfler
80*5af32e75SAxel Dörfler static struct _IO_jump_t _IO_strn_jumps =
81*5af32e75SAxel Dörfler {
82*5af32e75SAxel Dörfler JUMP_INIT_DUMMY,
83*5af32e75SAxel Dörfler JUMP_INIT(finish, _IO_str_finish),
84*5af32e75SAxel Dörfler JUMP_INIT(overflow, _IO_strn_overflow),
85*5af32e75SAxel Dörfler JUMP_INIT(underflow, INTUSE(_IO_str_underflow)),
86*5af32e75SAxel Dörfler JUMP_INIT(uflow, INTUSE(_IO_default_uflow)),
87*5af32e75SAxel Dörfler JUMP_INIT(pbackfail, INTUSE(_IO_str_pbackfail)),
88*5af32e75SAxel Dörfler JUMP_INIT(xsputn, INTUSE(_IO_default_xsputn)),
89*5af32e75SAxel Dörfler JUMP_INIT(xsgetn, INTUSE(_IO_default_xsgetn)),
90*5af32e75SAxel Dörfler JUMP_INIT(seekoff, INTUSE(_IO_str_seekoff)),
91*5af32e75SAxel Dörfler JUMP_INIT(seekpos, _IO_default_seekpos),
92*5af32e75SAxel Dörfler JUMP_INIT(setbuf, _IO_default_setbuf),
93*5af32e75SAxel Dörfler JUMP_INIT(sync, _IO_default_sync),
94*5af32e75SAxel Dörfler JUMP_INIT(doallocate, INTUSE(_IO_default_doallocate)),
95*5af32e75SAxel Dörfler JUMP_INIT(read, _IO_default_read),
96*5af32e75SAxel Dörfler JUMP_INIT(write, _IO_default_write),
97*5af32e75SAxel Dörfler JUMP_INIT(seek, _IO_default_seek),
98*5af32e75SAxel Dörfler JUMP_INIT(close, _IO_default_close),
99*5af32e75SAxel Dörfler JUMP_INIT(stat, _IO_default_stat),
100*5af32e75SAxel Dörfler JUMP_INIT(showmanyc, _IO_default_showmanyc),
101*5af32e75SAxel Dörfler JUMP_INIT(imbue, _IO_default_imbue)
102*5af32e75SAxel Dörfler };
103*5af32e75SAxel Dörfler
104*5af32e75SAxel Dörfler
105*5af32e75SAxel Dörfler int
_IO_vsnprintf(string,maxlen,format,args)106*5af32e75SAxel Dörfler _IO_vsnprintf (string, maxlen, format, args)
107*5af32e75SAxel Dörfler char *string;
108*5af32e75SAxel Dörfler _IO_size_t maxlen;
109*5af32e75SAxel Dörfler const char *format;
110*5af32e75SAxel Dörfler _IO_va_list args;
111*5af32e75SAxel Dörfler {
112*5af32e75SAxel Dörfler _IO_strnfile sf;
113*5af32e75SAxel Dörfler int ret;
114*5af32e75SAxel Dörfler #ifdef _IO_MTSAFE_IO
115*5af32e75SAxel Dörfler sf.f._sbf._f._lock = NULL;
116*5af32e75SAxel Dörfler #endif
117*5af32e75SAxel Dörfler
118*5af32e75SAxel Dörfler /* We need to handle the special case where MAXLEN is 0. Use the
119*5af32e75SAxel Dörfler overflow buffer right from the start. */
120*5af32e75SAxel Dörfler if (maxlen == 0)
121*5af32e75SAxel Dörfler {
122*5af32e75SAxel Dörfler string = sf.overflow_buf;
123*5af32e75SAxel Dörfler maxlen = sizeof (sf.overflow_buf);
124*5af32e75SAxel Dörfler }
125*5af32e75SAxel Dörfler
126*5af32e75SAxel Dörfler _IO_no_init (&sf.f._sbf._f, _IO_USER_LOCK, -1, NULL, NULL);
127*5af32e75SAxel Dörfler _IO_JUMPS ((struct _IO_FILE_plus *) &sf.f._sbf) = &_IO_strn_jumps;
128*5af32e75SAxel Dörfler string[0] = '\0';
129*5af32e75SAxel Dörfler INTUSE(_IO_str_init_static) (&sf.f, string, maxlen - 1, string);
130*5af32e75SAxel Dörfler ret = INTUSE(_IO_vfprintf) ((_IO_FILE *) &sf.f._sbf, format, args);
131*5af32e75SAxel Dörfler
132*5af32e75SAxel Dörfler if (sf.f._sbf._f._IO_buf_base != sf.overflow_buf)
133*5af32e75SAxel Dörfler *sf.f._sbf._f._IO_write_ptr = '\0';
134*5af32e75SAxel Dörfler return ret;
135*5af32e75SAxel Dörfler }
136*5af32e75SAxel Dörfler
137*5af32e75SAxel Dörfler #ifdef weak_alias
138*5af32e75SAxel Dörfler weak_alias (_IO_vsnprintf, __vsnprintf)
139*5af32e75SAxel Dörfler weak_alias (_IO_vsnprintf, vsnprintf)
140*5af32e75SAxel Dörfler #endif
141