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