1#define _BSD_SOURCE
2#include <string.h>
3#include <stdint.h>
4#include <limits.h>
5#include "libc.h"
6
7#define ALIGN (sizeof(size_t)-1)
8#define ONES ((size_t)-1/UCHAR_MAX)
9#define HIGHS (ONES * (UCHAR_MAX/2+1))
10#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
11
12size_t strlcpy(char *d, const char *s, size_t n)
13{
14	char *d0 = d;
15	size_t *wd;
16	const size_t *ws;
17
18	if (!n--) goto finish;
19	if (((uintptr_t)s & ALIGN) == ((uintptr_t)d & ALIGN)) {
20		for (; ((uintptr_t)s & ALIGN) && n && (*d=*s); n--, s++, d++);
21		if (n && *s) {
22			wd=(void *)d; ws=(const void *)s;
23			for (; n>=sizeof(size_t) && !HASZERO(*ws);
24			       n-=sizeof(size_t), ws++, wd++) *wd = *ws;
25			d=(void *)wd; s=(const void *)ws;
26		}
27	}
28	for (; n && (*d=*s); n--, s++, d++);
29	*d = 0;
30finish:
31	return d-d0 + strlen(s);
32}
33