]> git.saurik.com Git - apple/xnu.git/blame - osfmk/device/subrs.c
xnu-1699.22.81.tar.gz
[apple/xnu.git] / osfmk / device / subrs.c
CommitLineData
1c79356b 1/*
2d21ac55 2 * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved.
1c79356b 3 *
2d21ac55 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
1c79356b 5 *
2d21ac55
A
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
8f6c56a5 14 *
2d21ac55
A
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
8f6c56a5
A
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
2d21ac55
A
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
8f6c56a5 25 *
2d21ac55 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
1c79356b
A
27 */
28/*
29 * @OSF_COPYRIGHT@
30 */
31/*
32 *(C)UNIX System Laboratories, Inc. all or some portions of this file are
33 *derived from material licensed to the University of California by
34 *American Telephone and Telegraph Co. or UNIX System Laboratories,
35 *Inc. and are reproduced herein with the permission of UNIX System
36 *Laboratories, Inc.
37 */
38
39/*
40 * Mach Operating System
41 * Copyright (c) 1993,1991,1990,1989,1988 Carnegie Mellon University
42 * All Rights Reserved.
43 *
44 * Permission to use, copy, modify and distribute this software and its
45 * documentation is hereby granted, provided that both the copyright
46 * notice and this permission notice appear in all copies of the
47 * software, derivative works or modified versions, and any portions
48 * thereof, and that both notices appear in supporting documentation.
49 *
50 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
51 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
52 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
53 *
54 * Carnegie Mellon requests users of this software to return to
55 *
56 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
57 * School of Computer Science
58 * Carnegie Mellon University
59 * Pittsburgh PA 15213-3890
60 *
61 * any improvements or extensions that they make and grant Carnegie Mellon
62 * the rights to redistribute these changes.
63 */
64/*
65 */
66/*
67 * Copyright (c) 1988 Regents of the University of California.
68 * All rights reserved.
69 *
70 * Redistribution and use in source and binary forms, with or without
71 * modification, are permitted provided that the following conditions
72 * are met:
73 * 1. Redistributions of source code must retain the above copyright
74 * notice, this list of conditions and the following disclaimer.
75 * 2. Redistributions in binary form must reproduce the above copyright
76 * notice, this list of conditions and the following disclaimer in the
77 * documentation and/or other materials provided with the distribution.
78 * 3. All advertising materials mentioning features or use of this software
79 * must display the following acknowledgement:
80 * This product includes software developed by the University of
81 * California, Berkeley and its contributors.
82 * 4. Neither the name of the University nor the names of its contributors
83 * may be used to endorse or promote products derived from this software
84 * without specific prior written permission.
85 *
86 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
87 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
88 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
89 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
90 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
91 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
92 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
93 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
94 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
95 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
96 * SUCH DAMAGE.
97 */
2d21ac55
A
98
99/*
100 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
101 * All rights reserved.
102 *
103 * Redistribution and use in source and binary forms, with or without
104 * modification, are permitted provided that the following conditions
105 * are met:
106 * 1. Redistributions of source code must retain the above copyright
107 * notice, this list of conditions and the following disclaimer.
108 * 2. Redistributions in binary form must reproduce the above copyright
109 * notice, this list of conditions and the following disclaimer in the
110 * documentation and/or other materials provided with the distribution.
111 * 3. The name of the author may not be used to endorse or promote products
112 * derived from this software without specific prior written permission.
113 *
114 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
115 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
116 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
117 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
118 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
119 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
120 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
121 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
122 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
123 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
124 */
125
126/*
127 * NOTICE: This file was modified by McAfee Research in 2004 to introduce
128 * support for mandatory and extensible security protections. This notice
129 * is included in support of clause 2.2 (b) of the Apple Public License,
130 * Version 2.0.
131 */
1c79356b
A
132/*
133 * Random device subroutines and stubs.
134 */
135
136#include <vm/vm_kern.h>
137#include <kern/misc_protos.h>
2d21ac55
A
138#include <libsa/stdlib.h>
139#include <sys/malloc.h>
1c79356b
A
140
141/* String routines, from CMU */
142#ifdef strcpy
143#undef strcmp
144#undef strncmp
145#undef strcpy
146#undef strncpy
147#undef strlen
148#endif
149
150/*
151 * Abstract:
152 * strcmp (s1, s2) compares the strings "s1" and "s2".
153 * It returns 0 if the strings are identical. It returns
154 * > 0 if the first character that differs in the two strings
155 * is larger in s1 than in s2 or if s1 is longer than s2 and
156 * the contents are identical up to the length of s2.
157 * It returns < 0 if the first differing character is smaller
158 * in s1 than in s2 or if s1 is shorter than s2 and the
159 * contents are identical upto the length of s1.
2d21ac55
A
160 * Deprecation Warning:
161 * strcmp() is being deprecated. Please use strncmp() instead.
1c79356b
A
162 */
163
164int
165strcmp(
2d21ac55
A
166 const char *s1,
167 const char *s2)
1c79356b 168{
2d21ac55 169 unsigned int a, b;
1c79356b
A
170
171 do {
172 a = *s1++;
173 b = *s2++;
174 if (a != b)
175 return a-b; /* includes case when
176 'a' is zero and 'b' is not zero
177 or vice versa */
178 } while (a != '\0');
179
180 return 0; /* both are zero */
181}
182
183/*
184 * Abstract:
185 * strncmp (s1, s2, n) compares the strings "s1" and "s2"
186 * in exactly the same way as strcmp does. Except the
187 * comparison runs for at most "n" characters.
188 */
189
190int
191strncmp(
2d21ac55
A
192 const char *s1,
193 const char *s2,
1c79356b
A
194 size_t n)
195{
2d21ac55 196 unsigned int a, b;
1c79356b
A
197
198 while (n != 0) {
199 a = *s1++;
200 b = *s2++;
201 if (a != b)
202 return a-b; /* includes case when
203 'a' is zero and 'b' is not zero
204 or vice versa */
205 if (a == '\0')
206 return 0; /* both are zero */
207 n--;
208 }
209
210 return 0;
211}
212
91447636
A
213
214//
215// Lame implementation just for use by strcasecmp/strncasecmp
216//
217static int
218tolower(unsigned char ch)
219{
220 if (ch >= 'A' && ch <= 'Z')
221 ch = 'a' + (ch - 'A');
222
223 return ch;
224}
225
226int
227strcasecmp(const char *s1, const char *s2)
228{
229 const unsigned char *us1 = (const u_char *)s1,
230 *us2 = (const u_char *)s2;
231
232 while (tolower(*us1) == tolower(*us2++))
233 if (*us1++ == '\0')
234 return (0);
235 return (tolower(*us1) - tolower(*--us2));
236}
237
238int
239strncasecmp(const char *s1, const char *s2, size_t n)
240{
241 if (n != 0) {
242 const unsigned char *us1 = (const u_char *)s1,
243 *us2 = (const u_char *)s2;
244
245 do {
246 if (tolower(*us1) != tolower(*us2++))
247 return (tolower(*us1) - tolower(*--us2));
248 if (*us1++ == '\0')
249 break;
250 } while (--n != 0);
251 }
252 return (0);
253}
254
255
1c79356b
A
256/*
257 * Abstract:
258 * strcpy copies the contents of the string "from" including
259 * the null terminator to the string "to". A pointer to "to"
260 * is returned.
2d21ac55
A
261 * Deprecation Warning:
262 * strcpy() is being deprecated. Please use strlcpy() instead.
1c79356b 263 */
6d2010ae 264#if !CONFIG_EMBEDDED
1c79356b
A
265char *
266strcpy(
2d21ac55
A
267 char *to,
268 const char *from)
1c79356b 269{
2d21ac55 270 char *ret = to;
1c79356b
A
271
272 while ((*to++ = *from++) != '\0')
273 continue;
274
275 return ret;
276}
6d2010ae 277#endif
1c79356b
A
278
279/*
280 * Abstract:
281 * strncpy copies "count" characters from the "from" string to
282 * the "to" string. If "from" contains less than "count" characters
283 * "to" will be padded with null characters until exactly "count"
284 * characters have been written. The return value is a pointer
285 * to the "to" string.
286 */
287
288char *
289strncpy(
290 char *s1,
291 const char *s2,
292 size_t n)
293{
294 char *os1 = s1;
295 unsigned long i;
296
297 for (i = 0; i < n;)
298 if ((*s1++ = *s2++) == '\0')
299 for (i++; i < n; i++)
300 *s1++ = '\0';
301 else
302 i++;
303 return (os1);
304}
305
1c79356b
A
306/*
307 * atoi:
308 *
309 * This function converts an ascii string into an integer.
310 *
311 * input : string
312 * output : a number
313 */
314
315int
2d21ac55 316atoi(const char *cp)
1c79356b
A
317{
318 int number;
319
320 for (number = 0; ('0' <= *cp) && (*cp <= '9'); cp++)
321 number = (number * 10) + (*cp - '0');
322
323 return( number );
324}
325
326/*
327 * convert an ASCII string (decimal radix) to an integer
328 * inputs:
329 * p string pointer.
330 * t char **, return a pointer to the cahr which terminates the
331 * numeric string.
332 * returns:
333 * integer value of the numeric string.
334 * side effect:
335 * pointer to terminating char.
336 */
337
338int
339atoi_term(
340 char *p, /* IN */
341 char **t) /* OUT */
342{
2d21ac55
A
343 int n;
344 int f;
1c79356b
A
345
346 n = 0;
347 f = 0;
348 for(;;p++) {
349 switch(*p) {
350 case ' ':
351 case '\t':
352 continue;
353 case '-':
354 f++;
355 case '+':
356 p++;
357 }
358 break;
359 }
360 while(*p >= '0' && *p <= '9')
361 n = n*10 + *p++ - '0';
362
363 /* return pointer to terminating character */
364 if ( t )
365 *t = p;
366
367 return(f? -n: n);
368}
369
6601e61a
A
370/*
371 * Does the same thing as strlen, except only looks up
372 * to max chars inside the buffer.
373 * Taken from archive/kern-stuff/sbf_machine.c in
374 * seatbelt.
375 * inputs:
2d21ac55
A
376 * s string whose length is to be measured
377 * max maximum length of string to search for null
6601e61a 378 * outputs:
2d21ac55 379 * length of s or max; whichever is smaller
6601e61a
A
380 */
381size_t
382strnlen(const char *s, size_t max) {
383 const char *es = s + max, *p = s;
384 while(*p && p != es)
385 p++;
386
387 return p - s;
388}
389
1c79356b
A
390/*
391 * convert an integer to an ASCII string.
392 * inputs:
393 * num integer to be converted
394 * str string pointer.
395 *
396 * outputs:
397 * pointer to string start.
398 */
399
400char *
401itoa(
402 int num,
403 char *str)
404{
405 char digits[11];
2d21ac55
A
406 char *dp;
407 char *cp = str;
1c79356b
A
408
409 if (num == 0) {
410 *cp++ = '0';
411 }
412 else {
413 dp = digits;
414 while (num) {
415 *dp++ = '0' + num % 10;
416 num /= 10;
417 }
418 while (dp != digits) {
419 *cp++ = *--dp;
420 }
421 }
422 *cp++ = '\0';
423
424 return str;
425}
426
2d21ac55
A
427/*
428 * Deprecation Warning:
429 * strcat() is being deprecated. Please use strlcat() instead.
430 */
6d2010ae 431#if !CONFIG_EMBEDDED
1c79356b
A
432char *
433strcat(
2d21ac55
A
434 char *dest,
435 const char *src)
1c79356b
A
436{
437 char *old = dest;
438
439 while (*dest)
440 ++dest;
2d21ac55 441 while ((*dest++ = *src++))
1c79356b
A
442 ;
443 return (old);
444}
6d2010ae 445#endif
1c79356b 446
2d21ac55
A
447/*
448 * Appends src to string dst of size siz (unlike strncat, siz is the
449 * full size of dst, not space left). At most siz-1 characters
450 * will be copied. Always NUL terminates (unless siz <= strlen(dst)).
451 * Returns strlen(src) + MIN(siz, strlen(initial dst)).
452 * If retval >= siz, truncation occurred.
453 */
454size_t
455strlcat(char *dst, const char *src, size_t siz)
456{
457 char *d = dst;
458 const char *s = src;
459 size_t n = siz;
460 size_t dlen;
461
462 /* Find the end of dst and adjust bytes left but don't go past end */
463 while (n-- != 0 && *d != '\0')
464 d++;
465 dlen = d - dst;
466 n = siz - dlen;
467
468 if (n == 0)
469 return(dlen + strlen(s));
470 while (*s != '\0') {
471 if (n != 1) {
472 *d++ = *s;
473 n--;
474 }
475 s++;
476 }
477 *d = '\0';
478
479 return(dlen + (s - src)); /* count does not include NUL */
480}
481
482/*
483 * Copy src to string dst of size siz. At most siz-1 characters
484 * will be copied. Always NUL terminates (unless siz == 0).
485 * Returns strlen(src); if retval >= siz, truncation occurred.
486 */
487size_t
488strlcpy(char *dst, const char *src, size_t siz)
489{
490 char *d = dst;
491 const char *s = src;
492 size_t n = siz;
493
494 /* Copy as many bytes as will fit */
495 if (n != 0 && --n != 0) {
496 do {
497 if ((*d++ = *s++) == 0)
498 break;
499 } while (--n != 0);
500 }
501
502 /* Not enough room in dst, add NUL and traverse rest of src */
503 if (n == 0) {
504 if (siz != 0)
505 *d = '\0'; /* NUL-terminate dst */
506 while (*s++)
507 ;
508 }
509
510 return(s - src - 1); /* count does not include NUL */
511}
512
513/*
514 * STRDUP
515 *
516 * Description: The STRDUP function allocates sufficient memory for a copy
517 * of the string "string", does the copy, and returns a pointer
518 * it. The pointer may subsequently be used as an argument to
519 * the macro FREE().
520 *
521 * Parameters: string String to be duplicated
522 * type type of memory to be allocated (normally
523 * M_TEMP)
524 *
525 * Returns: char * A pointer to the newly allocated string with
526 * duplicated contents in it.
527 *
528 * NULL If MALLOC() fails.
529 *
530 * Note: This function can *not* be called from interrupt context as
531 * it calls MALLOC with M_WAITOK. In fact, you really
532 * shouldn't be doing string manipulation in interrupt context
533 * ever.
534 *
535 * This function name violates the kernel style(9) guide
536 * by being all caps. This was done on purpose to emphasize
537 * one should use FREE() with the allocated buffer.
538 *
539 */
6d2010ae 540char *
2d21ac55
A
541STRDUP(const char *string, int type)
542{
543 size_t len;
544 char *copy;
545
546 len = strlen(string) + 1;
547 MALLOC(copy, char *, len, type, M_WAITOK);
548 if (copy == NULL)
549 return (NULL);
550 bcopy(string, copy, len);
551 return (copy);
552}
553
554/*
555 * Return TRUE(1) if string 2 is a prefix of string 1.
556 */
557int
558strprefix(register const char *s1, register const char *s2)
559{
560 register int c;
561
562 while ((c = *s2++) != '\0') {
563 if (c != *s1++)
564 return (0);
565 }
566 return (1);
567}
568