xref: /dflybsd-src/lib/libc/stdio/fgetwln.c (revision 62f0872080cf6dbb5111fe3e9937501fd8e28c9c)
1*62f08720SJoerg Sonnenberger /*	$NetBSD: fgetwln.c,v 1.1 2005/05/14 23:51:02 christos Exp $	*/
2*62f08720SJoerg Sonnenberger /*	$DragonFly: src/lib/libc/stdio/fgetwln.c,v 1.1 2005/07/25 00:37:41 joerg Exp $ */
3*62f08720SJoerg Sonnenberger 
4*62f08720SJoerg Sonnenberger /*-
5*62f08720SJoerg Sonnenberger  * Copyright (c) 2002-2004 Tim J. Robbins.
6*62f08720SJoerg Sonnenberger  * All rights reserved.
7*62f08720SJoerg Sonnenberger  *
8*62f08720SJoerg Sonnenberger  * Redistribution and use in source and binary forms, with or without
9*62f08720SJoerg Sonnenberger  * modification, are permitted provided that the following conditions
10*62f08720SJoerg Sonnenberger  * are met:
11*62f08720SJoerg Sonnenberger  * 1. Redistributions of source code must retain the above copyright
12*62f08720SJoerg Sonnenberger  *    notice, this list of conditions and the following disclaimer.
13*62f08720SJoerg Sonnenberger  * 2. Redistributions in binary form must reproduce the above copyright
14*62f08720SJoerg Sonnenberger  *    notice, this list of conditions and the following disclaimer in the
15*62f08720SJoerg Sonnenberger  *    documentation and/or other materials provided with the distribution.
16*62f08720SJoerg Sonnenberger  *
17*62f08720SJoerg Sonnenberger  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18*62f08720SJoerg Sonnenberger  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19*62f08720SJoerg Sonnenberger  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20*62f08720SJoerg Sonnenberger  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21*62f08720SJoerg Sonnenberger  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22*62f08720SJoerg Sonnenberger  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23*62f08720SJoerg Sonnenberger  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24*62f08720SJoerg Sonnenberger  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25*62f08720SJoerg Sonnenberger  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26*62f08720SJoerg Sonnenberger  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27*62f08720SJoerg Sonnenberger  * SUCH DAMAGE.
28*62f08720SJoerg Sonnenberger  */
29*62f08720SJoerg Sonnenberger 
30*62f08720SJoerg Sonnenberger #include "namespace.h"
31*62f08720SJoerg Sonnenberger #include <stdio.h>
32*62f08720SJoerg Sonnenberger #include <wchar.h>
33*62f08720SJoerg Sonnenberger #include "un-namespace.h"
34*62f08720SJoerg Sonnenberger 
35*62f08720SJoerg Sonnenberger #include "libc_private.h"
36*62f08720SJoerg Sonnenberger #include "local.h"
37*62f08720SJoerg Sonnenberger #include "priv_stdio.h"
38*62f08720SJoerg Sonnenberger 
39*62f08720SJoerg Sonnenberger wchar_t *
40*62f08720SJoerg Sonnenberger fgetwln(FILE * __restrict fp, size_t *lenp)
41*62f08720SJoerg Sonnenberger {
42*62f08720SJoerg Sonnenberger 	wint_t wc;
43*62f08720SJoerg Sonnenberger 	size_t len;
44*62f08720SJoerg Sonnenberger 
45*62f08720SJoerg Sonnenberger 	FLOCKFILE(fp);
46*62f08720SJoerg Sonnenberger 	_SET_ORIENTATION(fp, 1);
47*62f08720SJoerg Sonnenberger 
48*62f08720SJoerg Sonnenberger 	len = 0;
49*62f08720SJoerg Sonnenberger 	while ((wc = __fgetwc_unlock(fp)) != WEOF) {
50*62f08720SJoerg Sonnenberger #define	GROW	512
51*62f08720SJoerg Sonnenberger 		if (len * sizeof(wchar_t) >= fp->_lb._size &&
52*62f08720SJoerg Sonnenberger 		    __slbexpand(fp, (len + GROW) * sizeof(wchar_t)))
53*62f08720SJoerg Sonnenberger 			goto error;
54*62f08720SJoerg Sonnenberger 		*((wchar_t *)(void *)fp->_lb._base + len++) = wc;
55*62f08720SJoerg Sonnenberger 		if (wc == L'\n')
56*62f08720SJoerg Sonnenberger 			break;
57*62f08720SJoerg Sonnenberger 	}
58*62f08720SJoerg Sonnenberger 	if (len == 0)
59*62f08720SJoerg Sonnenberger 		goto error;
60*62f08720SJoerg Sonnenberger 
61*62f08720SJoerg Sonnenberger 	FUNLOCKFILE(fp);
62*62f08720SJoerg Sonnenberger 	*lenp = len;
63*62f08720SJoerg Sonnenberger 	return ((wchar_t *)(void *)fp->_lb._base);
64*62f08720SJoerg Sonnenberger 
65*62f08720SJoerg Sonnenberger error:
66*62f08720SJoerg Sonnenberger 	FUNLOCKFILE(fp);
67*62f08720SJoerg Sonnenberger 	*lenp = 0;
68*62f08720SJoerg Sonnenberger 	return (NULL);
69*62f08720SJoerg Sonnenberger }
70