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