fgetwln.c revision 1.4
11.4Sjoerg/* $NetBSD: fgetwln.c,v 1.4 2010/01/11 20:39:29 joerg 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.4Sjoerg__RCSID("$NetBSD: fgetwln.c,v 1.4 2010/01/11 20:39:29 joerg 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.4Sjoerg if (_EXT(fp)->_fgetstr_len >= newsize) 701.3Sroy return (0); 711.4Sjoerg if ((p = realloc(_EXT(fp)->_fgetstr_buf, newsize)) == NULL) 721.3Sroy return (-1); 731.4Sjoerg _EXT(fp)->_fgetstr_buf = p; 741.4Sjoerg _EXT(fp)->_fgetstr_len = newsize; 751.3Sroy return (0); 761.3Sroy} 771.3Sroy 781.1Schristoswchar_t * 791.1Schristosfgetwln(FILE * __restrict fp, size_t *lenp) 801.1Schristos{ 811.1Schristos wint_t wc; 821.1Schristos size_t len; 831.1Schristos 841.1Schristos FLOCKFILE(fp); 851.1Schristos _SET_ORIENTATION(fp, 1); 861.1Schristos 871.1Schristos len = 0; 881.1Schristos while ((wc = __fgetwc_unlock(fp)) != WEOF) { 891.1Schristos#define GROW 512 901.4Sjoerg if (len * sizeof(wchar_t) >= _EXT(fp)->_fgetstr_len && 911.1Schristos __slbexpand(fp, (len + GROW) * sizeof(wchar_t))) 921.1Schristos goto error; 931.4Sjoerg *((wchar_t *)(void *)_EXT(fp)->_fgetstr_buf + len++) = wc; 941.1Schristos if (wc == L'\n') 951.1Schristos break; 961.1Schristos } 971.1Schristos if (len == 0) 981.1Schristos goto error; 991.1Schristos 1001.1Schristos FUNLOCKFILE(fp); 1011.1Schristos *lenp = len; 1021.4Sjoerg return ((wchar_t *)(void *)_EXT(fp)->_fgetstr_buf); 1031.1Schristos 1041.1Schristoserror: 1051.1Schristos FUNLOCKFILE(fp); 1061.1Schristos *lenp = 0; 1071.1Schristos return (NULL); 1081.1Schristos} 109