From patchwork Mon Nov 21 17:44:45 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zack Weinberg X-Patchwork-Id: 17676 Received: (qmail 68949 invoked by alias); 21 Nov 2016 17:44:59 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 68939 invoked by uid 89); 21 Nov 2016 17:44:58 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=1714, __n, __cplusplus, USE X-HELO: mail-qk0-f193.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:to:from:message-id:date:user-agent :mime-version:content-transfer-encoding; bh=Vbvm8zkakrpQmNiaGlXqIeDMCjPr0/9D3JEMBeDrNJo=; b=JmvO5i5u03gikBlwUOeic4B8xllDo79+yYHHWL6+eyzlZvq/MUyRWTLzbFLx9h16v1 Hj5OCila9vDMnDBa3VF7itawR2rfjBxB2PphADRlld+coDnfZo1iPJfhs1i8X+rUzqz8 hhE7SYkm0N4heM+VhPyx5zguO+SJ56pnh5/cBEo+HU+i5Rneqy6eo5IwS4l07AeHydG5 rCed4EjKMD0KVOAcKRWpfYcf43K+US1+IF+h7j2Brh5BdpyzOWidp1ZuxgBYSq88aCf7 j9OmMncRZYw2h+LiogW7mbitTov87ziX3LbRHnjU6qvhW0U0QNgZt31XbxsDnabQ/g6r 0GrQ== X-Gm-Message-State: AKaTC032fbsxHTn9x//fp4RAyuC40s/g2/Ty9zWxwBJTGoyRHVQ5nHBoRdtUa5GrtdDY8A== X-Received: by 10.55.156.81 with SMTP id f78mr18664372qke.123.1479750286715; Mon, 21 Nov 2016 09:44:46 -0800 (PST) Subject: [PATCH] Clean up conditionals for declaration of gets(). To: GNU C Library From: Zack Weinberg X-Forwarded-Message-Id: Message-ID: <47fd11c8-4210-8687-26e8-d75000250ada@panix.com> Date: Mon, 21 Nov 2016 12:44:45 -0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Icedove/45.4.0 MIME-Version: 1.0 gets() has the dubious honor of being the only C89 library feature that has been completely removed from the current C and C++ standards. glibc follows suit by not declaring it in _GNU_SOURCE mode either, but it remains present in older compatibility modes. Internally, two test cases need to see stdio.h make the declaration, but all our internal code is of course compiled under _GNU_SOURCE. This is currently kludged by duplicating the gets declaration, fortify wrapper and all, in include/stdio.h. Also, the conditional in the public headers for deciding when to declare gets is complicated and repeated in two places. This patch adds a new macro to features.h that encapsulates the complicated rule for when to declare gets. stdio.h and bits/stdio2.h can simply test __GLIBC_USE (DEPRECATED_GETS). Then, instead of having a duplicate gets declaration in include/stdio.h, debug/tst-chk1.c and stdio-common/tst-gets.c force that flag on. Tested on x86_64-linux-gnu, OK? (If you're wondering why this patch doesn't touch libio/iogets.c, it is because that file defines _IO_gets, not gets. Yes, this raises troubling questions about inconsistencies between the internal declarations in libioP.h and the public ones in stdio.h.) zw * include/features.h (__GLIBC_USE_DEPRECATED_GETS): New macro. * libio/stdio.h, libio/bits/stdio2.h: Condition gets on __GLIBC_USE (DEPRECATED_GETS). Update comments to indicate gets was removed from C++ in C++14. * include/stdio.h [!_ISOMAC]: Force gets to be declared by libio/stdio.h, instead of repeating its declaration. * debug/tst-chk1.c, stdio-common/tst-gets.c: Force gets to be declared, since we are testing it. * stdio-common/Makefile (tst-gets.c): Compile with -Wno-deprecated-declarations. --- debug/tst-chk1.c | 5 +++++ include/features.h | 9 +++++++++ include/stdio.h | 18 ------------------ libio/bits/stdio2.h | 3 +-- libio/stdio.h | 13 +++++-------- stdio-common/Makefile | 3 +++ stdio-common/tst-gets.c | 6 +++++- 7 files changed, 28 insertions(+), 29 deletions(-) diff --git a/debug/tst-chk1.c b/debug/tst-chk1.c index 478c2fb..3e9d3a5 100644 --- a/debug/tst-chk1.c +++ b/debug/tst-chk1.c @@ -16,6 +16,11 @@ License along with the GNU C Library; if not, see . */ +/* This file tests gets(). Force it to be declared. */ +#include +#undef __GLIBC_USE_DEPRECATED_GETS +#define __GLIBC_USE_DEPRECATED_GETS 1 + #include #include #include diff --git a/include/features.h b/include/features.h index 650d4c5..94feb1d 100644 --- a/include/features.h +++ b/include/features.h @@ -370,6 +370,15 @@ # define __USE_FORTIFY_LEVEL 0 #endif +/* The function 'gets' existed in C89, but is impossible to use safely. + It has been removed from ISO C11, ISO C++14, and _GNU_SOURCE. */ +#if !defined __USE_ISOC11 \ + || (defined __cplusplus && __cplusplus <= 201103L) +# define __GLIBC_USE_DEPRECATED_GETS 1 +#else +# define __GLIBC_USE_DEPRECATED_GETS 0 +#endif + /* Get definitions of __STDC_* predefined macros, if the compiler has not preincluded this header automatically. */ #include diff --git a/include/stdio.h b/include/stdio.h index 266c3bb..5965439 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -178,24 +178,6 @@ libc_hidden_proto (__vasprintf_chk) libc_hidden_proto (__vdprintf_chk) libc_hidden_proto (__obstack_vprintf_chk) -/* The header does not include the declaration for gets - anymore when compiling with _GNU_SOURCE. Provide a copy here. */ -extern char *gets (char *__s); -# if __USE_FORTIFY_LEVEL > 0 -extern char *__gets_chk (char *__str, size_t) __wur; -extern char *__REDIRECT (__gets_warn, (char *__str), gets) - __wur __warnattr ("please use fgets or getline instead, gets can't " - "specify buffer size"); - -__fortify_function __wur char * -gets (char *__str) -{ - if (__bos (__str) != (size_t) -1) - return __gets_chk (__str, __bos (__str)); - return __gets_warn (__str); -} -# endif - extern FILE * __fmemopen (void *buf, size_t len, const char *mode); libc_hidden_proto (__fmemopen) diff --git a/libio/bits/stdio2.h b/libio/bits/stdio2.h index fa3be79..df9662c 100644 --- a/libio/bits/stdio2.h +++ b/libio/bits/stdio2.h @@ -222,8 +222,7 @@ __NTH (obstack_vprintf (struct obstack *__restrict __obstack, #endif -#if !defined __USE_ISOC11 \ - || (defined __cplusplus && __cplusplus <= 201103L && !defined __USE_GNU) +#if __GLIBC_USE (DEPRECATED_GETS) extern char *__gets_chk (char *__str, size_t) __wur; extern char *__REDIRECT (__gets_warn, (char *__str), gets) __wur __warnattr ("please use fgets or getline instead, gets can't " diff --git a/libio/stdio.h b/libio/stdio.h index e37f901..792604f 100644 --- a/libio/stdio.h +++ b/libio/stdio.h @@ -625,16 +625,13 @@ __BEGIN_NAMESPACE_STD extern char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream) __wur; -#if !defined __USE_ISOC11 \ - || (defined __cplusplus && __cplusplus <= 201103L) +#if __GLIBC_USE (DEPRECATED_GETS) /* Get a newline-terminated string from stdin, removing the newline. - DO NOT USE THIS FUNCTION!! There is no limit on how much it will read. - The function has been officially removed in ISO C11. This opportunity - is used to also remove it from the GNU feature list. It is now only - available when explicitly using an old ISO C, Unix, or POSIX standard. - GCC defines _GNU_SOURCE when building C++ code and the function is still - in C++11, so it is also available for C++. + This function is impossible to use safely. It has been officially + removed from ISO C11 and ISO C++14, and we have also removed it + from the _GNU_SOURCE feature list. It remains available when + explicitly using an old ISO C, Unix, or POSIX standard. This function is a possible cancellation point and therefore not marked with __THROW. */ diff --git a/stdio-common/Makefile b/stdio-common/Makefile index 4c4834b..dcbf103 100644 --- a/stdio-common/Makefile +++ b/stdio-common/Makefile @@ -141,6 +141,9 @@ CFLAGS-scanf15.c = -I../libio -I../stdlib -I../wcsmbs -I../time -I../string \ CFLAGS-scanf17.c = -I../libio -I../stdlib -I../wcsmbs -I../time -I../string \ -I../wctype +# tst-gets.c tests a deprecated function. +CFLAGS-tst-gets.c += -Wno-deprecated-declarations + CPPFLAGS += $(libio-mtsafe) $(objpfx)tst-setvbuf1.out: /dev/null $(objpfx)tst-setvbuf1 diff --git a/stdio-common/tst-gets.c b/stdio-common/tst-gets.c index 073bc54..b12a7ed 100644 --- a/stdio-common/tst-gets.c +++ b/stdio-common/tst-gets.c @@ -17,10 +17,14 @@ License along with the GNU C Library; if not, see . */ +/* This file tests gets(). Force it to be declared. */ +#include +#undef __GLIBC_USE_DEPRECATED_GETS +#define __GLIBC_USE_DEPRECATED_GETS 1 + #include #include - static int do_test (void) { -- 2.10.2