1 /* 2 * Copyright (c) 2002-2004 Tim J. Robbins. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 /* 27 * Copyright 2010 Nexenta Systems, Inc. All rights reserved. 28 * Use is subject to license terms. 29 */ 30 31 #include "lint.h" 32 #include "mse_int.h" 33 #include "file64.h" 34 #include <errno.h> 35 #include <stdio.h> 36 #include <string.h> 37 #include <wchar.h> 38 #include "mblocal.h" 39 #include "mse.h" 40 #include "stdiom.h" 41 #include "libc.h" 42 43 /* 44 * FreeBSD implementation here included a full version that tried to be more 45 * efficient with memory strings. However, for simplicity's sake, we are 46 * going to just use fgetwc(). We also do the stream orientation thing for 47 * XPG5 if we need to. 48 */ 49 50 wchar_t * 51 _fgetws_impl(wchar_t *_RESTRICT_KYWD ws, int n, FILE *_RESTRICT_KYWD fp, 52 int orient) 53 { 54 wint_t wc; 55 wchar_t *wsp; 56 rmutex_t *lk; 57 58 FLOCKFILE(lk, fp); 59 if (orient && GET_NO_MODE(fp)) 60 _setorientation(fp, _WC_MODE); 61 62 if (n <= 0) { 63 errno = EINVAL; 64 FUNLOCKFILE(lk); 65 return (NULL); 66 } 67 68 wsp = ws; 69 while (n--) { 70 wc = _fgetwc_unlocked(fp); 71 if (wc == EOF) { 72 /* 73 * This can happen because of an EOF on 74 * the stream, or because of a decoding error. 75 * Its up to the caller to check errno. 76 */ 77 if (wsp == ws) { 78 /* EOF with no data read */ 79 FUNLOCKFILE(lk); 80 return (NULL); 81 } 82 break; 83 } 84 *wsp++ = wc; 85 86 if (wc == L'\n') 87 break; 88 } 89 *wsp = 0; 90 FUNLOCKFILE(lk); 91 return (ws); 92 } 93 94 wchar_t * 95 fgetws(wchar_t *_RESTRICT_KYWD ws, int n, FILE *_RESTRICT_KYWD fp) 96 { 97 return (_fgetws_impl(ws, n, fp, 0)); 98 } 99 100 wchar_t * 101 __fgetws_xpg5(wchar_t *ws, int n, FILE *fp) 102 { 103 return (_fgetws_impl(ws, n, fp, 1)); 104 } 105 106 wchar_t * 107 getws(wchar_t *ws) 108 { 109 wint_t wc; 110 wchar_t *wsp; 111 rmutex_t *lk; 112 113 FLOCKFILE(lk, stdin); 114 115 wsp = ws; 116 for (;;) { 117 wc = _fgetwc_unlocked(stdin); 118 if (wc == EOF) { 119 /* 120 * This can happen because of an EOF on 121 * the stream, or because of a decoding error. 122 * Its up to the caller to check errno. 123 */ 124 if (wsp == ws) { 125 /* EOF with no data read */ 126 FUNLOCKFILE(lk); 127 return (NULL); 128 } 129 break; 130 } 131 *wsp++ = wc; 132 133 if (wc == L'\n') 134 break; 135 } 136 *wsp = 0; 137 FUNLOCKFILE(lk); 138 return (ws); 139 } 140