fgetwln.c revision 1.3
11.3Sroy/* $NetBSD: fgetwln.c,v 1.3 2009/09/24 20:38:53 roy Exp $ */ 21.1Schristos 31.1Schristos/*- 41.1Schristos * Copyright (c) 2002-2004 Tim J. Robbins. 51.1Schristos * All rights reserved. 61.1Schristos * 71.1Schristos * Redistribution and use in source and binary forms, with or without 81.1Schristos * modification, are permitted provided that the following conditions 91.1Schristos * are met: 101.1Schristos * 1. Redistributions of source code must retain the above copyright 111.1Schristos * notice, this list of conditions and the following disclaimer. 121.1Schristos * 2. Redistributions in binary form must reproduce the above copyright 131.1Schristos * notice, this list of conditions and the following disclaimer in the 141.1Schristos * documentation and/or other materials provided with the distribution. 151.1Schristos * 161.1Schristos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 171.1Schristos * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 181.1Schristos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 191.1Schristos * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 201.1Schristos * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 211.1Schristos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 221.1Schristos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 231.1Schristos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 241.1Schristos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 251.1Schristos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 261.1Schristos * SUCH DAMAGE. 271.1Schristos */ 281.1Schristos 291.1Schristos#include <sys/cdefs.h> 301.1Schristos#if defined(LIBC_SCCS) && !defined(lint) 311.1Schristos#if 0 321.1Schristos__FBSDID("$FreeBSD: src/lib/libc/stdio/fgetwln.c,v 1.2 2004/08/06 17:00:09 tjr Exp $"); 331.1Schristos#else 341.3Sroy__RCSID("$NetBSD: fgetwln.c,v 1.3 2009/09/24 20:38:53 roy Exp $"); 351.1Schristos#endif 361.1Schristos#endif /* LIBC_SCCS and not lint */ 371.1Schristos 381.1Schristos#include "namespace.h" 391.3Sroy#include <assert.h> 401.3Sroy#include <errno.h> 411.3Sroy#include <limits.h> 421.1Schristos#include <stdio.h> 431.3Sroy#include <stdlib.h> 441.1Schristos#include <wchar.h> 451.1Schristos#include "reentrant.h" 461.1Schristos#include "local.h" 471.1Schristos 481.1Schristos#ifdef __weak_alias 491.1Schristos__weak_alias(fgetwln,_fgetwln) 501.1Schristos#endif 511.1Schristos 521.3Sroy/* 531.3Sroy * Expand the line buffer. Return -1 on error. 541.3Sroy#ifdef notdef 551.3Sroy * The `new size' does not account for a terminating '\0', 561.3Sroy * so we add 1 here. 571.3Sroy#endif 581.3Sroy */ 591.3Sroystatic int 601.3Sroy__slbexpand(FILE *fp, size_t newsize) 611.3Sroy{ 621.3Sroy void *p; 631.3Sroy 641.3Sroy#ifdef notdef 651.3Sroy ++newsize; 661.3Sroy#endif 671.3Sroy _DIAGASSERT(fp != NULL); 681.3Sroy 691.3Sroy /* fp->_lb._size is an int ..... */ 701.3Sroy if (newsize > INT_MAX) { 711.3Sroy errno = EOVERFLOW; 721.3Sroy return (-1); 731.3Sroy } 741.3Sroy if ((size_t)fp->_lb._size >= newsize) 751.3Sroy return (0); 761.3Sroy if ((p = realloc(fp->_lb._base, newsize)) == NULL) 771.3Sroy return (-1); 781.3Sroy fp->_lb._base = p; 791.3Sroy fp->_lb._size = newsize; 801.3Sroy return (0); 811.3Sroy} 821.3Sroy 831.1Schristoswchar_t * 841.1Schristosfgetwln(FILE * __restrict fp, size_t *lenp) 851.1Schristos{ 861.1Schristos wint_t wc; 871.1Schristos size_t len; 881.1Schristos 891.1Schristos FLOCKFILE(fp); 901.1Schristos _SET_ORIENTATION(fp, 1); 911.1Schristos 921.1Schristos len = 0; 931.1Schristos while ((wc = __fgetwc_unlock(fp)) != WEOF) { 941.1Schristos#define GROW 512 951.2Slukem if (len * sizeof(wchar_t) >= (size_t)fp->_lb._size && 961.1Schristos __slbexpand(fp, (len + GROW) * sizeof(wchar_t))) 971.1Schristos goto error; 981.1Schristos *((wchar_t *)(void *)fp->_lb._base + len++) = wc; 991.1Schristos if (wc == L'\n') 1001.1Schristos break; 1011.1Schristos } 1021.1Schristos if (len == 0) 1031.1Schristos goto error; 1041.1Schristos 1051.1Schristos FUNLOCKFILE(fp); 1061.1Schristos *lenp = len; 1071.1Schristos return ((wchar_t *)(void *)fp->_lb._base); 1081.1Schristos 1091.1Schristoserror: 1101.1Schristos FUNLOCKFILE(fp); 1111.1Schristos *lenp = 0; 1121.1Schristos return (NULL); 1131.1Schristos} 114