xref: /freebsd/contrib/pam-krb5/portable/strndup.c (revision bf6873c5786e333d679a7838d28812febf479a8a)
1*bf6873c5SCy Schubert /*
2*bf6873c5SCy Schubert  * Replacement for a missing strndup.
3*bf6873c5SCy Schubert  *
4*bf6873c5SCy Schubert  * The canonical version of this file is maintained in the rra-c-util package,
5*bf6873c5SCy Schubert  * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
6*bf6873c5SCy Schubert  *
7*bf6873c5SCy Schubert  * Written by Russ Allbery <eagle@eyrie.org>
8*bf6873c5SCy Schubert  * Copyright 2011-2012
9*bf6873c5SCy Schubert  *     The Board of Trustees of the Leland Stanford Junior University
10*bf6873c5SCy Schubert  *
11*bf6873c5SCy Schubert  * Copying and distribution of this file, with or without modification, are
12*bf6873c5SCy Schubert  * permitted in any medium without royalty provided the copyright notice and
13*bf6873c5SCy Schubert  * this notice are preserved.  This file is offered as-is, without any
14*bf6873c5SCy Schubert  * warranty.
15*bf6873c5SCy Schubert  *
16*bf6873c5SCy Schubert  * SPDX-License-Identifier: FSFAP
17*bf6873c5SCy Schubert  */
18*bf6873c5SCy Schubert 
19*bf6873c5SCy Schubert #include <config.h>
20*bf6873c5SCy Schubert #include <portable/system.h>
21*bf6873c5SCy Schubert 
22*bf6873c5SCy Schubert #include <errno.h>
23*bf6873c5SCy Schubert 
24*bf6873c5SCy Schubert /*
25*bf6873c5SCy Schubert  * If we're running the test suite, rename the functions to avoid conflicts
26*bf6873c5SCy Schubert  * with the system versions.
27*bf6873c5SCy Schubert  */
28*bf6873c5SCy Schubert #if TESTING
29*bf6873c5SCy Schubert #    undef strndup
30*bf6873c5SCy Schubert #    define strndup test_strndup
31*bf6873c5SCy Schubert char *test_strndup(const char *, size_t);
32*bf6873c5SCy Schubert #endif
33*bf6873c5SCy Schubert 
34*bf6873c5SCy Schubert char *
strndup(const char * s,size_t n)35*bf6873c5SCy Schubert strndup(const char *s, size_t n)
36*bf6873c5SCy Schubert {
37*bf6873c5SCy Schubert     const char *p;
38*bf6873c5SCy Schubert     size_t length;
39*bf6873c5SCy Schubert     char *copy;
40*bf6873c5SCy Schubert 
41*bf6873c5SCy Schubert     if (s == NULL) {
42*bf6873c5SCy Schubert         errno = EINVAL;
43*bf6873c5SCy Schubert         return NULL;
44*bf6873c5SCy Schubert     }
45*bf6873c5SCy Schubert 
46*bf6873c5SCy Schubert     /* Don't assume that the source string is nul-terminated. */
47*bf6873c5SCy Schubert     for (p = s; (size_t)(p - s) < n && *p != '\0'; p++)
48*bf6873c5SCy Schubert         ;
49*bf6873c5SCy Schubert     length = p - s;
50*bf6873c5SCy Schubert     copy = malloc(length + 1);
51*bf6873c5SCy Schubert     if (copy == NULL)
52*bf6873c5SCy Schubert         return NULL;
53*bf6873c5SCy Schubert     memcpy(copy, s, length);
54*bf6873c5SCy Schubert     copy[length] = '\0';
55*bf6873c5SCy Schubert     return copy;
56*bf6873c5SCy Schubert }
57