1a77546fbSCy Schubert /*- 2a77546fbSCy Schubert * SPDX-License-Identifier: BSD-3-Clause 3a77546fbSCy Schubert * 4a77546fbSCy Schubert * Copyright (c) 1990, 1993 5a77546fbSCy Schubert * The Regents of the University of California. All rights reserved. 6a77546fbSCy Schubert * Copyright (c) 2017, 2018 7*b97c07ccSCy Schubert * Cyril S. E. Schubert 8a77546fbSCy Schubert * 9a77546fbSCy Schubert * This code is derived from software contributed to Berkeley by 10a77546fbSCy Schubert * Chris Torek. 11a77546fbSCy Schubert * 12a77546fbSCy Schubert * Redistribution and use in source and binary forms, with or without 13a77546fbSCy Schubert * modification, are permitted provided that the following conditions 14a77546fbSCy Schubert * are met: 15a77546fbSCy Schubert * 1. Redistributions of source code must retain the above copyright 16a77546fbSCy Schubert * notice, this list of conditions and the following disclaimer. 17a77546fbSCy Schubert * 2. Redistributions in binary form must reproduce the above copyright 18a77546fbSCy Schubert * notice, this list of conditions and the following disclaimer in the 19a77546fbSCy Schubert * documentation and/or other materials provided with the distribution. 20a77546fbSCy Schubert * 3. Neither the name of the University nor the names of its contributors 21a77546fbSCy Schubert * may be used to endorse or promote products derived from this software 22a77546fbSCy Schubert * without specific prior written permission. 23a77546fbSCy Schubert * 24a77546fbSCy Schubert * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25a77546fbSCy Schubert * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26a77546fbSCy Schubert * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27a77546fbSCy Schubert * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28a77546fbSCy Schubert * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29a77546fbSCy Schubert * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30a77546fbSCy Schubert * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31a77546fbSCy Schubert * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32a77546fbSCy Schubert * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33a77546fbSCy Schubert * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34a77546fbSCy Schubert * SUCH DAMAGE. 35a77546fbSCy Schubert */ 36a77546fbSCy Schubert 37a77546fbSCy Schubert #include <sys/cdefs.h> 38a77546fbSCy Schubert __FBSDID("$FreeBSD$"); 39a77546fbSCy Schubert 40a77546fbSCy Schubert #include "namespace.h" 41a77546fbSCy Schubert #include <errno.h> 42a77546fbSCy Schubert #include <unistd.h> 43a77546fbSCy Schubert #include <stdint.h> 44a77546fbSCy Schubert #include <stdio.h> 45a77546fbSCy Schubert #include "un-namespace.h" 46a77546fbSCy Schubert #include "libc_private.h" 47a77546fbSCy Schubert #include "local.h" 48a77546fbSCy Schubert 49a77546fbSCy Schubert static inline char * 50a77546fbSCy Schubert _gets_s(char *buf, rsize_t n) 51a77546fbSCy Schubert { 52a77546fbSCy Schubert int c; 53a77546fbSCy Schubert char *s; 54a77546fbSCy Schubert 55a77546fbSCy Schubert ORIENT(stdin, -1); 56a77546fbSCy Schubert for (s = buf, n--; (c = __sgetc(stdin)) != '\n' && n > 0 ; n--) { 57a77546fbSCy Schubert if (c == EOF) { 58a77546fbSCy Schubert if (s == buf) { 59a77546fbSCy Schubert return (NULL); 60a77546fbSCy Schubert } else 61a77546fbSCy Schubert break; 62a77546fbSCy Schubert } else 63a77546fbSCy Schubert *s++ = c; 64a77546fbSCy Schubert } 65a77546fbSCy Schubert 66a77546fbSCy Schubert /* 67a77546fbSCy Schubert * If end of buffer reached, discard until \n or eof. 68a77546fbSCy Schubert * Then throw an error. 69a77546fbSCy Schubert */ 70a77546fbSCy Schubert if (n == 0) { 71a77546fbSCy Schubert /* discard */ 72a77546fbSCy Schubert while ((c = __sgetc(stdin)) != '\n' && c != EOF); 73a77546fbSCy Schubert /* throw the error after lock released prior to exit */ 74a77546fbSCy Schubert __throw_constraint_handler_s("gets_s : end of buffer", E2BIG); 75a77546fbSCy Schubert return (NULL); 76a77546fbSCy Schubert } 77a77546fbSCy Schubert *s = 0; 78a77546fbSCy Schubert return (buf); 79a77546fbSCy Schubert } 80a77546fbSCy Schubert 81a77546fbSCy Schubert /* ISO/IEC 9899:2011 K.3.7.4.1 */ 82a77546fbSCy Schubert char * 83a77546fbSCy Schubert gets_s(char *buf, rsize_t n) 84a77546fbSCy Schubert { 85a77546fbSCy Schubert char *ret; 86a77546fbSCy Schubert if (buf == NULL) { 87a77546fbSCy Schubert __throw_constraint_handler_s("gets_s : str is NULL", EINVAL); 88a77546fbSCy Schubert return(NULL); 89a77546fbSCy Schubert } else if (n > RSIZE_MAX) { 90a77546fbSCy Schubert __throw_constraint_handler_s("gets_s : n > RSIZE_MAX", 91a77546fbSCy Schubert EINVAL); 92a77546fbSCy Schubert return(NULL); 93a77546fbSCy Schubert } else if (n == 0) { 94a77546fbSCy Schubert __throw_constraint_handler_s("gets_s : n == 0", EINVAL); 95a77546fbSCy Schubert return(NULL); 96a77546fbSCy Schubert } 97a77546fbSCy Schubert 98a77546fbSCy Schubert FLOCKFILE_CANCELSAFE(stdin); 99a77546fbSCy Schubert ret = _gets_s(buf, n); 100a77546fbSCy Schubert FUNLOCKFILE_CANCELSAFE(); 101a77546fbSCy Schubert return (ret); 102a77546fbSCy Schubert } 103