| 1 |
/* $MirOS: src/lib/libc/string/strlfun.c,v 1.14 2007/01/07 02:11:40 tg Exp $ */ |
| 2 |
|
| 3 |
/*- |
| 4 |
* Copyright (c) 2006 |
| 5 |
* Thorsten Glaser <tg@mirbsd.de> |
| 6 |
* |
| 7 |
* Provided that these terms and disclaimer and all copyright notices |
| 8 |
* are retained or reproduced in an accompanying document, permission |
| 9 |
* is granted to deal in this work without restriction, including un- |
| 10 |
* limited rights to use, publicly perform, distribute, sell, modify, |
| 11 |
* merge, give away, or sublicence. |
| 12 |
* |
| 13 |
* This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to |
| 14 |
* the utmost extent permitted by applicable law, neither express nor |
| 15 |
* implied; without malicious intent or gross negligence. In no event |
| 16 |
* may a licensor, author or contributor be held liable for indirect, |
| 17 |
* direct, other damage, loss, or other issues arising in any way out |
| 18 |
* of dealing in the work, even if advised of the possibility of such |
| 19 |
* damage or existence of a defect, except proven that it results out |
| 20 |
* of said person's immediate fault when using the work as intended. |
| 21 |
*- |
| 22 |
* The strlcat() code below has been written by Thorsten Glaser. Bodo |
| 23 |
* Eggert suggested optimising the strlcpy() code, originally written |
| 24 |
* by Todd C. Miller (see below), which was carried out by Th. Glaser |
| 25 |
* as well as merging this code with strxfrm() for ISO-10646-only sy- |
| 26 |
* stems and writing wcslcat(), wcslcpy() and wcsxfrm() equivalents. |
| 27 |
*/ |
| 28 |
|
| 29 |
#ifdef STRXFRM |
| 30 |
#undef HAVE_STRLCPY |
| 31 |
#undef HAVE_STRLCAT |
| 32 |
#define HAVE_STRLCPY 0 |
| 33 |
#define HAVE_STRLCAT 1 |
| 34 |
#define strlcpy strxfrm |
| 35 |
#endif |
| 36 |
|
| 37 |
#include <sys/types.h> |
| 38 |
#if defined(_KERNEL) || defined(_STANDALONE) |
| 39 |
#include <lib/libkern/libkern.h> |
| 40 |
#undef HAVE_STRLCPY |
| 41 |
#undef HAVE_STRLCAT |
| 42 |
#else |
| 43 |
#if defined(HAVE_CONFIG_H) && (HAVE_CONFIG_H != 0) |
| 44 |
/* usually when packaged with third-party software */ |
| 45 |
#ifdef CONFIG_H_FILENAME |
| 46 |
#include CONFIG_H_FILENAME |
| 47 |
#else |
| 48 |
#include "config.h" |
| 49 |
#endif |
| 50 |
#endif |
| 51 |
extern size_t strlen(const char *); |
| 52 |
#endif |
| 53 |
|
| 54 |
#ifndef __RCSID |
| 55 |
#undef __IDSTRING |
| 56 |
#undef __IDSTRING_CONCAT |
| 57 |
#undef __IDSTRING_EXPAND |
| 58 |
#if defined(__ELF__) && defined(__GNUC__) |
| 59 |
#define __IDSTRING(prefix, string) \ |
| 60 |
__asm__(".section .comment" \ |
| 61 |
"\n .ascii \"@(\"\"#)" #prefix ": \"" \ |
| 62 |
"\n .asciz \"" string "\"" \ |
| 63 |
"\n .previous") |
| 64 |
#else |
| 65 |
#define __IDSTRING_CONCAT(l,p) __LINTED__ ## l ## _ ## p |
| 66 |
#define __IDSTRING_EXPAND(l,p) __IDSTRING_CONCAT(l,p) |
| 67 |
#define __IDSTRING(prefix, string) \ |
| 68 |
static const char __IDSTRING_EXPAND(__LINE__,prefix) [] \ |
| 69 |
__attribute__((used)) = "@(""#)" #prefix ": " string |
| 70 |
#endif |
| 71 |
#define __RCSID(x) __IDSTRING(rcsid,x) |
| 72 |
#endif |
| 73 |
|
| 74 |
#ifndef __predict_true |
| 75 |
#define __predict_true(exp) ((exp) != 0) |
| 76 |
#endif |
| 77 |
#ifndef __predict_false |
| 78 |
#define __predict_false(exp) ((exp) != 0) |
| 79 |
#endif |
| 80 |
|
| 81 |
#if !defined(_KERNEL) && !defined(_STANDALONE) |
| 82 |
__RCSID("$MirOS: src/lib/libc/string/strlfun.c,v 1.14 2007/01/07 02:11:40 tg Exp $"); |
| 83 |
#endif |
| 84 |
|
| 85 |
#ifndef _STRLCPY_DEFNS |
| 86 |
size_t strlcat(char *, const char *, size_t); |
| 87 |
size_t strlcpy(char *, const char *, size_t); |
| 88 |
#endif |
| 89 |
|
| 90 |
#if !defined(HAVE_STRLCAT) || (HAVE_STRLCAT == 0) |
| 91 |
/* |
| 92 |
* Appends src to string dst of size siz (unlike strncat, siz is the |
| 93 |
* full size of dst, not space left). At most siz-1 characters |
| 94 |
* will be copied. Always NUL terminates (unless siz <= strlen(dst)). |
| 95 |
* Returns strlen(src) + MIN(siz, strlen(initial dst)). |
| 96 |
* If retval >= siz, truncation occurred. |
| 97 |
*/ |
| 98 |
size_t |
| 99 |
strlcat(char *dst, const char *src, size_t dlen) |
| 100 |
{ |
| 101 |
size_t n = 0, slen; |
| 102 |
|
| 103 |
slen = strlen(src); |
| 104 |
while (__predict_true(n + 1 < dlen && dst[n] != '\0')) |
| 105 |
++n; |
| 106 |
if (__predict_false(dlen == 0 || dst[n] != '\0')) |
| 107 |
return (dlen + slen); |
| 108 |
while (__predict_true((slen > 0) && (n < (dlen - 1)))) { |
| 109 |
dst[n++] = *src++; |
| 110 |
--slen; |
| 111 |
} |
| 112 |
dst[n] = '\0'; |
| 113 |
return (n + slen); |
| 114 |
} |
| 115 |
#endif /* !HAVE_STRLCAT */ |
| 116 |
|
| 117 |
/* $OpenBSD: strlcpy.c,v 1.10 2005/08/08 08:05:37 espie Exp $ */ |
| 118 |
|
| 119 |
/*- |
| 120 |
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> |
| 121 |
* |
| 122 |
* Permission to use, copy, modify, and distribute this software for any |
| 123 |
* purpose with or without fee is hereby granted, provided that the above |
| 124 |
* copyright notice and this permission notice appear in all copies. |
| 125 |
*/ |
| 126 |
|
| 127 |
#if !defined(HAVE_STRLCPY) || (HAVE_STRLCPY == 0) |
| 128 |
/* |
| 129 |
* Copy src to string dst of size siz. At most siz-1 characters |
| 130 |
* will be copied. Always NUL terminates (unless siz == 0). |
| 131 |
* Returns strlen(src); if retval >= siz, truncation occurred. |
| 132 |
*/ |
| 133 |
size_t |
| 134 |
strlcpy(char *dst, const char *src, size_t siz) |
| 135 |
{ |
| 136 |
const char *s = src; |
| 137 |
|
| 138 |
if (__predict_false(siz == 0)) |
| 139 |
goto traverse_src; |
| 140 |
|
| 141 |
/* copy as many chars as will fit */ |
| 142 |
while (--siz && (*dst++ = *s++)) |
| 143 |
; |
| 144 |
|
| 145 |
/* not enough room in dst */ |
| 146 |
if (__predict_false(siz == 0)) { |
| 147 |
/* safe to NUL-terminate dst since we copied <= siz-1 chars */ |
| 148 |
*dst = '\0'; |
| 149 |
traverse_src: |
| 150 |
/* traverse rest of src */ |
| 151 |
while (*s++) |
| 152 |
; |
| 153 |
} |
| 154 |
|
| 155 |
/* count doesn't include NUL */ |
| 156 |
return (s - src - 1); |
| 157 |
} |
| 158 |
#endif /* !HAVE_STRLCPY */ |