Add versions of stpcpy(3), stpncpy(3), strnlen(3), all from FreeBSD.

These are defined in the latest POSIX

Also make related updates to documentation, mostly from FreeBSD,
though I cleaned a few other things up along the way.

Bump shlib_version.

We are still missing strcoll_l, strerror_l, strsignal, strxfrm_l to be
POSIX conformant.
This commit is contained in:
perry 2009-05-01 17:27:01 +00:00
parent bdb0c5fb32
commit be11851995
9 changed files with 319 additions and 56 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: shlib_version,v 1.210 2009/04/12 17:07:16 christos Exp $
# $NetBSD: shlib_version,v 1.211 2009/05/01 17:27:01 perry Exp $
# Remember to update distrib/sets/lists/base/shl.* when changing
#
# things we wish to do on next major version bump:
@ -35,4 +35,4 @@
# it's insufficient bitwidth to implement all ctype class.
# see isblank's comment in ctype.h.
major=12
minor=166
minor=167

View File

@ -1,11 +1,13 @@
# from: @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
# $NetBSD: Makefile.inc,v 1.70 2009/04/10 23:13:38 christos Exp $
# $NetBSD: Makefile.inc,v 1.71 2009/05/01 17:27:01 perry Exp $
# string sources
.PATH: ${ARCHDIR}/string ${.CURDIR}/string
SRCS+= bm.c strcasecmp.c strncasecmp.c strcasestr.c strcoll.c strdup.c \
strerror.c strlcat.c strlcpy.c strmode.c strsignal.c strtok.c \
SRCS+= bm.c stpcpy.c stpncpy.c \
strcasecmp.c strncasecmp.c strcasestr.c strcoll.c strdup.c \
strerror.c strlcat.c strlcpy.c strnlen.c \
strmode.c strsignal.c strtok.c \
strtok_r.c strxfrm.c __strsignal.c strerror_r.c strndup.c \
stresep.c memrchr.c
@ -66,8 +68,9 @@ MLINKS+=bm.3 bm_comp.3 bm.3 bm_exec.3 bm.3 bm_free.3
MLINKS+=strcasecmp.3 strncasecmp.3
MLINKS+=strcat.3 strncat.3
MLINKS+=strcmp.3 strncmp.3
MLINKS+=strcpy.3 strncpy.3
MLINKS+=strcpy.3 strncpy.3 strcpy.3 stpcpy.3 strcpy.3 stpncpy.3
MLINKS+=strlcpy.3 strlcat.3
MLINKS+=strlen.3 strnlen.3
MLINKS+=strstr.3 strcasestr.3
MLINKS+=memchr.3 memrchr.3
MLINKS+=strtok.3 strtok_r.3

52
lib/libc/string/stpcpy.c Normal file
View File

@ -0,0 +1,52 @@
/* $NetBSD: stpcpy.c,v 1.1 2009/05/01 17:27:01 perry Exp $ */
/*
* Copyright (c) 1999
* David E. O'Brien
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)strcpy.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: stpcpy.c,v 1.1 2009/05/01 17:27:01 perry Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
/* FreeBSD: src/lib/libc/string/stpcpy.c,v 1.2 2009/02/28 06:05:37 das Exp */
#include <string.h>
char *
stpcpy(char * __restrict to, const char * __restrict from)
{
for (; (*to = *from); ++from, ++to);
return(to);
}

50
lib/libc/string/stpncpy.c Normal file
View File

@ -0,0 +1,50 @@
/* $NetBSD: stpncpy.c,v 1.1 2009/05/01 17:27:01 perry Exp $ */
/*-
* Copyright (c) 2009 David Schultz <das@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: stpncpy.c,v 1.1 2009/05/01 17:27:01 perry Exp $");
#endif /* LIBC_SCCS and not lint */
/* FreeBSD: src/lib/libc/string/stpncpy.c,v 1.1 2009/02/28 06:00:58 das Exp */
#include <string.h>
char *
stpncpy(char * __restrict dst, const char * __restrict src, size_t n)
{
for (; n--; dst++, src++) {
if (!(*dst = *src)) {
char *ret = dst;
while (n--)
*++dst = '\0';
return (ret);
}
}
return (dst);
}

View File

@ -30,12 +30,14 @@
.\" SUCH DAMAGE.
.\"
.\" from: @(#)strcpy.3 8.1 (Berkeley) 6/4/93
.\" $NetBSD: strcpy.3,v 1.17 2006/10/16 08:48:45 wiz Exp $
.\" $NetBSD: strcpy.3,v 1.18 2009/05/01 17:27:01 perry Exp $
.\"
.Dd May 6, 2002
.Dd May 1, 2009
.Dt STRCPY 3
.Os
.Sh NAME
.Nm stpcpy ,
.Nm stpncpy ,
.Nm strcpy ,
.Nm strncpy
.Nd copy strings
@ -44,14 +46,18 @@
.Sh SYNOPSIS
.In string.h
.Ft char *
.Fn stpcpy "char * restrict dst" "const char * restrict src"
.Ft char *
.Fn stpncpy "char * restrict dst" "const char * restrict src" "size_t len"
.Ft char *
.Fn strcpy "char * restrict dst" "const char * restrict src"
.Ft char *
.Fn strncpy "char * restrict dst" "const char * restrict src" "size_t len"
.Sh DESCRIPTION
The
.Fn strcpy
.Fn stpcpy
and
.Fn strncpy
.Fn strcpy
functions
copy the string
.Fa src
@ -62,26 +68,30 @@ to
character).
.Pp
The
.Fn stpncpy
and
.Fn strncpy
function copies not more than
functions copy at most
.Fa len
characters into
.Fa dst ,
appending
.Ql \e0
characters if
characters from
.Fa src
into
.Fa dst .
If
.Fa src
is less than
.Fa len
characters long, and
.Em not
terminating
characters long,
the remainder of
.Fa dst
is filled with
.Ql \e0
characters.
Otherwise,
.Fa dst
if
.Fa src
is
.Fa len
or more characters long.
.Em not
terminated.
.Sh RETURN VALUES
The
.Fn strcpy
@ -90,64 +100,105 @@ and
functions
return
.Fa dst .
The
.Fn stpcpy
and
.Fn stpncpy
functions return a pointer to the terminating
.Ql \e0
character of
.Fa dst .
If
.Fn stpncpy
does not terminate
.Fa dst
with a
.Dv NUL
character, it instead returns a pointer to
.Li dst[len]
(which does not necessarily refer to a valid memory location.)
.Sh EXAMPLES
The following sets
.Dq Li chararray
.Va chararray
to
.Dq Li abc\e0\e0\e0 .
.Dq Li abc\e0\e0\e0 :
.Bd -literal -offset indent
(void)strncpy(chararray, "abc", 6);
char chararray[6];
(void)strncpy(chararray, "abc", sizeof(chararray));
.Ed
.Pp
The following sets
.Dq Li chararray
to
.Dq Li abcdef
and does
.Em not
nul-terminate
.Va chararray
because the source string is \*[Gt]= the length parameter.
to
.Dq Li abcdef :
.Bd -literal -offset indent
char chararray[6];
(void)strncpy(chararray, "abcdefgh", sizeof(chararray));
.Ed
.Pp
Note that it does
.Em not
.Tn NUL
terminate
.Va chararray
because the length of the source string is greater than or equal
to the length parameter.
.Fn strncpy
.Em only
nul-terminates the destination string when the length of the source
.Tn NUL
terminates
the destination string when the length of the source
string is less than the length parameter.
.Bd -literal -offset indent
(void)strncpy(chararray, "abcdefgh", 6);
.Ed
.Pp
The following copies as many characters from
.Va input
to
.Va buf
as will fit and nul-terminates the result.
as will fit and
.Tn NUL
terminates the result.
Because
.Fn strncpy
does
.Em not
guarantee to nul-terminate the string itself, we must do this by hand.
guarantee to
.Tn NUL
terminate the string itself, this must be done explicitly.
.Bd -literal -offset indent
char buf[BUFSIZ];
char buf[1024];
(void)strncpy(buf, input, sizeof(buf) - 1);
buf[sizeof(buf) - 1] = '\e0';
.Ed
.Pp
Note that
.Xr strlcpy 3
is a better choice for this kind of operation.
The equivalent using
.Xr strlcpy 3
is simply:
This could be better and more simply achieved using
.Xr strlcpy 3 ,
as shown in the following example:
.Bd -literal -offset indent
(void)strlcpy(buf, input, sizeof(buf));
.Ed
.Pp
Note that because
.Xr strlcpy 3
is not defined in any standards, it should
only be used when portability is not a concern.
.Sh SECURITY CONSIDERATIONS
The
.Fn strcpy
and
.Fn stpcpy
functions are easily misused in a manner which enables malicious users
to arbitrarily change a running program's functionality through a
buffer overflow attack.
.Sh SEE ALSO
.Xr bcopy 3 ,
.Xr memccpy 3 ,
.Xr memcpy 3 ,
.Xr memmove 3 ,
.Xr strlcpy 3
.Xr strlcpy 3 ,
.Xr wcscpy 3
.Sh STANDARDS
The
.Fn strcpy
@ -156,3 +207,16 @@ and
functions
conform to
.St -isoC-99 .
The
.Fn stpcpy
and
.Fn stpncpy
functions conform to
.St -p1003.1-2008 .
.Sh HISTORY
The
.Fn stpcpy
and
.Fn stpncpy
functions first appeared in
.Nx 6.0 .

View File

@ -28,12 +28,14 @@
.\" SUCH DAMAGE.
.\"
.\" from: @(#)string.3 8.2 (Berkeley) 12/11/93
.\" $NetBSD: string.3,v 1.15 2007/02/17 09:32:58 wiz Exp $
.\" $NetBSD: string.3,v 1.16 2009/05/01 17:27:01 perry Exp $
.\"
.Dd February 17, 2007
.Dd May 1, 2009
.Dt STRING 3
.Os
.Sh NAME
.Nm stpcpy ,
.Nm stpncpy ,
.Nm strcat ,
.Nm strlcat ,
.Nm strncat ,
@ -41,6 +43,8 @@
.Nm strrchr ,
.Nm strcmp ,
.Nm strncmp ,
.Nm strcasecmp ,
.Nm strncasecmp ,
.Nm strcoll ,
.Nm strcpy ,
.Nm strlcpy ,
@ -48,6 +52,7 @@
.Nm strerror ,
.Nm strerror_r ,
.Nm strlen ,
.Nm strnlen ,
.Nm strpbrk ,
.Nm strsep ,
.Nm stresep ,
@ -66,6 +71,10 @@
.Sh SYNOPSIS
.In string.h
.Ft char *
.Fn stpcpy "char *dst" "const char *src"
.Ft char *
.Fn stpncpy "char *dst" "const char *src" "size_t count"
.Ft char *
.Fn strcat "char *s" "const char * append"
.Ft size_t
.Fn strlcat "char *dst" "const char *src" "size_t size"
@ -80,6 +89,10 @@
.Ft int
.Fn strncmp "const char *s1" "const char *s2" "size_t count"
.Ft int
.Fn strcasecmp "const char *s1" "const char *s2"
.Ft int
.Fn strncasecmp "const char *s1" "const char *s2" "size_t count"
.Ft int
.Fn strcoll "const char *s1" "const char *s2"
.Ft char *
.Fn strcpy "char *dst" "const char *src"
@ -93,6 +106,8 @@
.Fn strerror_r "int errnum" "char *strerrbuf" "size_t buflen"
.Ft size_t
.Fn strlen "const char *s"
.Ft size_t
.Fn strnlen "const char *s" "size_t count"
.Ft char *
.Fn strpbrk "const char *s" "const char *charset"
.Ft char *

View File

@ -30,13 +30,14 @@
.\" SUCH DAMAGE.
.\"
.\" from: @(#)strlen.3 8.1 (Berkeley) 6/4/93
.\" $NetBSD: strlen.3,v 1.8 2003/08/07 16:43:51 agc Exp $
.\" $NetBSD: strlen.3,v 1.9 2009/05/01 17:27:01 perry Exp $
.\"
.Dd June 4, 1993
.Dd May 1, 2009
.Dt STRLEN 3
.Os
.Sh NAME
.Nm strlen
.Nm strlen ,
.Nm strnlen
.Nd find length of string
.Sh LIBRARY
.Lb libc
@ -44,12 +45,23 @@
.In string.h
.Ft size_t
.Fn strlen "const char *s"
.Ft size_t
.Fn strnlen "const char *s" "size_t maxlen"
.Sh DESCRIPTION
The
.Fn strlen
function
computes the length of the string
.Fa s .
.Pp
The
.Fn strnlen
function attempts to compute the length of
.Fa s ,
but never scans beyond the first
.Fa maxlen
bytes of
.Fa s .
.Sh RETURN VALUES
The
.Fn strlen
@ -59,11 +71,25 @@ the number of characters that precede the
terminating
.Dv NUL
character.
.Pp
The
.Fn strnlen
function returns either the same result as
.Fn strlen
or
.Fa maxlen ,
whichever is smaller.
.Sh SEE ALSO
.Xr string 3
.Xr string 3 ,
.Xr wcslen 3 ,
.Xr wcswidth 3
.Sh STANDARDS
The
.Fn strlen
function
conforms to
.St -ansiC .
.St -isoC .
The
.Fn strnlen
function conforms to
.St -p1003.1-2008 .

47
lib/libc/string/strnlen.c Normal file
View File

@ -0,0 +1,47 @@
/* $NetBSD: strnlen.c,v 1.1 2009/05/01 17:27:01 perry Exp $ */
/*-
* Copyright (c) 2009 David Schultz <das@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: strnlen.c,v 1.1 2009/05/01 17:27:01 perry Exp $");
#endif /* LIBC_SCCS and not lint */
/* FreeBSD: src/lib/libc/string/strnlen.c,v 1.1 2009/02/28 06:00:58 das Exp */
#include <string.h>
size_t
strnlen(const char *s, size_t maxlen)
{
size_t len;
for (len = 0; len < maxlen; len++, s++) {
if (!*s)
break;
}
return (len);
}

View File

@ -1,4 +1,4 @@
.\" $NetBSD: wmemchr.3,v 1.12 2006/10/14 07:52:15 wiz Exp $
.\" $NetBSD: wmemchr.3,v 1.13 2009/05/01 17:27:01 perry Exp $
.\"
.\" Copyright (c) 1990, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@ -33,7 +33,7 @@
.\"
.\" from: @(#)strcpy.3 8.1 (Berkeley) 6/4/93
.\"
.Dd October 13, 2006
.Dd May 1, 2009
.Dt WMEMCHR 3
.Os
.Sh NAME
@ -126,17 +126,23 @@ function is strongly recommended to be used.
.Xr memcpy 3 ,
.Xr memmove 3 ,
.Xr memset 3 ,
.Xr stpcpy 3 ,
.Xr stpncpy 3 ,
.Xr strcasecmp 3 ,
.Xr strcat 3 ,
.Xr strchr 3 ,
.Xr strcmp 3 ,
.Xr strcpy 3 ,
.Xr strcspn 3 ,
.Xr strdup 3 ,
.Xr strlcat 3 ,
.Xr strlcpy 3 ,
.Xr strlen 3 ,
.Xr strnlen 3 ,
.Xr strncat 3 ,
.Xr strncmp 3 ,
.Xr strncpy 3 ,
.Xr strnlen 3 ,
.Xr strpbrk 3 ,
.Xr strrchr 3 ,
.Xr strspn 3 ,