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 */
318d59ecb2SHans Petter Selasky #ifndef _LINUX_STRING_H_
328d59ecb2SHans Petter Selasky #define _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)74*10ee3d30SHans Petter Selasky memdup_user_nul(const void *ptr, size_t len)
75*10ee3d30SHans Petter Selasky {
76*10ee3d30SHans Petter Selasky char *retval;
77*10ee3d30SHans Petter Selasky int error;
78*10ee3d30SHans Petter Selasky
79*10ee3d30SHans Petter Selasky retval = malloc(len + 1, M_KMALLOC, M_WAITOK);
80*10ee3d30SHans Petter Selasky error = linux_copyin(ptr, retval, len);
81*10ee3d30SHans Petter Selasky if (error != 0) {
82*10ee3d30SHans Petter Selasky free(retval, M_KMALLOC);
83*10ee3d30SHans Petter Selasky return (ERR_PTR(error));
84*10ee3d30SHans Petter Selasky }
85*10ee3d30SHans Petter Selasky retval[len] = '\0';
86*10ee3d30SHans Petter Selasky return (retval);
87*10ee3d30SHans Petter Selasky }
88*10ee3d30SHans Petter Selasky
89*10ee3d30SHans 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
1060f32531aSHans Petter Selasky len = strlen(string) + 1;
1070f32531aSHans Petter Selasky retval = kmalloc(len, gfp);
1080f32531aSHans Petter Selasky if (retval != NULL)
1090f32531aSHans Petter Selasky memcpy(retval, string, len);
1100f32531aSHans Petter Selasky return (retval);
1110f32531aSHans Petter Selasky }
1120f32531aSHans Petter Selasky
1130f32531aSHans Petter Selasky static inline char *
kstrndup(const char * string,size_t len,gfp_t gfp)1140f32531aSHans Petter Selasky kstrndup(const char *string, size_t len, gfp_t gfp)
1150f32531aSHans Petter Selasky {
1160f32531aSHans Petter Selasky char *retval;
1170f32531aSHans Petter Selasky
1180f32531aSHans Petter Selasky retval = kmalloc(len + 1, gfp);
1190f32531aSHans Petter Selasky if (retval != NULL)
1200f32531aSHans Petter Selasky strncpy(retval, string, len);
1210f32531aSHans Petter Selasky return (retval);
1220f32531aSHans Petter Selasky }
1230f32531aSHans Petter Selasky
124510ebed7SHans Petter Selasky static inline const char *
kstrdup_const(const char * src,gfp_t gfp)125510ebed7SHans Petter Selasky kstrdup_const(const char *src, gfp_t gfp)
126510ebed7SHans Petter Selasky {
127510ebed7SHans Petter Selasky return (kmemdup(src, strlen(src) + 1, gfp));
128510ebed7SHans Petter Selasky }
129510ebed7SHans Petter Selasky
1300f32531aSHans Petter Selasky static inline char *
skip_spaces(const char * str)1310f32531aSHans Petter Selasky skip_spaces(const char *str)
1320f32531aSHans Petter Selasky {
1330f32531aSHans Petter Selasky while (isspace(*str))
1340f32531aSHans Petter Selasky ++str;
1350f32531aSHans Petter Selasky return (__DECONST(char *, str));
1360f32531aSHans Petter Selasky }
1370f32531aSHans Petter Selasky
1380f32531aSHans Petter Selasky static inline void *
memchr_inv(const void * start,int c,size_t length)1390f32531aSHans Petter Selasky memchr_inv(const void *start, int c, size_t length)
1400f32531aSHans Petter Selasky {
1410f32531aSHans Petter Selasky const u8 *ptr;
1420f32531aSHans Petter Selasky const u8 *end;
1430f32531aSHans Petter Selasky u8 ch;
1440f32531aSHans Petter Selasky
1450f32531aSHans Petter Selasky ch = c;
1460f32531aSHans Petter Selasky ptr = start;
1470f32531aSHans Petter Selasky end = ptr + length;
1480f32531aSHans Petter Selasky
1490f32531aSHans Petter Selasky while (ptr != end) {
1500f32531aSHans Petter Selasky if (*ptr != ch)
1510f32531aSHans Petter Selasky return (__DECONST(void *, ptr));
1520f32531aSHans Petter Selasky ptr++;
1530f32531aSHans Petter Selasky }
1540f32531aSHans Petter Selasky return (NULL);
1550f32531aSHans Petter Selasky }
1560f32531aSHans Petter Selasky
1578d59ecb2SHans Petter Selasky #endif /* _LINUX_STRING_H_ */
158