Skip to content

Commit 642e4e5

Browse files
committed
strlcpy: add strlcpy and strlcat.
1 parent f5dc093 commit 642e4e5

File tree

5 files changed

+130
-0
lines changed

5 files changed

+130
-0
lines changed

Makefile

+4
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ TESTS = \
3838
tests/bint$(TEST) \
3939
tests/slist$(TEST) \
4040
tests/cbuf$(TEST) \
41+
tests/strlcpy$(TEST) \
4142
tests/syserr$(TEST) \
4243
tests/clock$(TEST) \
4344
tests/thr$(TEST) \
@@ -109,6 +110,9 @@ tests/slist$(TEST): tests/test_slist.o src/slist.o
109110
tests/cbuf$(TEST): tests/test_cbuf.o src/cbuf.o
110111
$(CC) -o $@ $^
111112

113+
tests/strlcpy$(TEST): tests/test_strlcpy.o src/strlcpy.o
114+
$(CC) -o $@ $^
115+
112116
tests/syserr$(TEST): tests/test_syserr.o
113117
$(CC) -o $@ $^
114118

README

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ directory are:
1919
- slab: pooled object allocator
2020
- slist: intrusive singly-linked list
2121
- strbuf: resizable string-buffer
22+
- strlcpy: strlcpy() and strlcat()
2223
- vector: resizable array
2324

2425
* io: portable asynchronous IO and system utilities:

src/strlcpy.c

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/* strlcpy - safe string copy
2+
* Copyright (C) 2013 Daniel Beer <[email protected]>
3+
*
4+
* Permission to use, copy, modify, and/or distribute this software for any
5+
* purpose with or without fee is hereby granted, provided that the above
6+
* copyright notice and this permission notice appear in all copies.
7+
*
8+
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9+
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10+
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11+
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12+
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13+
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14+
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15+
*/
16+
17+
#include <string.h>
18+
#include "strlcpy.h"
19+
20+
size_t strlcpy(char *dst, const char *src, size_t size)
21+
{
22+
const size_t src_len = strlen(src);
23+
const size_t max_len = size - 1;
24+
const size_t len = src_len > max_len ? max_len : src_len;
25+
26+
if (!size)
27+
return 0;
28+
29+
memcpy(dst, src, len);
30+
dst[len] = 0;
31+
32+
return src_len;
33+
}
34+
35+
size_t strlcat(char *dst, const char *src, size_t size)
36+
{
37+
const size_t dst_len = strlen(dst);
38+
const size_t src_len = strlen(src);
39+
const size_t res_len = dst_len + src_len;
40+
const size_t max_len = size - dst_len - 1;
41+
const size_t copy = src_len > max_len ? max_len : src_len;
42+
43+
if (!size || (size - 1) < dst_len)
44+
return 0;
45+
46+
memcpy(dst + dst_len, src, copy);
47+
dst[dst_len + copy] = 0;
48+
49+
return res_len;
50+
}

src/strlcpy.h

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/* strlcpy - safe string copy
2+
* Copyright (C) 2013 Daniel Beer <[email protected]>
3+
*
4+
* Permission to use, copy, modify, and/or distribute this software for any
5+
* purpose with or without fee is hereby granted, provided that the above
6+
* copyright notice and this permission notice appear in all copies.
7+
*
8+
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9+
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10+
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11+
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12+
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13+
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14+
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15+
*/
16+
17+
#ifndef STRLCPY_H_
18+
#define STRLCPY_H_
19+
20+
#include <stddef.h>
21+
22+
/* As per OpenBSD man page */
23+
size_t strlcpy(char *dst, const char *src, size_t size);
24+
size_t strlcat(char *dst, const char *src, size_t size);
25+
26+
#endif

tests/test_strlcpy.c

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/* strlcpy - safe string copy
2+
* Copyright (C) 2013 Daniel Beer <[email protected]>
3+
*
4+
* Permission to use, copy, modify, and/or distribute this software for any
5+
* purpose with or without fee is hereby granted, provided that the above
6+
* copyright notice and this permission notice appear in all copies.
7+
*
8+
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9+
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10+
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11+
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12+
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13+
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14+
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15+
*/
16+
17+
#include <string.h>
18+
#include <assert.h>
19+
#include "strlcpy.h"
20+
21+
int main(void)
22+
{
23+
char buf[16];
24+
int i;
25+
26+
buf[0] = 0;
27+
i = strlcpy(buf, "Foo", sizeof(buf));
28+
assert(i == 3);
29+
30+
buf[0] = 0;
31+
i = strlcpy(buf, "This is a long string", sizeof(buf));
32+
assert(i >= sizeof(buf));
33+
assert(!strcmp(buf, "This is a long "));
34+
35+
buf[0] = 0;
36+
i = strlcat(buf, "This is", sizeof(buf));
37+
assert(i == 7);
38+
assert(!strcmp(buf, "This is"));
39+
40+
i = strlcat(buf, " a ", sizeof(buf));
41+
assert(i == 10);
42+
assert(!strcmp(buf, "This is a "));
43+
44+
i = strlcat(buf, "long string", sizeof(buf));
45+
assert(i >= sizeof(buf));
46+
assert(!strcmp(buf, "This is a long "));
47+
48+
return 0;
49+
}

0 commit comments

Comments
 (0)