18d59ecb2SHans Petter Selasky /*-
28d59ecb2SHans Petter Selasky * Copyright (c) 2010 Isilon Systems, Inc.
38d59ecb2SHans Petter Selasky * Copyright (c) 2010 iX Systems, Inc.
48d59ecb2SHans Petter Selasky * Copyright (c) 2010 Panasas, Inc.
50f32531aSHans Petter Selasky * Copyright (c) 2013-2017 Mellanox Technologies, Ltd.
68d59ecb2SHans Petter Selasky * All rights reserved.
78d59ecb2SHans Petter Selasky *
88d59ecb2SHans Petter Selasky * Redistribution and use in source and binary forms, with or without
98d59ecb2SHans Petter Selasky * modification, are permitted provided that the following conditions
108d59ecb2SHans Petter Selasky * are met:
118d59ecb2SHans Petter Selasky * 1. Redistributions of source code must retain the above copyright
128d59ecb2SHans Petter Selasky * notice unmodified, this list of conditions, and the following
138d59ecb2SHans Petter Selasky * disclaimer.
148d59ecb2SHans Petter Selasky * 2. Redistributions in binary form must reproduce the above copyright
158d59ecb2SHans Petter Selasky * notice, this list of conditions and the following disclaimer in the
168d59ecb2SHans Petter Selasky * documentation and/or other materials provided with the distribution.
178d59ecb2SHans Petter Selasky *
188d59ecb2SHans Petter Selasky * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
198d59ecb2SHans Petter Selasky * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
208d59ecb2SHans Petter Selasky * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
218d59ecb2SHans Petter Selasky * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
228d59ecb2SHans Petter Selasky * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
238d59ecb2SHans Petter Selasky * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
248d59ecb2SHans Petter Selasky * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
258d59ecb2SHans Petter Selasky * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
268d59ecb2SHans Petter Selasky * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
278d59ecb2SHans Petter Selasky * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
288d59ecb2SHans Petter Selasky *
298d59ecb2SHans Petter Selasky * $FreeBSD$
308d59ecb2SHans Petter Selasky */
31*2d0694b9SVladimir Kondratyev #ifndef _LINUXKPI_LINUX_STRING_H_
32*2d0694b9SVladimir Kondratyev #define _LINUXKPI_LINUX_STRING_H_
338d59ecb2SHans Petter Selasky
340f32531aSHans Petter Selasky #include <sys/ctype.h>
350f32531aSHans Petter Selasky
368d59ecb2SHans Petter Selasky #include <linux/types.h>
378d59ecb2SHans Petter Selasky #include <linux/gfp.h>
388d59ecb2SHans Petter Selasky #include <linux/slab.h>
390f32531aSHans Petter Selasky #include <linux/uaccess.h>
400f32531aSHans Petter Selasky #include <linux/err.h>
418d59ecb2SHans Petter Selasky
428d59ecb2SHans Petter Selasky #include <sys/libkern.h>
438d59ecb2SHans Petter Selasky
44510ebed7SHans Petter Selasky #define strnicmp(...) strncasecmp(__VA_ARGS__)
458d59ecb2SHans Petter Selasky
460f32531aSHans Petter Selasky static inline int
match_string(const char * const * table,int n,const char * key)470f32531aSHans Petter Selasky match_string(const char *const *table, int n, const char *key)
480f32531aSHans Petter Selasky {
490f32531aSHans Petter Selasky int i;
500f32531aSHans Petter Selasky
510f32531aSHans Petter Selasky for (i = 0; i != n && table[i] != NULL; i++) {
520f32531aSHans Petter Selasky if (strcmp(table[i], key) == 0)
530f32531aSHans Petter Selasky return (i);
540f32531aSHans Petter Selasky }
550f32531aSHans Petter Selasky return (-EINVAL);
560f32531aSHans Petter Selasky }
570f32531aSHans Petter Selasky
580f32531aSHans Petter Selasky static inline void *
memdup_user(const void * ptr,size_t len)590f32531aSHans Petter Selasky memdup_user(const void *ptr, size_t len)
600f32531aSHans Petter Selasky {
610f32531aSHans Petter Selasky void *retval;
620f32531aSHans Petter Selasky int error;
630f32531aSHans Petter Selasky
640f32531aSHans Petter Selasky retval = malloc(len, M_KMALLOC, M_WAITOK);
650f32531aSHans Petter Selasky error = linux_copyin(ptr, retval, len);
660f32531aSHans Petter Selasky if (error != 0) {
670f32531aSHans Petter Selasky free(retval, M_KMALLOC);
680f32531aSHans Petter Selasky return (ERR_PTR(error));
690f32531aSHans Petter Selasky }
700f32531aSHans Petter Selasky return (retval);
710f32531aSHans Petter Selasky }
720f32531aSHans Petter Selasky
738d59ecb2SHans Petter Selasky static inline void *
memdup_user_nul(const void * ptr,size_t len)7410ee3d30SHans Petter Selasky memdup_user_nul(const void *ptr, size_t len)
7510ee3d30SHans Petter Selasky {
7610ee3d30SHans Petter Selasky char *retval;
7710ee3d30SHans Petter Selasky int error;
7810ee3d30SHans Petter Selasky
7910ee3d30SHans Petter Selasky retval = malloc(len + 1, M_KMALLOC, M_WAITOK);
8010ee3d30SHans Petter Selasky error = linux_copyin(ptr, retval, len);
8110ee3d30SHans Petter Selasky if (error != 0) {
8210ee3d30SHans Petter Selasky free(retval, M_KMALLOC);
8310ee3d30SHans Petter Selasky return (ERR_PTR(error));
8410ee3d30SHans Petter Selasky }
8510ee3d30SHans Petter Selasky retval[len] = '\0';
8610ee3d30SHans Petter Selasky return (retval);
8710ee3d30SHans Petter Selasky }
8810ee3d30SHans Petter Selasky
8910ee3d30SHans Petter Selasky static inline void *
kmemdup(const void * src,size_t len,gfp_t gfp)908d59ecb2SHans Petter Selasky kmemdup(const void *src, size_t len, gfp_t gfp)
918d59ecb2SHans Petter Selasky {
928d59ecb2SHans Petter Selasky void *dst;
938d59ecb2SHans Petter Selasky
948d59ecb2SHans Petter Selasky dst = kmalloc(len, gfp);
950f32531aSHans Petter Selasky if (dst != NULL)
968d59ecb2SHans Petter Selasky memcpy(dst, src, len);
978d59ecb2SHans Petter Selasky return (dst);
988d59ecb2SHans Petter Selasky }
998d59ecb2SHans Petter Selasky
1000f32531aSHans Petter Selasky static inline char *
kstrdup(const char * string,gfp_t gfp)1010f32531aSHans Petter Selasky kstrdup(const char *string, gfp_t gfp)
1020f32531aSHans Petter Selasky {
1030f32531aSHans Petter Selasky char *retval;
1040f32531aSHans Petter Selasky size_t len;
1050f32531aSHans Petter Selasky
10634c2f79dSVladimir Kondratyev if (string == NULL)
10734c2f79dSVladimir Kondratyev return (NULL);
1080f32531aSHans Petter Selasky len = strlen(string) + 1;
1090f32531aSHans Petter Selasky retval = kmalloc(len, gfp);
1100f32531aSHans Petter Selasky if (retval != NULL)
1110f32531aSHans Petter Selasky memcpy(retval, string, len);
1120f32531aSHans Petter Selasky return (retval);
1130f32531aSHans Petter Selasky }
1140f32531aSHans Petter Selasky
1150f32531aSHans Petter Selasky static inline char *
kstrndup(const char * string,size_t len,gfp_t gfp)1160f32531aSHans Petter Selasky kstrndup(const char *string, size_t len, gfp_t gfp)
1170f32531aSHans Petter Selasky {
1180f32531aSHans Petter Selasky char *retval;
1190f32531aSHans Petter Selasky
12034c2f79dSVladimir Kondratyev if (string == NULL)
12134c2f79dSVladimir Kondratyev return (NULL);
1220f32531aSHans Petter Selasky retval = kmalloc(len + 1, gfp);
1230f32531aSHans Petter Selasky if (retval != NULL)
1240f32531aSHans Petter Selasky strncpy(retval, string, len);
1250f32531aSHans Petter Selasky return (retval);
1260f32531aSHans Petter Selasky }
1270f32531aSHans Petter Selasky
128510ebed7SHans Petter Selasky static inline const char *
kstrdup_const(const char * src,gfp_t gfp)129510ebed7SHans Petter Selasky kstrdup_const(const char *src, gfp_t gfp)
130510ebed7SHans Petter Selasky {
131510ebed7SHans Petter Selasky return (kmemdup(src, strlen(src) + 1, gfp));
132510ebed7SHans Petter Selasky }
133510ebed7SHans Petter Selasky
1340f32531aSHans Petter Selasky static inline char *
skip_spaces(const char * str)1350f32531aSHans Petter Selasky skip_spaces(const char *str)
1360f32531aSHans Petter Selasky {
1370f32531aSHans Petter Selasky while (isspace(*str))
1380f32531aSHans Petter Selasky ++str;
1390f32531aSHans Petter Selasky return (__DECONST(char *, str));
1400f32531aSHans Petter Selasky }
1410f32531aSHans Petter Selasky
1420f32531aSHans Petter Selasky static inline void *
memchr_inv(const void * start,int c,size_t length)1430f32531aSHans Petter Selasky memchr_inv(const void *start, int c, size_t length)
1440f32531aSHans Petter Selasky {
1450f32531aSHans Petter Selasky const u8 *ptr;
1460f32531aSHans Petter Selasky const u8 *end;
1470f32531aSHans Petter Selasky u8 ch;
1480f32531aSHans Petter Selasky
1490f32531aSHans Petter Selasky ch = c;
1500f32531aSHans Petter Selasky ptr = start;
1510f32531aSHans Petter Selasky end = ptr + length;
1520f32531aSHans Petter Selasky
1530f32531aSHans Petter Selasky while (ptr != end) {
1540f32531aSHans Petter Selasky if (*ptr != ch)
1550f32531aSHans Petter Selasky return (__DECONST(void *, ptr));
1560f32531aSHans Petter Selasky ptr++;
1570f32531aSHans Petter Selasky }
1580f32531aSHans Petter Selasky return (NULL);
1590f32531aSHans Petter Selasky }
1600f32531aSHans Petter Selasky
1611a7ba9a0SEmmanuel Vadot static inline size_t
str_has_prefix(const char * str,const char * prefix)1621a7ba9a0SEmmanuel Vadot str_has_prefix(const char *str, const char *prefix)
1631a7ba9a0SEmmanuel Vadot {
1641a7ba9a0SEmmanuel Vadot size_t len;
1651a7ba9a0SEmmanuel Vadot
1661a7ba9a0SEmmanuel Vadot len = strlen(prefix);
1671a7ba9a0SEmmanuel Vadot return (strncmp(str, prefix, len) == 0 ? len : 0);
1681a7ba9a0SEmmanuel Vadot }
1691a7ba9a0SEmmanuel Vadot
1709d2d8a27SBjoern A. Zeeb static inline char *
strreplace(char * str,char old,char new)1719d2d8a27SBjoern A. Zeeb strreplace(char *str, char old, char new)
1729d2d8a27SBjoern A. Zeeb {
1739d2d8a27SBjoern A. Zeeb char *p;
1749d2d8a27SBjoern A. Zeeb
1759d2d8a27SBjoern A. Zeeb p = strchrnul(str, old);
1769d2d8a27SBjoern A. Zeeb while (p != NULL && *p != '\0') {
1779d2d8a27SBjoern A. Zeeb *p = new;
1789d2d8a27SBjoern A. Zeeb p = strchrnul(str, old);
1799d2d8a27SBjoern A. Zeeb }
1809d2d8a27SBjoern A. Zeeb return (p);
1819d2d8a27SBjoern A. Zeeb }
1829d2d8a27SBjoern A. Zeeb
18322310af0SVladimir Kondratyev static inline ssize_t
strscpy(char * dst,const char * src,size_t len)18422310af0SVladimir Kondratyev strscpy(char* dst, const char* src, size_t len)
18522310af0SVladimir Kondratyev {
18622310af0SVladimir Kondratyev size_t i;
18722310af0SVladimir Kondratyev
18822310af0SVladimir Kondratyev if (len <= INT_MAX) {
18922310af0SVladimir Kondratyev for (i = 0; i < len; i++)
19022310af0SVladimir Kondratyev if ('\0' == (dst[i] = src[i]))
19122310af0SVladimir Kondratyev return ((ssize_t)i);
19222310af0SVladimir Kondratyev if (i != 0)
19322310af0SVladimir Kondratyev dst[--i] = '\0';
19422310af0SVladimir Kondratyev }
19522310af0SVladimir Kondratyev
19622310af0SVladimir Kondratyev return (-E2BIG);
19722310af0SVladimir Kondratyev }
19822310af0SVladimir Kondratyev
199*2d0694b9SVladimir Kondratyev #endif /* _LINUXKPI_LINUX_STRING_H_ */
200