Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F136494535
D12785.id34315.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D12785.id34315.diff
View Options
Index: include/stdio.h
===================================================================
--- include/stdio.h
+++ include/stdio.h
@@ -36,9 +36,7 @@
#ifndef _STDIO_H_
#define _STDIO_H_
-#include <sys/cdefs.h>
-#include <sys/_null.h>
-#include <sys/_types.h>
+#include <stddef.h>
__NULLABILITY_PRAGMA_PUSH
@@ -263,6 +261,9 @@
int getc(FILE *);
int getchar(void);
char *gets(char *);
+#if defined(__EXT1_VISIBLE) && __EXT1_VISIBLE == 1
+char *gets_s(char *, rsize_t);
+#endif
void perror(const char *);
int printf(const char * __restrict, ...);
int putc(int, FILE *);
Index: lib/libc/stdio/Makefile.inc
===================================================================
--- lib/libc/stdio/Makefile.inc
+++ lib/libc/stdio/Makefile.inc
@@ -49,7 +49,8 @@
ferror.3 feof.3 ferror.3 feof_unlocked.3 \
ferror.3 fileno.3 ferror.3 fileno_unlocked.3
MLINKS+=fflush.3 fpurge.3
-MLINKS+=fgets.3 gets.3
+MLINKS+=fgets.3 gets.3 gets_s.3
+MLINKS+=fgets.3 gets_s.3
MLINKS+=flockfile.3 ftrylockfile.3 flockfile.3 funlockfile.3
MLINKS+=fopen.3 fdopen.3 fopen.3 freopen.3 fopen.3 fmemopen.3
MLINKS+=fputs.3 puts.3
Index: lib/libc/stdio/Symbol.map
===================================================================
--- lib/libc/stdio/Symbol.map
+++ lib/libc/stdio/Symbol.map
@@ -165,6 +165,7 @@
FBSD_1.4 {
fdclose;
fopencookie;
+ gets_s;
};
FBSDprivate_1.0 {
Index: lib/libc/stdio/fgets.3
===================================================================
--- lib/libc/stdio/fgets.3
+++ lib/libc/stdio/fgets.3
@@ -46,6 +46,8 @@
.Ft char *
.Fn fgets "char * restrict str" "int size" "FILE * restrict stream"
.Ft char *
+.Fn gets_s "char *str" "rsize_t size"
+.Ft char *
.Fn gets "char *str"
.Sh DESCRIPTION
The
@@ -65,6 +67,17 @@
character is appended to end the string.
.Pp
The
+.Fn gets_s
+function
+is equivalent to
+.Fn fgets
+with a
+.Fa stream
+of
+.Dv stdin ,
+except that the newline character (if any) is not stored in the string.
+.Pp
+The
.Fn gets
function
is equivalent to
@@ -80,7 +93,8 @@
if any, is sufficiently short to fit in the string.
.Sh RETURN VALUES
Upon successful completion,
-.Fn fgets
+.Fn fgets ,
+.Fn gets_s
and
.Fn gets
return
@@ -94,7 +108,8 @@
.Dv NULL
and the buffer contents are indeterminate.
The
-.Fn fgets
+.Fn fgets ,
+.Fn gets_s
and
.Fn gets
functions
Index: lib/libc/stdio/gets.c
===================================================================
--- lib/libc/stdio/gets.c
+++ lib/libc/stdio/gets.c
@@ -37,31 +37,41 @@
__FBSDID("$FreeBSD$");
#include "namespace.h"
+#include <errno.h>
#include <unistd.h>
+#include <stdint.h>
#include <stdio.h>
#include <sys/cdefs.h>
#include "un-namespace.h"
#include "libc_private.h"
#include "local.h"
-__warn_references(gets, "warning: this program uses gets(), which is unsafe.");
-
+/* ISO/IEC 9899:2011 K.3.7.4.1 */
+static
char *
-gets(char *buf)
+_gets_s(char *buf, rsize_t *n)
{
int c;
+ int nn;
char *s, *ret;
- static int warned;
- static const char w[] =
- "warning: this program uses gets(), which is unsafe.\n";
+
+#define GETS_S_CALL (n != NULL)
+ if ( GETS_S_CALL ) {
+ /* gets_s() */
+ nn = *n;
+ } else {
+ /* Old school gets() call, not a gets_s() call. */
+ /* nn could be anything, it's inconsequential at this */
+ /* point. It's not used by old school gets(). This is */
+ /* done to pet the compiler. */
+ nn = 0;
+ }
FLOCKFILE_CANCELSAFE(stdin);
ORIENT(stdin, -1);
- if (!warned) {
- (void) _write(STDERR_FILENO, w, sizeof(w) - 1);
- warned = 1;
- }
- for (s = buf; (c = __sgetc(stdin)) != '\n'; ) {
+
+ for (s = buf, nn--; ((c = __sgetc(stdin)) != '\n' &&
+ ((nn > 0 && GETS_S_CALL) || ! GETS_S_CALL)); nn--) {
if (c == EOF)
if (s == buf) {
ret = NULL;
@@ -71,9 +81,62 @@
else
*s++ = c;
}
+
+ /****************************************************************/
+ /* */
+ /* If end of buffer reached, discard until \n or eof. */
+ /* Then throw an error. */
+ /* */
+ /****************************************************************/
+ if ( GETS_S_CALL && nn == 0) {
+ /* discard */
+ while (((c = __sgetc(stdin)) != '\n') && c != EOF);
+ /* throw the error */
+ __throw_constraint_handler_s("gets_s : end of buffer", E2BIG);
+ return(NULL);
+ }
+
*s = 0;
ret = buf;
end:
FUNLOCKFILE_CANCELSAFE();
return (ret);
}
+
+/* ISO/IEC 9899:2011 K.3.7.4.1 */
+char *
+gets_s(char *buf, rsize_t n)
+{
+ if (buf == NULL) {
+ __throw_constraint_handler_s("gets_s : str is NULL", EINVAL);
+ return(NULL);
+ } else if (n > RSIZE_MAX) {
+ __throw_constraint_handler_s("gets_s : n > RSIZE_MAX",
+ EINVAL);
+ return(NULL);
+ } else if (n == 0) {
+ __throw_constraint_handler_s("gets_s : n == 0", EINVAL);
+ return(NULL);
+ }
+ return(_gets_s(buf, &n));
+}
+
+#define __GETS_ENABLED
+#ifdef __GETS_ENABLED
+__warn_references(gets, "warning: this program uses gets(), which is unsafe.");
+
+char *
+gets(char *buf)
+{
+ static int warned;
+ static const char w[] =
+ "warning: this program uses gets(), which is unsafe.\n";
+
+ if (!warned) {
+ (void) _write(STDERR_FILENO, w, sizeof(w) - 1);
+ warned = 1;
+ }
+
+ return(_gets_s(buf, NULL));
+}
+#endif
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Nov 19, 1:19 AM (25 m, 26 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25574458
Default Alt Text
D12785.id34315.diff (5 KB)
Attached To
Mode
D12785: New gets_s(3) stdio function
Attached
Detach File
Event Timeline
Log In to Comment